summaryrefslogtreecommitdiff
path: root/components/drivers
diff options
context:
space:
mode:
authorbernard <[email protected]>2017-09-29 10:23:56 +0800
committerbernard <[email protected]>2017-09-29 10:23:56 +0800
commitcccff34fcac04f34233a33e453f2d0ec255bf231 (patch)
treed406036f73296b27f3cb96e77ede98dd7803c61d /components/drivers
parente9a77b513f0a4b37d539a030592a61b08d03602d (diff)
parent3691b67e83ab57196dfc62606b1be18db76994a7 (diff)
Merge branch 'master' of https://github.com/RT-Thread/rt-thread
Diffstat (limited to 'components/drivers')
-rw-r--r--components/drivers/audio/audio.c954
-rw-r--r--components/drivers/can/can.c40
-rw-r--r--components/drivers/i2c/fm24clxx.c157
-rw-r--r--components/drivers/i2c/fm24clxx.h40
-rw-r--r--components/drivers/i2c/i2c_core.c2
-rw-r--r--components/drivers/include/drivers/audio.h257
-rw-r--r--components/drivers/include/drivers/can.h2
-rw-r--r--components/drivers/include/drivers/mmcsd_card.h2
-rw-r--r--components/drivers/include/drivers/mmcsd_host.h2
-rw-r--r--components/drivers/include/drivers/sdio.h2
-rw-r--r--components/drivers/include/drivers/watchdog.h2
-rw-r--r--components/drivers/sdio/mmcsd_core.c8
-rw-r--r--components/drivers/sdio/sdio.c34
-rw-r--r--components/drivers/spi/sfud/LICENSE2
-rw-r--r--components/drivers/spi/sfud/README.md27
-rw-r--r--components/drivers/spi/sfud/inc/sfud_def.h8
-rw-r--r--components/drivers/spi/sfud/inc/sfud_flash_def.h7
-rw-r--r--components/drivers/spi/sfud/src/sfud.c55
-rw-r--r--components/drivers/spi/sfud/src/sfud_sfdp.c2
-rw-r--r--components/drivers/spi/spi_flash_at45dbxx.c12
-rw-r--r--components/drivers/spi/spi_wifi_rw009.c3
21 files changed, 776 insertions, 842 deletions
diff --git a/components/drivers/audio/audio.c b/components/drivers/audio/audio.c
index 3476d06412..0b2f9a0cdd 100644
--- a/components/drivers/audio/audio.c
+++ b/components/drivers/audio/audio.c
@@ -1,8 +1,25 @@
/*
- * audio.c
+ * File : audio.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
*
- * Created on: 2016��10��19��
- * Author: Urey
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-05-09 Urey first version
*/
#include <stdio.h>
@@ -19,383 +36,70 @@
#define AUDIO_DBG(...)
#endif
-
-rt_err_t _audio_queue_init(struct rt_audio_queue *queue, rt_uint16_t size, rt_uint16_t lwm)
+static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio)
{
- RT_ASSERT(queue != RT_NULL);
-
- queue->count = 0;
- queue->size = size;
- queue->lwm = lwm;
- queue->waiting_lwm = RT_FALSE;
-
- queue->get_index = 0;
- queue->put_index = 0;
+ rt_err_t result = RT_EOK;
+ rt_base_t level;
+ struct rt_audio_frame frame;
- rt_list_init(&(queue->suspended_push_list));
- rt_list_init(&(queue->suspended_pop_list));
+ RT_ASSERT(audio != RT_NULL);
- queue->queue = (struct rt_audio_frame *)rt_malloc(sizeof(struct rt_audio_frame) * size);
- if (queue->queue == RT_NULL)
+ //check repaly queue is empty
+ if (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) != RT_EOK)
{
- return -RT_ENOMEM;
- }
-
- return RT_EOK;
-}
-
-rt_err_t _audio_queue_push(struct rt_audio_queue *queue, struct rt_audio_frame *frame, rt_int32_t timeout)
-{
- rt_ubase_t level;
- rt_thread_t thread;
- rt_err_t result;
-
- RT_ASSERT(queue != RT_NULL);
-
- result = RT_EOK;
- thread = rt_thread_self();
-
- AUDIO_DBG("%s count = %d\n",__func__,queue->count);
-
- level = rt_hw_interrupt_disable();
- while(queue->count == queue->size)
- {// audio queue is full
- queue->waiting_lwm = RT_TRUE;
-
- /* queue is full */
- if (timeout == 0)
- {
- result = -RT_ETIMEOUT;
- goto __exit;
- }
+ AUDIO_DBG("TX queue is empty\n");
+ result = -RT_EEMPTY;
- /* current context checking */
- RT_DEBUG_NOT_IN_INTERRUPT;
-
- /* reset thread error number */
- thread->error = RT_EOK;
-
- /* suspend thread on the push list */
- rt_thread_suspend(thread);
- rt_list_insert_before(&(queue->suspended_push_list), &(thread->tlist));
- /* start timer */
- if (timeout > 0)
- {
- /* reset the timeout of thread timer and start it */
- rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout);
- rt_timer_start(&(thread->thread_timer));
- }
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
-
- /* do schedule */
- rt_schedule();
-
- /* thread is waked up */
- result = thread->error;
level = rt_hw_interrupt_disable();
- if (result != RT_EOK) goto __exit;
- }
-
- queue->queue[queue->put_index].data_ptr = frame->data_ptr;
- queue->queue[queue->put_index].data_size = frame->data_size;
- queue->queue[queue->put_index].data_ofs = frame->data_ofs;
- queue->put_index = (queue->put_index + 1) % queue->size;
- queue->count ++;
-
- if (!rt_list_isempty(&(queue->suspended_pop_list)))
- {
- /* there is at least one thread in suspended list */
-
- /* get thread entry */
- thread = rt_list_entry(queue->suspended_pop_list.next,
- struct rt_thread,
- tlist);
-
- /* resume it */
- rt_thread_resume(thread);
+ audio->replay->activated = RT_FALSE;
rt_hw_interrupt_enable(level);
- /* perform a schedule */
- rt_schedule();
-
- return result;
+ goto _exit;
}
-__exit:
- rt_hw_interrupt_enable(level);
-
- return result;
-}
-
-rt_err_t _audio_queue_pop(struct rt_audio_queue *queue, struct rt_audio_frame *frame, rt_int32_t timeout)
-{
- rt_ubase_t level;
- rt_thread_t thread;
- rt_err_t result;
-
- RT_ASSERT(queue != RT_NULL);
- RT_ASSERT(frame != RT_NULL);
-
- result = RT_EOK;
- thread = rt_thread_self();
-
- AUDIO_DBG("%s count = %d\n",__func__,queue->count);
- level = rt_hw_interrupt_disable();
- while (queue->count == 0)
- {
- /* queue is empty */
- if (timeout == 0)
- {
- result = -RT_ETIMEOUT;
- goto __exit;
- }
-
- /* current context checking */
- RT_DEBUG_NOT_IN_INTERRUPT;
-
- /* reset thread error number */
- thread->error = RT_EOK;
-
- /* suspend thread on the pop list */
- rt_thread_suspend(thread);
- rt_list_insert_before(&(queue->suspended_pop_list), &(thread->tlist));
- /* start timer */
- if (timeout > 0)
- {
- /* reset the timeout of thread timer and start it */
- rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout);
- rt_timer_start(&(thread->thread_timer));
- }
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
-
- /* do schedule */
- rt_schedule();
-
- /* thread is waked up */
- result = thread->error;
- level = rt_hw_interrupt_disable();
- if (result != RT_EOK)
- goto __exit;
- }
-
- frame->data_ptr = queue->queue[queue->get_index].data_ptr;
- frame->data_size = queue->queue[queue->get_index].data_size;
- frame->data_ofs = queue->queue[queue->get_index].data_ofs;
-
- queue->get_index = (queue->get_index + 1) % queue->size;
- queue->count --;
-
- if ((queue->waiting_lwm == RT_TRUE) &&
- (queue->put_index - queue->get_index) <= queue->lwm)
+ if (audio->ops->transmit != RT_NULL)
{
- queue->waiting_lwm = RT_FALSE;
-
- /*
- * there is at least one thread in suspended list
- * and less than low water mark
- */
- if (!rt_list_isempty(&(queue->suspended_push_list)))
+ AUDIO_DBG("audio transmit...\n");
+ if (audio->ops->transmit(audio, frame.data_ptr, RT_NULL, frame.data_size) != frame.data_size)
{
- /* get thread entry */
- thread = rt_list_entry(queue->suspended_push_list.next,
- struct rt_thread,
- tlist);
-
- /* resume it */
- rt_thread_resume(thread);
- rt_hw_interrupt_enable(level);
+ result = -RT_EBUSY;
- /* perform a schedule */
- rt_schedule();
+ goto _exit;
}
-
- return result;
- }
-__exit:
- rt_hw_interrupt_enable(level);
- return result;
-}
-
-rt_err_t _audio_queue_peak(struct rt_audio_queue *queue, struct rt_audio_frame *frame)
-{
- rt_ubase_t level;
-
- RT_ASSERT(queue != RT_NULL);
-
- AUDIO_DBG("%s count = %d\n",__func__,queue->count);
-
- level = rt_hw_interrupt_disable();
- if (queue->count == 0)
- {
- rt_hw_interrupt_enable(level);
-
- return -RT_EEMPTY;
}
- frame->data_ptr = queue->queue[queue->get_index].data_ptr;
- frame->data_size = queue->queue[queue->get_index].data_size;
- frame->data_ofs = queue->queue[queue->get_index].data_ofs;
-
- rt_hw_interrupt_enable(level);
+ //pop the head frame...
+ rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER);
- return RT_EOK;
+ _exit: return result;
}
-rt_err_t _audio_queue_unpeak(struct rt_audio_queue *queue, struct rt_audio_frame *frame)
+static rt_err_t _audio_flush_replay_frame(struct rt_audio_device *audio)
{
- rt_ubase_t level;
-
- RT_ASSERT(queue != RT_NULL);
+ struct rt_audio_frame frame;
- level = rt_hw_interrupt_disable();
-
- if (queue->count == 0)
+ if (audio->replay == RT_NULL)
+ return -RT_EIO;
+ while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK)
{
- rt_hw_interrupt_enable(level);
+ //pop the head frame...
+ rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER);
- return -RT_EEMPTY;
+ /* notify transmitted complete. */
+ if (audio->parent.tx_complete != RT_NULL)
+ audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr);
}
- queue->queue[queue->get_index].data_ptr = frame->data_ptr;
- queue->queue[queue->get_index].data_size = frame->data_size;
- queue->queue[queue->get_index].data_ofs = frame->data_ofs;
-
- rt_hw_interrupt_enable(level);
-
return RT_EOK;
}
-rt_err_t _audio_queue_reset(struct rt_audio_queue *queue)
-{
- struct rt_thread *thread;
- register rt_ubase_t temp;
-
- rt_enter_critical();
-
- /* wakeup all suspend threads */
- /* resume on pop list */
- while (!rt_list_isempty(&(queue->suspended_pop_list)))
- {
- /* disable interrupt */
- temp = rt_hw_interrupt_disable();
-
- /* get next suspend thread */
- thread = rt_list_entry(queue->suspended_pop_list.next,
- struct rt_thread,
- tlist);
- /* set error code to RT_ERROR */
- thread->error = -RT_ERROR;
-
- /*
- * resume thread
- * In rt_thread_resume function, it will remove current thread from
- * suspend list
- */
- rt_thread_resume(thread);
-
- /* enable interrupt */
- rt_hw_interrupt_enable(temp);
- }
-
- /* resume on push list */
- while (!rt_list_isempty(&(queue->suspended_push_list)))
- {
- /* disable interrupt */
- temp = rt_hw_interrupt_disable();
-
- /* get next suspend thread */
- thread = rt_list_entry(queue->suspended_push_list.next,
- struct rt_thread,
- tlist);
- /* set error code to RT_ERROR */
- thread->error = -RT_ERROR;
-
- /*
- * resume thread
- * In rt_thread_resume function, it will remove current thread from
- * suspend list
- */
- rt_thread_resume(thread);
-
- /* enable interrupt */
- rt_hw_interrupt_enable(temp);
- }
- rt_exit_critical();
-
- rt_schedule();
-}
-
-
-static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio)
-{
- rt_err_t result = RT_EOK;
- rt_base_t level;
- struct rt_audio_frame frame;
-
- RT_ASSERT(audio != RT_NULL);
-
- //check repaly queue is empty
- if(_audio_queue_peak(&audio->replay->queue,&frame) != RT_EOK)
- {
- AUDIO_DBG("TX queue is empty\n");
- result = -RT_EEMPTY;
-
- level = rt_hw_interrupt_disable();
- audio->replay->activated = RT_FALSE;
- rt_hw_interrupt_enable(level);
-
- goto _exit;
- }
-
- if(audio->ops->transmit != RT_NULL)
- {
- AUDIO_DBG("audio transmit...\n");
- if(audio->ops->transmit(audio,frame.data_ptr,RT_NULL, frame.data_size) != frame.data_size)
- {
- result = -RT_EBUSY;
-
- goto _exit;
- }
- }
-
- //pop the head frame...
- _audio_queue_pop(&audio->replay->queue,&frame,RT_WAITING_NO);
-
-_exit:
- return result;
-}
-
-static rt_err_t _audio_flush_replay_frame(struct rt_audio_device *audio)
-{
- struct rt_audio_frame frame;
-
- if(audio->replay == RT_NULL)
- return -RT_EIO;
-
- while(_audio_queue_peak(&audio->replay->queue,&frame) == RT_EOK)
- {
- //pop the head frame...
- _audio_queue_pop(&audio->replay->queue,&frame,RT_WAITING_NO);
-
- /* notify transmitted complete. */
- if(audio->parent.tx_complete != RT_NULL)
- audio->parent.tx_complete(&audio->parent,(void *)frame.data_ptr);
- }
-
- return RT_EOK;
-}
-
static rt_err_t _audio_dev_init(struct rt_device *dev)
{
rt_err_t result = RT_EOK;
struct rt_audio_device *audio;
RT_ASSERT(dev != RT_NULL);
- audio = (struct rt_audio_device *)dev;
+ audio = (struct rt_audio_device *) dev;
/* initialize replay & record */
audio->replay = RT_NULL;
@@ -410,12 +114,12 @@ static rt_err_t _audio_dev_init(struct rt_device *dev)
static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag)
{
- rt_err_t result = RT_EOK;
- rt_base_t level;
- struct rt_audio_device *audio;
+ rt_err_t result = RT_EOK;
+ rt_base_t level;
+ struct rt_audio_device *audio;
RT_ASSERT(dev != RT_NULL);
- audio = (struct rt_audio_device *)dev;
+ audio = (struct rt_audio_device *) dev;
/* check device flag with the open flag */
if ((oflag & RT_DEVICE_OFLAG_RDONLY) && !(dev->flag & RT_DEVICE_FLAG_RDONLY))
@@ -429,64 +133,65 @@ static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag)
/* initialize the Rx/Tx structure according to open flag */
if (oflag & RT_DEVICE_OFLAG_WRONLY)
{
- AUDIO_DBG("open audio device ,oflag = %x\n",oflag);
- if(audio->replay == RT_NULL)
- {
- struct rt_audio_replay *replay = (struct rt_audio_replay *)rt_malloc(sizeof(struct rt_audio_replay));
+ AUDIO_DBG("open audio device ,oflag = %x\n",oflag);
+ if (audio->replay == RT_NULL)
+ {
+ struct rt_audio_replay *replay = (struct rt_audio_replay *) rt_malloc(sizeof(struct rt_audio_replay));
- if(replay == RT_NULL)
- {
- AUDIO_DBG("request memory for replay error\n");
- return -RT_ENOMEM;
- }
+ if (replay == RT_NULL)
+ {
+ AUDIO_DBG("request memory for replay error\n");
+ return -RT_ENOMEM;
+ }
- //init queue for audio replay
- _audio_queue_init(&replay->queue,CFG_AUDIO_REPLAY_QUEUE_COUNT,CFG_AUDIO_REPLAY_QUEUE_COUNT / 2);
+ //init queue for audio replay
+ rt_data_queue_init(&replay->queue, CFG_AUDIO_REPLAY_QUEUE_COUNT, CFG_AUDIO_REPLAY_QUEUE_COUNT / 2, RT_NULL);
- replay->activated = RT_FALSE;
- audio->replay = replay;
- }
+ replay->activated = RT_FALSE;
+ audio->replay = replay;
+ }
dev->open_flag |= RT_DEVICE_OFLAG_WRONLY;
}
- if(oflag & RT_DEVICE_OFLAG_RDONLY)
+ if (oflag & RT_DEVICE_OFLAG_RDONLY)
{
- if(audio->record == RT_NULL)
- {
- struct rt_audio_record *record = (struct rt_audio_record *)rt_malloc(sizeof(struct rt_audio_record));
+ if (audio->record == RT_NULL)
+ {
+ struct rt_audio_record *record = (struct rt_audio_record *) rt_malloc(sizeof(struct rt_audio_record));
- if(record == RT_NULL)
- {
- AUDIO_DBG("request memory for record error\n");
- return -RT_ENOMEM;
- }
+ if (record == RT_NULL)
+ {
+ AUDIO_DBG("request memory for record error\n");
+ return -RT_ENOMEM;
+ }
- //init pipe for record
- {
- rt_size_t size = CFG_AUDIO_RECORD_PIPE_SIZE;
- rt_uint8_t *buf = rt_malloc(CFG_AUDIO_RECORD_PIPE_SIZE);
+ //init pipe for record
+ {
+ rt_size_t size = CFG_AUDIO_RECORD_PIPE_SIZE;
+ rt_uint8_t *buf = rt_malloc(CFG_AUDIO_RECORD_PIPE_SIZE);
- if(buf == RT_NULL)
- {
- rt_free(record);
- AUDIO_DBG("request pipe memory error\n");
+ if (buf == RT_NULL)
+ {
+ rt_free(record);
+ AUDIO_DBG("request pipe memory error\n");
- return -RT_ENOMEM;
- }
+ return -RT_ENOMEM;
+ }
- rt_pipe_init(&record->pipe,"recpipe",RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD,buf,CFG_AUDIO_RECORD_PIPE_SIZE);
- }
+ rt_pipe_init(&record->pipe, "recpipe", RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD, buf,
+ CFG_AUDIO_RECORD_PIPE_SIZE);
+ }
- record->activated = RT_FALSE;
- audio->record = record;
- }
+ record->activated = RT_FALSE;
+ audio->record = record;
+ }
- //open record pipe
- if(audio->record != RT_NULL)
- {
- rt_device_open(RT_DEVICE(&audio->record->pipe),RT_DEVICE_OFLAG_RDONLY);
- }
+ //open record pipe
+ if (audio->record != RT_NULL)
+ {
+ rt_device_open(RT_DEVICE(&audio->record->pipe), RT_DEVICE_OFLAG_RDONLY);
+ }
dev->open_flag |= RT_DEVICE_OFLAG_RDONLY;
}
@@ -496,96 +201,93 @@ static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag)
static rt_err_t _audio_dev_close(struct rt_device *dev)
{
- struct rt_audio_device *audio;
+ struct rt_audio_device *audio;
RT_ASSERT(dev != RT_NULL);
- audio = (struct rt_audio_device *)dev;
+ audio = (struct rt_audio_device *) dev;
- //shutdown the lower device
- if(audio->ops->shutdown != RT_NULL)
- audio->ops->shutdown(audio);
+ //shutdown the lower device
+ if (audio->ops->shutdown != RT_NULL)
+ audio->ops->shutdown(audio);
- if(dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
+ if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
{
- struct rt_audio_frame frame;
- //stop replay stream
- audio->ops->stop(audio,AUDIO_STREAM_REPLAY);
+ struct rt_audio_frame frame;
+ //stop replay stream
+ audio->ops->stop(audio, AUDIO_STREAM_REPLAY);
- //flush all frame
- while(_audio_queue_peak(&audio->replay->queue,&frame) == RT_EOK)
- {
- _audio_queue_pop(&audio->replay->queue,&frame,RT_WAITING_NO);
+ //flush all frame
+ while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK)
+ {
+ //pop the head frame...
+ rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER);
- //indicate this frame complete(maybe upper device need free data)
- if(dev->tx_complete != RT_NULL)
- dev->tx_complete(dev,(void *)frame.data_ptr);
- }
+ /* notify transmitted complete. */
+ if (audio->parent.tx_complete != RT_NULL)
+ audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr);
+ }
- dev->open_flag &= ~RT_DEVICE_OFLAG_WRONLY;
+ dev->open_flag &= ~RT_DEVICE_OFLAG_WRONLY;
}
- if(dev->open_flag & RT_DEVICE_OFLAG_RDONLY)
+ if (dev->open_flag & RT_DEVICE_OFLAG_RDONLY)
{
- //stop record stream
- audio->ops->stop(audio,AUDIO_STREAM_RECORD);
+ //stop record stream
+ audio->ops->stop(audio, AUDIO_STREAM_RECORD);
- //close record pipe
- if(audio->record != RT_NULL)
- rt_device_close(RT_DEVICE(&audio->record->pipe));
+ //close record pipe
+ if (audio->record != RT_NULL)
+ rt_device_close(RT_DEVICE(&audio->record->pipe));
- dev->open_flag &= ~RT_DEVICE_OFLAG_RDONLY;
+ dev->open_flag &= ~RT_DEVICE_OFLAG_RDONLY;
}
- return RT_EOK;
+ return RT_EOK;
}
static rt_size_t _audio_dev_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size)
{
- struct rt_audio_device *audio;
+ struct rt_audio_device *audio;
RT_ASSERT(dev != RT_NULL);
- audio = (struct rt_audio_device *)dev;
- if(!(dev->open_flag & RT_DEVICE_OFLAG_RDONLY) || (audio->record == RT_NULL))
- return 0;
+ audio = (struct rt_audio_device *) dev;
+ if (!(dev->open_flag & RT_DEVICE_OFLAG_RDONLY) || (audio->record == RT_NULL))
+ return 0;
return rt_device_read(RT_DEVICE(&audio->record->pipe), pos, buffer, size);
}
static rt_size_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
- rt_err_t result = RT_EOK;
- rt_base_t level;
- struct rt_audio_device *audio;
+ rt_err_t result = RT_EOK;
+ rt_base_t level;
+ struct rt_audio_device *audio;
RT_ASSERT(dev != RT_NULL);
- audio = (struct rt_audio_device *)dev;
+ audio = (struct rt_audio_device *) dev;
- if(!(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) || (audio->replay == RT_NULL))
- return 0;
+ if (!(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) || (audio->replay == RT_NULL))
+ return 0;
AUDIO_DBG("audio write : pos = %d,buffer = %x,size = %d\n",pos,(rt_uint32_t)buffer,size);
//push a new frame to tx queue
{
- struct rt_audio_frame frame;
- frame.data_ptr = buffer;
- frame.data_size = size;
- frame.data_ofs = 0;
-
- result = _audio_queue_push(&audio->replay->queue,&frame,RT_WAITING_FOREVER);
- if(result != RT_EOK)
+ result = rt_data_queue_push(&audio->replay->queue, buffer, size,
+ RT_WAITING_FOREVER);
+ if (result != RT_EOK)
{
- AUDIO_DBG("TX frame queue push error\n");
- rt_set_errno(-RT_EFULL);
+ AUDIO_DBG("TX frame queue push error\n");
+ rt_set_errno(-RT_EFULL);
return 0;
}
}
//check tx state...
level = rt_hw_interrupt_disable();
- if(audio->replay->activated != RT_TRUE)
+ if (audio->replay->activated != RT_TRUE)
{
- audio->replay->activated = RT_TRUE;
- rt_hw_interrupt_enable(level);
+ audio->replay->activated = RT_TRUE;
+ rt_hw_interrupt_enable(level);
- _audio_send_replay_frame(audio);
+ _audio_send_replay_frame(audio);
}
return size;
@@ -593,251 +295,243 @@ static rt_size_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const voi
static rt_err_t _audio_dev_control(struct rt_device *dev, rt_uint8_t cmd, void *args)
{
- rt_err_t result = RT_EOK;
- struct rt_audio_device *audio;
+ rt_err_t result = RT_EOK;
+ struct rt_audio_device *audio;
RT_ASSERT(dev != RT_NULL);
- audio = (struct rt_audio_device *)dev;
+ audio = (struct rt_audio_device *) dev;
//dev stat...
- switch (cmd)
- {
- case AUDIO_CTL_GETCAPS:
- {
- struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
+ switch (cmd)
+ {
+ case AUDIO_CTL_GETCAPS:
+ {
+ struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
- AUDIO_DBG("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type);
- if (audio->ops->getcaps != RT_NULL)
- {
- result = audio->ops->getcaps(audio, caps);
- }
- }
- break;
- case AUDIO_CTL_CONFIGURE:
- {
- struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
+ AUDIO_DBG("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type);
+ if (audio->ops->getcaps != RT_NULL)
+ {
+ result = audio->ops->getcaps(audio, caps);
+ }
+ }
+ break;
+ case AUDIO_CTL_CONFIGURE:
+ {
+ struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
- AUDIO_DBG("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type);
- if (audio->ops->configure != RT_NULL)
- {
- result = audio->ops->configure(audio, caps);
- }
- }
+ AUDIO_DBG("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type);
+ if (audio->ops->configure != RT_NULL)
+ {
+ result = audio->ops->configure(audio, caps);
+ }
+ }
- break;
- case AUDIO_CTL_SHUTDOWN:
- {
- AUDIO_DBG("AUDIO_CTL_SHUTDOWN\n");
+ break;
+ case AUDIO_CTL_SHUTDOWN:
+ {
+ AUDIO_DBG("AUDIO_CTL_SHUTDOWN\n");
- if (audio->ops->shutdown != RT_NULL)
- result = audio->ops->shutdown(audio);
+ if (audio->ops->shutdown != RT_NULL)
+ result = audio->ops->shutdown(audio);
- //flush replay frame...
- _audio_flush_replay_frame(audio);
- }
- break;
+ //flush replay frame...
+ _audio_flush_replay_frame(audio);
+ }
+ break;
- case AUDIO_CTL_START:
- {
- int stream = *(int *) args;
+ case AUDIO_CTL_START:
+ {
+ int stream = *(int *) args;
- AUDIO_DBG("AUDIO_CTL_START: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->start(audio, stream);
- }
- break;
- case AUDIO_CTL_STOP:
- {
- int stream = *(int *) args;
+ AUDIO_DBG("AUDIO_CTL_START: stream = %d\n",stream);
+ if (audio->ops->start != RT_NULL)
+ result = audio->ops->start(audio, stream);
+ }
+ break;
+ case AUDIO_CTL_STOP:
+ {
+ int stream = *(int *) args;
- AUDIO_DBG("AUDIO_CTL_STOP: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->stop(audio, stream);
+ AUDIO_DBG("AUDIO_CTL_STOP: stream = %d\n",stream);
+ if (audio->ops->start != RT_NULL)
+ result = audio->ops->stop(audio, stream);
- if(stream == AUDIO_STREAM_REPLAY)
- {
- _audio_flush_replay_frame(audio);
- }
- }
- break;
- case AUDIO_CTL_PAUSE:
- {
- int stream = *(int *) args;
+ if (stream == AUDIO_STREAM_REPLAY)
+ {
+ _audio_flush_replay_frame(audio);
+ }
+ }
+ break;
+ case AUDIO_CTL_PAUSE:
+ {
+ int stream = *(int *) args;
- AUDIO_DBG("AUDIO_CTL_PAUSE: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->suspend(audio, stream);
- }
- break;
- case AUDIO_CTL_RESUME:
- {
- int stream = *(int *) args;
+ AUDIO_DBG("AUDIO_CTL_PAUSE: stream = %d\n",stream);
+ if (audio->ops->start != RT_NULL)
+ result = audio->ops->suspend(audio, stream);
+ }
+ break;
+ case AUDIO_CTL_RESUME:
+ {
+ int stream = *(int *) args;
- AUDIO_DBG("AUDIO_CTL_RESUME: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->resume(audio, stream);
+ AUDIO_DBG("AUDIO_CTL_RESUME: stream = %d\n",stream);
+ if (audio->ops->start != RT_NULL)
+ result = audio->ops->resume(audio, stream);
- //resume tx frame...
- if(stream == AUDIO_STREAM_REPLAY)
- _audio_send_replay_frame(audio);
- }
- break;
-#ifdef AUDIO_DEVICE_USE_PRIVATE_BUFFER
- case AUDIO_CTL_ALLOCBUFFER:
- {
- struct rt_audio_buf_desc *desc = (struct rt_audio_buf_desc *)args;
+ //resume tx frame...
+ if (stream == AUDIO_STREAM_REPLAY)
+ _audio_send_replay_frame(audio);
+ }
+ break;
+ case AUDIO_CTL_ALLOCBUFFER:
+ {
+ struct rt_audio_buf_desc *desc = (struct rt_audio_buf_desc *) args;
- if((audio->ops->buffer_alloc != RT_NULL) && (desc != RT_NULL))
- {
- result = audio->ops->buffer_alloc(audio,&desc->data_ptr,&desc->data_size);
- break;
- }
+ if (desc)
+ {
+ desc->data_size = AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2;
+ desc->data_ptr = rt_mp_alloc(&audio->mp, RT_WAITING_FOREVER);
- result = -RT_EIO;
- }
- break;
- case AUDIO_CTL_FREEBUFFER:
- {
- rt_uint8_t *data_ptr = (rt_uint8_t *)args;
- if((audio->ops->buffer_free != RT_NULL) && (data_ptr != RT_NULL))
- {
- audio->ops->buffer_free(audio,data_ptr);
- break;
- }
- }
- break;
-#endif
- default:
- result = audio->ops->control(audio, cmd, args);
- break;
- }
+ result = RT_EOK;
+ }
+ else result = -RT_EIO;
+ }
+ break;
+ case AUDIO_CTL_FREEBUFFER:
+ {
+ rt_uint8_t *data_ptr = (rt_uint8_t *) args;
+ if (data_ptr)
+ rt_mp_free(data_ptr);
+ }
+ break;
+ default:
+ result = audio->ops->control(audio, cmd, args);
+ break;
+ }
return result;
}
-
rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data)
{
struct rt_device *device;
RT_ASSERT(audio != RT_NULL);
device = &(audio->parent);
- device->type = RT_Device_Class_Sound;
+ device->type = RT_Device_Class_Sound;
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
- device->init = _audio_dev_init;
- device->open = _audio_dev_open;
- device->close = _audio_dev_close;
- device->read = _audio_dev_read;
- device->write = _audio_dev_write;
- device->control = _audio_dev_control;
- device->user_data = data;
+ device->init = _audio_dev_init;
+ device->open = _audio_dev_open;
+ device->close = _audio_dev_close;
+ device->read = _audio_dev_read;
+ device->write = _audio_dev_write;
+ device->control = _audio_dev_control;
+ device->user_data = data;
+
+ //init memory pool for replay
+ {
+ rt_uint8_t *mempool = rt_malloc(AUDIO_DEVICE_DECODE_MP_SZ);
+ rt_mp_init(&audio->mp, "adu_mp", mempool, AUDIO_DEVICE_DECODE_MP_SZ,
+ AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2);
+ }
/* register a character device */
return rt_device_register(device, name, flag | RT_DEVICE_FLAG_REMOVABLE);
}
-
-
-rt_size_t rt_audio_get_buffer_size(struct rt_audio_device *audio)
-{
-// return (audio->config.period_count * audio->config.period_size);
- return 0;
-}
-
int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
{
- int speed = 0;
- switch (bitValue)
- {
- case AUDIO_SAMP_RATE_8K:
- speed = 8000;
- break;
- case AUDIO_SAMP_RATE_11K:
- speed = 11052;
- break;
- case AUDIO_SAMP_RATE_16K:
- speed = 16000;
- break;
- case AUDIO_SAMP_RATE_22K:
- speed = 22050;
- break;
- case AUDIO_SAMP_RATE_32K:
- speed = 32000;
- break;
- case AUDIO_SAMP_RATE_44K:
- speed = 44100;
- break;
- case AUDIO_SAMP_RATE_48K:
- speed = 48000;
- break;
- case AUDIO_SAMP_RATE_96K:
- speed = 96000;
- break;
- case AUDIO_SAMP_RATE_128K:
- speed = 128000;
- break;
- case AUDIO_SAMP_RATE_160K:
- speed = 160000;
- break;
- case AUDIO_SAMP_RATE_172K:
- speed = 176400;
- break;
- case AUDIO_SAMP_RATE_192K:
- speed = 192000;
- break;
- default:
+ int speed = 0;
+ switch (bitValue)
+ {
+ case AUDIO_SAMP_RATE_8K:
+ speed = 8000;
+ break;
+ case AUDIO_SAMP_RATE_11K:
+ speed = 11052;
+ break;
+ case AUDIO_SAMP_RATE_16K:
+ speed = 16000;
+ break;
+ case AUDIO_SAMP_RATE_22K:
+ speed = 22050;
+ break;
+ case AUDIO_SAMP_RATE_32K:
+ speed = 32000;
+ break;
+ case AUDIO_SAMP_RATE_44K:
+ speed = 44100;
+ break;
+ case AUDIO_SAMP_RATE_48K:
+ speed = 48000;
+ break;
+ case AUDIO_SAMP_RATE_96K:
+ speed = 96000;
+ break;
+ case AUDIO_SAMP_RATE_128K:
+ speed = 128000;
+ break;
+ case AUDIO_SAMP_RATE_160K:
+ speed = 160000;
+ break;
+ case AUDIO_SAMP_RATE_172K:
+ speed = 176400;
+ break;
+ case AUDIO_SAMP_RATE_192K:
+ speed = 192000;
+ break;
+ default:
- break;
- }
+ break;
+ }
- return speed;
+ return speed;
}
-
-
rt_uint32_t rt_audio_format_to_bits(rt_uint32_t format)
{
switch (format)
{
- case AUDIO_FMT_PCM_U8:
- case AUDIO_FMT_PCM_S8:
- return 8;
- case AUDIO_FMT_PCM_S16_LE:
- case AUDIO_FMT_PCM_S16_BE:
- case AUDIO_FMT_PCM_U16_LE:
- case AUDIO_FMT_PCM_U16_BE:
- return 16;
- default:
- return 32;
+ case AUDIO_FMT_PCM_U8:
+ case AUDIO_FMT_PCM_S8:
+ return 8;
+ case AUDIO_FMT_PCM_S16_LE:
+ case AUDIO_FMT_PCM_S16_BE:
+ case AUDIO_FMT_PCM_U16_LE:
+ case AUDIO_FMT_PCM_U16_BE:
+ return 16;
+ default:
+ return 32;
};
}
-void rt_audio_tx_complete(struct rt_audio_device *audio,rt_uint8_t *pbuf)
+void rt_audio_tx_complete(struct rt_audio_device *audio, rt_uint8_t *pbuf)
{
- rt_err_t result;
- AUDIO_DBG("audio tx complete ptr=%x...\n",(rt_uint32_t)pbuf);
+ rt_err_t result;
+ AUDIO_DBG("audio tx complete ptr=%x...\n",(rt_uint32_t)pbuf);
- //try to send all frame
- do
- {
- result = _audio_send_replay_frame(audio);
- }while(result == RT_EOK);
+ //try to send all frame
+ do
+ {
+ result = _audio_send_replay_frame(audio);
+ } while (result == RT_EOK);
- /* notify transmitted complete. */
- if(audio->parent.tx_complete != RT_NULL)
- audio->parent.tx_complete(&audio->parent,(void *)pbuf);
+ /* notify transmitted complete. */
+ if (audio->parent.tx_complete != RT_NULL)
+ audio->parent.tx_complete(&audio->parent, (void *) pbuf);
}
-void rt_audio_rx_done(struct rt_audio_device *audio,rt_uint8_t *pbuf,rt_size_t len)
+void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len)
{
- rt_err_t result = RT_EOK;
+ rt_err_t result = RT_EOK;
//save data to record pipe
- rt_device_write(RT_DEVICE(RT_DEVICE(&audio->record->pipe)),0,pbuf,len);
+ rt_device_write(RT_DEVICE(RT_DEVICE(&audio->record->pipe)), 0, pbuf, len);
/* invoke callback */
- if(audio->parent.rx_indicate != RT_NULL)
- audio->parent.rx_indicate(&audio->parent,len);
+ if (audio->parent.rx_indicate != RT_NULL)
+ audio->parent.rx_indicate(&audio->parent, len);
}
diff --git a/components/drivers/can/can.c b/components/drivers/can/can.c
index d1cc21dd3f..bbd1e2dcf6 100644
--- a/components/drivers/can/can.c
+++ b/components/drivers/can/can.c
@@ -154,20 +154,11 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
rt_uint32_t result;
struct rt_can_sndbxinx_list *tx_tosnd = RT_NULL;
+ rt_sem_take(&(tx_fifo->sem), RT_WAITING_FOREVER);
level = rt_hw_interrupt_disable();
- if (!rt_list_isempty(&tx_fifo->freelist))
- {
- tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list);
- RT_ASSERT(tx_tosnd != RT_NULL);
- rt_list_remove(&tx_tosnd->list);
- }
- else
- {
- rt_hw_interrupt_enable(level);
-
- rt_completion_wait(&(tx_fifo->completion), RT_WAITING_FOREVER);
- continue;
- }
+ tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list);
+ RT_ASSERT(tx_tosnd != RT_NULL);
+ rt_list_remove(&tx_tosnd->list);
rt_hw_interrupt_enable(level);
no = ((rt_uint32_t)tx_tosnd - (rt_uint32_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list);
@@ -178,6 +169,7 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
level = rt_hw_interrupt_disable();
rt_list_insert_after(&tx_fifo->freelist, &tx_tosnd->list);
rt_hw_interrupt_enable(level);
+ rt_sem_release(&(tx_fifo->sem));
continue;
}
@@ -191,8 +183,8 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
rt_list_remove(&tx_tosnd->list);
}
rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
- rt_completion_done(&(tx_fifo->completion));
rt_hw_interrupt_enable(level);
+ rt_sem_release(&(tx_fifo->sem));
if (result == RT_CAN_SND_RESULT_OK)
{
@@ -280,7 +272,7 @@ rt_inline int _can_int_tx_priv(struct rt_can_device *can, const struct rt_can_ms
static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
{
struct rt_can_device *can;
-
+ char tmpname[16];
RT_ASSERT(dev != RT_NULL);
can = (struct rt_can_device *)dev;
@@ -341,7 +333,9 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
rt_completion_init(&(tx_fifo->buffer[i].completion));
tx_fifo->buffer[i].result = RT_CAN_SND_RESULT_OK;
}
- rt_completion_init(&(tx_fifo->completion));
+
+ rt_sprintf(tmpname, "%stl", dev->parent.name);
+ rt_sem_init(&(tx_fifo->sem), tmpname, can->config.sndboxnumber, RT_IPC_FLAG_FIFO);
can->can_tx = tx_fifo;
dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
@@ -535,14 +529,20 @@ static rt_err_t rt_can_control(struct rt_device *dev,
tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
if (can->config.privmode)
{
- rt_completion_done(&(tx_fifo->completion));
-
for (i = 0; i < can->config.sndboxnumber; i++)
{
- level = rt_hw_interrupt_disable();
- rt_list_remove(&tx_fifo->buffer[i].list);
+ level = rt_hw_interrupt_disable();
+ if(rt_list_isempty(&tx_fifo->buffer[i].list))
+ {
+ rt_sem_release(&(tx_fifo->sem));
+ }
+ else
+ {
+ rt_list_remove(&tx_fifo->buffer[i].list);
+ }
rt_hw_interrupt_enable(level);
}
+
}
else
{
diff --git a/components/drivers/i2c/fm24clxx.c b/components/drivers/i2c/fm24clxx.c
new file mode 100644
index 0000000000..4856a945da
--- /dev/null
+++ b/components/drivers/i2c/fm24clxx.c
@@ -0,0 +1,157 @@
+/*
+ * File : fm24clxx.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-07-14 aubr.cool 1st version
+ */
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "fm24clxx.h"
+
+struct fm24clxx_device
+{
+ struct rt_device parent;
+ struct rt_i2c_bus_device *bus;
+};
+
+/* RT-Thread device interface */
+
+static rt_err_t fm24clxx_init(rt_device_t dev)
+{
+ return RT_EOK;
+}
+static rt_err_t fm24clxx_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ return RT_EOK;
+}
+
+static rt_err_t fm24clxx_close(rt_device_t dev)
+{
+ return RT_EOK;
+}
+
+static rt_err_t fm24clxx_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+ return RT_EOK;
+}
+
+static rt_size_t fm24clxx_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ struct fm24clxx_device *fm24clxx;
+ const struct fm24clxx_config *cfg;
+ struct rt_i2c_msg msg[2];
+ rt_uint8_t mem_addr[2] = {0,};
+ rt_size_t ret = 0;
+ RT_ASSERT(dev != 0);
+
+ fm24clxx = (struct fm24clxx_device *) dev;
+
+ RT_ASSERT(fm24clxx->parent.user_data != 0);
+ cfg = (const struct fm24clxx_config *) fm24clxx->parent.user_data;
+
+ if(pos > cfg->size)
+ {
+ return 0;
+ }
+
+ if(pos + size > cfg->size)
+ {
+ size = cfg->size - pos;
+ }
+
+ msg[0].addr = cfg->addr;
+ msg[0].flags = cfg->flags | RT_I2C_WR;
+ mem_addr[0] = (pos >> 8);
+ mem_addr[1] = (rt_uint8_t) pos;
+ msg[0].buf = (rt_uint8_t *) mem_addr;
+ msg[0].len = 2;
+
+ msg[1].addr = cfg->addr;
+ msg[1].flags = cfg->flags | RT_I2C_RD;
+ msg[1].buf = (rt_uint8_t *) buffer;
+ msg[1].len = size;
+
+ ret = rt_i2c_transfer(fm24clxx->bus, msg, 2);
+ return (ret == 2) ? size : 0;
+}
+
+static rt_size_t fm24clxx_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ struct fm24clxx_device *fm24clxx;
+ const struct fm24clxx_config *cfg;
+ struct rt_i2c_msg msg[2];
+ rt_uint8_t mem_addr[2] = {0,};
+ rt_size_t ret = 0;
+ RT_ASSERT(dev != 0);
+
+ fm24clxx = (struct fm24clxx_device *) dev;
+
+ RT_ASSERT(fm24clxx->parent.user_data != 0);
+ cfg = (const struct fm24clxx_config *) fm24clxx->parent.user_data;
+
+ if(pos > cfg->size)
+ {
+ return 0;
+ }
+
+ if(pos + size > cfg->size)
+ {
+ size = cfg->size - pos;
+ }
+
+ msg[0].addr = cfg->addr;
+ msg[0].flags = cfg->flags | RT_I2C_WR;
+ mem_addr[0] = (pos >> 8);
+ mem_addr[1] = (rt_uint8_t) pos;
+ msg[0].buf = (rt_uint8_t *) mem_addr;
+ msg[0].len = 2;
+
+ msg[1].addr = cfg->addr;
+ msg[1].flags = cfg->flags | RT_I2C_WR | RT_I2C_NO_START;
+ msg[1].buf = (rt_uint8_t *) buffer;
+ msg[1].len = size;
+
+ ret = rt_i2c_transfer(fm24clxx->bus, msg, 2);
+ return (ret == 2) ? size : 0;
+}
+
+rt_err_t fm24clxx_register(const char *fm_device_name, const char *i2c_bus, void *user_data)
+{
+ static struct fm24clxx_device fm24clxx_drv;
+ struct rt_i2c_bus_device *bus;
+
+ bus = rt_i2c_bus_device_find(i2c_bus);
+ if (bus == RT_NULL)
+ {
+ return RT_ENOSYS;
+ }
+
+ fm24clxx_drv.bus = bus;
+ fm24clxx_drv.parent.type = RT_Device_Class_Block;
+ fm24clxx_drv.parent.init = fm24clxx_init;
+ fm24clxx_drv.parent.open = fm24clxx_open;
+ fm24clxx_drv.parent.close = fm24clxx_close;
+ fm24clxx_drv.parent.read = fm24clxx_read;
+ fm24clxx_drv.parent.write = fm24clxx_write;
+ fm24clxx_drv.parent.control = fm24clxx_control;
+ fm24clxx_drv.parent.user_data = user_data;
+
+ return rt_device_register(&fm24clxx_drv.parent, fm_device_name, RT_DEVICE_FLAG_RDWR);
+} \ No newline at end of file
diff --git a/components/drivers/i2c/fm24clxx.h b/components/drivers/i2c/fm24clxx.h
new file mode 100644
index 0000000000..fa84dd5e29
--- /dev/null
+++ b/components/drivers/i2c/fm24clxx.h
@@ -0,0 +1,40 @@
+/*
+ * File : fm24clxx.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-07-14 aubr.cool 1st version
+ */
+
+#ifndef __FM24CLXX_H__
+#define __FM24CLXX_H__
+
+#include <rtthread.h>
+
+struct fm24clxx_config
+{
+ rt_uint32_t size;
+ rt_uint16_t addr;
+ rt_uint16_t flags;
+};
+
+extern rt_err_t fm24clxx_register(const char *e2m_device_name,
+ const char *i2c_bus, void *user_data);
+
+#endif /*__FM24CLXX_H__*/ \ No newline at end of file
diff --git a/components/drivers/i2c/i2c_core.c b/components/drivers/i2c/i2c_core.c
index 739ae7ad43..67778ce0d3 100644
--- a/components/drivers/i2c/i2c_core.c
+++ b/components/drivers/i2c/i2c_core.c
@@ -67,7 +67,7 @@ rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
#ifdef RT_I2C_DEBUG
for (ret = 0; ret < num; ret++)
{
- i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d%s\n", ret,
+ i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d\n", ret,
(msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W',
msgs[ret].addr, msgs[ret].len);
}
diff --git a/components/drivers/include/drivers/audio.h b/components/drivers/include/drivers/audio.h
index e94c677368..70e837421b 100644
--- a/components/drivers/include/drivers/audio.h
+++ b/components/drivers/include/drivers/audio.h
@@ -1,98 +1,123 @@
+/*
+ * File : audio.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-05-09 Urey first version
+ */
+
#ifndef __AUDIO_H__
#define __AUDIO_H__
-//#define AUDIO_DEVICE_USE_PRIVATE_BUFFER
-
-
/* AUDIO command */
-#define _AUDIO_CTL(a) (0x10 + a)
+#define _AUDIO_CTL(a) (0x10 + a)
-#define AUDIO_CTL_GETCAPS _AUDIO_CTL(1)
-#define AUDIO_CTL_CONFIGURE _AUDIO_CTL(2)
-#define AUDIO_CTL_SHUTDOWN _AUDIO_CTL(3)
-#define AUDIO_CTL_START _AUDIO_CTL(4)
-#define AUDIO_CTL_STOP _AUDIO_CTL(5)
-#define AUDIO_CTL_PAUSE _AUDIO_CTL(6)
-#define AUDIO_CTL_RESUME _AUDIO_CTL(7)
-#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(8)
-#define AUDIO_CTL_ALLOCBUFFER _AUDIO_CTL(9)
-#define AUDIO_CTL_FREEBUFFER _AUDIO_CTL(10)
-#define AUDIO_CTL_HWRESET _AUDIO_CTL(11)
+#define AUDIO_CTL_GETCAPS _AUDIO_CTL(1)
+#define AUDIO_CTL_CONFIGURE _AUDIO_CTL(2)
+#define AUDIO_CTL_SHUTDOWN _AUDIO_CTL(3)
+#define AUDIO_CTL_START _AUDIO_CTL(4)
+#define AUDIO_CTL_STOP _AUDIO_CTL(5)
+#define AUDIO_CTL_PAUSE _AUDIO_CTL(6)
+#define AUDIO_CTL_RESUME _AUDIO_CTL(7)
+#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(8)
+#define AUDIO_CTL_ALLOCBUFFER _AUDIO_CTL(9)
+#define AUDIO_CTL_FREEBUFFER _AUDIO_CTL(10)
+#define AUDIO_CTL_HWRESET _AUDIO_CTL(11)
/* Audio Device Types */
-#define AUDIO_TYPE_QUERY 0x00
-#define AUDIO_TYPE_INPUT 0x01
-#define AUDIO_TYPE_OUTPUT 0x02
-#define AUDIO_TYPE_MIXER 0x04
-#define AUDIO_TYPE_SELECTOR 0x08
-#define AUDIO_TYPE_EFFECT 0x10
+#define AUDIO_TYPE_QUERY 0x00
+#define AUDIO_TYPE_INPUT 0x01
+#define AUDIO_TYPE_OUTPUT 0x02
+#define AUDIO_TYPE_MIXER 0x04
+#define AUDIO_TYPE_SELECTOR 0x08
+#define AUDIO_TYPE_EFFECT 0x10
/* Audio Format Types */
-#define AUDIO_FMT_PCM_U8 0x0001
-#define AUDIO_FMT_PCM_S8 0x0002
+#define AUDIO_FMT_PCM_U8 0x0001
+#define AUDIO_FMT_PCM_S8 0x0002
-#define AUDIO_FMT_PCM_U16_LE 0x0010
-#define AUDIO_FMT_PCM_S16_BE 0x0020
-#define AUDIO_FMT_PCM_S16_LE 0x0040
-#define AUDIO_FMT_PCM_U16_BE 0x0080
-#define AUDIO_FMT_PCM_U24_LE 0x0100
-#define AUDIO_FMT_PCM_S24_BE 0x0200
-#define AUDIO_FMT_PCM_S24_LE 0x0400
-#define AUDIO_FMT_PCM_U24_BE 0x0800
-#define AUDIO_FMT_PCM_U32_LE 0x1000
-#define AUDIO_FMT_PCM_S32_BE 0x2000
-#define AUDIO_FMT_PCM_S32_LE 0x4000
-#define AUDIO_FMT_PCM_U32_BE 0x8000
+#define AUDIO_FMT_PCM_U16_LE 0x0010
+#define AUDIO_FMT_PCM_S16_BE 0x0020
+#define AUDIO_FMT_PCM_S16_LE 0x0040
+#define AUDIO_FMT_PCM_U16_BE 0x0080
+#define AUDIO_FMT_PCM_U24_LE 0x0100
+#define AUDIO_FMT_PCM_S24_BE 0x0200
+#define AUDIO_FMT_PCM_S24_LE 0x0400
+#define AUDIO_FMT_PCM_U24_BE 0x0800
+#define AUDIO_FMT_PCM_U32_LE 0x1000
+#define AUDIO_FMT_PCM_S32_BE 0x2000
+#define AUDIO_FMT_PCM_S32_LE 0x4000
+#define AUDIO_FMT_PCM_U32_BE 0x8000
/* Supported Sampling Rates */
-#define AUDIO_SAMP_RATE_8K 0x0001
-#define AUDIO_SAMP_RATE_11K 0x0002
-#define AUDIO_SAMP_RATE_16K 0x0004
-#define AUDIO_SAMP_RATE_22K 0x0008
-#define AUDIO_SAMP_RATE_32K 0x0010
-#define AUDIO_SAMP_RATE_44K 0x0020
-#define AUDIO_SAMP_RATE_48K 0x0040
-#define AUDIO_SAMP_RATE_96K 0x0080
-#define AUDIO_SAMP_RATE_128K 0x0100
-#define AUDIO_SAMP_RATE_160K 0x0200
-#define AUDIO_SAMP_RATE_172K 0x0400
-#define AUDIO_SAMP_RATE_192K 0x0800
+#define AUDIO_SAMP_RATE_8K 0x0001
+#define AUDIO_SAMP_RATE_11K 0x0002
+#define AUDIO_SAMP_RATE_16K 0x0004
+#define AUDIO_SAMP_RATE_22K 0x0008
+#define AUDIO_SAMP_RATE_32K 0x0010
+#define AUDIO_SAMP_RATE_44K 0x0020
+#define AUDIO_SAMP_RATE_48K 0x0040
+#define AUDIO_SAMP_RATE_96K 0x0080
+#define AUDIO_SAMP_RATE_128K 0x0100
+#define AUDIO_SAMP_RATE_160K 0x0200
+#define AUDIO_SAMP_RATE_172K 0x0400
+#define AUDIO_SAMP_RATE_192K 0x0800
/* Supported Bit Rates */
-#define AUDIO_BIT_RATE_22K 0x01
-#define AUDIO_BIT_RATE_44K 0x02
-#define AUDIO_BIT_RATE_48K 0x04
-#define AUDIO_BIT_RATE_96K 0x08
-#define AUDIO_BIT_RATE_128K 0x10
-#define AUDIO_BIT_RATE_160K 0x20
-#define AUDIO_BIT_RATE_172K 0x40
-#define AUDIO_BIT_RATE_192K 0x80
+#define AUDIO_BIT_RATE_22K 0x01
+#define AUDIO_BIT_RATE_44K 0x02
+#define AUDIO_BIT_RATE_48K 0x04
+#define AUDIO_BIT_RATE_96K 0x08
+#define AUDIO_BIT_RATE_128K 0x10
+#define AUDIO_BIT_RATE_160K 0x20
+#define AUDIO_BIT_RATE_172K 0x40
+#define AUDIO_BIT_RATE_192K 0x80
/* Support Dsp(input/output) Units controls */
-#define AUDIO_DSP_PARAM 0 /* get/set all params */
-#define AUDIO_DSP_SAMPLERATE 1 /* ����Ƶ�� */
-#define AUDIO_DSP_FMT 2
-#define AUDIO_DSP_CHANNELS 3
+#define AUDIO_DSP_PARAM 0 /* get/set all params */
+#define AUDIO_DSP_SAMPLERATE 1 /* ����Ƶ�� */
+#define AUDIO_DSP_FMT 2
+#define AUDIO_DSP_CHANNELS 3
/* Supported Mixer Units controls */
-#define AUDIO_MIXER_QUERY 0x0000
-#define AUDIO_MIXER_MUTE 0x0001
-#define AUDIO_MIXER_VOLUME 0x0002
-#define AUDIO_MIXER_BASS 0x0004
-#define AUDIO_MIXER_MID 0x0008
-#define AUDIO_MIXER_TREBLE 0x0010
-#define AUDIO_MIXER_EQUALIZER 0x0020
-#define AUDIO_MIXER_LINE 0x0040
-#define AUDIO_MIXER_DIGITAL 0x0080
-#define AUDIO_MIXER_MIC 0x0100
+#define AUDIO_MIXER_QUERY 0x0000
+#define AUDIO_MIXER_MUTE 0x0001
+#define AUDIO_MIXER_VOLUME 0x0002
+#define AUDIO_MIXER_BASS 0x0004
+#define AUDIO_MIXER_MID 0x0008
+#define AUDIO_MIXER_TREBLE 0x0010
+#define AUDIO_MIXER_EQUALIZER 0x0020
+#define AUDIO_MIXER_LINE 0x0040
+#define AUDIO_MIXER_DIGITAL 0x0080
+#define AUDIO_MIXER_MIC 0x0100
-#define AUDIO_MIXER_EXTEND 0x8000 //extend mixer command
+#define AUDIO_MIXER_EXTEND 0x8000 //extend mixer command
+
+#define CFG_AUDIO_REPLAY_QUEUE_COUNT 4
+#define CFG_AUDIO_RECORD_PIPE_SIZE (8 * 1024)
+#define AUDIO_DEVICE_MP_CNT (4)
+#define AUDIO_DEVICE_DECODE_MP_BLOCK_SZ (4352 * 4)
+#define AUDIO_DEVICE_DECODE_MP_SZ ((AUDIO_DEVICE_DECODE_MP_BLOCK_SZ*2 + 4)*AUDIO_DEVICE_MP_CNT)
-#define CFG_AUDIO_REPLAY_QUEUE_COUNT 4
-#define CFG_AUDIO_RECORD_PIPE_SIZE (8 * 1024)
enum
{
@@ -104,36 +129,19 @@ enum
/* the preferred number and size of audio pipeline buffer for the audio device */
struct rt_audio_buf_info
{
- rt_uint32_t buffer_size; /* Preferred qty of buffers */
- rt_uint32_t buffer_count; /* Preferred size of the buffers */
+ rt_uint32_t buffer_size; /* Preferred qty of buffers */
+ rt_uint32_t buffer_count; /* Preferred size of the buffers */
};
struct rt_audio_buf_desc
{
- rt_uint8_t *data_ptr;
- rt_size_t data_size;
+ rt_uint8_t *data_ptr;
+ rt_size_t data_size;
};
struct rt_audio_frame
{
const void *data_ptr;
rt_size_t data_size;
- rt_size_t data_ofs;
-};
-
-struct rt_audio_queue
-{
- rt_uint16_t count;
- rt_uint16_t size;
- rt_uint16_t lwm;
- rt_bool_t waiting_lwm;
-
- rt_uint16_t get_index;
- rt_uint16_t put_index;
-
- struct rt_audio_frame *queue;
-
- rt_list_t suspended_push_list;
- rt_list_t suspended_pop_list;
};
struct rt_audio_device;
@@ -141,25 +149,21 @@ struct rt_audio_caps;
struct rt_audio_configure;
struct rt_audio_ops
{
- rt_err_t (*getcaps) (struct rt_audio_device *audio,struct rt_audio_caps *caps);
- rt_err_t (*configure) (struct rt_audio_device *audio,struct rt_audio_caps *caps);
+ rt_err_t (*getcaps) (struct rt_audio_device *audio,struct rt_audio_caps *caps);
+ rt_err_t (*configure) (struct rt_audio_device *audio,struct rt_audio_caps *caps);
- rt_err_t (*init) (struct rt_audio_device *audio);
- rt_err_t (*shutdown) (struct rt_audio_device *audio);
- rt_err_t (*start) (struct rt_audio_device *audio,int stream);
- rt_err_t (*stop) (struct rt_audio_device *audio,int stream);
- rt_err_t (*suspend) (struct rt_audio_device *audio,int stream);
- rt_err_t (*resume) (struct rt_audio_device *audio,int stream);
+ rt_err_t (*init) (struct rt_audio_device *audio);
+ rt_err_t (*shutdown) (struct rt_audio_device *audio);
+ rt_err_t (*start) (struct rt_audio_device *audio,int stream);
+ rt_err_t (*stop) (struct rt_audio_device *audio,int stream);
+ rt_err_t (*suspend) (struct rt_audio_device *audio,int stream);
+ rt_err_t (*resume) (struct rt_audio_device *audio,int stream);
- rt_err_t (*control) (struct rt_audio_device *audio, rt_uint8_t cmd, void *arg);
- rt_size_t (*transmit) (struct rt_audio_device *audio, const void *writeBuf,void *readBuf, rt_size_t size);
+ rt_err_t (*control) (struct rt_audio_device *audio, rt_uint8_t cmd, void *arg);
+ rt_size_t (*transmit) (struct rt_audio_device *audio, const void *writeBuf,void *readBuf, rt_size_t size);
//get page size of codec or private buffer's info
- void (*buffer_info) (struct rt_audio_device *audio,struct rt_audio_buf_info *info );
-#ifdef AUDIO_DEVICE_USE_PRIVATE_BUFFER
- rt_err_t (*buffer_alloc) (struct rt_audio_device *audio,rt_uint8_t **data_ptr,rt_size_t *size);
- void (*buffer_free) (struct rt_audio_device *audio,rt_uint8_t *data_ptr);
-#endif
+ void (*buffer_info) (struct rt_audio_device *audio,struct rt_audio_buf_info *info );
};
@@ -174,42 +178,44 @@ struct rt_audio_configure
struct rt_audio_caps
{
- int main_type;
- int sub_type;
+ int main_type;
+ int sub_type;
- union
- {
- rt_uint32_t mask;
- int value;
- struct rt_audio_configure config;
- }udata;
+ union
+ {
+ rt_uint32_t mask;
+ int value;
+ struct rt_audio_configure config;
+ }udata;
};
struct rt_audio_replay
{
rt_bool_t activated;
- struct rt_audio_queue queue;
+ struct rt_data_queue queue;
};
struct rt_audio_record
{
rt_bool_t activated;
- struct rt_pipe_device pipe;
+ struct rt_pipe_device pipe;
};
struct rt_audio_device
{
struct rt_device parent;
- struct rt_audio_ops *ops;
+ struct rt_audio_ops *ops;
+
+ struct rt_mempool mp;
- struct rt_audio_replay *replay;
- struct rt_audio_record *record;
+ struct rt_audio_replay *replay;
+ struct rt_audio_record *record;
};
-rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data);
-void rt_audio_tx_complete(struct rt_audio_device *audio,rt_uint8_t *pbuf);
-void rt_audio_rx_done(struct rt_audio_device *audio,rt_uint8_t *pbuf,rt_size_t len);
-rt_uint32_t rt_audio_format_to_bits(rt_uint32_t format);
+rt_err_t rt_audio_register (struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data);
+void rt_audio_tx_complete (struct rt_audio_device *audio,rt_uint8_t *pbuf);
+void rt_audio_rx_done (struct rt_audio_device *audio,rt_uint8_t *pbuf,rt_size_t len);
+rt_uint32_t rt_audio_format_to_bits (rt_uint32_t format);
/* Device Control Commands */
@@ -219,7 +225,6 @@ rt_uint32_t rt_audio_format_to_bits(rt_uint32_t format);
#define CODEC_CMD_SAMPLERATE 3
#define CODEC_CMD_EQ 4
#define CODEC_CMD_3D 5
-#define CODEC_CMD_SWITCH 6
#define CODEC_VOLUME_MAX (63)
diff --git a/components/drivers/include/drivers/can.h b/components/drivers/include/drivers/can.h
index 71b577eba0..ecf3b5f51e 100644
--- a/components/drivers/include/drivers/can.h
+++ b/components/drivers/include/drivers/can.h
@@ -280,7 +280,7 @@ struct rt_can_sndbxinx_list
struct rt_can_tx_fifo
{
struct rt_can_sndbxinx_list *buffer;
- struct rt_completion completion;
+ struct rt_semaphore sem;
struct rt_list_node freelist;
};
diff --git a/components/drivers/include/drivers/mmcsd_card.h b/components/drivers/include/drivers/mmcsd_card.h
index 4a82bc58f5..18470a5ea9 100644
--- a/components/drivers/include/drivers/mmcsd_card.h
+++ b/components/drivers/include/drivers/mmcsd_card.h
@@ -135,6 +135,8 @@ struct rt_sdio_function {
rt_uint32_t enable_timeout_val; /* max enable timeout in msec */
struct rt_sdio_function_tuple *tuples;
+
+ void *priv;
};
#define SDIO_MAX_FUNCTIONS 7
diff --git a/components/drivers/include/drivers/mmcsd_host.h b/components/drivers/include/drivers/mmcsd_host.h
index 3b68058ba4..877a04d8e0 100644
--- a/components/drivers/include/drivers/mmcsd_host.h
+++ b/components/drivers/include/drivers/mmcsd_host.h
@@ -111,7 +111,7 @@ struct rt_mmcsd_host {
rt_uint32_t max_blk_count; /* maximum block count */
rt_uint32_t spi_use_crc;
- struct rt_semaphore bus_lock;
+ struct rt_mutex bus_lock;
struct rt_semaphore sem_ack;
rt_uint32_t sdio_irq_num;
diff --git a/components/drivers/include/drivers/sdio.h b/components/drivers/include/drivers/sdio.h
index 5f65882952..2cd1c7dfd1 100644
--- a/components/drivers/include/drivers/sdio.h
+++ b/components/drivers/include/drivers/sdio.h
@@ -229,6 +229,8 @@ rt_int32_t sdio_detach_irq(struct rt_sdio_function *func);
void sdio_irq_wakeup(struct rt_mmcsd_host *host);
rt_int32_t sdio_enable_func(struct rt_sdio_function *func);
rt_int32_t sdio_disable_func(struct rt_sdio_function *func);
+void sdio_set_drvdata(struct rt_sdio_function *func, void *data);
+void* sdio_get_drvdata(struct rt_sdio_function *func);
rt_int32_t sdio_set_block_size(struct rt_sdio_function *func,
rt_uint32_t blksize);
rt_int32_t sdio_register_driver(struct rt_sdio_driver *driver);
diff --git a/components/drivers/include/drivers/watchdog.h b/components/drivers/include/drivers/watchdog.h
index 15ae5a1f44..5c74dc82be 100644
--- a/components/drivers/include/drivers/watchdog.h
+++ b/components/drivers/include/drivers/watchdog.h
@@ -38,7 +38,7 @@ struct rt_watchdog_ops;
struct rt_watchdog_device
{
struct rt_device parent;
- struct rt_watchdog_ops *ops;
+ const struct rt_watchdog_ops *ops;
};
typedef struct rt_watchdog_device rt_watchdog_t;
diff --git a/components/drivers/sdio/mmcsd_core.c b/components/drivers/sdio/mmcsd_core.c
index adda6a4910..02063efdd2 100644
--- a/components/drivers/sdio/mmcsd_core.c
+++ b/components/drivers/sdio/mmcsd_core.c
@@ -49,12 +49,12 @@ static rt_uint32_t mmcsd_hotpluge_mb_pool[4];
void mmcsd_host_lock(struct rt_mmcsd_host *host)
{
- rt_sem_take(&host->bus_lock, RT_WAITING_FOREVER);
+ rt_mutex_take(&host->bus_lock, RT_WAITING_FOREVER);
}
void mmcsd_host_unlock(struct rt_mmcsd_host *host)
{
- rt_sem_release(&host->bus_lock);
+ rt_mutex_release(&host->bus_lock);
}
void mmcsd_req_complete(struct rt_mmcsd_host *host)
@@ -713,7 +713,7 @@ struct rt_mmcsd_host *mmcsd_alloc_host(void)
host->max_blk_size = 512;
host->max_blk_count = 4096;
- rt_sem_init(&host->bus_lock, "sd_bus_lock", 1, RT_IPC_FLAG_FIFO);
+ rt_mutex_init(&host->bus_lock, "sd_bus_lock", RT_IPC_FLAG_FIFO);
rt_sem_init(&host->sem_ack, "sd_ack", 0, RT_IPC_FLAG_FIFO);
return host;
@@ -721,7 +721,7 @@ struct rt_mmcsd_host *mmcsd_alloc_host(void)
void mmcsd_free_host(struct rt_mmcsd_host *host)
{
- rt_sem_detach(&host->bus_lock);
+ rt_mutex_detach(&host->bus_lock);
rt_sem_detach(&host->sem_ack);
rt_free(host);
}
diff --git a/components/drivers/sdio/sdio.c b/components/drivers/sdio/sdio.c
index 59f1456e6f..496765854e 100644
--- a/components/drivers/sdio/sdio.c
+++ b/components/drivers/sdio/sdio.c
@@ -29,8 +29,8 @@
#ifndef RT_SDIO_STACK_SIZE
#define RT_SDIO_STACK_SIZE 512
#endif
-#ifndef RT_SDIO_THREAD_PREORITY
-#define RT_SDIO_THREAD_PREORITY 0x40
+#ifndef RT_SDIO_THREAD_PRIORITY
+#define RT_SDIO_THREAD_PRIORITY 0x40
#endif
static rt_list_t sdio_cards;
@@ -1059,7 +1059,7 @@ static rt_int32_t sdio_irq_thread_create(struct rt_mmcsd_card *card)
RT_ASSERT(host->sdio_irq_sem != RT_NULL);
host->sdio_irq_thread = rt_thread_create("sdio_irq", sdio_irq_thread, host,
- RT_SDIO_STACK_SIZE, RT_SDIO_THREAD_PREORITY, 20);
+ RT_SDIO_STACK_SIZE, RT_SDIO_THREAD_PRIORITY, 20);
if (host->sdio_irq_thread != RT_NULL)
{
rt_thread_startup(host->sdio_irq_thread);
@@ -1079,7 +1079,7 @@ static rt_int32_t sdio_irq_thread_delete(struct rt_mmcsd_card *card)
if (!host->sdio_irq_num)
{
if (host->flags & MMCSD_SUP_SDIO_IRQ)
- host->ops->enable_sdio_irq(host, 0);
+ host->ops->enable_sdio_irq(host, 0);
rt_sem_delete(host->sdio_irq_sem);
host->sdio_irq_sem = RT_NULL;
rt_thread_delete(host->sdio_irq_thread);
@@ -1253,6 +1253,16 @@ err:
return -RT_EIO;
}
+void sdio_set_drvdata(struct rt_sdio_function *func, void *data)
+{
+ func->priv = data;
+}
+
+void* sdio_get_drvdata(struct rt_sdio_function *func)
+{
+ return func->priv;
+}
+
rt_int32_t sdio_set_block_size(struct rt_sdio_function *func,
rt_uint32_t blksize)
{
@@ -1284,16 +1294,24 @@ rt_int32_t sdio_set_block_size(struct rt_sdio_function *func,
rt_inline rt_int32_t sdio_match_card(struct rt_mmcsd_card *card,
const struct rt_sdio_device_id *id)
{
+ rt_uint8_t num = 1;
+
if ((id->manufacturer != SDIO_ANY_MAN_ID) &&
(id->manufacturer != card->cis.manufacturer))
return 0;
- if ((id->product != SDIO_ANY_PROD_ID) &&
- (id->product != (card->cis.product | 1)))
- return 0;
+
+ while (num <= card->sdio_function_num)
+ {
+ if ((id->product != SDIO_ANY_PROD_ID) &&
+ (id->product == card->sdio_function[num]->product))
+ return 1;
+ num++;
+ }
- return 1;
+ return 0;
}
+
static struct rt_mmcsd_card *sdio_match_driver(struct rt_sdio_device_id *id)
{
rt_list_t *l;
diff --git a/components/drivers/spi/sfud/LICENSE b/components/drivers/spi/sfud/LICENSE
index 6b761d3f4a..f956e1683d 100644
--- a/components/drivers/spi/sfud/LICENSE
+++ b/components/drivers/spi/sfud/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2016 Armink ([email protected])
+Copyright (c) 2016-2017 Armink ([email protected])
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/components/drivers/spi/sfud/README.md b/components/drivers/spi/sfud/README.md
index 69ea4a67f6..13ef219154 100644
--- a/components/drivers/spi/sfud/README.md
+++ b/components/drivers/spi/sfud/README.md
@@ -10,7 +10,7 @@
- 资源占用
- 标准占用:RAM:0.2KB ROM:5.5KB
- 最小占用:RAM:0.1KB ROM:3.6KB
-- 设计思路:这里要首先跟大家介绍一个标准: **SFDP** ,它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B ([点击这里查看](https://www.jedec.org/standards-documents/docs/jesd216b))。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粗粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数,如果该 Flash 不支持 SFDP,则查询配置文件 ( `/sfud/inc/sfud_flash_def.h` ) 中提供的 **Flash 参数信息表** 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 [2.5 添加库目前不支持的 Flash](#25-添加库目前不支持的-flash))。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。
+- 设计思路:这里要首先跟大家介绍一个标准: **SFDP** ,它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B ([点击这里查看](https://www.jedec.org/standards-documents/docs/jesd216b))。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数,如果该 Flash 不支持 SFDP,则查询配置文件 ( [`/sfud/inc/sfud_flash_def.h`](https://github.com/armink/SFUD/blob/master/sfud/inc/sfud_flash_def.h#L110-L122) ) 中提供的 **Flash 参数信息表** 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 [2.5 添加库目前不支持的 Flash](#25-添加库目前不支持的-flash))。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。
## 1、为什么选择 SFUD
@@ -25,7 +25,7 @@
下表为所有在 Demo 平台上进行过真机测试的 Flash。目前 SFUD 提供的 **Flash 参数信息表** 只包括下表中 **不支持** SFDP 标准的 Flash,其他不支持 SFDP 标准的 Flash 需要大家以后 **共同来完善和维护** **([Github](https://github.com/armink/SFUD)|[OSChina](http://git.oschina.net/armink/SFUD)|[Coding](https://coding.net/u/armink/p/SFUD/git))** 。如果觉得这个开源项目很赞,可以点击 [项目主页](https://github.com/armink/SFUD) 右上角的 **Star** ,同时把它推荐给更多有需要的朋友。
-|型号|制造商|容量|最高速度|SFDP|备注|
+|型号|制造商|容量|最高速度|SFDP 标准|备注|
|:--:|:----:|:--:|:--:|:--:|:--:|
|[W25Q40BV](http://microchip.ua/esp8266/W25Q40BV(EOL).pdf)|Winbond|4Mb|50Mhz|不支持|已停产|
|[W25Q80DV](http://www.winbond.com/resource-files/w25q80dv_revg_07212015.pdf)|Winbond|8Mb|104Mhz|支持||
@@ -39,7 +39,8 @@
|[SST25VF016B](http://ww1.microchip.com/downloads/en/DeviceDoc/20005044C.pdf)|Microchip|16Mb|50MHz|不支持| SST 已被 Microchip 收购|
|[M25P32](https://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/m25p/m25p32.pdf)|Micron|32Mb|75Mhz|不支持||
|[EN25Q32B](http://www.kean.com.au/oshw/WR703N/teardown/EN25Q32B%2032Mbit%20SPI%20Flash.pdf)|EON|32Mb|104MHz|不支持||
-|[GD25Q64B](http://www.gigadevice.com/product/download/24.html)|GigaDevice|64Mb|120Mhz|不支持||
+|[GD25Q64B](http://www.gigadevice.com/product/detail/5/364.html)|GigaDevice|64Mb|120Mhz|不支持||
+|[GD25Q16B](http://www.gigadevice.com/product/detail/5/410.html)|GigaDevice|16Mb|120Mhz|不支持| by [TanekLiang](https://github.com/TanekLiang) |
|[S25FL216K](http://www.cypress.com/file/197346/download)|Cypress|16Mb|65Mhz|不支持||
|[S25FL164K](http://www.cypress.com/file/196886/download)|Cypress|64Mb|108Mhz|支持||
|[A25LQ64](http://www.amictechnology.com/datasheets/A25LQ64.pdf)|AMIC|64Mb|104Mhz|支持||
@@ -50,8 +51,12 @@
### 2.2 API 说明
+先说明下本库主要使用的一个结构体 `sfud_flash` 。其定义位于 `/sfud/inc/sfud_def.h`。每个 SPI Flash 会对应一个该结构体,该结构体指针下面统称为 Flash 设备对象。初始化成功后在 `sfud_flash->chip` 结构体中会存放 SPI Flash 的常见参数。如果 SPI Flash 还支持 SFDP ,还可以通过 `sfud_flash->sfdp` 看到更加全面的参数信息。以下很多函数都将使用 Flash 设备对象作为第一个入参,实现对指定 SPI Flash 的操作。
+
#### 2.2.1 初始化 SFUD 库
+> 注意:初始化完的 SPI Flash 默认都 **已取消写保护** 状态,如需开启写保护,请使用 sfud_write_status 函数修改 SPI Flash 状态。
+
```C
sfud_err sfud_init(void)
```
@@ -92,11 +97,13 @@ sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t
|:----- |:----|
|flash |Flash 设备对象|
|addr |起始地址|
-|size |读取数据的大小|
+|size |从起始地址开始读取数据的总大小|
|data |读取到的数据|
#### 2.2.6 擦除 Flash 数据
+> 注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 `sfud_flash->chip.erase_gran` 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。
+
```C
sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size)
```
@@ -105,7 +112,7 @@ sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size)
|:----- |:----|
|flash |Flash 设备对象|
|addr |起始地址|
-|size |擦除数据的大小|
+|size |从起始地址开始擦除数据的总大小|
#### 2.2.7 擦除 Flash 全部数据
@@ -127,11 +134,13 @@ sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const u
|:----- |:----|
|flash |Flash 设备对象|
|addr |起始地址|
-|size |写数据的大小|
+|size |从起始地址开始写入数据的总大小|
|data |待写入的数据|
#### 2.2.9 先擦除再往 Flash 写数据
+> 注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 `sfud_flash->chip.erase_gran` 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。
+
```C
sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data)
```
@@ -140,7 +149,7 @@ sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, c
|:----- |:----|
|flash |Flash 设备对象|
|addr |起始地址|
-|size |写数据的大小|
+|size |从起始地址开始写入数据的总大小|
|data |待写入的数据|
#### 2.2.10 读取 Flash 状态
@@ -211,7 +220,7 @@ enum {
### 2.5 添加库目前不支持的 Flash
-这里需要修改 `/sfud/inc/sfdu_flash_def.h` ,所有已经支持的 Flash 见 `SFUD_FLASH_CHIP_TABLE` 宏定义,需要提前准备的 Flash 参数内容分别为:| 名称 | 制造商 ID | 类型 ID | 容量 ID | 容量 | 写模式 | 擦除粗粒度(擦除的最小单位) | 擦除粗粒度对应的命令 | 。这里以添加 兆易创新 ( GigaDevice ) 的 `GD25Q64B` Flash 来举例。
+这里需要修改 `/sfud/inc/sfdu_flash_def.h` ,所有已经支持的 Flash 见 `SFUD_FLASH_CHIP_TABLE` 宏定义,需要提前准备的 Flash 参数内容分别为:| 名称 | 制造商 ID | 类型 ID | 容量 ID | 容量 | 写模式 | 擦除粒度(擦除的最小单位) | 擦除粒度对应的命令 | 。这里以添加 兆易创新 ( GigaDevice ) 的 `GD25Q64B` Flash 来举例。
此款 Flash 为兆易创新的早期生产的型号,所以不支持 SFDP 标准。首先需要下载其数据手册,找到 0x9F 命令返回的 3 种 ID, 这里需要最后面两字节 ID ,即 `type id` 及 `capacity id` 。 `GD25Q64B` 对应这两个 ID 分别为 `0x40` 及 `0x17` 。上面要求的其他 Flash 参数都可以在数据手册中找到,这里要重点说明下 **写模式** 这个参数,库本身提供的写模式共计有 4 种,详见文件顶部的 `sfud_write_mode` 枚举类型,同一款 Flash 可以同时支持多种写模式,视情况而定。对于 `GD25Q64B` 而言,其支持的写模式应该为 `SFUD_WM_PAGE_256B` ,即写 1-256 字节每页。结合上述 `GD25Q64B` 的 Flash 参数应如下:
@@ -232,4 +241,4 @@ enum {
### 2.7 许可
-采用 MIT 开源协议,细节请阅读项目中的 LICENSE 文件内容。 \ No newline at end of file
+采用 MIT 开源协议,细节请阅读项目中的 LICENSE 文件内容。
diff --git a/components/drivers/spi/sfud/inc/sfud_def.h b/components/drivers/spi/sfud/inc/sfud_def.h
index 44dd03c745..cc38c3fa1a 100644
--- a/components/drivers/spi/sfud/inc/sfud_def.h
+++ b/components/drivers/spi/sfud/inc/sfud_def.h
@@ -41,12 +41,16 @@ extern "C" {
/* debug print function. Must be implement by user. */
#ifdef SFUD_DEBUG_MODE
+#ifndef SFUD_DEBUG
#define SFUD_DEBUG(...) sfud_log_debug(__FILE__, __LINE__, __VA_ARGS__)
+#endif /* SFUD_DEBUG */
#else
#define SFUD_DEBUG(...)
-#endif
+#endif /* SFUD_DEBUG_MODE */
+#ifndef SFUD_INFO
#define SFUD_INFO(...) sfud_log_info(__VA_ARGS__)
+#endif
/* assert for developer. */
#ifdef SFUD_DEBUG_MODE
@@ -73,7 +77,7 @@ if (!(EXPR)) \
else {if (__delay_temp) {__delay_temp();} retry --;}
/* software version number */
-#define SFUD_SW_VERSION "0.10.14"
+#define SFUD_SW_VERSION "1.0.1"
/*
* all defined supported command
*/
diff --git a/components/drivers/spi/sfud/inc/sfud_flash_def.h b/components/drivers/spi/sfud/inc/sfud_flash_def.h
index b593297df6..06c95b775a 100644
--- a/components/drivers/spi/sfud/inc/sfud_flash_def.h
+++ b/components/drivers/spi/sfud/inc/sfud_flash_def.h
@@ -1,7 +1,7 @@
/*
* This file is part of the Serial Flash Universal Driver Library.
*
- * Copyright (c) 2016, Armink, <[email protected]>
+ * Copyright (c) 2016-2017, Armink, <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -103,8 +103,8 @@ typedef struct {
#ifdef SFUD_USING_FLASH_INFO_TABLE
/* SFUD supported flash chip information table. If the flash not support JEDEC JESD216 standard,
- * then the SFUD will find the flash chip information by this table. Developer can add other flash to here.
- * The configuration information name and index reference the sfud_flash_chip structure.
+ * then the SFUD will find the flash chip information by this table. You can add other flash to here then
+ * notice me for update it. The configuration information name and index reference the sfud_flash_chip structure.
* | name | mf_id | type_id | capacity_id | capacity | write_mode | erase_gran | erase_gran_cmd |
*/
#define SFUD_FLASH_CHIP_TABLE \
@@ -115,6 +115,7 @@ typedef struct {
{"M25P32", SFUD_MF_ID_MICRON, 0x20, 0x16, 4*1024*1024, SFUD_WM_PAGE_256B, 64*1024, 0xD8}, \
{"EN25Q32B", SFUD_MF_ID_EON, 0x30, 0x16, 4*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"GD25Q64B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, 8*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \
+ {"GD25Q16B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x15, 2*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"S25FL216K", SFUD_MF_ID_CYPRESS, 0x40, 0x15, 2*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"A25L080", SFUD_MF_ID_AMIC, 0x30, 0x14, 1*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"F25L004", SFUD_MF_ID_ESMT, 0x20, 0x13, 512*1024, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \
diff --git a/components/drivers/spi/sfud/src/sfud.c b/components/drivers/spi/sfud/src/sfud.c
index b616e3fad8..475cbd5d9e 100644
--- a/components/drivers/spi/sfud/src/sfud.c
+++ b/components/drivers/spi/sfud/src/sfud.c
@@ -110,7 +110,7 @@ sfud_err sfud_init(void) {
cur_flash_result = sfud_device_init(&flash_table[i]);
if (cur_flash_result != SFUD_SUCCESS) {
- cur_flash_result = cur_flash_result;
+ all_flash_result = cur_flash_result;
}
}
@@ -587,12 +587,9 @@ static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, c
sfud_err result = SFUD_SUCCESS;
const sfud_spi *spi = &flash->spi;
uint8_t cmd_data[6], cmd_size;
- const size_t data_size = 2;
bool first_write = true;
SFUD_ASSERT(flash);
- SFUD_ASSERT(size >= 2);
- /* must be call this function after initialize OK */
SFUD_ASSERT(flash->init_ok);
/* check the flash address bound */
if (addr + size > flash->chip.capacity) {
@@ -603,41 +600,35 @@ static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, c
if (spi->lock) {
spi->lock(spi);
}
-
+ /* The address must be even for AAI write mode. So it must write one byte first when address is odd. */
+ if (addr % 2 != 0) {
+ result = page256_or_1_byte_write(flash, addr++, 1, 1, data++);
+ if (result != SFUD_SUCCESS) {
+ goto __exit;
+ }
+ size--;
+ }
/* set the flash write enable */
result = set_write_enabled(flash, true);
if (result != SFUD_SUCCESS) {
goto __exit;
}
- /* loop write operate. write unit is write granularity */
+ /* loop write operate. */
cmd_data[0] = SFUD_CMD_AAI_WORD_PROGRAM;
- while (size) {
+ while (size >= 2) {
if (first_write) {
make_adress_byte_array(flash, addr, &cmd_data[1]);
cmd_size = flash->addr_in_4_byte ? 5 : 4;
- if (addr % 2 == 0) {
- cmd_data[cmd_size] = *data;
- cmd_data[cmd_size + 1] = *(data + 1);
- } else {
- cmd_data[cmd_size] = 0xFF;
- cmd_data[cmd_size + 1] = *data;
- size++;
- data--;
- }
+ cmd_data[cmd_size] = *data;
+ cmd_data[cmd_size + 1] = *(data + 1);
first_write = false;
} else {
cmd_size = 1;
- if (size != 1) {
- cmd_data[1] = *data;
- cmd_data[2] = *(data + 1);
- } else {
- cmd_data[1] = *data;
- cmd_data[2] = 0xFF;
- size++;
- }
+ cmd_data[1] = *data;
+ cmd_data[2] = *(data + 1);
}
- result = spi->wr(spi, cmd_data, cmd_size + data_size, NULL, 0);
+ result = spi->wr(spi, cmd_data, cmd_size + 2, NULL, 0);
if (result != SFUD_SUCCESS) {
SFUD_INFO("Error: Flash write SPI communicate error.");
goto __exit;
@@ -649,12 +640,20 @@ static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, c
}
size -= 2;
- data += data_size;
+ addr += 2;
+ data += 2;
+ }
+ /* set the flash write disable for exit AAI mode */
+ result = set_write_enabled(flash, false);
+ /* write last one byte data when origin write size is odd */
+ if (result == SFUD_SUCCESS && size == 1) {
+ result = page256_or_1_byte_write(flash, addr, 1, 1, data);
}
__exit:
- /* set the flash write disable for exist AAI mode */
- set_write_enabled(flash, false);
+ if (result != SFUD_SUCCESS) {
+ set_write_enabled(flash, false);
+ }
/* unlock SPI */
if (spi->unlock) {
spi->unlock(spi);
diff --git a/components/drivers/spi/sfud/src/sfud_sfdp.c b/components/drivers/spi/sfud/src/sfud_sfdp.c
index 95157e613f..32873ab8cb 100644
--- a/components/drivers/spi/sfud/src/sfud_sfdp.c
+++ b/components/drivers/spi/sfud/src/sfud_sfdp.c
@@ -119,7 +119,7 @@ static bool read_sfdp_header(sfud_flash *flash) {
header[1] == 'F' &&
header[2] == 'D' &&
header[3] == 'P')) {
- SFUD_INFO("Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P').");
+ SFUD_DEBUG("Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P').");
return false;
}
sfdp->minor_rev = header[4];
diff --git a/components/drivers/spi/spi_flash_at45dbxx.c b/components/drivers/spi/spi_flash_at45dbxx.c
index 0585e395ca..f9a15b27dd 100644
--- a/components/drivers/spi/spi_flash_at45dbxx.c
+++ b/components/drivers/spi/spi_flash_at45dbxx.c
@@ -140,12 +140,12 @@ static rt_size_t AT45DB_flash_read_page_256(rt_device_t dev, rt_off_t pos, void*
{
uint32_t index, nr;
uint8_t * read_buffer = buffer;
+ uint32_t page = pos;
nr = size;
for (index = 0; index < nr; index++)
{
- uint32_t page = pos;
uint8_t send_buffer[8];
uint32_t i;
@@ -170,12 +170,12 @@ static rt_size_t AT45DB_flash_read_page_512(rt_device_t dev, rt_off_t pos, void*
{
uint32_t index, nr;
uint8_t * read_buffer = buffer;
+ uint32_t page = pos;
nr = size;
for (index = 0; index < nr; index++)
{
- uint32_t page = pos;
uint8_t send_buffer[8];
uint32_t i;
@@ -200,12 +200,12 @@ static rt_size_t AT45DB_flash_read_page_1024(rt_device_t dev, rt_off_t pos, void
{
uint32_t index, nr;
uint8_t * read_buffer = buffer;
+ uint32_t page = pos;
nr = size;
for (index = 0; index < nr; index++)
{
- uint32_t page = pos;
uint8_t send_buffer[8];
uint32_t i;
@@ -230,12 +230,12 @@ static rt_size_t AT45DB_flash_write_page_256(rt_device_t dev, rt_off_t pos, cons
{
rt_uint32_t index, nr;
const uint8_t * write_buffer = buffer;
+ uint32_t page = pos;
nr = size;
for (index = 0; index < nr; index++)
{
- uint32_t page = pos;
uint8_t send_buffer[4];
send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
@@ -258,12 +258,12 @@ static rt_size_t AT45DB_flash_write_page_512(rt_device_t dev, rt_off_t pos, cons
{
rt_uint32_t index, nr;
const uint8_t * write_buffer = buffer;
+ uint32_t page = pos;
nr = size;
for (index = 0; index < nr; index++)
{
- uint32_t page = pos;
uint8_t send_buffer[4];
send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
@@ -286,12 +286,12 @@ static rt_size_t AT45DB_flash_write_page_1024(rt_device_t dev, rt_off_t pos, con
{
rt_uint32_t index, nr;
const uint8_t * write_buffer = buffer;
+ uint32_t page = pos;
nr = size;
for (index = 0; index < nr; index++)
{
- uint32_t page = pos;
uint8_t send_buffer[4];
send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
diff --git a/components/drivers/spi/spi_wifi_rw009.c b/components/drivers/spi/spi_wifi_rw009.c
index 9f5601bf26..5faf63642a 100644
--- a/components/drivers/spi/spi_wifi_rw009.c
+++ b/components/drivers/spi/spi_wifi_rw009.c
@@ -21,6 +21,7 @@
* Date Author Notes
* 2014-07-31 aozima the first version
* 2014-09-18 aozima update command & response.
+ * 2017-07-28 armink fix auto reconnect feature
*/
#include <rtthread.h>
@@ -165,6 +166,8 @@ static void resp_handler(struct rw009_wifi *wifi_device, struct rw009_resp *resp
}
else
{
+ wifi_device->active = 1;
+ eth_device_linkchange(&wifi_device->parent, RT_FALSE);
WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result );
}