19.7.1.11
DMAC中斷回調函數
DMAC中斷回調函數如下所示:
列表10: 代碼清單20?9DMAC中斷回調函數
// DMA 傳輸完成標志位volatilebool dmac0_complete_transmission_sign = false;// 傳輸次數計數(中斷次數)volatileuint16_t dmac0_transfer_count;/* DMAC 中斷回調函數 */voiddmac0_callback(dmac_callback_args_t *p_args){(void)(p_args);dmac0_complete_transmission_sign = true;dmac0_transfer_count ++;}
dmac0_transfer_count用于記錄DMAC產生中斷的次數。
19.7.1.12
hal_entry 入口函數
在hal_entry函數中,程序遵循以下步驟來執行:
調用DMAC_Init函數初始化DMAC。
調用R_DMAC_Enable函數使能DMAC使之可以響應傳輸請求。
調用R_DMAC_SoftwareStart函數來發起軟件觸發請求信號來啟動DMAC傳輸。
通過一定的延時等待所有傳輸完成,因為在產生多次的中斷的情況下,僅通過中斷標志位判斷可能出錯。
在傳輸完成之后,比較傳輸目標地址的數據(DST_Buffer)和期待的正確數據(Expected_DST_Buffer)是否一致。
傳入R_DMAC_SoftwareStart函數的參數 TRANSFER_START_MODE_SINGLE和TRANS-FER_START_MODE_REPEAT的區別如下:
傳入參數為TRANSFER_START_MODE_SINGLE時,正常模式和重復模式下每發起一次軟件請求只會傳輸一個數據單元大小(transfer_size_tsize)的數據。塊模式下則是只會傳輸一個塊大小(transfer_info_t::length)的數據。
傳入參數為TRANSFER_START_MODE_REPEAT時,會自動重復地觸發傳輸,期間可能會產生多次中斷,直至所有數據都傳輸完成為止。
hal_entry入口函數如下所示。
列表11:代碼清單20?10hal_entry入口函數
/*用戶頭文件包含*/extern constuint32_tSRC_Buffer[BUFFER_SIZE];extern uint32_tDST_Buffer[BUFFER_SIZE];extern uint32_tExpected_DST_Buffer[BUFFER_SIZE];extern volatilebooldmac0_complete_transmission_sign;extern volatileuint16_tdmac0_transfer_count;uint8_tBufferCompare(constuint32_t*pBuffer1,constuint32_t*pBuffer2,?→uint16_tBufferLength);voidBufferShow_HexData(constuint32_t*pBuffer,uint16_tBufferLength);voidhal_entry(void){/*TODO:addyourowncodehere*/fsp_err_terr= FSP_SUCCESS;uint8_t res;LED_Init();// LED 初始化Debug_UART4_Init(); // SCI4 UART 調試串口初始化/* 初始化 DMAC */DMAC_Init();dmac0_complete_transmission_sign = false; //傳輸完成標志位清零printf("這是一個 DMAC 存儲器到存儲器的傳輸實驗例程\r\n");printf("打開串口助手,查看接收窗口打印的相關提示信息\r\n");printf("觀察板載 LED 燈,本實驗使用兩個 LED 燈來指示 DMAC 傳輸結果\r\n");printf("- DMA 數據傳輸失敗,則 LED1 亮(紅色)\r\n");printf("- DMA 數據傳輸成功,則 LED2 亮(藍色)\r\n");printf("--------------------------------------------\r\n");/* 使能 DMAC 使之可以響應傳輸請求 */R_DMAC_Enable(&g_transfer_dmac0_ctrl);/************************************//* 使用軟件觸發的方式啟動 DMAC 傳輸 *//************************************//* 根據 FSP 配置界面的傳輸信息配置進行傳輸 *///可以用下面這種方式:R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_START_MODE_→REPEAT);//也可以用這種方式://for (uint16_t i = 0; i < 1; i++)//{//err = R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_→START_MODE_SINGLE);//assert(FSP_SUCCESS == err);//}(相當于重復次數為 1 的重復模式)//可以用下面這種方式:R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_START_MODE_→REPEAT);//也可以用這種方式://for (uint16_t i = 0; i < BUFFER_SIZE; i++)//{////正常模式err = R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_→START_MODE_SINGLE);//assert(FSP_SUCCESS == err);//}//可以用下面這種方式:R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_START_MODE_→REPEAT);//也可以用這種方式://for (uint16_t i = 0; i < BUFFER_SIZE; i++)//{////重復模式err = R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_→START_MODE_SINGLE);//assert(FSP_SUCCESS == err);//}//可以用下面這種方式:R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_START_MODE_→REPEAT);//塊模式//也可以用這種方式://for (uint16_t i = 0; i < 4; i++)//{//err = R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_→START_MODE_SINGLE);//assert(FSP_SUCCESS == err);////出錯////}//加個小延時,確保 DMAC 通道 0 傳輸完成之后才再次軟件觸發啟動,否則傳輸可能R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);式//可以用下面這種方式:R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_START_MODE_→REPEAT);//也可以用這種方式://for (uint16_t i = 0; i < 4; i++)//{//err = R_DMAC_SoftwareStart(&g_transfer_dmac0_ctrl, TRANSFER_→START_MODE_SINGLE);//assert(FSP_SUCCESS == err);////出錯////}//加個小延時,確保 DMAC 通道 0 傳輸完成之后才再次軟件觸發啟動,否則傳輸可能R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);/* 判斷傳輸完成中斷(需至少觸發過 1 次) */while (false == dmac0_complete_transmission_sign);/* 等待所有傳輸完成(如果是 TRANSFER_IRQ_EACH 模式,傳輸過程中可能會觸發多次中斷)*/R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MILLISECONDS); //加上延時確保所有傳輸都已完成printf("\r\n傳輸計數(中斷次數):dmac0_transfer_count = %d\r\n", dmac0_→transfer_count);/* 將傳輸后的數據與我們所期待的結果相比較 */res = BufferCompare(DST_Buffer, Expected_DST_Buffer, BUFFER_SIZE);printf("傳輸結果:");/* 根據兩者數據的比較結果進行判斷 */if( res != 0){/* 源數據與傳輸后數據不相等時,LED1 亮(紅色),表示傳輸失敗 */LED1_ON;printf("< 傳輸失敗>\r\n");}else{/*源數據與傳輸后數據相等時,LED1亮(藍色),表示傳輸成功*/LED2_ON;printf("<傳輸成功>\r\n");}printf("\r\nSRC:");BufferShow_HexData(SRC_Buffer,BUFFER_SIZE);printf("\r\nDST:(應與Expected_DST一致)");BufferShow_HexData(DST_Buffer,BUFFER_SIZE);printf("\r\nExpected_DST:");BufferShow_HexData(Expected_DST_Buffer,BUFFER_SIZE);while(1){}#ifBSP_TZ_SECURE_BUILD/*Enternon-securecode*/R_BSP_NonSecureEnter();}
19.7.1.13
緩沖區數據比較函數
下面是DMAC在重復-塊傳輸模式下傳輸的配置代碼:
列表12:代碼清單20?11緩沖區數據比較函數
/*緩沖區數據比較函數返回0表示兩個緩沖區數據一致*/uint8_tBufferCompare(constuint32_t*pBuffer1,constuint32_t*pBuffer2,?→uint16_tBufferLength){/*數據長度遞減*/while(BufferLength--){/*判斷兩個數據源是否對應相等*/if(*pBuffer1!= *pBuffer2){/*對應數據源不相等馬上退出函數,并返回1*/return1;}/*遞增兩個數據源的地址指針*/pBuffer1++;pBuffer2++;}/*完成判斷并且兩組數據完全一致*/return0;}
19.7.1.14
打印緩沖區數據函數
列表13:代碼清單20?12打印緩沖區數據函數
/*打印緩沖區數據函數打印緩沖區數據:十六進制格式*/voidBufferShow_HexData(constuint32_t*pBuffer,uint16_tBufferLength){while(BufferLength){if((BufferLength % 4) == 0)printf("\r\n\t");printf("0x%08X", *pBuffer);pBuffer++;BufferLength--;}printf("\r\n");}
下載驗證
首先通過宏USE_MY_TRANSFER_INFOR_CONFIG(在bsp_dmac_m2m.h文件中)來選擇是使用我們自定義的傳輸信息,還是使用在FSP配置界面配置的傳輸信息。
其次通過宏DMAC_TRANSFER_MODE(在bsp_dmac_m2m.h文件中)來選擇不同的傳輸模式。
最后編譯工程并下載到開發板上,打開串口助手可以查看程序運行打印的提示信息。如果DMAC傳輸成功,則藍色LED2亮起,如果傳輸失敗則紅色LED1亮起。
如您在使用瑞薩MCU/MPU產品中有任何問題,可識別下方二維碼或復制網址到瀏覽器中打開,進入瑞薩技術論壇尋找答案或獲取在線技術支持。
https://community-ja.renesas.com/zh/forums-groups/mcu-mpu/
未完待續
推薦閱讀
DMAC和DTC關鍵特性對比——瑞薩RA系列FSP庫開發實戰指南(54)
定義傳輸源和目標存儲器——瑞薩RA系列FSP庫開發實戰指南(55)
使用代碼配置:重復傳輸模式——瑞薩RA系列FSP庫開發實戰指南(56)

