BLE5.2 1.0
开发文档说明
xc_drv_spi_dma.c
浏览该文件的文档.
1
25/*-----------------------------------------------------------------------------------
26 INCLUDE HEADE FILES
27 ------------------------------------------------------------------------------------*/
28#include "xc_drv_spi_dma.h"
29
30/*------------------------------------------------------------------------------------
31 Local Variables
32 -------------------------------------------------------------------------------------*/
33
34// Declare global variables
35//static volatile bool tfr_flag;
36static volatile bool wr_tfr_flag;
37static volatile bool rd_tfr_flag;
38static volatile bool err_flag;
39// static volatile bool srcTran_flag;
40// static volatile bool dstTran_flag;
41
42// Intermediate buffer
43uint8_t mid[FLASH_PAGE_SIZE+4];
44
45/*------------------------------------------------------------------------------------
46 Global Variables
47 -------------------------------------------------------------------------------------*/
48
49/*------------------------------------------------------------------------------------
50 Func Prototype
51 -------------------------------------------------------------------------------------*/
52uint8_t xc_spi_dma_flash_read_status(uint8_t spi_idx);
53
54/*------------------------------------------------------------------------------------
55 Functions
56 -------------------------------------------------------------------------------------*/
65void spi_dma_write_callback(uint8_t eCode)
66{
67// DEBUG("T\n");
68 wr_tfr_flag = true;
69}
70
79void spi_dma_read_callback(uint8_t eCode)
80{
81// DEBUG("R\n");
82 rd_tfr_flag = true;
83}
84
93void spi_dma_write_err(uint8_t eCode)
94{
95 // -------
96 // This function is called by the IRQ handler.
97 // We use this function to deal with interrupts that the DMA
98 // driver is unable to cater for (these are application
99 // specific). All of the interrupts handled by this function
100 // are cleared by the DMA driver, so there's no need to clear here.
101 // -------
102
103 // Check the source of the interrupt
104
105 if(eCode == DMA_IRQ_ERR) {
106
107 // Just inform the application that this interrupt has occured.
108 err_flag = true;
109 }
110}
111
120void spi_dma_read_err(uint8_t eCode)
121{
122 // -------
123 // This function is called by the IRQ handler.
124 // We use this function to deal with interrupts that the DMA
125 // driver is unable to cater for (these are application
126 // specific). All of the interrupts handled by this function
127 // are cleared by the DMA driver, so there's no need to clear here.
128 // -------
129
130 // Check the source of the interrupt
131
132 if(eCode == DMA_IRQ_ERR) {
133
134 // Just inform the application that this interrupt has occured.
135 err_flag = true;
136 }
137}
138
148{
149 while(wr_tfr_flag == false) {
150 if(err_flag == true) {
151 // Wasn't expecting this !!
152 DEBUG("\nERROR: Recieved an err interrupt\n");
153 }
154 }
155}
156
166{
167 while(rd_tfr_flag == false) {
168 if(err_flag == true) {
169 // Wasn't expecting this !!
170 DEBUG("\nERROR: Recieved an err interrupt\n");
171 }
172 }
173}
174
183uint32_t xc_spi_prf_data_addr(uint8_t spi_idx, uint8_t *eCode)
184{
185 uint32_t spi_prf_addr = XC_REG_SPI_BASE_ADDR;
186
187 if(spi_idx == SPI2_IDX) {
188 spi_prf_addr += (SPI2_BASE_OFFSET + SSIx_DATA_OFFSET);
189 } else if(spi_idx < SPI2_IDX) {
190 if(spi_idx == SPI1_IDX)
191 spi_prf_addr += (SPI1_BASE_OFFSET + SSIx_DATA_OFFSET);
192 else
193 spi_prf_addr += SSIx_DATA_OFFSET;
194 } else {
195 *eCode = DMA_EPERM;
196 }
197
198 return spi_prf_addr;
199}
200
209uint8_t xc_spi_dma_write_config(uint8_t spi_idx, eDMA_Ch_Num ch_num, uint16_t blockSize, uint8_t *tx_buff)
210{
211 DMA_Chx_Cfg_t ch_cfg;
212 uint8_t errorCode = DMA_OK;
213 uint8_t data_size = spi_ctrl0__ssi_dfs__getf(spi_idx);
214
215 uint32_t spi_prf_addr = xc_spi_prf_data_addr(spi_idx, &errorCode);
216 if(errorCode != DMA_OK)
217 {
218 return errorCode;
219 }
220
221 ch_cfg.sar = (uint32_t)tx_buff;
222 ch_cfg.dar = (uint32_t)spi_prf_addr;
223
224 ch_cfg.ctl_src_msize = DMA_MSIZE_1;//DMAC_MSIZE_4;//DMAC_MSIZE_1;
225 ch_cfg.ctl_dst_msize = DMA_MSIZE_1;//DMAC_MSIZE_4;//DMAC_MSIZE_1;
226
229
230 if(data_size == 0x07) {
233 } else if(data_size == 0x0f) {
236 }
237
238 ch_cfg.ctl_tt_fc = DMA_MEM2PRF_DMA;
239
240 ch_cfg.ctl_block_ts = blockSize;
241
244
246
247 if(spi_idx == 0)
249 else if(spi_idx == 1)
251 else if(spi_idx == 2)
253
254// ch_cfg.cfg_ch_prior = DMA_PRIORITY_0;
255 // Now we can intialise the channel configuration structure for
256 // DMA channel 0 by loading the structure members with the
257 // contents of the DMAC's channel 0 registers.
258 errorCode = xc_dma_set_channel_config(ch_num, &ch_cfg);
259 if(errorCode != 0) {
260 DEBUG("\nERROR: Failed to initialise configuration\n");
261 }
262
264
265 return errorCode;
266}
267
276uint8_t xc_spi_dma_read_config(uint8_t spi_idx, eDMA_Ch_Num ch_num, uint16_t blockSize, uint8_t *rx_buff)
277{
278 DMA_Chx_Cfg_t ch_cfg;
279 uint8_t errorCode = DMA_OK;
280 uint8_t data_size = spi_ctrl0__ssi_dfs__getf(spi_idx);
281
282 uint32_t spi_prf_addr = xc_spi_prf_data_addr(spi_idx, &errorCode);
283 if(errorCode != DMA_OK)
284 {
285 return errorCode;
286 }
287
288 ch_cfg.sar = (uint32_t)spi_prf_addr;
289 ch_cfg.dar = (uint32_t)rx_buff;
290
291 ch_cfg.ctl_src_msize = DMA_MSIZE_1;
292 ch_cfg.ctl_dst_msize = DMA_MSIZE_1;
293
296
297 if(data_size == 0x07) {
300 } else if(data_size == 0x0f) {
303 }
304
305 ch_cfg.ctl_tt_fc = DMA_PRF2MEM_DMA;
306
307 ch_cfg.ctl_block_ts = blockSize;
308
311
313
314 if(spi_idx == 0)
316 else if(spi_idx == 1)
318 else if(spi_idx == 2)
320
321// ch_cfg.cfg_ch_prior = DMAC_PRIORITY_1;
322 // Now we can intialise the channel configuration structure for
323 // DMA channel 0 by loading the structure members with the
324 // contents of the DMAC's channel 0 registers.
325 errorCode = xc_dma_set_channel_config(ch_num, &ch_cfg);
326 if(errorCode != 0) {
327 DEBUG("\nERROR: Failed to initialise configuration\n");
328 }
329
331
332 return errorCode;
333}
334
343void xc_spi_dma_write_and_read(uint8_t spi_idx,
344 eDMA_Ch_Num w_chnum, uint16_t w_size, uint8_t *w_buff,
345 eDMA_Ch_Num r_chnum, uint16_t r_size, uint8_t *r_buff)
346{
347 uint8_t errorCode;
348
349 xc_dma_init( );
350
351 errorCode = xc_spi_dma_read_config(spi_idx, r_chnum, r_size, r_buff);
352 if(errorCode != 0) {
353 DEBUG("\nERROR: Failed SPI_DMAC_Recv_Cfg\n");
354 }
355 errorCode = xc_spi_dma_write_config(spi_idx, w_chnum, w_size+1, w_buff); //w_size+1
356 if(errorCode != 0) {
357 DEBUG("\nERROR: Failed SPI_DMAC_Send_Cfg\n");
358 }
359
360 xc_dma_enable( );
361
362 errorCode = xc_dma_start_transfer(r_chnum, spi_dma_read_callback);
363 if(errorCode != 0) {
364 DEBUG("\nERROR: Failed DMAC_StartTransfer read\n");
365 }
366
367 errorCode = xc_dma_start_transfer(w_chnum, spi_dma_write_callback);
368 if(errorCode != 0) {
369 DEBUG("\nERROR: Failed DMAC_StartTransfer write\n");
370 }
371
374
376
377 wr_tfr_flag = false;
378 rd_tfr_flag = false;
379 err_flag = false;
380}
381
390void xc_spi_dma_read_and_write(uint8_t spi_idx,
391 eDMA_Ch_Num w_chnum, uint16_t w_size, uint8_t *w_buff,
392 eDMA_Ch_Num r_chnum, uint16_t r_size, uint8_t *r_buff)
393{
394 uint8_t errorCode;
395
396 xc_dma_init( );
397
398 errorCode = xc_spi_dma_read_config(spi_idx, r_chnum, r_size, r_buff);
399 if(errorCode != 0) {
400 DEBUG("\nERROR: Failed SPI_DMAC_Recv_Cfg\n");
401 }
402 errorCode = xc_spi_dma_write_config(spi_idx, w_chnum, w_size+1, w_buff); //w_size+1
403 if(errorCode != 0) {
404 DEBUG("\nERROR: Failed SPI_DMAC_Send_Cfg\n");
405 }
406
407 xc_dma_enable( );
408
409 errorCode = xc_dma_start_transfer(r_chnum, spi_dma_read_callback);
410 if(errorCode != 0) {
411 DEBUG("\nERROR: Failed DMAC_StartTransfer read\n");
412 }
413
414 errorCode = xc_dma_start_transfer(w_chnum, spi_dma_write_callback);
415 if(errorCode != 0) {
416 DEBUG("\nERROR: Failed DMAC_StartTransfer write\n");
417 }
418
421
423
424 wr_tfr_flag = false;
425 rd_tfr_flag = false;
426 err_flag = false;
427}
428
437void xc_spi_dma_write(uint8_t spi_idx, eDMA_Ch_Num w_chnum, uint16_t w_size, uint8_t *w_buff)
438{
439 uint8_t errorCode;
440
441 xc_dma_init( );
442
443 errorCode = xc_spi_dma_write_config(spi_idx, w_chnum, w_size, w_buff); //w_size+1
444 if(errorCode != 0) {
445 DEBUG("\nERROR: Failed SPI_DMAC_Send_Cfg\n");
446 }
447
448 xc_dma_enable( );
449
450 errorCode = xc_dma_start_transfer(w_chnum, spi_dma_write_callback);
451 if(errorCode != 0) {
452 DEBUG("\nERROR: Failed DMAC_StartTransfer write\n");
453 }
454
456// xc_dma_prf2mem_finish( );
457
459
460 wr_tfr_flag = false;
461// rd_tfr_flag = false;
462 err_flag = false;
463}
464
473void xc_spi_dma_read(uint8_t spi_idx, eDMA_Ch_Num r_chnum, uint16_t r_size, uint8_t *r_buff)
474{
475 uint8_t errorCode;
476
477 xc_dma_init( );
478
479 errorCode = xc_spi_dma_read_config(spi_idx, r_chnum, r_size, r_buff);
480 if(errorCode != 0) {
481 DEBUG("\nERROR: Failed SPI_DMAC_Send_Cfg\n");
482 }
483
484 xc_dma_enable( );
485
486 errorCode = xc_dma_start_transfer(r_chnum, spi_dma_read_callback);
487 if(errorCode != 0) {
488 DEBUG("\nERROR: Failed DMAC_StartTransfer read\n");
489 }
490
491// xc_dma_mem2prf_finish( );
493
495
496// wr_tfr_flag = false;
497 rd_tfr_flag = false;
498 err_flag = false;
499}
500
509void xc_spi_dma_init(uint8_t spi_idx, uint8_t dfs, uint8_t tdl, uint8_t rdl)
510{
511 spi_en__ssi_sen__setf(spi_idx, DISABLE);
512 spi_dmas_pack(spi_idx, ENABLE, ENABLE);
513 spi_ctrl0__ssi_dfs__setf(spi_idx, dfs);
514 spi_dmatdl_set(spi_idx, tdl);
515 spi_dmardl_set(spi_idx, rdl);
516 spi_en__ssi_sen__setf(spi_idx, ENABLE);
517}
518
527void xc_spi_dma_deinit(uint8_t spi_idx)
528{
529 spi_dmas_pack(spi_idx, DISABLE, DISABLE);
530 spi_en__ssi_sen__setf(spi_idx, DISABLE);;
531}
532
544void xc_spi_dma_write_data(uint8_t spi_idx, uint8_t *data, uint16_t size)
545{
546 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
547
548 xc_spi_dma_write(spi_idx, DMA_CHANNEL0, size, data); //DMA_CHANNEL0
549
550 xc_spi_dma_deinit(spi_idx);
551}
552
564void xc_spi_dma_read_data(uint8_t spi_idx, uint8_t *data, uint16_t size)
565{
566 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
567
568 xc_spi_dma_read(spi_idx, DMA_CHANNEL0, size, data); //DMA_CHANNEL0
569
570 xc_spi_dma_deinit(spi_idx);
571}
572
584void xc_spi_dma_write_and_read_data(uint8_t spi_idx,
585 uint8_t *w_data, uint16_t w_size,
586 uint8_t *r_data, uint16_t r_size)
587{
588 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
589
591 DMA_CHANNEL1, w_size, w_data,
592 DMA_CHANNEL0, r_size, r_data); //DMA_CHANNEL0
593
594 xc_spi_dma_deinit(spi_idx);
595}
596
608void xc_spi_dma_read_and_write_data(uint8_t spi_idx,
609 uint8_t *w_data, uint16_t w_size,
610 uint8_t *r_data, uint16_t r_size)
611{
612 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
613
615 DMA_CHANNEL1, w_size, w_data,
616 DMA_CHANNEL0, r_size, r_data); //DMA_CHANNEL0
617
618 xc_spi_dma_deinit(spi_idx);
619}
620
621
630void xc_spi_dma_flash_power_down(uint8_t spi_idx)
631{
632 uint8_t cmd[1];
633
635
636 cmd[0] = CMD_PWRDWN;
637
638 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
639
640 xc_spi_dma_write(spi_idx, DMA_CHANNEL0, sizeof(cmd), cmd);
641
642 xc_spi_dma_deinit(spi_idx);
643}
644
653void xc_spi_dma_flash_wakeup(uint8_t spi_idx)
654{
655 uint8_t cmd[1];
656
658
659 cmd[0] = CMD_RELEASE_PWRDWN;
660
661 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
662
663 xc_spi_dma_write(spi_idx, DMA_CHANNEL0, sizeof(cmd), cmd);
664
665 xc_spi_dma_deinit(spi_idx);
666}
667
668
677void xc_spi_dma_flash_wait_busy(uint8_t spi_idx)
678{
679 while( ( xc_spi_dma_flash_read_status(spi_idx) & 0x01 ) );
680}
681
690void xc_spi_dma_flash_write_enable(uint8_t spi_idx)
691{
692 uint8_t cmd[1];
693
695
696 cmd[0] = CMD_WRITE_ENABLE;
697
698 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
699
700 xc_spi_dma_write(spi_idx, DMA_CHANNEL0, sizeof(cmd), cmd);
701
702 xc_spi_dma_deinit(spi_idx);
703}
704
714{
715 uint8_t cmd[1];
716
718
719 cmd[0] = CMD_WRITE_DISABLE;
720
721 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
722
723 xc_spi_dma_write(spi_idx, DMA_CHANNEL0, sizeof(cmd), cmd);
724
725 xc_spi_dma_deinit(spi_idx);
726}
727
736void xc_spi_dma_flash_erase_sector(uint8_t spi_idx, uint32_t Dst_Addr)
737{
738 uint8_t cmd[4] = { 0 };
739
743
744 cmd[0] = CMD_SECTOR_ERASE;
745 cmd[1] = Dst_Addr>>16;
746 cmd[2] = Dst_Addr>>8;
747 cmd[3] = Dst_Addr;
748
749 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
750
751 xc_spi_dma_write(spi_idx, DMA_CHANNEL0, sizeof(cmd), cmd);
752
753 xc_spi_dma_deinit(spi_idx);
754}
755
764void xc_spi_dma_flash_erase_page(uint8_t spi_idx, uint32_t Dst_Addr)
765{
766 uint8_t cmd[4] = { 0 };
767 uint32_t mid = 0;
768 xc_spi_dma_flash_rdid(spi_idx, (uint8_t*)&mid);
769 if(mid != GD_FlASH_RDID){
773
774 cmd[0] = CMD_PAGE_ERASE;
775 cmd[1] = Dst_Addr>>16;
776 cmd[2] = Dst_Addr>>8;
777 cmd[3] = Dst_Addr;
778
779 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
780
781 xc_spi_dma_write(spi_idx, DMA_CHANNEL0, sizeof(cmd), cmd);
782
783 xc_spi_dma_deinit(spi_idx);
784 }
785}
786
787
799uint8_t xc_spi_dma_flash_read_status(uint8_t spi_idx)
800{
801 uint8_t cmd[2] = { 0 };
802 uint8_t sta[2] = { 0xff, 0xff };
803
804 // memset(sta, 0xff, sizeof(sta));
805
806 cmd[0] = CMD_READ_STATUS;
807 cmd[1] = 0xff;
808
809 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
810
812 DMA_CHANNEL1, sizeof(cmd), cmd,
813 DMA_CHANNEL0, sizeof(sta), sta);
814
815 xc_spi_dma_deinit(spi_idx);
816
817 return sta[1];
818}
819
831void xc_spi_dma_flash_write_page(uint8_t spi_idx, uint32_t WriteAddr, uint8_t *data, uint16_t size)
832{
833 uint8_t dts = 0x07;
834 uint8_t cmd[FLASH_PAGE_SIZE+4] = { 0 };
835
836 if(size > FLASH_PAGE_SIZE)
837 return;
838
842
843 cmd[0] = CMD_PAGE_PROGRAM;
844 cmd[1] = WriteAddr >> 16;
845 cmd[2] = WriteAddr >> 8;
846 cmd[3] = WriteAddr;
847
848 dts = 0x07;
849 memcpy(&cmd[4], data, FLASH_PAGE_SIZE);
850
851 xc_spi_dma_init(spi_idx, dts, 1, 1);
852
853 xc_spi_dma_write(spi_idx, DMA_CHANNEL1, FLASH_PAGE_SIZE+4, cmd);
854
855 xc_spi_dma_deinit(spi_idx);
856}
857
869void xc_spi_dma_flash_read_page(uint8_t spi_idx, uint32_t ReadAddr, uint8_t *data, uint16_t size)
870{
871 uint16_t buad_idx = spi_baud__ssi_sckdv__getf(spi_idx);
872 uint8_t dts = 0x07;
873 uint8_t cmd[FLASH_PAGE_SIZE+4] = { 0 };
874
875 if(size > FLASH_PAGE_SIZE)
876 return;
877
879
880 memset(mid, 0xff, sizeof(mid));
881
882 if(buad_idx != SSI_BAUD_DIV_2) {
883 cmd[0] = CMD_READ_DATA;
884 cmd[1] = ReadAddr >> 16;
885 cmd[2] = ReadAddr >> 8;
886 cmd[3] = ReadAddr;
887
888 dts = 0x07;
889 } else {
890 cmd[0] = ReadAddr >> 16;
891 cmd[1] = CMD_READ_DATA;
892 cmd[2] = ReadAddr;
893 cmd[3] = ReadAddr >> 8;
894
895 dts = 0x0f;
896 }
897
898 xc_spi_dma_init(spi_idx, dts, 1, 1);
899
901 DMA_CHANNEL0, (FLASH_PAGE_SIZE+4), cmd,
902 DMA_CHANNEL1, (FLASH_PAGE_SIZE+4), mid);
903
904 xc_spi_dma_deinit(spi_idx);
905
906 if(buad_idx != SSI_BAUD_DIV_2) {
907 memcpy(data, mid+4, FLASH_PAGE_SIZE);
908 } else {
909 for(uint16_t n=0; n<(FLASH_PAGE_SIZE/2); n++)
910 {
911 data[2*n] = mid[2*n+5];
912 data[2*n+1] = mid[2*n+4];
913 }
914 }
915}
916
928eXC_RESULT xc_spi_dma_flash_read(uint8_t spi_idx, uint32_t readAddr, uint8_t *buff, uint16_t len)
929{
930 eXC_RESULT ret = XR_OK;
931 uint16_t ReqPageCnt = 0; //本次读取数据要占用的页号
932 uint16_t CurPageNum = 0; //本次数据读取所占用的当前页号
933 uint16_t CurStartPsr = 0; //本次地址在 当前页所占的位置
934 uint16_t NextPageNum = 0; //本次数据读取可能 占用到的下一个页号
935 uint16_t NextStopPsr = 0; //本次数据读取可能 占用的下一个页的结束地址
936 uint8_t temp_buff[FLASH_PAGE_SIZE] = { 0 };
937
938 if(len <= FLASH_PAGE_SIZE)
939 {
940 CurPageNum = CUR_PAGE_NUM(readAddr);
941 CurStartPsr = CUR_START_PSR(readAddr);
942 if((len + CurStartPsr) > FLASH_PAGE_SIZE)
943 ReqPageCnt = 2;
944 else
945 ReqPageCnt = 1;
946
947 if(ReqPageCnt == 1 ) //说明这里只读取一个页
948 {
949 xc_spi_dma_flash_read_page(spi_idx, CurPageNum*FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
950 memcpy(buff, &temp_buff[CurStartPsr], len);
951 }
952 else if(ReqPageCnt == 2)
953 {
954 NextPageNum = CurPageNum + 1;
955 NextStopPsr = len + CurStartPsr - FLASH_PAGE_SIZE;
956 //读取的第一个页
957 xc_spi_dma_flash_read_page(spi_idx, CurPageNum*FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
958 memcpy(buff, &temp_buff[CurStartPsr], len-NextStopPsr);
959 //读取的第二个页
960 uint16_t HaveCopyNum = len - NextStopPsr;
961 xc_spi_dma_flash_read_page(spi_idx, NextPageNum*FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
962 memcpy(buff+HaveCopyNum, temp_buff, NextStopPsr);
963 }
964 }
965 else
966 {
967 CurPageNum = CUR_PAGE_NUM(readAddr);
968 CurStartPsr = CUR_START_PSR(readAddr);
969 NextPageNum = CurPageNum + 1;
970
971 uint16_t buff_idx = 0;
972 uint16_t pre_len = NextPageNum*FLASH_PAGE_SIZE - readAddr;
973 uint32_t pre_addr = CurPageNum*FLASH_PAGE_SIZE;
974 xc_spi_dma_flash_read_page(spi_idx, pre_addr, temp_buff, FLASH_PAGE_SIZE);
975 memcpy(buff, &temp_buff[CurStartPsr], pre_len);
976 buff_idx += pre_len;
977
978 pre_addr = NextPageNum*FLASH_PAGE_SIZE;
979 while(buff_idx < len)
980 {
981 if((len - buff_idx) >= FLASH_PAGE_SIZE)
982 {
983 xc_spi_dma_flash_read_page(spi_idx, pre_addr, temp_buff, FLASH_PAGE_SIZE);
984 memcpy(&buff[buff_idx], temp_buff, FLASH_PAGE_SIZE);
985 buff_idx += FLASH_PAGE_SIZE;
986 pre_addr += FLASH_PAGE_SIZE;
987 }
988 else
989 {
990 xc_spi_dma_flash_read_page(spi_idx, pre_addr, temp_buff, FLASH_PAGE_SIZE);
991 memcpy(&buff[buff_idx], temp_buff, len - buff_idx);
992 buff_idx += (len - buff_idx);
993 pre_addr += (len - buff_idx);
994 }
995 }
996 }
997
998 return ret;
999}
1000
1012eXC_RESULT xc_spi_dma_flash_write(uint8_t reg_idx, uint32_t writeAddr, uint8_t *buff,
1013 uint16_t size)
1014{
1015 uint32_t cur_addr = writeAddr;
1016 uint32_t end_addr = writeAddr + size;
1017 uint16_t wt_len = 0;
1018 // The current page number occupied by this data storage
1019 uint16_t CurPageNum = 0;
1020 uint16_t CurSectorNum = 0;
1021 // The position occupied by this address on the current page
1022 uint32_t CurStartPsr = 0;
1023
1024 uint32_t mid = 0;
1025 xc_spi_dma_flash_rdid(reg_idx ,(uint8_t*)&mid);
1026
1027 if(mid != GD_FlASH_RDID){
1028 uint8_t temp_buff[FLASH_PAGE_SIZE];
1029 while (cur_addr != end_addr) {
1030 /* code */
1031 CurPageNum = CUR_PAGE_NUM(cur_addr);
1032 CurStartPsr = CUR_START_PSR(cur_addr);
1033
1034 xc_spi_dma_flash_read_page(reg_idx, CurPageNum * FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
1035
1036 xc_spi_dma_flash_erase_page(reg_idx, CurPageNum * FLASH_PAGE_SIZE);
1037
1038 if (CurStartPsr) {
1039 memcpy(&temp_buff[CurStartPsr], buff + wt_len,
1040 (FLASH_PAGE_SIZE - CurStartPsr) > size - wt_len // 当前扇区剩余的空间是否满足写长度
1041 ? size - wt_len
1042 : (FLASH_PAGE_SIZE - CurStartPsr));
1043 wt_len += wt_len + ((FLASH_PAGE_SIZE - CurStartPsr) > size - wt_len
1044 ? size - wt_len
1045 : (FLASH_PAGE_SIZE - CurStartPsr));
1046 cur_addr += wt_len;
1047 } else {
1048 memcpy(temp_buff, buff + wt_len,
1049 size - wt_len > FLASH_PAGE_SIZE ? FLASH_PAGE_SIZE
1050 : size - wt_len);
1051 cur_addr += (size - wt_len > FLASH_PAGE_SIZE ? FLASH_PAGE_SIZE
1052 : size - wt_len);
1053 wt_len += (size - wt_len > FLASH_PAGE_SIZE ? FLASH_PAGE_SIZE
1054 : size - wt_len);
1055 }
1056
1057 xc_spi_dma_flash_write_page(reg_idx, CurPageNum * FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
1058 }
1059
1060 }else if(mid == GD_FlASH_RDID){
1061 uint8_t temp_buff[FLASH_SECTOR_SIZE];
1062 while (cur_addr != end_addr) {
1063 /* code */
1064 CurSectorNum = CUR_SECTOR_NUM(cur_addr);
1065 CurStartPsr = CUR_START_PSR(cur_addr);
1066 for(int i=0;i<FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;i++){
1067 xc_spi_dma_flash_read_page(reg_idx, CurSectorNum * FLASH_SECTOR_SIZE + i* FLASH_PAGE_SIZE, temp_buff+i*FLASH_PAGE_SIZE, FLASH_PAGE_SIZE);
1068 }
1069
1070 xc_spi_dma_flash_erase_sector(reg_idx ,CurSectorNum * FLASH_SECTOR_SIZE);
1071
1072 if (CurStartPsr) {
1073 memcpy(&temp_buff[CurStartPsr], buff + wt_len,
1074 (FLASH_SECTOR_SIZE - CurStartPsr) > size - wt_len // 当前扇区剩余的空间是否满足写长度
1075 ? size - wt_len
1076 : (FLASH_SECTOR_SIZE - CurStartPsr));
1077 wt_len += wt_len + ((FLASH_SECTOR_SIZE - CurStartPsr) > size - wt_len
1078 ? size - wt_len
1079 : (FLASH_SECTOR_SIZE - CurStartPsr));
1080 cur_addr += wt_len;
1081 } else {
1082 memcpy(temp_buff, buff + wt_len,
1083 size - wt_len > FLASH_SECTOR_SIZE ? FLASH_SECTOR_SIZE
1084 : size - wt_len);
1085 cur_addr += (size - wt_len > FLASH_SECTOR_SIZE ? FLASH_SECTOR_SIZE
1086 : size - wt_len);
1087 wt_len += (size - wt_len > FLASH_SECTOR_SIZE ? FLASH_SECTOR_SIZE
1088 : size - wt_len);
1089 }
1090
1091 for(int i=0;i<FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;i++){
1092 xc_spi_dma_flash_write_page(reg_idx, CurSectorNum * FLASH_SECTOR_SIZE + i* FLASH_PAGE_SIZE, temp_buff+i*FLASH_PAGE_SIZE, FLASH_PAGE_SIZE);
1093 }
1094 }
1095 }
1096
1097 return XR_OK;
1098}
1099
1111void xc_spi_dma_flash_rdid(uint8_t spi_idx, uint8_t *rdid)
1112{
1113 uint8_t cmd[4] = { 0 };
1114 uint8_t id[4] = { 0 };
1115
1117
1118 cmd[0] = CMD_RDID;
1119 cmd[1] = 0xff;
1120 cmd[2] = 0xff;
1121 cmd[3] = 0xff;
1122
1123 xc_spi_dma_init(spi_idx, 0x07, 1, 1);
1124
1126 DMA_CHANNEL1, sizeof(cmd), cmd,
1127 DMA_CHANNEL0, sizeof(id), id);
1128
1129 xc_spi_dma_deinit(spi_idx);
1130
1131 memcpy(rdid, &id[1], 3);
1132}
1133
1145void xc_spi_dma_flash_ruid(uint8_t spi_idx, uint8_t *ruid)
1146{
1147 uint16_t buad_idx = spi_baud__ssi_sckdv__getf(spi_idx);
1148 uint8_t dts = 0x07;
1149 uint8_t cmd[22] = { 0 };
1150 uint8_t id[22] = { 0 };
1151
1153
1154 if(buad_idx != SSI_BAUD_DIV_2) {
1155 cmd[0] = CMD_RUID;
1156 cmd[1] = 0x00;
1157 cmd[2] = 0x00;
1158 cmd[3] = 0x00;
1159 cmd[4] = 0x00;
1160
1161 dts = 0x07;
1162 } else {
1163 cmd[0] = 0x00;
1164 cmd[1] = CMD_RUID;
1165 cmd[2] = 0x00;
1166 cmd[3] = 0x00;
1167 cmd[4] = 0x00;
1168 cmd[5] = 0x00;
1169
1170 dts = 0x0f;
1171 }
1172
1173 xc_spi_dma_init(spi_idx, dts, 1, 1);
1174
1176 DMA_CHANNEL1, sizeof(cmd), cmd,
1177 DMA_CHANNEL0, sizeof(id), id);
1178
1179 xc_spi_dma_deinit(spi_idx);
1180
1181 if(buad_idx != SSI_BAUD_DIV_2) {
1182 memcpy(ruid, &id[5], 16);
1183 } else {
1184 ruid[0] = id[4];
1185 ruid[15] = id[21];
1186 for(uint8_t i=0; i<7; i++)
1187 {
1188 ruid[2*i+1] = id[2*i+7];
1189 ruid[2*i+2] = id[2*i+6];
1190 }
1191 }
1192}
eDMA_Burst_Trans_Len ctl_dst_msize
Definition xc_drv_dma.h:218
eDMA_Fifo_Mode cfg_fifo_mode
Definition xc_drv_dma.h:227
eDMA_Trans_Width ctl_src_tr_width
Definition xc_drv_dma.h:221
eDMA_SW_HW_HS_Select cfg_hs_sel_src
Definition xc_drv_dma.h:228
eDMA_SW_HW_HS_Select cfg_hs_sel_dst
Definition xc_drv_dma.h:229
eDMA_Burst_Trans_Len ctl_src_msize
Definition xc_drv_dma.h:217
eDMA_Trans_Flow ctl_tt_fc
Definition xc_drv_dma.h:226
eDMA_Trans_Width ctl_dst_tr_width
Definition xc_drv_dma.h:222
eDMA_HS_Interface cfg_dst_per
Definition xc_drv_dma.h:223
eDMA_Addr_Increment ctl_dinc
Definition xc_drv_dma.h:220
eDMA_HS_Interface cfg_src_per
Definition xc_drv_dma.h:224
eDMA_Addr_Increment ctl_sinc
Definition xc_drv_dma.h:219
__RAM_CODE uint8_t xc_dma_disable(void)
xc_dma_disable
Definition xc_drv_dma.c:235
__RAM_CODE uint8_t xc_dma_set_channel_config(eDMA_Ch_Num ch_num, DMA_Chx_Cfg_t *ch)
xc_dma_set_channel_config
Definition xc_drv_dma.c:630
__RAM_CODE bool xc_dma_set_listener(eDMA_Ch_Num ch_num, DMA_Callback userFunction)
xc_dma_set_listener
Definition xc_drv_dma.c:673
__RAM_CODE uint8_t xc_dma_init(void)
xc_dma_init
Definition xc_drv_dma.c:588
__RAM_CODE void xc_dma_enable(void)
xc_dma_enable
Definition xc_drv_dma.c:222
__RAM_CODE uint8_t xc_dma_start_transfer(eDMA_Ch_Num ch_num, DMA_Callback cb_func)
xc_dma_start_transfer
Definition xc_drv_dma.c:705
@ DMA_FIFO_MODE_SINGLE
Definition xc_drv_dma.h:197
@ DMA_PRF2MEM_DMA
Definition xc_drv_dma.h:187
@ DMA_MEM2PRF_DMA
Definition xc_drv_dma.h:186
@ DMA_MSIZE_1
Definition xc_drv_dma.h:130
@ DMA_IRQ_ERR
Definition xc_drv_dma.h:124
@ SSI2_DMA_RX_HS_IF14
Definition xc_drv_dma.h:179
@ SSI2_DMA_TX_HS_IF4
Definition xc_drv_dma.h:169
@ SSI1_DMA_TX_HS_IF3
Definition xc_drv_dma.h:168
@ SSI1_DMA_RX_HS_IF11
Definition xc_drv_dma.h:176
@ SSI0_DMA_TX_HS_IF2
Definition xc_drv_dma.h:167
@ SSI0_DMA_RX_HS_IF10
Definition xc_drv_dma.h:175
enum dmac_channel_number eDMA_Ch_Num
@ DMA_HS_HARDWARE
Definition xc_drv_dma.h:159
@ DMA_ADDR_INCREMENT
Definition xc_drv_dma.h:142
@ DMA_ADDR_NOCHANGE
Definition xc_drv_dma.h:144
@ DMA_CHANNEL1
Definition xc_drv_dma.h:72
@ DMA_CHANNEL0
Definition xc_drv_dma.h:71
@ DMA_TRANS_WIDTH_16
Definition xc_drv_dma.h:150
@ DMA_TRANS_WIDTH_8
Definition xc_drv_dma.h:149
void xc_spi_dma_flash_erase_page(uint8_t spi_idx, uint32_t Dst_Addr)
_idx
eXC_RESULT xc_spi_dma_flash_read(uint8_t spi_idx, uint32_t readAddr, uint8_t *buff, uint16_t len)
eXC_RESULT xc_spi_dma_flash_write(uint8_t reg_idx, uint32_t writeAddr, uint8_t *buff, uint16_t size)
uint8_t mid[FLASH_PAGE_SIZE+4]
void spi_dma_read_err(uint8_t eCode)
void xc_spi_dma_flash_power_down(uint8_t spi_idx)
void spi_dma_write_callback(uint8_t eCode)
void xc_spi_dma_read_and_write_data(uint8_t spi_idx, uint8_t *w_data, uint16_t w_size, uint8_t *r_data, uint16_t r_size)
void xc_spi_dma_write_data(uint8_t spi_idx, uint8_t *data, uint16_t size)
void spi_dma_read_callback(uint8_t eCode)
void xc_spi_dma_deinit(uint8_t spi_idx)
void xc_spi_dma_write_and_read_data(uint8_t spi_idx, uint8_t *w_data, uint16_t w_size, uint8_t *r_data, uint16_t r_size)
uint8_t xc_spi_dma_flash_read_status(uint8_t spi_idx)
void xc_dma_prf2mem_finish(void)
void xc_spi_dma_flash_rdid(uint8_t spi_idx, uint8_t *rdid)
uint8_t xc_spi_dma_read_config(uint8_t spi_idx, eDMA_Ch_Num ch_num, uint16_t blockSize, uint8_t *rx_buff)
uint32_t xc_spi_prf_data_addr(uint8_t spi_idx, uint8_t *eCode)
static volatile bool wr_tfr_flag
void xc_spi_dma_write(uint8_t spi_idx, eDMA_Ch_Num w_chnum, uint16_t w_size, uint8_t *w_buff)
void xc_spi_dma_flash_ruid(uint8_t spi_idx, uint8_t *ruid)
void xc_spi_dma_flash_read_page(uint8_t spi_idx, uint32_t ReadAddr, uint8_t *data, uint16_t size)
uint8_t xc_spi_dma_write_config(uint8_t spi_idx, eDMA_Ch_Num ch_num, uint16_t blockSize, uint8_t *tx_buff)
void xc_spi_dma_flash_write_enable(uint8_t spi_idx)
void xc_spi_dma_read_and_write(uint8_t spi_idx, eDMA_Ch_Num w_chnum, uint16_t w_size, uint8_t *w_buff, eDMA_Ch_Num r_chnum, uint16_t r_size, uint8_t *r_buff)
void xc_spi_dma_flash_write_page(uint8_t spi_idx, uint32_t WriteAddr, uint8_t *data, uint16_t size)
static volatile bool rd_tfr_flag
void xc_spi_dma_flash_wakeup(uint8_t spi_idx)
void xc_spi_dma_flash_write_disable(uint8_t spi_idx)
void xc_spi_dma_read(uint8_t spi_idx, eDMA_Ch_Num r_chnum, uint16_t r_size, uint8_t *r_buff)
static volatile bool err_flag
void xc_spi_dma_flash_erase_sector(uint8_t spi_idx, uint32_t Dst_Addr)
void spi_dma_write_err(uint8_t eCode)
void xc_dma_mem2prf_finish(void)
void xc_spi_dma_init(uint8_t spi_idx, uint8_t dfs, uint8_t tdl, uint8_t rdl)
void xc_spi_dma_flash_wait_busy(uint8_t spi_idx)
void xc_spi_dma_read_data(uint8_t spi_idx, uint8_t *data, uint16_t size)
void xc_spi_dma_write_and_read(uint8_t spi_idx, eDMA_Ch_Num w_chnum, uint16_t w_size, uint8_t *w_buff, eDMA_Ch_Num r_chnum, uint16_t r_size, uint8_t *r_buff)
The header of xc_drv_spi_dma.c