mirror of
https://gitee.com/Vancouver2017/luban-lite.git
synced 2025-12-17 09:38:55 +00:00
V1.0.5
This commit is contained in:
@@ -300,7 +300,11 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
|
||||
|
||||
dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
|
||||
/* open can rx interrupt */
|
||||
can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
|
||||
/* If TX/RX/ERR interrupt is enabled in rt_can_open(),
|
||||
* an error interrupt will be triggered if CAN data is received
|
||||
* because the CAN baudrate has not been configured.
|
||||
*/
|
||||
// can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,11 +336,11 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
|
||||
|
||||
dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
|
||||
/* open can tx interrupt */
|
||||
can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX);
|
||||
// can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX);
|
||||
}
|
||||
}
|
||||
|
||||
can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_CAN_INT_ERR);
|
||||
// can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_CAN_INT_ERR);
|
||||
|
||||
#ifdef RT_CAN_USING_HDR
|
||||
if (can->hdr == RT_NULL)
|
||||
|
||||
@@ -102,6 +102,26 @@ rt_err_t rt_i2c_control(struct rt_i2c_bus_device *bus,
|
||||
}
|
||||
}
|
||||
|
||||
rt_err_t rt_i2c_slave_control(struct rt_i2c_bus_device *bus,
|
||||
rt_uint32_t cmd,
|
||||
void *arg)
|
||||
{
|
||||
rt_err_t ret;
|
||||
|
||||
if(bus->ops->i2c_slave_control)
|
||||
{
|
||||
ret = bus->ops->i2c_slave_control(bus, cmd, arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("I2C bus operation not supported");
|
||||
|
||||
return -RT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus,
|
||||
rt_uint16_t addr,
|
||||
rt_uint16_t flags,
|
||||
|
||||
@@ -88,6 +88,13 @@ static rt_err_t i2c_bus_device_control(rt_device_t dev,
|
||||
return -RT_EIO;
|
||||
}
|
||||
break;
|
||||
case RT_I2C_DEV_SLAVE_CONFIG:
|
||||
ret = rt_i2c_slave_control(bus, cmd, args);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -RT_EIO;
|
||||
}
|
||||
break;
|
||||
case RT_I2C_DEV_CTRL_CLK:
|
||||
bus_clock = *(rt_uint32_t *)args;
|
||||
ret = rt_i2c_control(bus, cmd, bus_clock);
|
||||
|
||||
@@ -23,10 +23,13 @@ struct rt_adc_ops
|
||||
rt_err_t (*config_dma)(struct rt_adc_device *device, void *dma_info);
|
||||
rt_err_t (*get_dma_data)(struct rt_adc_device *device,
|
||||
rt_uint32_t channel);
|
||||
rt_uint32_t (*get_irq_count)(struct rt_adc_device *device,
|
||||
rt_uint32_t channel);
|
||||
rt_err_t (*get_mode)(struct rt_adc_device *device, void *chan_info);
|
||||
rt_uint32_t (*get_obtaining_data_mode)(struct rt_adc_device *device,
|
||||
rt_uint32_t channel);
|
||||
rt_uint32_t (*get_irq_count)(struct rt_adc_device *device,
|
||||
rt_uint32_t channel);
|
||||
rt_err_t (*irq_callback)(struct rt_adc_device *device, void *dma_info);
|
||||
rt_err_t (*get_ch_info)(struct rt_adc_device *device, void *chan_info);
|
||||
#endif
|
||||
#ifdef AIC_PSADC_DRV
|
||||
rt_err_t (*get_adc_values_poll)(struct rt_adc_device *device,
|
||||
@@ -57,11 +60,14 @@ typedef enum
|
||||
RT_ADC_CMD_GET_DMA_DATA = RT_DEVICE_CTRL_BASE(ADC) + 6,
|
||||
RT_ADC_CMD_CONFIG_DMA = RT_DEVICE_CTRL_BASE(ADC) + 7,
|
||||
RT_ADC_CMD_OBTAIN_DATA_MODE = RT_DEVICE_CTRL_BASE(ADC) + 8,
|
||||
RT_ADC_CMD_IRQ_CALLBACK = RT_DEVICE_CTRL_BASE(ADC) + 9,
|
||||
RT_ADC_CMD_GET_CH_INFO = RT_DEVICE_CTRL_BASE(ADC) + 10,
|
||||
RT_ADC_CMD_GET_MODE = RT_DEVICE_CTRL_BASE(ADC) + 11,
|
||||
#endif
|
||||
#ifdef AIC_PSADC_DRV
|
||||
RT_ADC_CMD_GET_VALUES_POLL = RT_DEVICE_CTRL_BASE(ADC) + 9,
|
||||
RT_ADC_CMD_GET_VALUES = RT_DEVICE_CTRL_BASE(ADC) + 10,
|
||||
RT_ADC_CMD_GET_CHAN_COUNT = RT_DEVICE_CTRL_BASE(ADC) + 11,
|
||||
RT_ADC_CMD_GET_VALUES_POLL = RT_DEVICE_CTRL_BASE(ADC) + 12,
|
||||
RT_ADC_CMD_GET_VALUES = RT_DEVICE_CTRL_BASE(ADC) + 13,
|
||||
RT_ADC_CMD_GET_CHAN_COUNT = RT_DEVICE_CTRL_BASE(ADC) + 14,
|
||||
#endif
|
||||
} rt_adc_cmd_t;
|
||||
|
||||
|
||||
@@ -47,6 +47,9 @@ struct rt_i2c_bus_device_ops
|
||||
rt_err_t (*i2c_bus_control)(struct rt_i2c_bus_device *bus,
|
||||
rt_uint32_t,
|
||||
rt_uint32_t);
|
||||
rt_err_t (*i2c_slave_control)(struct rt_i2c_bus_device *bus,
|
||||
rt_uint32_t,
|
||||
void *);
|
||||
};
|
||||
|
||||
/*for i2c bus driver*/
|
||||
@@ -76,6 +79,9 @@ rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
|
||||
rt_err_t rt_i2c_control(struct rt_i2c_bus_device *bus,
|
||||
rt_uint32_t cmd,
|
||||
rt_uint32_t arg);
|
||||
rt_err_t rt_i2c_slave_control(struct rt_i2c_bus_device *bus,
|
||||
rt_uint32_t cmd,
|
||||
void *arg);
|
||||
rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus,
|
||||
rt_uint16_t addr,
|
||||
rt_uint16_t flags,
|
||||
|
||||
@@ -23,6 +23,7 @@ extern "C" {
|
||||
#define RT_I2C_DEV_CTRL_TIMEOUT (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x03)
|
||||
#define RT_I2C_DEV_CTRL_RW (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x04)
|
||||
#define RT_I2C_DEV_CTRL_CLK (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x05)
|
||||
#define RT_I2C_DEV_SLAVE_CONFIG (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x06)
|
||||
|
||||
struct rt_i2c_priv_data
|
||||
{
|
||||
|
||||
@@ -126,6 +126,9 @@ extern "C" {
|
||||
#define RT_SENSOR_CTRL_SET_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 4) /* Set sensor's work mode. ex. RT_SENSOR_MODE_POLLING,RT_SENSOR_MODE_INT */
|
||||
#define RT_SENSOR_CTRL_SET_POWER (RT_DEVICE_CTRL_BASE(Sensor) + 5) /* Set power mode. args type of sensor power mode. ex. RT_SENSOR_POWER_DOWN,RT_SENSOR_POWER_NORMAL */
|
||||
#define RT_SENSOR_CTRL_SELF_TEST (RT_DEVICE_CTRL_BASE(Sensor) + 6) /* Take a self test */
|
||||
#ifdef AIC_TSEN_DRV
|
||||
#define RT_SENSOR_CTRL_GET_CH_INFO (RT_DEVICE_CTRL_BASE(Sensor) + 7) /* Get sensor chan info */
|
||||
#endif
|
||||
|
||||
#define RT_SENSOR_CTRL_USER_CMD_START 0x100 /* User commands should be greater than 0x100 */
|
||||
|
||||
|
||||
@@ -65,6 +65,12 @@
|
||||
#define RT_SERIAL_EVENT_TX_DMADONE 0x04 /* Tx DMA transfer done */
|
||||
#define RT_SERIAL_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */
|
||||
|
||||
#define RT_SERIAL_DMA_FCH_BUFFER 50 /* DMA mode flow control high level buffer */
|
||||
#define RT_SERIAL_DMA_FCL_BUFFER 100 /* DMA mode flow control low level buffer */
|
||||
|
||||
#define RT_SERIAL_INT_FCH_BUFFER 50 /* INT mode flow control high level buffer */
|
||||
#define RT_SERIAL_INT_FCL_BUFFER 100 /* INT mode flow control low level buffer */
|
||||
|
||||
#define RT_SERIAL_DMA_RX 0x01
|
||||
#define RT_SERIAL_DMA_TX 0x02
|
||||
|
||||
@@ -81,9 +87,26 @@
|
||||
#define RT_SERIAL_FLOWCONTROL_CTSRTS 1
|
||||
#define RT_SERIAL_FLOWCONTROL_NONE 0
|
||||
|
||||
#define RT_SERIAL_RS485_MODE 1 /* ArtInChip Uart 485 mode flag */
|
||||
#define RT_SERIAL_RS485_MODE 1 /* ArtInChip Uart 485 mode flag */
|
||||
#define RT_SERIAL_RS485_SIMULATION_MODE 7 /* ArtInChip Uart simulation 485 mode flag */
|
||||
#define RT_SERIAL_RS485_RTS_LOW 0x80 /* ArtInChip Uart 485 RTS_Pin Low level*/
|
||||
#define RT_SERIAL_RS485_RTS_HIGH 0x81 /* ArtInChip Uart 485 RTS_Pin High Level */
|
||||
#define RT_SERIAL_232_RESUME_DATA 0x83
|
||||
#define RT_SERIAL_232_SUSPEND_DATA 0x84
|
||||
#define RT_SERIAL_SW_FLOW_CTRL 0x85
|
||||
#define RT_SERIAL_SW_RECEIVE_ON_OFF 0x86
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RT_SERIAL_FUNC_RS232 = 0, ///< RS232
|
||||
RT_SERIAL_FUNC_RS485 = 1, ///< RS485 normal
|
||||
RT_SERIAL_FUNC_RS485_COMACT_IO = 2, ///< RS485 compact io
|
||||
RT_SERIAL_RS232_AUTO_FLOW_CTRL = 3, ///< RS232 flow conctrol
|
||||
RT_SERIAL_RS232_UNAUTO_FLOW_CTRL = 4, ///< RS232 hardware unauto flow conctrol
|
||||
RT_SERIAL_RS232_SW_FLOW_CTRL = 5, ///< RS232 software flow conctrol
|
||||
RT_SERIAL_RS232_SW_HW_FLOW_CTRL = 6, ///< RS232 software and hardware flow conctrol
|
||||
}rt_serial_mode;
|
||||
|
||||
|
||||
/* Default config for serial_configure structure */
|
||||
#define RT_SERIAL_CONFIG_DEFAULT \
|
||||
@@ -98,8 +121,10 @@
|
||||
RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \
|
||||
0, \
|
||||
259, \
|
||||
USART_FUNC_RS232, \
|
||||
0, \
|
||||
0, \
|
||||
0, \
|
||||
0, \
|
||||
0, \
|
||||
0x0F \
|
||||
}
|
||||
|
||||
@@ -118,6 +143,8 @@ struct serial_configure
|
||||
rt_uint32_t flag;
|
||||
rt_uint32_t function :4;
|
||||
rt_uint32_t flow_ctrl_suspend :1;
|
||||
rt_uint32_t flowctrl_cts_enable :1;
|
||||
rt_uint32_t flowctrl_rts_enable :1;
|
||||
rt_uint32_t uart_index :4;
|
||||
};
|
||||
|
||||
@@ -186,4 +213,7 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
|
||||
rt_uint32_t flag,
|
||||
void *data);
|
||||
|
||||
void rt_flowctrl_low_detect(struct rt_serial_device *serial, rt_size_t len, rt_size_t flow_ctrl_low_flag);
|
||||
void rt_flowctrl_high_detect(struct rt_serial_device *serial, rt_size_t len, rt_size_t flow_ctrl_low_flag);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -81,20 +81,30 @@ static rt_err_t _adc_control(rt_device_t dev, int cmd, void *args)
|
||||
else if (cmd == RT_ADC_CMD_CONFIG_DMA && adc->ops->config_dma)
|
||||
{
|
||||
return adc->ops->config_dma(adc, args);
|
||||
|
||||
}
|
||||
else if (cmd == RT_ADC_CMD_GET_DMA_DATA && adc->ops->get_dma_data)
|
||||
{
|
||||
return adc->ops->get_dma_data(adc, (rt_uint32_t)(long)args);
|
||||
|
||||
}
|
||||
else if (cmd == RT_ADC_CMD_GET_MODE && adc->ops->get_mode)
|
||||
{
|
||||
return adc->ops->get_mode(adc, args);
|
||||
}
|
||||
else if (cmd == RT_ADC_CMD_OBTAIN_DATA_MODE && adc->ops->get_obtaining_data_mode)
|
||||
{
|
||||
return adc->ops->get_obtaining_data_mode(adc, (rt_uint32_t)(long)args);
|
||||
}
|
||||
else if (cmd == RT_ADC_CMD_IRQ_COUNT && adc->ops->get_irq_count)
|
||||
{
|
||||
return adc->ops->get_irq_count(adc, (rt_uint32_t)(long)args);
|
||||
}
|
||||
else if (cmd == RT_ADC_CMD_OBTAIN_DATA_MODE && adc->ops->get_obtaining_data_mode)
|
||||
else if (cmd == RT_ADC_CMD_IRQ_CALLBACK && adc->ops->irq_callback)
|
||||
{
|
||||
return adc->ops->get_obtaining_data_mode(adc, (rt_uint32_t)(long)args);
|
||||
return adc->ops->irq_callback(adc, args);
|
||||
}
|
||||
else if (cmd == RT_ADC_CMD_GET_CH_INFO && adc->ops->get_ch_info)
|
||||
{
|
||||
return adc->ops->get_ch_info(adc, args);
|
||||
}
|
||||
#endif
|
||||
else if (cmd == RT_ADC_CMD_GET_VREF && adc->ops->get_vref && args)
|
||||
|
||||
@@ -181,327 +181,4 @@ rt_err_t rt_mtd_nand_mark_badblock(struct rt_mtd_nand_device *device, rt_uint32_
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(RT_MTD_NAND_DEBUG) && defined(RT_USING_FINSH)
|
||||
#include <finsh.h>
|
||||
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
|
||||
|
||||
static void mtd_dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
|
||||
{
|
||||
unsigned char *buf = (unsigned char *)ptr;
|
||||
int i, j;
|
||||
for (i = 0; i < buflen; i += 16)
|
||||
{
|
||||
rt_kprintf("%06x: ", i);
|
||||
for (j = 0; j < 16; j++)
|
||||
if (i + j < buflen)
|
||||
rt_kprintf("%02x ", buf[i + j]);
|
||||
else
|
||||
rt_kprintf(" ");
|
||||
rt_kprintf(" ");
|
||||
for (j = 0; j < 16; j++)
|
||||
if (i + j < buflen)
|
||||
rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
|
||||
rt_kprintf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int mtd_nandid(const char *name)
|
||||
{
|
||||
struct rt_mtd_nand_device *nand;
|
||||
nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
|
||||
if (nand == RT_NULL)
|
||||
{
|
||||
rt_kprintf("no nand device found!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return rt_mtd_nand_read_id(nand);
|
||||
}
|
||||
|
||||
int mtd_nand_read(const char *name, int block, int page)
|
||||
{
|
||||
rt_err_t result;
|
||||
rt_uint8_t *page_ptr;
|
||||
rt_uint8_t *oob_ptr;
|
||||
struct rt_mtd_nand_device *nand;
|
||||
|
||||
nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
|
||||
if (nand == RT_NULL)
|
||||
{
|
||||
rt_kprintf("no nand device found!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
page_ptr = rt_malloc(nand->page_size + nand->oob_size);
|
||||
if (page_ptr == RT_NULL)
|
||||
{
|
||||
rt_kprintf("out of memory!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
oob_ptr = page_ptr + nand->page_size;
|
||||
rt_memset(page_ptr, 0xff, nand->page_size + nand->oob_size);
|
||||
|
||||
/* calculate the page number */
|
||||
page = block * nand->pages_per_block + page;
|
||||
result = rt_mtd_nand_read(nand, page, page_ptr, nand->page_size,
|
||||
oob_ptr, nand->oob_size);
|
||||
|
||||
rt_kprintf("read page, rc=%d\n", result);
|
||||
mtd_dump_hex(page_ptr, nand->page_size);
|
||||
mtd_dump_hex(oob_ptr, nand->oob_size);
|
||||
|
||||
rt_free(page_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_speed(char *msg, u32 len, u32 us)
|
||||
{
|
||||
u32 tmp, speed;
|
||||
|
||||
/* Split to serval step to avoid overflow */
|
||||
tmp = 1000 * len;
|
||||
tmp = tmp / us;
|
||||
tmp = 1000 * tmp;
|
||||
speed = tmp / 1024;
|
||||
|
||||
rt_kprintf("%s: %d byte, %d us -> %d KB/s\n", msg, len, us, speed);
|
||||
}
|
||||
|
||||
int mtd_nand_read_cont(const char *name, int block, int page, int size)
|
||||
{
|
||||
rt_err_t result;
|
||||
rt_uint8_t *data_ptr;
|
||||
struct rt_mtd_nand_device *nand;
|
||||
rt_uint64_t start_us;
|
||||
|
||||
nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
|
||||
if (nand == RT_NULL)
|
||||
{
|
||||
rt_kprintf("no nand device found!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
data_ptr = rt_malloc_align(size, CACHE_LINE_SIZE);
|
||||
if (data_ptr == RT_NULL)
|
||||
{
|
||||
rt_kprintf("out of memory!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_memset(data_ptr, 0xff, size);
|
||||
|
||||
/* calculate the page number */
|
||||
page = block * nand->pages_per_block + page;
|
||||
start_us = aic_get_time_us();
|
||||
result = rt_mtd_nand_read_cont(nand, page, data_ptr, size);
|
||||
show_speed("read speed", size, aic_get_time_us() - start_us);
|
||||
rt_kprintf("cont read page, rc=%d\n", result);
|
||||
|
||||
mtd_dump_hex(data_ptr, size);
|
||||
|
||||
rt_free_align(data_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtd_nand_readoob(const char *name, int block, int page)
|
||||
{
|
||||
struct rt_mtd_nand_device *nand;
|
||||
rt_uint8_t *oob_ptr;
|
||||
|
||||
nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
|
||||
if (nand == RT_NULL)
|
||||
{
|
||||
rt_kprintf("no nand device found!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
oob_ptr = rt_malloc(nand->oob_size);
|
||||
if (oob_ptr == RT_NULL)
|
||||
{
|
||||
rt_kprintf("out of memory!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
/* calculate the page number */
|
||||
page = block * nand->pages_per_block + page;
|
||||
rt_mtd_nand_read(nand, page, RT_NULL, nand->page_size,
|
||||
oob_ptr, nand->oob_size);
|
||||
mtd_dump_hex(oob_ptr, nand->oob_size);
|
||||
|
||||
rt_free(oob_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtd_nand_write(const char *name, int block, int page)
|
||||
{
|
||||
rt_err_t result;
|
||||
rt_uint8_t *page_ptr;
|
||||
rt_uint8_t *oob_ptr;
|
||||
rt_uint32_t index;
|
||||
struct rt_mtd_nand_device *nand;
|
||||
|
||||
nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
|
||||
if (nand == RT_NULL)
|
||||
{
|
||||
rt_kprintf("no nand device found!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
page_ptr = rt_malloc(nand->page_size + nand->oob_size);
|
||||
if (page_ptr == RT_NULL)
|
||||
{
|
||||
rt_kprintf("out of memory!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
oob_ptr = page_ptr + nand->page_size;
|
||||
/* prepare page data */
|
||||
for (index = 0; index < nand->page_size; index ++)
|
||||
{
|
||||
page_ptr[index] = index & 0xff;
|
||||
}
|
||||
/* prepare oob data */
|
||||
for (index = 0; index < nand->oob_size; index ++)
|
||||
{
|
||||
oob_ptr[index] = index & 0xff;
|
||||
}
|
||||
|
||||
/* calculate the page number */
|
||||
page = block * nand->pages_per_block + page;
|
||||
result = rt_mtd_nand_write(nand, page, page_ptr, nand->page_size,
|
||||
oob_ptr, nand->oob_size);
|
||||
if (result != RT_MTD_EOK)
|
||||
{
|
||||
rt_kprintf("write page failed!, rc=%d\n", result);
|
||||
}
|
||||
|
||||
rt_free(page_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtd_nand_erase(const char *name, int block)
|
||||
{
|
||||
struct rt_mtd_nand_device *nand;
|
||||
nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
|
||||
if (nand == RT_NULL)
|
||||
{
|
||||
rt_kprintf("no nand device found!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return rt_mtd_nand_erase_block(nand, block);
|
||||
}
|
||||
|
||||
int mtd_nand_erase_all(const char *name)
|
||||
{
|
||||
rt_uint32_t index = 0;
|
||||
struct rt_mtd_nand_device *nand;
|
||||
|
||||
nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
|
||||
if (nand == RT_NULL)
|
||||
{
|
||||
rt_kprintf("no nand device found!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
for (index = 0; index < (nand->block_end - nand->block_start); index ++)
|
||||
{
|
||||
rt_mtd_nand_erase_block(nand, index);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
static void mtd_nand(int argc, char **argv)
|
||||
{
|
||||
/* If the number of arguments less than 2 */
|
||||
if (argc < 3)
|
||||
{
|
||||
help:
|
||||
rt_kprintf("\n");
|
||||
rt_kprintf("mtd_nand [OPTION] [PARAM ...]\n");
|
||||
rt_kprintf(" id <name> Get nandid by given name\n");
|
||||
rt_kprintf(" read <name> <bn> <pn> Read data on page <pn> of block <bn> of device <name>\n");
|
||||
rt_kprintf(" readcont <name> <bn> <pn> <size> Read size data on page <pn> of block <bn> of device <name>\n");
|
||||
rt_kprintf(" readoob <name> <bn> <pn> Read oob on page <pn> of block <bn> of device <name>\n");
|
||||
rt_kprintf(" write <name> <bn> <pn> Run write test on page <pn> of block <bn> of device <name>\n");
|
||||
rt_kprintf(" erase <name> <bn> Erase on block <bn> of device <name>\n");
|
||||
rt_kprintf(" eraseall <name> Erase all block on device <name>\n");
|
||||
return;
|
||||
}
|
||||
else if (!rt_strcmp(argv[1], "id"))
|
||||
{
|
||||
mtd_nandid(argv[2]);
|
||||
}
|
||||
else if (!rt_strcmp(argv[1], "read"))
|
||||
{
|
||||
if (argc < 5)
|
||||
{
|
||||
rt_kprintf("The input parameters are too few!\n");
|
||||
goto help;
|
||||
}
|
||||
mtd_nand_read(argv[2], atoi(argv[3]), atoi(argv[4]));
|
||||
}
|
||||
else if (!rt_strcmp(argv[1], "readcont"))
|
||||
{
|
||||
if (argc < 6)
|
||||
{
|
||||
rt_kprintf("The input parameters are too few!\n");
|
||||
goto help;
|
||||
}
|
||||
mtd_nand_read_cont(argv[2], atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
|
||||
}
|
||||
else if (!rt_strcmp(argv[1], "readoob"))
|
||||
{
|
||||
if (argc < 5)
|
||||
{
|
||||
rt_kprintf("The input parameters are too few!\n");
|
||||
goto help;
|
||||
}
|
||||
mtd_nand_readoob(argv[2], atoi(argv[3]), atoi(argv[4]));
|
||||
}
|
||||
else if (!rt_strcmp(argv[1], "write"))
|
||||
{
|
||||
if (argc < 5)
|
||||
{
|
||||
rt_kprintf("The input parameters are too few!\n");
|
||||
goto help;
|
||||
}
|
||||
mtd_nand_write(argv[2], atoi(argv[3]), atoi(argv[4]));
|
||||
}
|
||||
else if (!rt_strcmp(argv[1], "erase"))
|
||||
{
|
||||
if (argc < 4)
|
||||
{
|
||||
rt_kprintf("The input parameters are too few!\n");
|
||||
goto help;
|
||||
}
|
||||
mtd_nand_erase(argv[2], atoi(argv[3]));
|
||||
}
|
||||
else if (!rt_strcmp(argv[1], "eraseall"))
|
||||
{
|
||||
mtd_nand_erase_all(argv[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("Input parameters are not supported!\n");
|
||||
goto help;
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT(mtd_nand, MTD nand device test function);
|
||||
#endif /* RT_USING_FINSH */
|
||||
|
||||
#ifndef RT_USING_FINSH_ONLY
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nandid, nand_id, read ID - nandid(name));
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_read, nand_read, read page in nand - nand_read(name, block, page));
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_readoob, nand_readoob, read spare data in nand - nand_readoob(name, block, page));
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_write, nand_write, write dump data to nand - nand_write(name, block, page));
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase, nand_erase, nand_erase(name, block));
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase_all, nand_erase_all, erase all of nand device - nand_erase_all(name, block));
|
||||
#endif /* RT_USING_FINSH_ONLY */
|
||||
|
||||
#endif /* defined(RT_MTD_NAND_DEBUG) && defined(RT_USING_FINSH) */
|
||||
|
||||
#endif /* RT_USING_MTD_NAND */
|
||||
|
||||
@@ -310,17 +310,6 @@ static rt_bool_t _pm_device_check_idle(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef AIC_CHIP_AIC1606SP
|
||||
//check CSYS/SCSS/SESS is idle
|
||||
volatile uint32_t cpu_status = 0;
|
||||
#define PRCM_CPU_STATUS 0x8800010C
|
||||
|
||||
cpu_status = readl((void *)PRCM_CPU_STATUS);
|
||||
if (cpu_status == 0x7)
|
||||
return RT_TRUE;
|
||||
else
|
||||
return RT_FALSE;
|
||||
#endif
|
||||
|
||||
return RT_TRUE;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
#endif /* RT_SDIO_DEBUG */
|
||||
#include <rtdbg.h>
|
||||
|
||||
#ifdef AIC_AB_SYSTEM_INTERFACE
|
||||
#include <absystem.h>
|
||||
#include <boot_param.h>
|
||||
#endif
|
||||
|
||||
#define BLK_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
@@ -217,14 +221,86 @@ static rt_err_t rt_mmcsd_close(rt_device_t dev)
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t mmcsd_erase(struct mmcsd_blk_device *blk_dev, u64 start,
|
||||
u64 blkcnt)
|
||||
{
|
||||
rt_err_t err;
|
||||
u64 start_temp = 0, end_temp = 0;
|
||||
struct rt_mmcsd_cmd cmd;
|
||||
struct dfs_partition *part = &blk_dev->part;
|
||||
struct rt_mmcsd_card *card = blk_dev->card;
|
||||
|
||||
start = start + part->offset;
|
||||
|
||||
if (!(card->flags & CARD_FLAG_SDHC))
|
||||
{
|
||||
start_temp = start << 9;
|
||||
end_temp = (start + blkcnt - 1) << 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
start_temp = start;
|
||||
end_temp = start + blkcnt - 1;
|
||||
}
|
||||
|
||||
rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
|
||||
|
||||
if (card->card_type == CARD_TYPE_MMC)
|
||||
cmd.cmd_code = ERASE_GROUP_START;
|
||||
else
|
||||
cmd.cmd_code = ERASE_GROUP_START - 3;
|
||||
cmd.arg = start_temp;
|
||||
cmd.flags = RESP_R1;
|
||||
|
||||
err = mmcsd_send_cmd(card->host, &cmd, 0);
|
||||
if (err) {
|
||||
LOG_E("mmcsd_erase send ERASE_GROUP_START ERROR!");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
|
||||
|
||||
if (card->card_type == CARD_TYPE_MMC)
|
||||
cmd.cmd_code = ERASE_GROUP_END;
|
||||
else
|
||||
cmd.cmd_code = ERASE_GROUP_END - 3;
|
||||
cmd.arg = end_temp;
|
||||
cmd.flags = RESP_R1;
|
||||
|
||||
err = mmcsd_send_cmd(card->host, &cmd, 0);
|
||||
if (err) {
|
||||
LOG_E("mmcsd_erase send ERASE_GROUP_END ERROR!");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
|
||||
|
||||
cmd.cmd_code = ERASE;
|
||||
cmd.arg = 0;
|
||||
cmd.flags = RESP_R1B;
|
||||
|
||||
err = mmcsd_send_cmd(card->host, &cmd, 0);
|
||||
if (err) {
|
||||
LOG_E("mmcsd_erase send ERASE ERROR!");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rt_mmcsd_control(rt_device_t dev, int cmd, void *args)
|
||||
{
|
||||
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
|
||||
u64 *p = (u64 *)args;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_BLK_GETGEOME:
|
||||
rt_memcpy(args, &blk_dev->geometry, sizeof(struct rt_device_blk_geometry));
|
||||
break;
|
||||
case RT_DEVICE_CTRL_BLK_ERASE:
|
||||
mmcsd_erase(blk_dev, p[0], p[1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -414,6 +490,22 @@ static struct mmcsd_blk_device * rt_mmcsd_create_blkdev(struct rt_mmcsd_card *ca
|
||||
if ( blk_dev )
|
||||
{
|
||||
LOG_D("Try to mount %s\n", blk_dev->dev.parent.name);
|
||||
#ifdef AIC_AB_SYSTEM_INTERFACE
|
||||
char target[32] = { 0 };
|
||||
enum boot_device boot_dev = aic_get_boot_device();
|
||||
|
||||
if (boot_dev == BD_SDMC0) {
|
||||
if ((strcmp("mmc0p5", blk_dev->dev.parent.name) == 0) ||
|
||||
(strcmp("mmc0p6", blk_dev->dev.parent.name) == 0)) {
|
||||
aic_ota_status_update();
|
||||
aic_get_mmc_rodata_to_mount(target);
|
||||
|
||||
if (dfs_mount(target, "/rodata", "elm", 0, 0) == 0)
|
||||
LOG_I("mount fs[elm] device[%s] to /rodata ok.\n", target);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* try to mount file system on this block device */
|
||||
dfs_mount_device(&(blk_dev->dev));
|
||||
}
|
||||
@@ -487,11 +579,12 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
||||
ops.blk_read = mmcsd_read;
|
||||
aic_disk_part_set_ops(&ops);
|
||||
dev_desc.blksz = card->card_blksize;
|
||||
dev_desc.lba_count = card->card_capacity * (1024 / card->card_blksize);
|
||||
dev_desc.lba_count = card->card_capacity * (1024 / 512);
|
||||
dev_desc.priv = card;
|
||||
parts = aic_disk_get_parts(&dev_desc);
|
||||
p = parts;
|
||||
i = 0;
|
||||
memset(&part, 0, sizeof(part));
|
||||
while (p) {
|
||||
/* Given name is with allocated host id and its partition index. */
|
||||
if (card->card_type == CARD_TYPE_MMC)
|
||||
@@ -519,7 +612,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
||||
rt_snprintf(dname, sizeof(dname), "mmc%d", host_id);
|
||||
else
|
||||
rt_snprintf(dname, sizeof(dname), "sd%d", host_id);
|
||||
blk_dev = rt_mmcsd_create_blkdev(card, (const char*)dname, RT_NULL);
|
||||
blk_dev = rt_mmcsd_create_blkdev(card, (const char*)dname, &part);
|
||||
if ( blk_dev == RT_NULL )
|
||||
{
|
||||
err = -RT_ENOMEM;
|
||||
|
||||
@@ -304,6 +304,19 @@ rt_inline int _serial_int_rx(struct rt_serial_device *serial, rt_uint8_t *data,
|
||||
/* otherwise there's the data: */
|
||||
ch = rx_fifo->buffer[rx_fifo->get_index];
|
||||
rx_fifo->get_index += 1;
|
||||
|
||||
if (serial->config.function == RT_SERIAL_RS232_UNAUTO_FLOW_CTRL ||
|
||||
serial->config.function == RT_SERIAL_RS232_SW_FLOW_CTRL ||
|
||||
serial->config.function == RT_SERIAL_RS232_SW_HW_FLOW_CTRL )
|
||||
{
|
||||
if (serial->config.flowctrl_rts_enable == 1)
|
||||
{
|
||||
rt_flowctrl_low_detect(serial, 1, RT_SERIAL_INT_FCL_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
|
||||
|
||||
if (rx_fifo->is_full == RT_TRUE)
|
||||
@@ -398,6 +411,83 @@ static rt_size_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial)
|
||||
}
|
||||
#endif /* RT_USING_POSIX_STDIO || RT_SERIAL_USING_DMA */
|
||||
|
||||
/**
|
||||
* Flow control high level detect.
|
||||
*
|
||||
* @param serial serial device
|
||||
* @param len received length for this transmit
|
||||
* @param flow_ctrl_high_flag flow control high level buffer
|
||||
*/
|
||||
void rt_flowctrl_high_detect(struct rt_serial_device *serial, rt_size_t len, rt_size_t flow_ctrl_high_flag)
|
||||
{
|
||||
struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
|
||||
rt_size_t temp = 0;
|
||||
|
||||
RT_ASSERT(rx_fifo != RT_NULL);
|
||||
|
||||
if ((rx_fifo->get_index <= rx_fifo->put_index) &&
|
||||
(serial->config.flow_ctrl_suspend == 0))
|
||||
{
|
||||
temp = rx_fifo->put_index + len - rx_fifo->get_index;
|
||||
if (temp >= serial->config.bufsz - flow_ctrl_high_flag)
|
||||
{
|
||||
serial->ops->control(serial, RT_SERIAL_232_SUSPEND_DATA, NULL);
|
||||
serial->config.flow_ctrl_suspend = 1;
|
||||
LOG_D("uart rs232 suspend data!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = rx_fifo->put_index + len + serial->config.bufsz - rx_fifo->get_index;
|
||||
if ((temp >= serial->config.bufsz - flow_ctrl_high_flag) &&
|
||||
(serial->config.flow_ctrl_suspend == 0))
|
||||
{
|
||||
serial->ops->control(serial, RT_SERIAL_232_SUSPEND_DATA, NULL);
|
||||
serial->config.flow_ctrl_suspend = 1;
|
||||
LOG_D("uart rs232 suspend data!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow control low level detect.
|
||||
*
|
||||
* @param serial serial device
|
||||
* @param len received length for this transmit
|
||||
* @param flow_ctrl_low_flag flow control low level buffer
|
||||
*/
|
||||
void rt_flowctrl_low_detect(struct rt_serial_device *serial, rt_size_t len, rt_size_t flow_ctrl_low_flag)
|
||||
{
|
||||
struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
|
||||
rt_size_t temp = 0;
|
||||
|
||||
RT_ASSERT(rx_fifo != RT_NULL);
|
||||
RT_ASSERT(len <= rt_dma_calc_recved_len(serial));
|
||||
|
||||
if ((rx_fifo->get_index <= rx_fifo->put_index) &&
|
||||
serial->config.flow_ctrl_suspend == 1)
|
||||
{
|
||||
temp = rx_fifo->put_index - len - rx_fifo->get_index;
|
||||
if (temp <= serial->config.bufsz - flow_ctrl_low_flag)
|
||||
{
|
||||
serial->ops->control(serial, RT_SERIAL_232_RESUME_DATA, NULL);
|
||||
serial->config.flow_ctrl_suspend = 0;
|
||||
LOG_D("uart rs232 resume data!");
|
||||
}
|
||||
}
|
||||
else if ((rx_fifo->get_index > rx_fifo->put_index) &&
|
||||
serial->config.flow_ctrl_suspend == 1)
|
||||
{
|
||||
temp = rx_fifo->put_index - len + serial->config.bufsz - rx_fifo->get_index;
|
||||
if (temp <= serial->config.bufsz - flow_ctrl_low_flag)
|
||||
{
|
||||
serial->ops->control(serial, RT_SERIAL_232_RESUME_DATA, NULL);
|
||||
serial->config.flow_ctrl_suspend = 0;
|
||||
LOG_D("uart rs232 resume data!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RT_SERIAL_USING_DMA
|
||||
/**
|
||||
* Calculate DMA received data length.
|
||||
@@ -535,6 +625,17 @@ rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data,
|
||||
rt_memcpy(data + serial->config.bufsz - rx_fifo->get_index, rx_fifo->buffer,
|
||||
recv_len + rx_fifo->get_index - serial->config.bufsz);
|
||||
}
|
||||
|
||||
if (serial->config.function == RT_SERIAL_RS232_UNAUTO_FLOW_CTRL ||
|
||||
serial->config.function == RT_SERIAL_RS232_SW_FLOW_CTRL ||
|
||||
serial->config.function == RT_SERIAL_RS232_SW_HW_FLOW_CTRL)
|
||||
{
|
||||
if (serial->config.flowctrl_rts_enable == 1)
|
||||
{
|
||||
rt_flowctrl_low_detect(serial, recv_len, RT_SERIAL_DMA_FCL_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
rt_dma_recv_update_get_index(serial, recv_len);
|
||||
rt_hw_interrupt_enable(level);
|
||||
return recv_len;
|
||||
@@ -857,7 +958,7 @@ static rt_size_t rt_serial_read(struct rt_device *dev,
|
||||
|
||||
if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
|
||||
{
|
||||
if (serial->config.function == RT_SERIAL_RS485_MODE) {
|
||||
if (serial->config.function == RT_SERIAL_RS485_SIMULATION_MODE) {
|
||||
serial->ops->control(serial, RT_SERIAL_RS485_RTS_LOW, RT_NULL);
|
||||
}
|
||||
return _serial_int_rx(serial, (rt_uint8_t *)buffer, size);
|
||||
@@ -869,7 +970,7 @@ static rt_size_t rt_serial_read(struct rt_device *dev,
|
||||
}
|
||||
#endif /* RT_SERIAL_USING_DMA */
|
||||
|
||||
if (serial->config.function == RT_SERIAL_RS485_MODE) {
|
||||
if (serial->config.function == RT_SERIAL_RS485_SIMULATION_MODE) {
|
||||
serial->ops->control(serial, RT_SERIAL_RS485_RTS_LOW, RT_NULL);
|
||||
}
|
||||
return _serial_poll_rx(serial, (rt_uint8_t *)buffer, size);
|
||||
@@ -889,7 +990,7 @@ static rt_size_t rt_serial_write(struct rt_device *dev,
|
||||
|
||||
if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
|
||||
{
|
||||
if (serial->config.function == RT_SERIAL_RS485_MODE) {
|
||||
if (serial->config.function == RT_SERIAL_RS485_SIMULATION_MODE) {
|
||||
serial->ops->control(serial, RT_SERIAL_RS485_RTS_HIGH, RT_NULL);
|
||||
}
|
||||
return _serial_int_tx(serial, (const rt_uint8_t *)buffer, size);
|
||||
@@ -902,7 +1003,7 @@ static rt_size_t rt_serial_write(struct rt_device *dev,
|
||||
#endif /* RT_SERIAL_USING_DMA */
|
||||
else
|
||||
{
|
||||
if (serial->config.function == RT_SERIAL_RS485_MODE) {
|
||||
if (serial->config.function == RT_SERIAL_RS485_SIMULATION_MODE) {
|
||||
serial->ops->control(serial, RT_SERIAL_RS485_RTS_HIGH, RT_NULL);
|
||||
}
|
||||
return _serial_poll_tx(serial, (const rt_uint8_t *)buffer, size);
|
||||
@@ -1312,6 +1413,86 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rt_serial_rx_ind(struct rt_serial_device *serial)
|
||||
{
|
||||
int ch = -1;
|
||||
rt_base_t level;
|
||||
struct rt_serial_rx_fifo* rx_fifo;
|
||||
|
||||
/* interrupt mode receive */
|
||||
if (NULL == serial->serial_rx) {
|
||||
while (1)
|
||||
{
|
||||
ch = serial->ops->getc(serial);
|
||||
if (ch == -1) break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
|
||||
RT_ASSERT(rx_fifo != RT_NULL);
|
||||
|
||||
while (1)
|
||||
{
|
||||
ch = serial->ops->getc(serial);
|
||||
if (ch == -1) break;
|
||||
|
||||
|
||||
/* disable interrupt */
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
rx_fifo->buffer[rx_fifo->put_index] = ch;
|
||||
rx_fifo->put_index += 1;
|
||||
if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0;
|
||||
|
||||
if ((serial->config.function == RT_SERIAL_RS232_UNAUTO_FLOW_CTRL ||
|
||||
serial->config.function == RT_SERIAL_RS232_SW_FLOW_CTRL ||
|
||||
serial->config.function == RT_SERIAL_RS232_SW_HW_FLOW_CTRL) &&
|
||||
serial->config.flowctrl_rts_enable == 1)
|
||||
{
|
||||
rt_flowctrl_high_detect(serial, 1, RT_SERIAL_INT_FCH_BUFFER);
|
||||
}
|
||||
|
||||
if ((serial->config.function == RT_SERIAL_RS232_SW_FLOW_CTRL ||
|
||||
serial->config.function == RT_SERIAL_RS232_SW_HW_FLOW_CTRL) &&
|
||||
serial->config.flowctrl_cts_enable == 1)
|
||||
{
|
||||
serial->ops->control(serial, RT_SERIAL_SW_RECEIVE_ON_OFF, &ch);
|
||||
}
|
||||
|
||||
/* if the next position is read index, discard this 'read char' */
|
||||
if (rx_fifo->put_index == rx_fifo->get_index)
|
||||
{
|
||||
rx_fifo->get_index += 1;
|
||||
rx_fifo->is_full = RT_TRUE;
|
||||
if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
|
||||
|
||||
_serial_check_buffer_size();
|
||||
}
|
||||
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/* invoke callback */
|
||||
if (serial->parent.rx_indicate != RT_NULL)
|
||||
{
|
||||
rt_size_t rx_length;
|
||||
|
||||
/* get rx length */
|
||||
level = rt_hw_interrupt_disable();
|
||||
rx_length = (rx_fifo->put_index >= rx_fifo->get_index)?
|
||||
(rx_fifo->put_index - rx_fifo->get_index):
|
||||
(serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index));
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
if (rx_length)
|
||||
{
|
||||
serial->parent.rx_indicate(&serial->parent, rx_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ISR for serial interrupt */
|
||||
void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
|
||||
{
|
||||
@@ -1319,66 +1500,7 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
|
||||
{
|
||||
case RT_SERIAL_EVENT_RX_IND:
|
||||
{
|
||||
int ch = -1;
|
||||
rt_base_t level;
|
||||
struct rt_serial_rx_fifo* rx_fifo;
|
||||
|
||||
/* interrupt mode receive */
|
||||
if (NULL == serial->serial_rx) {
|
||||
while (1)
|
||||
{
|
||||
ch = serial->ops->getc(serial);
|
||||
if (ch == -1) break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
|
||||
RT_ASSERT(rx_fifo != RT_NULL);
|
||||
|
||||
while (1)
|
||||
{
|
||||
ch = serial->ops->getc(serial);
|
||||
if (ch == -1) break;
|
||||
|
||||
|
||||
/* disable interrupt */
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
rx_fifo->buffer[rx_fifo->put_index] = ch;
|
||||
rx_fifo->put_index += 1;
|
||||
if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0;
|
||||
|
||||
/* if the next position is read index, discard this 'read char' */
|
||||
if (rx_fifo->put_index == rx_fifo->get_index)
|
||||
{
|
||||
rx_fifo->get_index += 1;
|
||||
rx_fifo->is_full = RT_TRUE;
|
||||
if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
|
||||
|
||||
_serial_check_buffer_size();
|
||||
}
|
||||
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/* invoke callback */
|
||||
if (serial->parent.rx_indicate != RT_NULL)
|
||||
{
|
||||
rt_size_t rx_length;
|
||||
|
||||
/* get rx length */
|
||||
level = rt_hw_interrupt_disable();
|
||||
rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index):
|
||||
(serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index));
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
if (rx_length)
|
||||
{
|
||||
serial->parent.rx_indicate(&serial->parent, rx_length);
|
||||
}
|
||||
}
|
||||
rt_serial_rx_ind(serial);
|
||||
break;
|
||||
}
|
||||
case RT_SERIAL_EVENT_TX_DONE:
|
||||
@@ -1441,6 +1563,15 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
|
||||
{
|
||||
/* disable interrupt */
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
/* flow control high level detect */
|
||||
if ((serial->config.function == RT_SERIAL_RS232_UNAUTO_FLOW_CTRL ||
|
||||
serial->config.function == RT_SERIAL_RS232_SW_FLOW_CTRL ||
|
||||
serial->config.function == RT_SERIAL_RS232_SW_HW_FLOW_CTRL) &&
|
||||
serial->config.flowctrl_rts_enable == 1)
|
||||
{
|
||||
rt_flowctrl_high_detect(serial, length, RT_SERIAL_DMA_FCH_BUFFER);
|
||||
}
|
||||
/* update fifo put index */
|
||||
rt_dma_recv_update_put_index(serial, length);
|
||||
/* calculate received total length */
|
||||
|
||||
@@ -25,12 +25,14 @@
|
||||
#define RT_SFUD_SPI_MAX_HZ 50000000
|
||||
#endif
|
||||
|
||||
#define RT_SPI_MAX_HZ 133000000
|
||||
|
||||
/* read the JEDEC SFDP command must run at 50 MHz or less */
|
||||
#define RT_SFUD_DEFAULT_SPI_CFG \
|
||||
{ \
|
||||
.mode = RT_SPI_MODE_0 | RT_SPI_MSB, \
|
||||
.data_width = 8, \
|
||||
.max_hz = RT_SFUD_SPI_MAX_HZ, \
|
||||
.max_hz = RT_SPI_MAX_HZ, \
|
||||
}
|
||||
#endif /* RT_SFUD_DEFAULT_SPI_CFG */
|
||||
|
||||
@@ -605,302 +607,4 @@ __error:
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
#if defined(RT_USING_FINSH)
|
||||
|
||||
#include <finsh.h>
|
||||
|
||||
static void show_speed(char *msg, u32 len, u32 us)
|
||||
{
|
||||
u32 tmp, speed;
|
||||
|
||||
/* Split to serval step to avoid overflow */
|
||||
tmp = 1000 * len;
|
||||
tmp = tmp / us;
|
||||
tmp = 1000 * tmp;
|
||||
speed = tmp / 1024;
|
||||
|
||||
printf("%s: %d byte, %d us -> %d KB/s\n", msg, len, us, speed);
|
||||
}
|
||||
|
||||
static void sf(uint8_t argc, char **argv) {
|
||||
|
||||
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
|
||||
#define HEXDUMP_WIDTH 16
|
||||
#define CMD_PROBE_INDEX 0
|
||||
#define CMD_READ_INDEX 1
|
||||
#define CMD_WRITE_INDEX 2
|
||||
#define CMD_ERASE_INDEX 3
|
||||
#define CMD_RW_STATUS_INDEX 4
|
||||
#define CMD_BYPASS_INDEX 5
|
||||
#define CMD_BENCH_INDEX 6
|
||||
|
||||
sfud_err result = SFUD_SUCCESS;
|
||||
static const sfud_flash *sfud_dev = NULL;
|
||||
static rt_spi_flash_device_t rtt_dev = NULL, rtt_dev_bak = NULL;
|
||||
size_t i = 0, j = 0;
|
||||
|
||||
const char* sf_help_info[] = {
|
||||
[CMD_PROBE_INDEX] = "sf probe [spi_device] - probe and init SPI flash by given 'spi_device'",
|
||||
[CMD_READ_INDEX] = "sf read addr size - read 'size' bytes starting at 'addr'",
|
||||
[CMD_WRITE_INDEX] = "sf write addr data1 ... dataN - write some bytes 'data' to flash starting at 'addr'",
|
||||
[CMD_ERASE_INDEX] = "sf erase addr size - erase 'size' bytes starting at 'addr'",
|
||||
[CMD_RW_STATUS_INDEX] = "sf status [<volatile> <status>] - read or write '1:volatile|0:non-volatile' 'status'",
|
||||
#if defined(AIC_SPIENC_DRV)
|
||||
[CMD_BYPASS_INDEX] = "sf bypass status - status 0:disable' 1:'enable'",
|
||||
#endif
|
||||
[CMD_BENCH_INDEX] = "sf bench - full chip benchmark. DANGER: It will erase full chip!",
|
||||
};
|
||||
|
||||
if (argc < 2) {
|
||||
rt_kprintf("Usage:\n");
|
||||
for (i = 0; i < sizeof(sf_help_info) / sizeof(char*); i++) {
|
||||
rt_kprintf("%s\n", sf_help_info[i]);
|
||||
}
|
||||
rt_kprintf("\n");
|
||||
} else {
|
||||
const char *operator = argv[1];
|
||||
uint32_t addr, size;
|
||||
|
||||
if (!strcmp(operator, "probe")) {
|
||||
if (argc < 3) {
|
||||
rt_kprintf("Usage: %s.\n", sf_help_info[CMD_PROBE_INDEX]);
|
||||
} else {
|
||||
char *spi_dev_name = argv[2];
|
||||
rtt_dev_bak = rtt_dev;
|
||||
|
||||
/* delete the old SPI flash device */
|
||||
if(rtt_dev_bak) {
|
||||
rt_sfud_flash_delete(rtt_dev_bak);
|
||||
}
|
||||
|
||||
rtt_dev = rt_sfud_flash_probe("sf_cmd", spi_dev_name);
|
||||
if (!rtt_dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
sfud_dev = (sfud_flash_t)rtt_dev->user_data;
|
||||
if (sfud_dev->chip.capacity < 1024 * 1024) {
|
||||
rt_kprintf("%d KB %s is current selected device.\n", sfud_dev->chip.capacity / 1024, sfud_dev->name);
|
||||
} else {
|
||||
rt_kprintf("%d MB %s is current selected device.\n", sfud_dev->chip.capacity / 1024 / 1024,
|
||||
sfud_dev->name);
|
||||
}
|
||||
}
|
||||
#if defined(AIC_SPIENC_DRV)
|
||||
} else if (!strcmp(operator, "bypass")) {
|
||||
uint32_t status;
|
||||
if (!sfud_dev) {
|
||||
rt_kprintf("No flash device selected. Please run 'sf probe'.\n");
|
||||
return;
|
||||
}
|
||||
status = strtol(argv[2], NULL, 0);
|
||||
spienc_set_bypass(status);
|
||||
#endif
|
||||
} else {
|
||||
if (!sfud_dev) {
|
||||
rt_kprintf("No flash device selected. Please run 'sf probe'.\n");
|
||||
return;
|
||||
}
|
||||
if (!rt_strcmp(operator, "read")) {
|
||||
if (argc < 4) {
|
||||
rt_kprintf("Usage: %s.\n", sf_help_info[CMD_READ_INDEX]);
|
||||
return;
|
||||
} else {
|
||||
addr = strtol(argv[2], NULL, 0);
|
||||
size = strtol(argv[3], NULL, 0);
|
||||
uint8_t *data = aicos_malloc_align(0, size, CACHE_LINE_SIZE);
|
||||
uint64_t start_us;
|
||||
if (data) {
|
||||
start_us = aic_get_time_us();
|
||||
result = sfud_read(sfud_dev, addr, size, data);
|
||||
show_speed("sfud_read speed", size, aic_get_time_us() - start_us);
|
||||
|
||||
if (result == SFUD_SUCCESS) {
|
||||
rt_kprintf("Read the %s flash data success. Start from 0x%08X, size is %ld. The data is:\n",
|
||||
sfud_dev->name, addr, size);
|
||||
rt_kprintf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
|
||||
for (i = 0; i < size; i += HEXDUMP_WIDTH)
|
||||
{
|
||||
rt_kprintf("[%08X] ", addr + i);
|
||||
/* dump hex */
|
||||
for (j = 0; j < HEXDUMP_WIDTH; j++) {
|
||||
if (i + j < size) {
|
||||
rt_kprintf("%02X ", data[i + j]);
|
||||
} else {
|
||||
rt_kprintf(" ");
|
||||
}
|
||||
}
|
||||
/* dump char for hex */
|
||||
for (j = 0; j < HEXDUMP_WIDTH; j++) {
|
||||
if (i + j < size) {
|
||||
rt_kprintf("%c", __is_print(data[i + j]) ? data[i + j] : '.');
|
||||
}
|
||||
}
|
||||
rt_kprintf("\n");
|
||||
}
|
||||
rt_kprintf("\n");
|
||||
}
|
||||
aicos_free_align(0, data);
|
||||
} else {
|
||||
rt_kprintf("Low memory!\n");
|
||||
}
|
||||
}
|
||||
} else if (!rt_strcmp(operator, "write")) {
|
||||
if (argc < 4) {
|
||||
rt_kprintf("Usage: %s.\n", sf_help_info[CMD_WRITE_INDEX]);
|
||||
return;
|
||||
} else {
|
||||
addr = strtol(argv[2], NULL, 0);
|
||||
size = argc - 3;
|
||||
uint8_t *data = rt_malloc(size);
|
||||
if (data) {
|
||||
for (i = 0; i < size; i++) {
|
||||
data[i] = strtol(argv[3 + i], NULL, 0);
|
||||
}
|
||||
result = sfud_write(sfud_dev, addr, size, data);
|
||||
if (result == SFUD_SUCCESS) {
|
||||
rt_kprintf("Write the %s flash data success. Start from 0x%08X, size is %ld.\n",
|
||||
sfud_dev->name, addr, size);
|
||||
rt_kprintf("Write data: ");
|
||||
for (i = 0; i < size; i++) {
|
||||
rt_kprintf("%d ", data[i]);
|
||||
}
|
||||
rt_kprintf(".\n");
|
||||
}
|
||||
rt_free(data);
|
||||
} else {
|
||||
rt_kprintf("Low memory!\n");
|
||||
}
|
||||
}
|
||||
} else if (!rt_strcmp(operator, "erase")) {
|
||||
if (argc < 4) {
|
||||
rt_kprintf("Usage: %s.\n", sf_help_info[CMD_ERASE_INDEX]);
|
||||
return;
|
||||
} else {
|
||||
addr = strtol(argv[2], NULL, 0);
|
||||
size = strtol(argv[3], NULL, 0);
|
||||
result = sfud_erase(sfud_dev, addr, size);
|
||||
if (result == SFUD_SUCCESS) {
|
||||
rt_kprintf("Erase the %s flash data success. Start from 0x%08X, size is %ld.\n", sfud_dev->name,
|
||||
addr, size);
|
||||
}
|
||||
}
|
||||
} else if (!rt_strcmp(operator, "status")) {
|
||||
if (argc < 3) {
|
||||
uint8_t status;
|
||||
result = sfud_read_status(sfud_dev, &status);
|
||||
if (result == SFUD_SUCCESS) {
|
||||
rt_kprintf("The %s flash status register current value is 0x%02X.\n", sfud_dev->name, status);
|
||||
}
|
||||
} else if (argc == 4) {
|
||||
bool is_volatile = strtol(argv[2], NULL, 0);
|
||||
uint8_t status = strtol(argv[3], NULL, 0);
|
||||
result = sfud_write_status(sfud_dev, is_volatile, status);
|
||||
if (result == SFUD_SUCCESS) {
|
||||
rt_kprintf("Write the %s flash status register to 0x%02X success.\n", sfud_dev->name, status);
|
||||
}
|
||||
} else {
|
||||
rt_kprintf("Usage: %s.\n", sf_help_info[CMD_RW_STATUS_INDEX]);
|
||||
return;
|
||||
}
|
||||
} else if (!rt_strcmp(operator, "bench")) {
|
||||
if ((argc > 2 && rt_strcmp(argv[2], "yes")) || argc < 3) {
|
||||
rt_kprintf("DANGER: It will erase full chip! Please run 'sf bench yes'.\n");
|
||||
return;
|
||||
}
|
||||
/* full chip benchmark test */
|
||||
addr = 0;
|
||||
size = sfud_dev->chip.capacity;
|
||||
uint32_t start_time, time_cast;
|
||||
size_t write_size = SFUD_WRITE_MAX_PAGE_SIZE, read_size = SFUD_WRITE_MAX_PAGE_SIZE, cur_op_size;
|
||||
uint8_t *write_data = rt_malloc(write_size), *read_data = rt_malloc(read_size);
|
||||
|
||||
if (write_data && read_data) {
|
||||
for (i = 0; i < write_size; i ++) {
|
||||
write_data[i] = i & 0xFF;
|
||||
}
|
||||
/* benchmark testing */
|
||||
rt_kprintf("Erasing the %s %ld bytes data, waiting...\n", sfud_dev->name, size);
|
||||
start_time = rt_tick_get();
|
||||
result = sfud_erase(sfud_dev, addr, size);
|
||||
if (result == SFUD_SUCCESS) {
|
||||
time_cast = rt_tick_get() - start_time;
|
||||
rt_kprintf("Erase benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND,
|
||||
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
|
||||
} else {
|
||||
rt_kprintf("Erase benchmark has an error. Error code: %d.\n", result);
|
||||
}
|
||||
/* write test */
|
||||
rt_kprintf("Writing the %s %ld bytes data, waiting...\n", sfud_dev->name, size);
|
||||
start_time = rt_tick_get();
|
||||
for (i = 0; i < size; i += write_size) {
|
||||
if (i + write_size <= size) {
|
||||
cur_op_size = write_size;
|
||||
} else {
|
||||
cur_op_size = size - i;
|
||||
}
|
||||
result = sfud_write(sfud_dev, addr + i, cur_op_size, write_data);
|
||||
if (result != SFUD_SUCCESS) {
|
||||
rt_kprintf("Writing %s failed, already wr for %lu bytes, write %d each time\n", sfud_dev->name, i, write_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result == SFUD_SUCCESS) {
|
||||
time_cast = rt_tick_get() - start_time;
|
||||
rt_kprintf("Write benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND,
|
||||
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
|
||||
} else {
|
||||
rt_kprintf("Write benchmark has an error. Error code: %d.\n", result);
|
||||
}
|
||||
/* read test */
|
||||
rt_kprintf("Reading the %s %ld bytes data, waiting...\n", sfud_dev->name, size);
|
||||
start_time = rt_tick_get();
|
||||
for (i = 0; i < size; i += read_size) {
|
||||
if (i + read_size <= size) {
|
||||
cur_op_size = read_size;
|
||||
} else {
|
||||
cur_op_size = size - i;
|
||||
}
|
||||
result = sfud_read(sfud_dev, addr + i, cur_op_size, read_data);
|
||||
/* data check */
|
||||
if (memcmp(write_data, read_data, cur_op_size))
|
||||
{
|
||||
rt_kprintf("Data check ERROR! Please check you flash by other command.\n");
|
||||
result = SFUD_ERR_READ;
|
||||
}
|
||||
|
||||
if (result != SFUD_SUCCESS) {
|
||||
rt_kprintf("Read %s failed, already rd for %lu bytes, read %d each time\n", sfud_dev->name, i, read_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result == SFUD_SUCCESS) {
|
||||
time_cast = rt_tick_get() - start_time;
|
||||
rt_kprintf("Read benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND,
|
||||
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
|
||||
} else {
|
||||
rt_kprintf("Read benchmark has an error. Error code: %d.\n", result);
|
||||
}
|
||||
} else {
|
||||
rt_kprintf("Low memory!\n");
|
||||
}
|
||||
rt_free(write_data);
|
||||
rt_free(read_data);
|
||||
} else {
|
||||
rt_kprintf("Usage:\n");
|
||||
for (i = 0; i < sizeof(sf_help_info) / sizeof(char*); i++) {
|
||||
rt_kprintf("%s\n", sf_help_info[i]);
|
||||
}
|
||||
rt_kprintf("\n");
|
||||
return;
|
||||
}
|
||||
if (result != SFUD_SUCCESS) {
|
||||
rt_kprintf("This flash operate has an error. Error code: %d.\n", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT(sf, SPI Flash operate);
|
||||
#endif /* defined(RT_USING_FINSH) */
|
||||
|
||||
#endif /* RT_USING_SFUD */
|
||||
|
||||
Reference in New Issue
Block a user