/** SPI receive multiple bytes */ uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { Spi* pSpi = SPI0; int rtn = 0; #if USE_SAM3X_DMAC // clear overrun error uint32_t s = pSpi->SPI_SR; spiDmaRX(buf, n); spiDmaTX(0, n); uint32_t m = millis(); while (!dmac_channel_transfer_done(SPI_DMAC_RX_CH)) { if ((millis() - m) > SAM3X_DMA_TIMEOUT) { dmac_channel_disable(SPI_DMAC_RX_CH); dmac_channel_disable(SPI_DMAC_TX_CH); rtn = 2; break; } } if (pSpi->SPI_SR & SPI_SR_OVRES) { rtn |= 1; } #else // USE_SAM3X_DMAC for (size_t i = 0; i < n; i++) { pSpi->SPI_TDR = 0XFF; while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} buf[i] = pSpi->SPI_RDR; } #endif // USE_SAM3X_DMAC return rtn; }
void AJ_WSL_SPI_DMATransfer(void* buffer, uint32_t size, uint8_t direction) { dma_transfer_descriptor_t transfer; AJ_ASSERT(AJ_WSL_DMA_send_done == 0); /* Disable both channels before parameters are set */ dmac_channel_disable(DMAC, AJ_DMA_TX_CHANNEL); dmac_channel_disable(DMAC, AJ_DMA_RX_CHANNEL); if (direction == AJ_DMA_TX) { /* Direction is TX so set the destination to the SPI hardware */ transfer = transfer_descriptors[AJ_DMA_TX][AJ_DMA_TX_CHANNEL]; /* Set the source to the buffer your sending */ transfer.ul_source_addr = (uint32_t) buffer; transfer.ul_ctrlA |= size; dmac_channel_single_buf_transfer_init(DMAC, AJ_DMA_TX_CHANNEL, (dma_transfer_descriptor_t*) &transfer); /* Enable the channel to start DMA */ dmac_channel_enable(DMAC, AJ_DMA_TX_CHANNEL); /* Setup RX direction as NULL destination and SPI0 as source */ transfer = transfer_descriptors[AJ_DMA_TX][AJ_DMA_RX_CHANNEL]; transfer.ul_ctrlA |= size; dmac_channel_single_buf_transfer_init(DMAC, AJ_DMA_RX_CHANNEL, &transfer); /* Enable the channel to start DMA */ dmac_channel_enable(DMAC, AJ_DMA_RX_CHANNEL); /* Wait for the transfer to complete */ while (!AJ_WSL_DMA_send_done); } else { /* We are transferring in the RX direction */ /* Set up the destination address */ transfer = transfer_descriptors[AJ_DMA_RX][AJ_DMA_RX_CHANNEL]; transfer.ul_destination_addr = (uint32_t) buffer; transfer.ul_ctrlA |= size; dmac_channel_single_buf_transfer_init(DMAC, AJ_DMA_RX_CHANNEL, &transfer); dmac_channel_enable(DMAC, AJ_DMA_RX_CHANNEL); /* Setup the TX channel to transfer from a NULL pointer * This must be done in order for the transfer to start */ transfer = transfer_descriptors[AJ_DMA_RX][AJ_DMA_TX_CHANNEL]; transfer.ul_ctrlA |= size; dmac_channel_single_buf_transfer_init(DMAC, AJ_DMA_TX_CHANNEL, (dma_transfer_descriptor_t*) &transfer); dmac_channel_enable(DMAC, AJ_DMA_TX_CHANNEL); while (!AJ_WSL_DMA_send_done); } /* reset the DMA completed indicator */ AJ_WSL_DMA_send_done = 0; dmac_channel_disable(DMAC, AJ_DMA_TX_CHANNEL); dmac_channel_disable(DMAC, AJ_DMA_RX_CHANNEL); }
/** * \brief Stop DMA transfer of the DMAC channel. * * \note Under normal operation, the hardware disables a channel on transfer * completion by clearing the DMAC_CHSR.ENAx register bit. * The recommended way for software to disable a channel without losing data * is to use the SUSPx bit in conjunction with the EMPTx bit in the Channel * Handler Status Register. * * \param p_dmac Pointer to a DMAC peripheral instance. * \param ul_num Channel number. */ void dmac_channel_stop_transfer(Dmac *p_dmac, uint32_t ul_num) { uint32_t status; status = dmac_channel_get_status(p_dmac); if (!(status & (DMAC_CHSR_ENA0 << ul_num))) { /* The channel is already stopped. */ return; } else { /* Suspend channel and the channel FIFO receives no new data. */ dmac_channel_suspend(p_dmac, ul_num); /* Check if the channel FIFO is empty. */ do { status = dmac_channel_get_status(p_dmac); if (status & (DMAC_CHSR_EMPT0 << ul_num)) { break; } } while (1); /* Disable the channel. */ dmac_channel_disable(p_dmac, ul_num); /* Clear suspend flag. */ dmac_channel_resume(p_dmac, ul_num); } }
/** * \brief DMAC tx channel configuration. */ static void configure_dmac_tx(void) { uint32_t ul_cfg; dma_transfer_descriptor_t dmac_trans; ul_cfg = 0; ul_cfg |= DMAC_CFG_DST_PER(USART_TX_IDX) | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD_ENABLE | DMAC_CFG_FIFOCFG_ALAP_CFG; dmac_channel_set_configuration(DMAC, BOARD_USART_DMAC_TX_CH, ul_cfg); dmac_channel_disable(DMAC, BOARD_USART_DMAC_TX_CH); dmac_trans.ul_source_addr = (uint32_t) gs_puc_buffer; dmac_trans.ul_destination_addr = (uint32_t) & BOARD_USART->US_THR; dmac_trans.ul_ctrlA = DMAC_CTRLA_BTSIZE(BUFFER_SIZE) | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; dmac_trans.ul_ctrlB = DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | DMAC_CTRLB_SRC_INCR_INCREMENTING | DMAC_CTRLB_DST_INCR_FIXED; dmac_trans.ul_descriptor_addr = 0; dmac_channel_single_buf_transfer_init(DMAC, BOARD_USART_DMAC_TX_CH, &dmac_trans); dmac_channel_enable(DMAC, BOARD_USART_DMAC_TX_CH); }
/** * \brief DMA driver configuration */ static void init_dma(void) { uint32_t cfg; /* Enable DMA controller */ dmac_enable(DMAC); /* Initialize and enable DMA controller */ pmc_enable_periph_clk(ID_DMAC); dmac_init(DMAC); dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN); dmac_enable(DMAC); /* Disable the DMA channel for SSC */ dmac_channel_disable(DMAC, DMA_CH); /* Set channel configuration register */ cfg = DMAC_CFG_SOD_ENABLE | /* Enable stop on done */ DMAC_CFG_DST_H2SEL | /* Hardware Selection for the Destination */ DMAC_CFG_DST_PER(3) | /* Destination with Peripheral identifier */ DMAC_CFG_AHB_PROT(1) | /* Set AHB Protection */ DMAC_CFG_FIFOCFG_ALAP_CFG; /* FIFO Configuration */ dmac_channel_set_configuration(DMAC, DMA_CH, cfg); /* Set interrupt */ NVIC_EnableIRQ(DMAC_IRQn); dmac_enable_interrupt(DMAC, (DMAC_EBCIER_CBTC0 << DMA_CH)); }
void audio_adc_Stop(void) { REG32(AUDIO_ACON) |= BIT(4);//mute adc REG32(AUDIO_ACON) &= ~(BIT(0)|BIT(1));//mic disable/adc analog wr_reg(AUADC_CFG,rd_reg(AUADC_CFG)&(~AUADC_EN)); wr_reg(DACCFG,rd_reg(DACCFG)&(~G_AUADC_EN)&(~G_AGC_EN)); ClrIntSrc(AUADC_INT); dmac_channel_disable(AUDIO_ADC_DMA_CH); }
void llp_peri2mem(u8 ch, u32 cfgh, u32 cfgl, DMA_LLP *llp) { u32 offset; offset = ch*0x58; dmac_channel_disable(ch); REG32(DMA_CfgRegL) = 1; REG32(DMA_CTL0L + offset) = (1<<28) | (1<<27); REG32(DMA_LLP0L + offset) = (u32)(llp) & 0xFFFFFFFC; REG32(DMA_CFG0H + offset) = cfgh; REG32(DMA_CFG0L + offset) = cfgl; REG32(DMA_ChEnRegL) |= (1<<(ch+8)) | (1<<ch); }
void audio_adc_init() { u8 adr; REG32(PCON0) &= ~(1<<21); // enable dac clock REG32(CLKCON1) &= ~(0xf<<8); REG32(CLKCON1) |= (9<<8);//10 div 240M/(9+1)=24M REG32(CLKCON0) &= ~((1<<6)|(1<<7)); g_stcJpegInfo.u32AudioDataReady = 0; g_stcJpegInfo.iAudioFillBufCnt=0; g_stcJpegInfo.iAudioFSWriteBufCnt=0; g_stcJpegInfo.dwAudiobufSize = 0x2000; g_stcJpegInfo.pAudioDataBuf = (u8 *)((u32)JPEG_BUFFER_END_ADDRESS - 0x2000); audio_adc_analog_init();// //llp_peri2mem(AUDIO_ADC_DMA_CH, (6<<7)|(0<<11), 0, (DMA_LLP *)(&adc_llp0)); dmac_channel_disable(AUDIO_ADC_DMA_CH); dma_peri2mem_Ext(AUDIO_ADC_DMA_CH, (0<<11)|(6<<7)|(0<<1), (0<<11)|(0<<10), AUADC_DMA_TX_ADR, (audio_buffer_ptr+8), (2048-2)); REG32(DMA_ClearTfrL) = BIT(3); REG32(DMA_MaskTfrL) |= (BIT(3) | BIT(3+8)); SetIntSrc(DMA_INT); wr_reg(DACCFG,rd_reg(DACCFG)|G_AUADC_EN|G_AGC_EN);//AGC EN ADC EN for(adr=0; adr<140; adr++) { wr_reg(AUADC_DAT,0); } wr_reg(AUADC_BAUD,4);//24000000/192000/25-1 wr_reg(AUADC_CFG,AUADC_FILT1_DOWN(2)|AUADC_FILT2_DOWN(2)|AUADC_FILT3_DOWN(3)|AUADC_COEF_EN|AUADC_FILT1_EN|AUADC_FILT2_EN|AUADC_EN); // DMA enable and AGC enable //wr_reg(AGC_CFG0,rd_reg(AGC_CFG0)|DMA_EN|AGC_IE); wr_reg(AGC_CFG0,rd_reg(AGC_CFG0)|DMA_EN); // block number, block size wr_reg(AGC_CFG3,(1<<12)|((2048-2)<<0)); // clear DMA_DONE pending flag before kit-start AGC wr_reg(AGC_CFG_CLR,1<<0); // kit-start AGC wr_reg(AGC_CFG_CLR,1<<4); wr_reg(AGC_CFG1,0x17e6); //mic sound is max wr_reg(AGC_CFG2,0x780); //mic sound set REG32(AUDIO_ACON) |= BIT(5); SetIntSrc(AUADC_INT); deg_Printf("audio adc init ok\n"); }
//------------------------------------------------------------------------------ // start RX DMA static void spiDmaRX(uint8_t* dst, uint16_t count) { dmac_channel_disable(SPI_DMAC_RX_CH); DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_SADDR = (uint32_t)&SPI0->SPI_RDR; DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_DADDR = (uint32_t)dst; DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_DSCR = 0; DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CTRLA = count | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_PER2MEM_DMA_FC | DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING; DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CFG = DMAC_CFG_SRC_PER(SPI_RX_IDX) | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG; dmac_channel_enable(SPI_DMAC_RX_CH); }
void dma_peri2mem_Ext(u8 ch, u32 cfgh, u32 cfgl, u32 sar, u32 dar, u16 cnt) { u32 offset; offset = ch*0x58; dmac_channel_disable(ch); REG32(DMA_CfgRegL) = 1; REG32(DMA_CTL0L + offset) = (2<<20) | (2<<9) | (2<<4) | (2<<1) | (1<<25)|(1<<0); REG32(DMA_LLP0L + offset) = 0; REG32(DMA_CFG0H + offset) = cfgh; REG32(DMA_CFG0L + offset) = cfgl; REG32(DMA_SAR0L + offset) = sar; REG32(DMA_DAR0L + offset) = (u32)dar; REG32(DMA_CTL0H + offset) = cnt; REG32(DMA_ChEnRegL) |= (1<<(ch+8)) | (1<<ch); }
/** SPI receive multiple bytes */ uint8_t spiRec(uint8_t* buf, size_t len) { Spi* pSpi = SPI0; int rtn = 0; #if USE_SAM3X_DMAC // clear overrun error uint32_t s = pSpi->SPI_SR; spiDmaRX(buf, len); spiDmaTX(0, len); uint32_t m = millis(); while (!dmac_channel_transfer_done(SPI_DMAC_RX_CH)) { if ((millis() - m) > SAM3X_DMA_TIMEOUT) { dmac_channel_disable(SPI_DMAC_RX_CH); dmac_channel_disable(SPI_DMAC_TX_CH); rtn = 2; break; } } if (pSpi->SPI_SR & SPI_SR_OVRES) rtn |= 1; #else // USE_SAM3X_DMAC for (size_t i = 0; i < len; i++) { pSpi->SPI_TDR = 0XFF; while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} buf[i] = pSpi->SPI_RDR; } #endif // USE_SAM3X_DMAC if (bitOrder == LSBFIRST) { for (register int i=0; i<len; i++) { buf[i] = __REV(__RBIT(buf[i])); } } return rtn; }
void spi_start_transmit_dma(Dmac *p_dmac, Spi *p_spi, uint32_t ul_num, const void *src, uint32_t nb_bytes) { static uint8_t ff = 0xFF; uint32_t cfg, src_incr = DMAC_CTRLB_SRC_INCR_INCREMENTING; dma_transfer_descriptor_t desc; // Send 0xFF repeatedly if src is NULL if (!src) { src = &ff; src_incr = DMAC_CTRLB_SRC_INCR_FIXED; } // Disable the DMA channel prior to configuring dmac_enable(p_dmac); dmac_channel_disable(p_dmac, ul_num); cfg = DMAC_CFG_SOD | DMAC_CFG_DST_H2SEL | DMAC_CFG_DST_PER(SPI_TX_IDX) | DMAC_CFG_FIFOCFG_ALAP_CFG; dmac_channel_set_configuration(p_dmac, ul_num, cfg); // Prepare DMA transfer desc.ul_source_addr = (uint32_t)src; desc.ul_destination_addr = (uint32_t)&(p_spi->SPI_TDR); desc.ul_ctrlA = DMAC_CTRLA_BTSIZE(nb_bytes) | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; desc.ul_ctrlB = DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | src_incr | DMAC_CTRLB_DST_INCR_FIXED; // Next field is ignored, but set it anyway desc.ul_descriptor_addr = (uint32_t)NULL; // Finish configuring the transfer dmac_channel_single_buf_transfer_init(p_dmac, ul_num, &desc); // And now start the DMA transfer dmac_channel_enable(p_dmac, ul_num); }
void spi_start_receive_dma(Dmac *p_dmac, Spi *p_spi, uint32_t ul_num, const void *dest, uint32_t nb_bytes) { uint32_t cfg; dma_transfer_descriptor_t desc; // clear any potential overrun error cfg = p_spi->SPI_SR; // Turn the DMA channel off before configuring dmac_enable(p_dmac); dmac_channel_disable(p_dmac, ul_num); cfg = DMAC_CFG_SOD | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SRC_PER(SPI_RX_IDX) | DMAC_CFG_FIFOCFG_ASAP_CFG; dmac_channel_set_configuration(p_dmac, ul_num, cfg); // Prepare DMA transfer desc.ul_source_addr = (uint32_t)&(p_spi->SPI_RDR); desc.ul_destination_addr = (uint32_t)dest; desc.ul_ctrlA = DMAC_CTRLA_BTSIZE(nb_bytes) | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; desc.ul_ctrlB = DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_PER2MEM_DMA_FC | DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING; // This next field is ignored but set it anyway desc.ul_descriptor_addr = (uint32_t)NULL; // Finish configuring the DMA transfer dmac_channel_single_buf_transfer_init(p_dmac, ul_num, &desc); // And now allow the DMA transfer to begin dmac_channel_enable(p_dmac, ul_num); }
//------------------------------------------------------------------------------ // start TX DMA static void spiDmaTX(const uint8_t* src, uint16_t count) { static uint8_t ff = 0XFF; uint32_t src_incr = DMAC_CTRLB_SRC_INCR_INCREMENTING; if (!src) { src = &ff; src_incr = DMAC_CTRLB_SRC_INCR_FIXED; } dmac_channel_disable(SPI_DMAC_TX_CH); DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_SADDR = (uint32_t)src; DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_DADDR = (uint32_t)&SPI0->SPI_TDR; DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_DSCR = 0; DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CTRLA = count | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | src_incr | DMAC_CTRLB_DST_INCR_FIXED; DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CFG = DMAC_CFG_DST_PER(SPI_TX_IDX) | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG; dmac_channel_enable(SPI_DMAC_TX_CH); }
void audio_AGC_DMA_Isr(void) { u32 agc_sta = rd_reg(AGC_STA); //deg_Printf(" %x\n",agc_sta); if((agc_sta & 0x1) == 0x1) wr_reg(AGC_CFG_CLR, rd_reg(AGC_CFG_CLR)|BIT(0)); wr_reg(AGC_CFG0,rd_reg(AGC_CFG0)&(~BIT(5))); if((g_stcJpegInfo.iAudioFillBufCnt+1) < (g_stcJpegInfo.iAudioFSWriteBufCnt + AUDIO_BUFFER_NUM)) { if(audio_buffer_ptr == ((u32)JPEG_BUFFER_END_ADDRESS - 0x2000)) audio_buffer_ptr = (u32)JPEG_BUFFER_END_ADDRESS-(AUDIO_BUFFER_NUM*0x2000); else audio_buffer_ptr += g_stcJpegInfo.dwAudiobufSize; g_stcJpegInfo.iAudioFillBufCnt++; } else { deg_Printf("d"); g_stcJpegInfo.i30FrameCnt -=((192*(u32Framecount+1))/25 -(192*u32Framecount)/25); u32Framecount++; if(u32Framecount >= 25) { u32Framecount = 0; } g_stcJpegInfo.iJpeg10MSCnt -= 25; } dmac_channel_disable(AUDIO_ADC_DMA_CH); //dma_peri2mem_Ext(AUDIO_ADC_DMA_CH, (0<<11)|(6<<7)|(0<<1), (0<<11)|(0<<10), AUADC_DMA_TX_ADR, (audio_buffer_ptr+8), (2048-2)); REG32(DMA_DAR0L + AUDIO_ADC_DMA_CH*0x58) = (u32)(audio_buffer_ptr+8); dmac_channel_enable(AUDIO_ADC_DMA_CH); wr_reg(AGC_CFG0,rd_reg(AGC_CFG0)|(BIT(5))); wr_reg(AGC_CFG_CLR, rd_reg(AGC_CFG_CLR)|BIT(5)); }
/** * \brief Test ECB mode encryption and decryption with DMA. * * \param test Current test case. */ static void run_ecb_mode_test_dma(const struct test_case *test) { /* Configure DMAC. */ configure_dmac(); /* Disable DMAC channel. */ dmac_channel_disable(DMAC, AES_DMA_TX_CH); dmac_channel_disable(DMAC, AES_DMA_RX_CH); /* Configure the AES. */ g_aes_cfg.encrypt_mode = AES_ENCRYPTION; g_aes_cfg.key_size = AES_KEY_SIZE_128; g_aes_cfg.start_mode = AES_DMA_MODE; g_aes_cfg.opmode = AES_ECB_MODE; g_aes_cfg.cfb_size = AES_CFB_SIZE_128; g_aes_cfg.lod = false; aes_set_config(AES, &g_aes_cfg); /* Set the cryptographic key. */ aes_write_key(AES, key128); /* The initialization vector is not used by the ECB cipher mode. */ /* Write the data to be ciphered by DMA. */ aes_dma_transmit_config(ref_plain_text, AES_EXAMPLE_REFBUF_SIZE); aes_dma_receive_config(output_data, AES_EXAMPLE_REFBUF_SIZE); /* Enable DMAC channel. */ dmac_channel_enable(DMAC, AES_DMA_RX_CH); dmac_channel_enable(DMAC, AES_DMA_TX_CH); /* Wait for the end of the encryption process. */ delay_ms(30); /* Disable DMAC channel. */ dmac_channel_disable(DMAC, AES_DMA_TX_CH); dmac_channel_disable(DMAC, AES_DMA_RX_CH); if ((ref_cipher_text_ecb[0] != output_data[0]) || (ref_cipher_text_ecb[1] != output_data[1]) || (ref_cipher_text_ecb[2] != output_data[2]) || (ref_cipher_text_ecb[3] != output_data[3])) { flag = false; } else { flag = true; } test_assert_true(test, flag == true, "ECB mode encryption not work!"); /* Configure the AES. */ g_aes_cfg.encrypt_mode = AES_DECRYPTION; g_aes_cfg.key_size = AES_KEY_SIZE_128; g_aes_cfg.start_mode = AES_DMA_MODE; g_aes_cfg.opmode = AES_ECB_MODE; g_aes_cfg.cfb_size = AES_CFB_SIZE_128; g_aes_cfg.lod = false; aes_set_config(AES, &g_aes_cfg); /* Set the cryptographic key. */ aes_write_key(AES, key128); /* The initialization vector is not used by the ECB cipher mode. */ /* Write the data to be ciphered by DMA. */ aes_dma_transmit_config(ref_cipher_text_ecb, AES_EXAMPLE_REFBUF_SIZE); aes_dma_receive_config(output_data, AES_EXAMPLE_REFBUF_SIZE); /* Enable DMAC channel. */ dmac_channel_enable(DMAC, AES_DMA_RX_CH); dmac_channel_enable(DMAC, AES_DMA_TX_CH); /* Wait for the end of the decryption process. */ delay_ms(30); /* Disable DMAC channel. */ dmac_channel_disable(DMAC, AES_DMA_TX_CH); dmac_channel_disable(DMAC, AES_DMA_RX_CH); /* check the result. */ if ((ref_plain_text[0] != output_data[0]) || (ref_plain_text[1] != output_data[1]) || (ref_plain_text[2] != output_data[2]) || (ref_plain_text[3] != output_data[3])) { flag = false; } else { flag = true; } test_assert_true(test, flag == true, "ECB mode decryption not work!"); /* Disable DMAC module */ dmac_disable(DMAC); }
/* * Configure the SPI hardware, including SPI clock speed, mode, delays, chip select pins * It uses values listed in */ void AJ_WSL_SPI_InitializeSPIController(void) { uint32_t config; /* Initialize and enable DMA controller. */ pmc_enable_periph_clk(ID_DMAC); dmac_init(DMAC); dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN); dmac_enable(DMAC); /* Configure DMA TX channel. */ config = 0; config |= DMAC_CFG_DST_PER(AJ_SPI_TX_INDEX) | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG; dmac_channel_set_configuration(DMAC, AJ_DMA_TX_CHANNEL, config); /* Configure DMA RX channel. */ config = 0; config |= DMAC_CFG_SRC_PER(AJ_SPI_RX_INDEX) | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG; dmac_channel_set_configuration(DMAC, AJ_DMA_RX_CHANNEL, config); /* Enable receive channel interrupt for DMAC. */ uint8_t* interruptEnableAddress = AJ_SPI_ISER1_IEN_ADDR; *interruptEnableAddress = AJ_SPI_DMAC_IEN_BIT; dmac_enable_interrupt(DMAC, (1 << AJ_DMA_RX_CHANNEL)); dmac_enable_interrupt(DMAC, (1 << AJ_DMA_TX_CHANNEL)); //AJ_WSL_DMA_Setup(); dmac_channel_disable(DMAC, AJ_DMA_TX_CHANNEL); dmac_channel_disable(DMAC, AJ_DMA_RX_CHANNEL); /* * Configure the hardware to enable SPI and some output pins */ { pmc_enable_periph_clk(ID_PIOA); pmc_enable_periph_clk(ID_PIOB); pmc_enable_periph_clk(ID_PIOC); pmc_enable_periph_clk(ID_PIOD); // make all of these pins controlled by the right I/O controller pio_configure_pin_group(PIOA, 0xFFFFFFFF, PIO_TYPE_PIO_PERIPH_A); pio_configure_pin_group(PIOB, 0xFFFFFFFF, PIO_TYPE_PIO_PERIPH_B); pio_configure_pin_group(PIOC, 0xFFFFFFFF, PIO_TYPE_PIO_PERIPH_C); pio_configure_pin_group(PIOD, 0xFFFFFFFF, PIO_TYPE_PIO_PERIPH_D); /* * Reset the device by toggling the CHIP_POWER */ ioport_set_pin_dir(AJ_WSL_SPI_CHIP_POWER_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_level(AJ_WSL_SPI_CHIP_POWER_PIN, IOPORT_PIN_LEVEL_LOW); AJ_Sleep(10); ioport_set_pin_level(AJ_WSL_SPI_CHIP_POWER_PIN, IOPORT_PIN_LEVEL_HIGH); /* * Reset the device by toggling the CHIP_PWD# signal */ ioport_set_pin_dir(AJ_WSL_SPI_CHIP_PWD_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_level(AJ_WSL_SPI_CHIP_PWD_PIN, IOPORT_PIN_LEVEL_LOW); AJ_Sleep(10); ioport_set_pin_level(AJ_WSL_SPI_CHIP_PWD_PIN, IOPORT_PIN_LEVEL_HIGH); /* configure the pin that detects SPI data ready from the target chip */ ioport_set_pin_dir(AJ_WSL_SPI_CHIP_SPI_INT_PIN, IOPORT_DIR_INPUT); ioport_set_pin_sense_mode(AJ_WSL_SPI_CHIP_SPI_INT_PIN, IOPORT_SENSE_LEVEL_LOW); pio_handler_set(PIOC, ID_PIOC, AJ_WSL_SPI_CHIP_SPI_INT_BIT, (PIO_PULLUP | PIO_IT_FALL_EDGE), &AJ_WSL_SPI_CHIP_SPI_ISR); pio_handler_set_priority(PIOD, (IRQn_Type) ID_PIOC, 0xB); pio_enable_interrupt(PIOC, AJ_WSL_SPI_CHIP_SPI_INT_BIT); } spi_enable_clock(AJ_WSL_SPI_DEVICE); spi_reset(AJ_WSL_SPI_DEVICE); spi_set_lastxfer(AJ_WSL_SPI_DEVICE); spi_set_master_mode(AJ_WSL_SPI_DEVICE); spi_disable_mode_fault_detect(AJ_WSL_SPI_DEVICE); spi_set_peripheral_chip_select_value(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS); spi_set_clock_polarity(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, AJ_WSL_SPI_CLOCK_POLARITY); spi_set_clock_phase(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, AJ_WSL_SPI_CLOCK_PHASE); spi_set_bits_per_transfer(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, SPI_CSR_BITS_8_BIT); spi_set_baudrate_div(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, (sysclk_get_cpu_hz() / AJ_WSL_SPI_CLOCK_RATE)); spi_set_transfer_delay(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, AJ_WSL_SPI_DELAY_BEFORE_CLOCK, AJ_WSL_SPI_DELAY_BETWEEN_TRANSFERS); spi_set_fixed_peripheral_select(AJ_WSL_SPI_DEVICE); spi_configure_cs_behavior(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, SPI_CS_RISE_FORCED); spi_enable_interrupt(AJ_WSL_SPI_DEVICE, SPI_IER_TDRE | SPI_IER_RDRF); spi_enable(AJ_WSL_SPI_DEVICE); }
/** * \brief ECB mode encryption and decryption test with DMA. */ static void ecb_mode_test_dma(void) { /* Configure DMAC. */ configure_dmac(); /* Disable DMAC channel. */ dmac_channel_disable(DMAC, AES_DMA_TX_CH); dmac_channel_disable(DMAC, AES_DMA_RX_CH); printf("\r\n-----------------------------------\r\n"); printf("- 128bit cryptographic key\r\n"); printf("- ECB cipher mode\r\n"); printf("- DMA mode\r\n"); printf("- input of 4 32bit words with DMA\r\n"); printf("-----------------------------------\r\n"); state = false; /* Configure the AES. */ g_aes_cfg.encrypt_mode = AES_ENCRYPTION; g_aes_cfg.key_size = AES_KEY_SIZE_128; g_aes_cfg.start_mode = AES_IDATAR0_START; g_aes_cfg.opmode = AES_ECB_MODE; g_aes_cfg.cfb_size = AES_CFB_SIZE_128; g_aes_cfg.lod = false; aes_set_config(AES, &g_aes_cfg); /* Set the cryptographic key. */ aes_write_key(AES, key128); /* The initialization vector is not used by the ECB cipher mode. */ /* Write the data to be ciphered by DMA. */ aes_dma_transmit_config(ref_plain_text, AES_EXAMPLE_REFBUF_SIZE); aes_dma_receive_config(output_data, AES_EXAMPLE_REFBUF_SIZE); /* Enable DMAC channel. */ dmac_channel_enable(DMAC, AES_DMA_RX_CH); dmac_channel_enable(DMAC, AES_DMA_TX_CH); /* Wait for the end of the encryption process. */ while (false == state) { } /* Disable DMAC channel. */ dmac_channel_disable(DMAC, AES_DMA_TX_CH); dmac_channel_disable(DMAC, AES_DMA_RX_CH); if ((ref_cipher_text_ecb[0] != output_data[0]) || (ref_cipher_text_ecb[1] != output_data[1]) || (ref_cipher_text_ecb[2] != output_data[2]) || (ref_cipher_text_ecb[3] != output_data[3])) { printf("\r\nKO!!!\r\n"); } else { printf("\r\nOK!!!\r\n"); } printf("\r\n-----------------------------------\r\n"); printf("- 128bit cryptographic key\r\n"); printf("- ECB decipher mode\r\n"); printf("- DMA mode\r\n"); printf("- input of 4 32bit words with DMA\r\n"); printf("-----------------------------------\r\n"); state = false; /* Configure the AES. */ g_aes_cfg.encrypt_mode = AES_DECRYPTION; g_aes_cfg.key_size = AES_KEY_SIZE_128; g_aes_cfg.start_mode = AES_IDATAR0_START; g_aes_cfg.opmode = AES_ECB_MODE; g_aes_cfg.cfb_size = AES_CFB_SIZE_128; g_aes_cfg.lod = false; aes_set_config(AES, &g_aes_cfg); /* Set the cryptographic key. */ aes_write_key(AES, key128); /* The initialization vector is not used by the ECB cipher mode. */ /* Write the data to be ciphered by DMA. */ aes_dma_transmit_config(ref_cipher_text_ecb, AES_EXAMPLE_REFBUF_SIZE); aes_dma_receive_config(output_data, AES_EXAMPLE_REFBUF_SIZE); /* Enable DMAC channel. */ dmac_channel_enable(DMAC, AES_DMA_RX_CH); dmac_channel_enable(DMAC, AES_DMA_TX_CH); /* Wait for the end of the decryption process. */ while (false == state) { } /* Disable DMAC channel. */ dmac_channel_disable(DMAC, AES_DMA_TX_CH); dmac_channel_disable(DMAC, AES_DMA_RX_CH); /* check the result. */ if ((ref_plain_text[0] != output_data[0]) || (ref_plain_text[1] != output_data[1]) || (ref_plain_text[2] != output_data[2]) || (ref_plain_text[3] != output_data[3])) { printf("\r\nKO!!!\r\n"); } else { printf("\r\nOK!!!\r\n"); } /* Disable DMAC module */ dmac_disable(DMAC); }