123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860 |
- /*================================================================
- 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 <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #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"
- #include "ql_fs.h"
- #include "ql_api_dev.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__)
- uint8_t OTA_FLAG = 1;
- output_control_t output_control_t_info = {0};
- sleep_control_t sleep_control_t_info = {0};
- communication_control_t communication_control_t_info = {0};
- /**
- * 使用SPI DMA注意事项:
- * 8910:
- * 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
- * 8850:
- * 1. SPI DMA POLLING和SPI DMA IRQ支持8bits、16bits和32bits的数据传输,但是传输的数据大小需要framesize对齐。
- */
- #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;
- #if 1
- #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
- #else
- #define QL_CUR_SPI_PORT QL_SPI_PORT2
- #define QL_CUR_SPI_CS_PIN QL_CUR_SPI2_CS_PIN
- #define QL_CUR_SPI_CS_FUNC QL_CUR_SPI2_CS_FUNC
- #define QL_CUR_SPI_CLK_PIN QL_CUR_SPI2_CLK_PIN
- #define QL_CUR_SPI_CLK_FUNC QL_CUR_SPI2_CLK_FUNC
- #define QL_CUR_SPI_DO_PIN QL_CUR_SPI2_DO_PIN
- #define QL_CUR_SPI_DO_FUNC QL_CUR_SPI2_DO_FUNC
- #define QL_CUR_SPI_DI_PIN QL_CUR_SPI2_DI_PIN
- #define QL_CUR_SPI_DI_FUNC QL_CUR_SPI2_DI_FUNC
- #endif
- #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;
- int write_len = 0;
- int 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);
- for (i=count; i<count+count_len; i++)
- {
- //sprintf((char *)str_data,"%s%02x", str_data, data[i]);
- if((i+1) % 128 == 0)
- write_len += snprintf((char *)(str_data + write_len),(len*2+64 - write_len), "%02x \n",data[i]);
- else
- write_len += snprintf((char *)(str_data + write_len),(len*2+64 - write_len), "%02x",data[i]);
- }
- QL_SPI_DEMO_LOG("data[%d-%d]=%s", count, count+count_len, (char *)(str_data+pos));
- pos += write_len;
- count += count_len;
- }
- free(str_data);
- }
- void ql_spi_demo_cb_handler(ql_spi_irq_s cause)
- {
- if (cause.tx_dma_done == 1 && spi_demo_wait_write_read == QL_SPI_DEMO_WAIT_WRITE)
- {
- spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_NONE;
- ql_rtos_semaphore_release(spi_demo_write);
- }
- if (cause.rx_dma_done == 1 && spi_demo_wait_write_read == QL_SPI_DEMO_WAIT_READ)
- {
- spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_NONE;
- ql_rtos_semaphore_release(spi_demo_read);
- }
- QL_SPI_DEMO_LOG("cause.tx_dma_done=%d", cause.tx_dma_done);
- QL_SPI_DEMO_LOG("cause.rx_dma_done=%d", cause.rx_dma_done);
- }
- static void ql_spi_demo_task_pthread(void *ctx)
- {
- QlOSStatus err = 0;
- unsigned char *outdata = NULL;
- unsigned short outlen;
- unsigned char *indata = NULL;
- unsigned short inlen;
- unsigned char *out_mal_data = NULL;
- unsigned char *in_mal_data = NULL;
- ql_errcode_gpio ret;
- ql_spi_clk_e spiclk;
- ql_spi_transfer_mode_e transmode;
- unsigned int framesize;
-
- ql_spi_config_s spi_config = {0};
-
- if (QL_CUR_SPI_CS_PIN == QUEC_PIN_NONE || QL_CUR_SPI_CS_PIN == QUEC_PIN_NONE || \
- QL_CUR_SPI_DO_PIN == QUEC_PIN_NONE || QL_CUR_SPI_DI_PIN == QUEC_PIN_NONE)
- {
- QL_SPI_DEMO_LOG("pin err");
- goto QL_SPI_EXIT;
- }
- ret = ql_pin_set_func(QL_CUR_SPI_CS_PIN, QL_CUR_SPI_CS_FUNC);
- if (ret != QL_GPIO_SUCCESS)
- {
- QL_SPI_DEMO_LOG("set pin err");
- goto QL_SPI_EXIT;
- }
-
- ret = ql_pin_set_func(QL_CUR_SPI_CLK_PIN, QL_CUR_SPI_CLK_FUNC);
- if (ret != QL_GPIO_SUCCESS)
- {
- QL_SPI_DEMO_LOG("set pin err");
- goto QL_SPI_EXIT;
- }
- ret = ql_pin_set_func(QL_CUR_SPI_DO_PIN, QL_CUR_SPI_DO_FUNC);
- if (ret != QL_GPIO_SUCCESS)
- {
- QL_SPI_DEMO_LOG("set pin err");
- goto QL_SPI_EXIT;
- }
- ret = ql_pin_set_func(QL_CUR_SPI_DI_PIN, QL_CUR_SPI_DI_FUNC);
- if (ret != QL_GPIO_SUCCESS)
- {
- QL_SPI_DEMO_LOG("set pin err");
- goto QL_SPI_EXIT;
- }
- //If you use the default parameters, you can initialize it with ql_spi_init
- /*transmode = QL_SPI_DMA_IRQ;
- spiclk = QL_SPI_CLK_25MHZ;
- framesize = 8;
- ql_spi_init(QL_CUR_SPI_PORT, transmode, spiclk);
- */
- spi_config.input_mode = QL_SPI_INPUT_TRUE;
- spi_config.port = QL_CUR_SPI_PORT;
- #if QL_SPI_16BIT_DMA
- framesize = 16;
- #else
- framesize = 8;
- #endif
- transmode = QL_SPI_DMA_IRQ; //使用QL_SPI_DMA_IRQ模式,传输一次最大的数据量为512个字节
- spiclk = QL_SPI_CLK_1_3MHZ;
- spi_config.spiclk = spiclk;
- spi_config.framesize = framesize;
- spi_config.cs_polarity0 = QL_SPI_CS_ACTIVE_LOW;
- spi_config.cs_polarity1 = QL_SPI_CS_ACTIVE_LOW;
- spi_config.cpol = QL_SPI_CPOL_LOW;
- spi_config.cpha = QL_SPI_CPHA_1Edge;
- spi_config.input_sel = QL_SPI_DI_1;
- spi_config.transmode = transmode;
- spi_config.cs = QL_SPI_CS0;
- spi_config.clk_delay = QL_SPI_CLK_DELAY_0;
- ql_spi_init_ext(spi_config);
- //使用QL_SPI_DMA_IRQ模式才会使用到信号量
- if(transmode == QL_SPI_DMA_IRQ)
- {
- ql_spi_irq_s mask = {0};
- mask.rx_dma_done = 1;
- mask.tx_dma_done = 1;
- //mask.tx_threshold = QL_SPI_TRIGGER_4_DATA;
- //mask.rx_threshold = QL_SPI_TRIGGER_4_DATA;
- ql_rtos_semaphore_create(&spi_demo_write, 0);
- ql_rtos_semaphore_create(&spi_demo_read, 0);
- ql_spi_set_irq(QL_CUR_SPI_PORT, mask, ql_spi_demo_cb_handler);
- }
-
- //用来测试SPI CS脚可以强制拉低,CS脚恢复成系统控制后,不需要强制拉高拉低
- ql_spi_cs_low(QL_CUR_SPI_PORT);
- ql_rtos_task_sleep_s(3);
- ql_spi_cs_auto(QL_CUR_SPI_PORT);
- //使用QL_SPI_DMA_IRQ模式,传输一次最大的数据量为512个字节,如果采用16bit传输数据,需要填充256字节无效数据用于DMA对齐,实际有效最大数据量为256字节
- #if QL_SPI_16BIT_DMA
- outlen = QL_SPI_DMA_IRQ_SIZE/2;
- inlen = QL_SPI_DMA_IRQ_SIZE/2;
- #else
- outlen = QL_SPI_DMA_IRQ_SIZE;
- inlen = QL_SPI_DMA_IRQ_SIZE;
- #endif
- out_mal_data = (unsigned char *)malloc(QL_SPI_DMA_ADDR_ALIN+outlen);
- in_mal_data = (unsigned char *)malloc(QL_SPI_DMA_ADDR_ALIN+outlen);
- if (out_mal_data == NULL || in_mal_data == NULL)
- {
- QL_SPI_DEMO_LOG("malloc err");
- goto QL_SPI_EXIT;
- }
- //使用QL_SPI_DMA_POLLING和QL_SPI_DMA_IRQ模式,使用的地址必须4字节对齐
- if(transmode == QL_SPI_DMA_POLLING || transmode == QL_SPI_DMA_IRQ)
- {
- outdata = (unsigned char *)OSI_ALIGN_UP(out_mal_data, QL_SPI_DMA_ADDR_ALIN);
- indata = (unsigned char *)OSI_ALIGN_UP(in_mal_data, QL_SPI_DMA_ADDR_ALIN);
- }
- else
- {
- outdata = out_mal_data;
- indata = in_mal_data;
- }
-
- memset(outdata, 0x00, outlen);
- memset(indata, 0x00, inlen);
- ql_spi_flash_data_printf(outdata, outlen);
- #if QL_SPI_DEMO_LOW_POWER_USE
- ql_autosleep_enable(QL_ALLOW_SLEEP);
- ql_rtos_task_sleep_s(2);
- #endif
- //static uint8_t cmd_type = 0;
- OTA_FLAG = 1;
- while(1)
- {
- if(0)
- {
- OTA_FLAG = 1;
- QL_SPI_DEMO_LOG("ota test mode");
- data_mpu_pack(outdata, &outlen, 0X60, 0X03, spiclk);;
- }
- #if 0
- cmd_type = cmd_type + 1 > 4 ? 1 : cmd_type + 1;
- data_mpu_pack(outdata, &outlen, 0X50, cmd_type, spiclk);;
- spi_dma_write_hc(QL_CUR_SPI_PORT, outdata, 512, spiclk);
- ql_spi_flash_data_printf(outdata, 256);
- spi_dma_read_hc(QL_CUR_SPI_PORT, indata, 512, spiclk);
- unsigned short sendLen = 0;
- ql_spi_flash_data_printf(indata, 512);
- data_decode_mpu(indata, 512, outdata, &sendLen, spiclk);
- if(0X03 != cmd_type)
- {
- data_mpu_pack(outdata, &outlen, 0X60, cmd_type, spiclk);
- }
- spi_dma_write_hc(QL_CUR_SPI_PORT, outdata, 512, spiclk);
- spi_dma_read_hc(QL_CUR_SPI_PORT, indata, 512, spiclk);
- #endif
- ql_rtos_task_sleep_ms(500);
- }
- ql_spi_release(QL_CUR_SPI_PORT);
- free(out_mal_data);
- free(in_mal_data);
- QL_SPI_EXIT:
- QL_SPI_DEMO_LOG("ql_rtos_task_delete");
- err = ql_rtos_task_delete(NULL);
- if(err != QL_OSI_SUCCESS)
- {
- QL_SPI_DEMO_LOG("task deleted failed");
- }
- }
- QlOSStatus ql_spi_demo_init(void)
- {
- QlOSStatus err = QL_OSI_SUCCESS;
- #if QL_SPI_DEMO_LOW_POWER_USE
- spi_power_lock = ql_lpm_wakelock_create("spi_irq", strlen("spi_irq"));
- #endif
- err = ql_rtos_task_create(&spi_demo_task, SPI_DEMO_TASK_STACK_SIZE, SPI_DEMO_TASK_PRIO, "ql_spi_demo", ql_spi_demo_task_pthread, NULL, SPI_DEMO_TASK_EVENT_CNT);
- if(err != QL_OSI_SUCCESS)
- {
- QL_SPI_DEMO_LOG("demo_task created failed");
- return err;
- }
-
- return err;
- }
- uint16_t Full_Frame_Verifi(uint8_t *srcdata, uint16_t srcLen, uint16_t* frame_start)
- {
- uint16_t frame_len = 0; // 获取帧长度
- uint8_t frame_flag = 0; //找到帧起始位
-
- for(uint32_t i = 0; i < (srcLen - sizeof(frame_pack_t)) && 0 == frame_flag; i++)
- {
- if(0X5A == srcdata[i])
- {
- frame_len = srcdata[i + FRAME_LEN_INDEX] + (srcdata[i + FRAME_LEN_INDEX + 1] << 8);
- if((i + frame_len + 1) < srcLen &&
- (srcdata[i + frame_len - 2] + (srcdata[i + frame_len - 1] << 8) == crc16_modbus(srcdata + i, frame_len -2)))
- {
- frame_flag = 1;
- *frame_start = i;
- QL_SPI_DEMO_LOG("verfi successfully ");
- break;
- }
- }
- }
-
- if(0 == frame_flag)
- return 0;
- else
- return frame_len;
- }
- uint8_t data_mpu_pack(uint8_t* output, uint16_t* output_data_len, uint8_t cmd, uint8_t cmd_type, ql_spi_clk_e spiclk)
- {
- #define FLASH_SEND_DATA_LEN (256)
- #define FLASH_HEAD_0X6003 (0X03)
- #define FLASH_SEND_LEN_ALGINE (FLASH_SEND_DATA_LEN + sizeof(frame_pack_t) + 2 + 2 + FLASH_HEAD_0X6003)
- #define FLASH_SEND_LEN (512)
- #define FLASH_READ_LEN (512)
- frame_pack_t frame_tmp = {0};
- frame_tmp.destination_addr = MCU_ADDR;
- frame_tmp.source_addr = MPU_ADDR;
- frame_tmp.frame_head = 0X5A;
- (*output_data_len) = sizeof(frame_pack_t);
- switch (cmd)
- {
- case 0X50:
- /* code */
- frame_tmp.cmd = 0X50;
- switch (cmd_type)
- {
- case 0X01:
- frame_tmp.cmd_type = 0X01;
- break;
- case 0X02:
- frame_tmp.cmd_type = 0X02;
- break;
- case 0X03:
- frame_tmp.cmd_type = 0X03;
- break;
- default:
- break;
- }
- break;
- case 0X60:
- /* code */
- frame_tmp.cmd = 0X60;
- switch (cmd_type)
- {
- case 0X01:
- frame_tmp.cmd_type = 0X01;
- output_control_t_info.output_number = 6;
- output_control_t_info.pwm_number = 2;
- memcpy(output, &output_control_t_info, sizeof(output_control_t));
- *output_data_len += sizeof(output_control_t_info);
- break;
- case 0X02:
- frame_tmp.cmd_type = 0X02;
- sleep_control_t_info.control_type = 1;
- sleep_control_t_info.sleep_time = 256;
- memcpy(output, &sleep_control_t_info, sizeof(sleep_control_t));
- *output_data_len += sizeof(sleep_control_t_info);
- break;
- case 0X03:
- frame_tmp.cmd_type = 0X03;
- int fd_updata_file = 0;
- fd_updata_file = ql_fopen("UFS:/updata.bin", "r+");
- if(0 == fd_updata_file)
- {
- QL_SPI_DEMO_LOG("fd open failed");
- break;
- }
- else
- QL_SPI_DEMO_LOG("fd open succeeded");
- uint16_t crcFile = 0;
- creat_software_crc16(fd_updata_file, &crcFile);
- QL_SPI_DEMO_LOG("fd file %d", crcFile);
- ql_frewind(fd_updata_file);
-
- uint8_t pbuf[FLASH_SEND_DATA_LEN] = {0};
- int readLen = ql_fread(pbuf, FLASH_SEND_DATA_LEN, 1, fd_updata_file);
- uint16 crc16_tmp = 0;
- static uint16 frame_index = 0;
- uint8* indata_tmp = (unsigned char *)malloc(QL_SPI_DMA_ADDR_ALIN + FLASH_READ_LEN);
- uint8*indata = (unsigned char *)OSI_ALIGN_UP(indata_tmp, QL_SPI_DMA_ADDR_ALIN);
- #define DELAY_TIME_FLASH_TEST (150)
- while((readLen) > 0)
- {
- *output_data_len = sizeof(frame_pack_t);
- frame_tmp.data_lenth = sizeof(frame_pack_t) + FLASH_HEAD_0X6003 + readLen + 2 + 2;
- memcpy(output, &frame_tmp, sizeof(frame_pack_t));
- QL_SPI_DEMO_LOG("circle index %d head len %d send len %d", frame_index, *output_data_len, frame_tmp.data_lenth);
- output[(*output_data_len)++] = 0X01;
- output[(*output_data_len)++] = frame_index & 0XFF;
- output[(*output_data_len)++] = (frame_index >> 8) & 0XFF;
- memcpy(output + (*output_data_len), pbuf, readLen);
- (*output_data_len) += readLen;
- crc16_tmp = crc16_modbus(pbuf, readLen);
- output[(*output_data_len)++] = crc16_tmp & 0XFF;
- output[(*output_data_len)++] = (crc16_tmp >> 8) & 0XFF;
- crc16_tmp = crc16_modbus(output, *output_data_len);
- output[(*output_data_len)++] = crc16_tmp & 0XFF;
- output[(*output_data_len)++] = (crc16_tmp >> 8) & 0XFF;
- QL_SPI_DEMO_LOG("out data,frame_tmp.data_lenth %d readLen %d fdSize:%d", frame_tmp.data_lenth, readLen , ql_fsize(fd_updata_file));
- spi_dma_write_hc(QL_CUR_SPI_PORT, output, FLASH_SEND_LEN, spiclk);
- ql_rtos_task_sleep_ms(DELAY_TIME_FLASH_TEST);
- spi_dma_read_hc(QL_CUR_SPI_PORT, indata, FLASH_SEND_LEN, spiclk);
-
- QL_SPI_DEMO_LOG("out data,frame_tmp.data_lenth %d", frame_tmp.data_lenth);
- ql_spi_flash_data_printf(output, frame_tmp.data_lenth);
- QL_SPI_DEMO_LOG("in data");
- ql_spi_flash_data_printf(indata, FLASH_READ_LEN);
-
- uint8_t tmp[256];
- uint16_t len_tmp = 0;
- uint16 orIndex = data_decode_mpu(indata, FLASH_READ_LEN, tmp, &len_tmp, spiclk);
- static uint8_t errorNum = 0;
- while(frame_index != (orIndex - 1))
- {
- QL_SPI_DEMO_LOG("in data orindex %d", orIndex);
- ql_spi_flash_data_printf(indata, FLASH_READ_LEN);
- spi_dma_write_hc(QL_CUR_SPI_PORT, output, FLASH_SEND_LEN, spiclk);
- QL_SPI_DEMO_LOG("out data,frame_tmp.data_lenth %d", frame_tmp.data_lenth);
- ql_spi_flash_data_printf(output, frame_tmp.data_lenth);
- ql_rtos_task_sleep_ms(DELAY_TIME_FLASH_TEST);
- spi_dma_read_hc(QL_CUR_SPI_PORT, indata, FLASH_READ_LEN, spiclk);
- orIndex = data_decode_mpu(indata, FLASH_READ_LEN, tmp, &len_tmp, spiclk);
- errorNum++;
- if(errorNum > 20)
- {
- //升级失败
- ql_fclose(fd_updata_file);
- free(indata_tmp);
- *output_data_len = 0;
- return errorNum;
- }
-
- }
- frame_index++;
- readLen = ql_fread(pbuf, FLASH_SEND_DATA_LEN, 1, fd_updata_file);
- }
- memset(output, 0, FLASH_SEND_LEN);
- *output_data_len = sizeof(frame_pack_t);
- output[(*output_data_len)++] = 0X00;
- output[(*output_data_len)++] = frame_index & 0XFF;
- output[(*output_data_len)++] = (frame_index >> 8) & 0XFF;
- output[(*output_data_len)++] = crcFile & 0XFF;
- output[(*output_data_len)++] = (crcFile >> 8) & 0XFF;
- output[(*output_data_len)++] = ql_fsize(fd_updata_file) & 0XFF;
- output[(*output_data_len)++] = (ql_fsize(fd_updata_file) >> 8) & 0XFF;
- frame_tmp.data_lenth = (*output_data_len) + 2;
- memcpy(output, &frame_tmp, sizeof(frame_pack_t));
- crc16_tmp = crc16_modbus(output, (*output_data_len));
- output[(*output_data_len)++] = crc16_tmp & 0XFF;
- output[(*output_data_len)++] = (crc16_tmp >> 8) & 0XFF;
-
- spi_dma_write_hc(QL_CUR_SPI_PORT, output, FLASH_SEND_LEN, spiclk);
- QL_SPI_DEMO_LOG("end of frame_tmp.data_lenth:%d crc16_tmp:%d crcFile:%d", frame_tmp.data_lenth, crc16_tmp, crcFile);
- ql_spi_flash_data_printf(output, FLASH_READ_LEN);
- #undef DATA_SEND_LEN
- ql_fclose(fd_updata_file);
- free(indata_tmp);
- *output_data_len = 0;
- return 0;
- break;
- case 0X04:
- frame_tmp.cmd_type = 0X04;
- communication_control_t_info.can_send_data_type = 1;
- memcpy(output, &communication_control_t_info, sizeof(communication_control_t));
- *output_data_len += sizeof(communication_control_t);
- break;
- default:
- break;
- }
- break;
-
- default:
- break;
- }
- frame_tmp.data_lenth = 2 + *output_data_len;
- memcpy(output, &frame_tmp, sizeof(frame_pack_t));
- uint16_t crc16 = crc16_modbus(output, *output_data_len);
- output[(*output_data_len)++] = crc16 & 0XFF;
- output[(*output_data_len)++] = (crc16 >> 8) & 0XFF;
- return 0;
- }
- uint16_t data_decode_mpu(uint8_t *input_data, uint16_t input_data_len, uint8_t* output, uint16_t* output_data_len, ql_spi_clk_e spiclk)
- {
-
- uint16_t frame_start = 0; // 帧起始位
- uint16_t frame_len = 0;
-
- *output_data_len = 0;
- static frame_pack_t frame_tmp = {0};
- frame_tmp.frame_head = 0X5A;
- frame_tmp.destination_addr = MCU_ADDR;
- frame_tmp.source_addr = MPU_ADDR;
- //frame_pack_t* frame_read_tmp;
- frame_len = Full_Frame_Verifi(input_data, input_data_len, &frame_start);
- //QL_SPI_DEMO_LOG("cmd :%d %dxxxxxx",frame_len, frame_start);
- if(0 == frame_len)
- return 1;
- else
- {}
- *output_data_len += sizeof(frame_pack_t);
- //QL_SPI_DEMO_LOG("cmd :%d %dxxxxxx",input_data[frame_start + FRAME_CMD_INDEX], frame_start);
- uint8_t *pack_data = input_data + frame_start + sizeof(frame_pack_t);
- switch(input_data[frame_start + FRAME_CMD_INDEX])
- {
- case 0X50:
- frame_tmp.cmd = 0X50;
- switch(input_data[frame_start + FRAME_CMD_TYPE_INDEX])
- {
- case 0X01:
- // // uint8_t temperatures_number;
- // int8_t temperatures_data[TEMP_NUMBER];
- QL_SPI_DEMO_LOG("cmd :0X01----");
- cmd_05_01_device_status_t* tmp_read1 = (cmd_05_01_device_status_t * )(input_data + frame_start + sizeof(frame_pack_t));
- QL_SPI_DEMO_LOG("work_status %d, backup_voltage:%d, backup_temperature:%d,high_driver_number:%d,\n\
- high_driver_status:%d, low_driver_number:%d low_driver_status:%d last_wake_up_source %d location_status:%d", tmp_read1->work_status, tmp_read1->backup_voltage,\
- tmp_read1->backup_temperature,tmp_read1->high_driver_number,tmp_read1->high_driver_status,\
- tmp_read1->low_driver_number,tmp_read1->low_driver_status, tmp_read1->last_wake_up_source,tmp_read1->location_status\
- );
- (void)tmp_read1;
- break;
- case 0X02:;
- QL_SPI_DEMO_LOG("cmd :0X02----");
- gps_info_t* tmp_read2 = (gps_info_t *)(input_data + frame_start + sizeof(frame_pack_t));
- QL_SPI_DEMO_LOG("gps locate_mark %d,satellite_num %d,", tmp_read2->locate_mark, tmp_read2->satellite_num);
- (void)tmp_read2;
- break;
- case 0X03:
- QL_SPI_DEMO_LOG("cmd :0X03----");
- cmd_05_03_communication_data_t* tmp_read = (cmd_05_03_communication_data_t *)(input_data + frame_start + sizeof(frame_pack_t));
- QL_SPI_DEMO_LOG("%d, %d,%d, %d,%d, %d,%d, %d,%d, %d,%d,",\
- tmp_read->x_data,tmp_read->y_data,tmp_read->z_data,tmp_read-> can0_data_status,tmp_read-> can0_fault_status,tmp_read->can0_data_lenth,\
- tmp_read-> can1_data_status,tmp_read-> can1_fault_status,tmp_read->can1_data_lenth,tmp_read-> rs485_data_status,tmp_read->rs485_data_lenth);
- (void)tmp_read;
- break;
- default:
- break;
- }
- break;
- case 0X60:
- //
- switch(input_data[frame_start + FRAME_CMD_TYPE_INDEX])
- {
- case 0X01:
- ///
- *output_data_len = 0;
- break;
- case 0X02:
- ///
- break;
- case 0X03:
- QL_SPI_DEMO_LOG("cmd60 03----flash\nframe_index :%d\n", (pack_data[0] + (pack_data[1] << 8)));
- return (pack_data[0] + (pack_data[1] << 8));
- break;
- case 0X04:
- //
- break;
- default:
- break;
- }
- *output_data_len = 0;
- return 0;
- break;
- default:
- break;
- }
- memcpy(output, &frame_tmp, sizeof(frame_pack_t)); //帧固定帧在此复制
-
- uint16_t crc16 = crc16_modbus(output, *output_data_len);
- output[(*output_data_len)++] = crc16 & 0XFF;
- output[(*output_data_len)++] = (crc16 << 8) & 0XFF;
- return 0;
- }
- unsigned short crc16_modbus(unsigned char *pdata, int len)
- {
- int j = 0;
- int i = 0;
- uint16_t reg_crc = 0xffff;
- while (i < len )
- {
- reg_crc ^= pdata[i];
- i++;
- for (j = 0; j < 8; j++)
- {
- if ((reg_crc & 0x01) == 1)
- {
- reg_crc = (uint16_t)((reg_crc >> 1) ^ 0xa001);
- }
- else
- {
- reg_crc = (uint16_t)( reg_crc >> 1);
- }
- }
- }
-
- return reg_crc;
- }
- #if 1
- uint16_t g_dnpcrc_table[256] =
- {
- 0x0000, 0x365E, 0x6CBC, 0x5AE2, 0xD978, 0xEF26, 0xB5C4, 0x839A,
- 0xFF89, 0xC9D7, 0x9335, 0xA56B, 0x26F1, 0x10AF, 0x4A4D, 0x7C13,
- 0xB26B, 0x8435, 0xDED7, 0xE889, 0x6B13, 0x5D4D, 0x07AF, 0x31F1,
- 0x4DE2, 0x7BBC, 0x215E, 0x1700, 0x949A, 0xA2C4, 0xF826, 0xCE78,
- 0x29AF, 0x1FF1, 0x4513, 0x734D, 0xF0D7, 0xC689, 0x9C6B, 0xAA35,
- 0xD626, 0xE078, 0xBA9A, 0x8CC4, 0x0F5E, 0x3900, 0x63E2, 0x55BC,
- 0x9BC4, 0xAD9A, 0xF778, 0xC126, 0x42BC, 0x74E2, 0x2E00, 0x185E,
- 0x644D, 0x5213, 0x08F1, 0x3EAF, 0xBD35, 0x8B6B, 0xD189, 0xE7D7,
- 0x535E, 0x6500, 0x3FE2, 0x09BC, 0x8A26, 0xBC78, 0xE69A, 0xD0C4,
- 0xACD7, 0x9A89, 0xC06B, 0xF635, 0x75AF, 0x43F1, 0x1913, 0x2F4D,
- 0xE135, 0xD76B, 0x8D89, 0xBBD7, 0x384D, 0x0E13, 0x54F1, 0x62AF,
- 0x1EBC, 0x28E2, 0x7200, 0x445E, 0xC7C4, 0xF19A, 0xAB78, 0x9D26,
- 0x7AF1, 0x4CAF, 0x164D, 0x2013, 0xA389, 0x95D7, 0xCF35, 0xF96B,
- 0x8578, 0xB326, 0xE9C4, 0xDF9A, 0x5C00, 0x6A5E, 0x30BC, 0x06E2,
- 0xC89A, 0xFEC4, 0xA426, 0x9278, 0x11E2, 0x27BC, 0x7D5E, 0x4B00,
- 0x3713, 0x014D, 0x5BAF, 0x6DF1, 0xEE6B, 0xD835, 0x82D7, 0xB489,
- 0xA6BC, 0x90E2, 0xCA00, 0xFC5E, 0x7FC4, 0x499A, 0x1378, 0x2526,
- 0x5935, 0x6F6B, 0x3589, 0x03D7, 0x804D, 0xB613, 0xECF1, 0xDAAF,
- 0x14D7, 0x2289, 0x786B, 0x4E35, 0xCDAF, 0xFBF1, 0xA113, 0x974D,
- 0xEB5E, 0xDD00, 0x87E2, 0xB1BC, 0x3226, 0x0478, 0x5E9A, 0x68C4,
- 0x8F13, 0xB94D, 0xE3AF, 0xD5F1, 0x566B, 0x6035, 0x3AD7, 0x0C89,
- 0x709A, 0x46C4, 0x1C26, 0x2A78, 0xA9E2, 0x9FBC, 0xC55E, 0xF300,
- 0x3D78, 0x0B26, 0x51C4, 0x679A, 0xE400, 0xD25E, 0x88BC, 0xBEE2,
- 0xC2F1, 0xF4AF, 0xAE4D, 0x9813, 0x1B89, 0x2DD7, 0x7735, 0x416B,
- 0xF5E2, 0xC3BC, 0x995E, 0xAF00, 0x2C9A, 0x1AC4, 0x4026, 0x7678,
- 0x0A6B, 0x3C35, 0x66D7, 0x5089, 0xD313, 0xE54D, 0xBFAF, 0x89F1,
- 0x4789, 0x71D7, 0x2B35, 0x1D6B, 0x9EF1, 0xA8AF, 0xF24D, 0xC413,
- 0xB800, 0x8E5E, 0xD4BC, 0xE2E2, 0x6178, 0x5726, 0x0DC4, 0x3B9A,
- 0xDC4D, 0xEA13, 0xB0F1, 0x86AF, 0x0535, 0x336B, 0x6989, 0x5FD7,
- 0x23C4, 0x159A, 0x4F78, 0x7926, 0xFABC, 0xCCE2, 0x9600, 0xA05E,
- 0x6E26, 0x5878, 0x029A, 0x34C4, 0xB75E, 0x8100, 0xDBE2, 0xEDBC,
- 0x91AF, 0xA7F1, 0xFD13, 0xCB4D, 0x48D7, 0x7E89, 0x246B, 0x1235,
- };
- #endif
- void creat_software_crc16(int fd, uint16_t *cur_crc)
- {
- #if 1
- uint16_t crc = 0u;
- uint32_t index = 0u;
- uint8 pbuf[256] = {0};
- int readLen = 0;
- readLen = ql_fread(pbuf, 256, 1, fd);
- while((readLen) > 0)
- {
- for (index = 0u; index < readLen; index++)
- {
- crc = ( crc >> 8 ) ^ g_dnpcrc_table[( crc ^ pbuf[index]) & 0x00ff] ;
- }
- readLen = ql_fread(pbuf, sizeof(pbuf), 1, fd);
- }
- *cur_crc = ((~crc) & 0xFFFFu);
- QL_SPI_DEMO_LOG("file len crc", *cur_crc);
- #else
- uint8 pbuf[256] = {0};
- int len = ql_fread(pbuf, 256, 1, fd);
- QL_SPI_DEMO_LOG("read len %d %d", len, pbuf[0]);
- for(int i = 0; i < len; i++)
- {
- QL_SPI_DEMO_LOG("%c ", pbuf[i]);
- }
- #endif
- }
- void spi_dma_write_hc(ql_spi_port_e spi_port, uint8_t *pbuf, uint32 len, ql_spi_clk_e spiclk)
- {
- unsigned int tx_free = 0;
- unsigned int framesize = 8;
- ql_spi_cs_low(QL_CUR_SPI_PORT);
- spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_WRITE;
- //不允许进入慢时钟
- ql_spi_request_sys_clk(QL_CUR_SPI_PORT);
- ql_spi_write(spi_port, pbuf, len);
- ql_rtos_semaphore_wait(spi_demo_write, QL_WAIT_FOREVER);
- //tx_dma_done只是DMA完成了,但是SPI的FIFO还可能存在数据未发送,在进入慢时钟或clk频率较低时出现
- ql_spi_get_tx_fifo_free(QL_CUR_SPI_PORT, &tx_free);
- QL_SPI_DEMO_LOG("tx_free=%d",tx_free);
- ql_delay_us((framesize+2)*(QL_SPI_FIFO_SIZE - tx_free)*1000000/spiclk);
- //恢复允许进入慢时钟
- ql_spi_release_sys_clk(QL_CUR_SPI_PORT);
-
- ql_spi_cs_high(QL_CUR_SPI_PORT);
- }
- void spi_dma_read_hc(ql_spi_port_e spi_port, uint8_t *pbuf, uint32 len, ql_spi_clk_e spiclk)
- {
- unsigned int tx_free = 0;
- unsigned int framesize = 8;
- ql_spi_cs_low(QL_CUR_SPI_PORT);
- spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_READ;
- //不允许进入慢时钟
- ql_spi_request_sys_clk(QL_CUR_SPI_PORT);
- ql_spi_read(spi_port, pbuf, len);
- ql_rtos_semaphore_wait(spi_demo_read, QL_WAIT_FOREVER);
- //tx_dma_done只是DMA完成了,但是SPI的FIFO还可能存在数据未发送,在进入慢时钟或clk频率较低时出现
- ql_spi_get_tx_fifo_free(QL_CUR_SPI_PORT, &tx_free);
- QL_SPI_DEMO_LOG("tx_free=%d",tx_free);
- ql_delay_us((framesize+2)*(QL_SPI_FIFO_SIZE - tx_free)*1000000/spiclk);
- //恢复允许进入慢时钟
- ql_spi_release_sys_clk(QL_CUR_SPI_PORT);
- ql_spi_cs_high(QL_CUR_SPI_PORT);
- }
|