/*================================================================ Copyright (c) 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. =================================================================*/ /*================================================================= EDIT HISTORY FOR MODULE This section contains comments describing changes made to the module. Notice that changes are listed in reverse chronological order. WHEN WHO WHAT, WHERE, WHY ------------ ------- ------------------------------------------------------------------------------- =================================================================*/ #include #include #include #include "ql_api_osi.h" #include "ql_api_spi.h" #include "ql_log.h" #include "spi_demo.h" #include "ql_gpio.h" #include "ql_power.h" #define QL_SPI_DEMO_LOG_LEVEL QL_LOG_LEVEL_INFO #define QL_SPI_DEMO_LOG(msg, ...) QL_LOG(QL_SPI_DEMO_LOG_LEVEL, "ql_SPI_DEMO", msg, ##__VA_ARGS__) #define QL_SPI_DEMO_LOG_PUSH(msg, ...) QL_LOG_PUSH("ql_SPI_DEMO", msg, ##__VA_ARGS__) /** * 使用SPI DMA注意事项: * 1. SPI DMA POLLING和SPI DMA IRQ只支持8bit和16bit的数据传输,不支持32bit数据传输 * 2. 在使用16bit传输数据时,DMA实际使用的是32bit位宽,需要对输出数据插入一些无效数据,对输入数据去除无效数据, * 因此新增16bit dma api用于16bit情况下的读写,api包含ql_spi_write_16bit_dma、ql_spi_read_16bit_dma、 * ql_spi_write_read_16bit_dma,这部分代码在demo中开源,客户可自行优化,或直接使用 * 3. QL_SPI_16BIT_DMA置为1表示使用16bit DMA demo */ #define QL_SPI_16BIT_DMA 0 //16bit DMA demo #define QL_SPI_DEMO_LOW_POWER_USE 0 //0-not run in lower power mode;1-run in lower power mode ql_task_t spi_demo_task = NULL; ql_sem_t spi_demo_write; ql_sem_t spi_demo_read; int spi_power_lock = 0; #define QL_SPI_DEMO_WAIT_NONE 0 #define QL_SPI_DEMO_WAIT_WRITE 1 #define QL_SPI_DEMO_WAIT_READ 2 unsigned char spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_NONE; #define QL_CUR_SPI_PORT QL_SPI_PORT1 #define QL_CUR_SPI_CS_PIN QL_CUR_SPI1_CS_PIN #define QL_CUR_SPI_CS_FUNC QL_CUR_SPI1_CS_FUNC #define QL_CUR_SPI_CLK_PIN QL_CUR_SPI1_CLK_PIN #define QL_CUR_SPI_CLK_FUNC QL_CUR_SPI1_CLK_FUNC #define QL_CUR_SPI_DO_PIN QL_CUR_SPI1_DO_PIN #define QL_CUR_SPI_DO_FUNC QL_CUR_SPI1_DO_FUNC #define QL_CUR_SPI_DI_PIN QL_CUR_SPI1_DI_PIN #define QL_CUR_SPI_DI_FUNC QL_CUR_SPI1_DI_FUNC #define QL_TYPE_SHIFT_8 8 uint32_t g_inbuf[QL_SPI_DMA_IRQ_SIZE/4] OSI_CACHE_LINE_ALIGNED; uint32_t g_outbuf[QL_SPI_DMA_IRQ_SIZE/4] OSI_CACHE_LINE_ALIGNED; void ql_spi_read_data_transform(unsigned char *buf, unsigned int len) { if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2) { QL_SPI_DEMO_LOG("invalid parm"); return; } for(int i = 0; i < len/2; i++) { buf[i*2] = (g_inbuf[i] >> QL_TYPE_SHIFT_8) & 0xFF; buf[i*2+1] = g_inbuf[i] & 0xFF; } } ql_errcode_spi_e ql_spi_write_16bit_dma(ql_spi_port_e port, unsigned char *buf, unsigned int len) { if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2) { QL_SPI_DEMO_LOG("invalid parm"); return QL_SPI_PARAM_DATA_ERROR; } unsigned short out_temp = 0; for(int i = 0; i < len/2; i++) { out_temp = buf[i*2]; g_outbuf[i] = (out_temp << QL_TYPE_SHIFT_8) + buf[i*2+1]; } return ql_spi_write(port, (unsigned char*)g_outbuf, len*2); } ql_errcode_spi_e ql_spi_read_16bit_dma(ql_spi_port_e port, unsigned char *buf, unsigned int len) { if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2) { QL_SPI_DEMO_LOG("invalid parm"); return QL_SPI_PARAM_DATA_ERROR; } return ql_spi_read(port, (unsigned char*)g_inbuf, len*2); } ql_errcode_spi_e ql_spi_write_read_16bit_dma(ql_spi_port_e port, unsigned char *inbuf, unsigned char *outbuf, unsigned int len) { if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2) { QL_SPI_DEMO_LOG("invalid parm"); return QL_SPI_PARAM_DATA_ERROR; } unsigned short out_temp = 0; for(int i = 0; i < len/2; i++) { out_temp = outbuf[i*2]; g_outbuf[i] = (out_temp << QL_TYPE_SHIFT_8) + outbuf[i*2+1]; } return ql_spi_write_read(port, (unsigned char*)g_inbuf, (unsigned char*)g_outbuf, len*2); } void ql_spi_flash_data_printf(unsigned char *data, int len) { int i = 0; int count_len = 256; int count = 0; int exit = 0; unsigned int buf_pos = 0; unsigned char *str_data = (unsigned char *)malloc(len*2+64); if (str_data == NULL) { QL_SPI_DEMO_LOG("malloc err"); return ; } QL_SPI_DEMO_LOG("read len=%d", len); while ((exit == 0)) { if (len - count > 256) { count_len = 256; } else { count_len = len - count; exit = 1; } memset(str_data, 0, len*2+64); buf_pos = 0; for (i=count; i