This commit is contained in:
刘可亮
2024-06-04 19:00:30 +08:00
parent 990c72f5be
commit 0a13af6a1d
1668 changed files with 342810 additions and 37726 deletions

View File

@@ -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)

View File

@@ -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,

View File

@@ -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);

View File

@@ -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;

View File

@@ -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,

View File

@@ -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
{

View File

@@ -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 */

View File

@@ -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

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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 */