//----------------------------------------------------------------------------- // See cul.h for a description of this function. //----------------------------------------------------------------------------- void culDmaToAes(DMA_DESC* pDmaChannel, BYTE *pSrcAddr, WORD length, BOOL generateInterrupt){ // Making sure a multiplum of 16 bytes is transferred to the AES module. while(length & 0x000F){ length++; } SET_WORD(pDmaChannel->SRCADDRH, pDmaChannel->SRCADDRL, pSrcAddr); // The start address of the segment SET_WORD(pDmaChannel->DESTADDRH, pDmaChannel->DESTADDRL, &X_ENCDI); // Input of the AES module SET_WORD(pDmaChannel->LENH, pDmaChannel->LENL, length); // Setting the length of the transfer (bytes) //len to lenL pDmaChannel->VLEN = VLEN_USE_LEN; // Using the length field pDmaChannel->PRIORITY = PRI_LOW; // High priority pDmaChannel->M8 = M8_USE_8_BITS; // Transferring all 8 bits in each byte. pDmaChannel->IRQMASK = generateInterrupt; // The DMA complete interrupt flag is set at completion. pDmaChannel->DESTINC = DESTINC_0; // The destination address is constant pDmaChannel->SRCINC = SRCINC_1; // The address for data fetch is inremented by 1 byte // after each transfer. pDmaChannel->TRIG = DMATRIG_ENC_DW; // Setting the AES module to generate the DMA trigger pDmaChannel->TMODE = TMODE_SINGLE; // A single byte is transferred each time. pDmaChannel->WORDSIZE = WORDSIZE_BYTE; // One byte is transferred each time. return; }
void Mem::restart_header(void) { zword screen_x_size; zword screen_y_size; zbyte font_x_size; zbyte font_y_size; int i; SET_BYTE(H_CONFIG, h_config); SET_WORD(H_FLAGS, h_flags); if (h_version >= V4) { SET_BYTE(H_INTERPRETER_NUMBER, h_interpreter_number); SET_BYTE(H_INTERPRETER_VERSION, h_interpreter_version); SET_BYTE(H_SCREEN_ROWS, h_screen_rows); SET_BYTE(H_SCREEN_COLS, h_screen_cols); } // It's less trouble to use font size 1x1 for V5 games, especially because of // a bug in the unreleased German version of "Zork 1" if (h_version != V6) { screen_x_size = (zword)h_screen_cols; screen_y_size = (zword)h_screen_rows; font_x_size = 1; font_y_size = 1; } else { screen_x_size = h_screen_width; screen_y_size = h_screen_height; font_x_size = h_font_width; font_y_size = h_font_height; } if (h_version >= V5) { SET_WORD(H_SCREEN_WIDTH, screen_x_size); SET_WORD(H_SCREEN_HEIGHT, screen_y_size); SET_BYTE(H_FONT_HEIGHT, font_y_size); SET_BYTE(H_FONT_WIDTH, font_x_size); SET_BYTE(H_DEFAULT_BACKGROUND, h_default_background); SET_BYTE(H_DEFAULT_FOREGROUND, h_default_foreground); } if (h_version == V6) for (i = 0; i < 8; i++) storeb((zword)(H_USER_NAME + i), h_user_name[i]); SET_BYTE(H_STANDARD_HIGH, h_standard_high); SET_BYTE(H_STANDARD_LOW, h_standard_low); set_header_extension(HX_FLAGS, hx_flags); set_header_extension(HX_FORE_COLOUR, hx_fore_colour); set_header_extension(HX_BACK_COLOUR, hx_back_colour); }
void dmaToAudioOut(){ SET_WORD(DmaDesc1_4[3].SRCADDRH, DmaDesc1_4[3].SRCADDRL, USB_fifo_all); // Set the USB_fifo_all as the source SET_WORD(DmaDesc1_4[3].LENH, DmaDesc1_4[3].LENL, 2*ADC_SAMPLES); // Set the length of the transfer (bytes) DmaDesc1_4[3].VLEN = VLEN_FIXED; DmaDesc1_4[3].PRIORITY = PRI_LOW; DmaDesc1_4[3].M8 = M8_USE_8_BITS; // Transferring all 8 bits in each byte. DmaDesc1_4[3].IRQMASK = IRQMASK_DISABLE; // No interrupt on DMA completion. DmaDesc1_4[3].SRCINC = SRCINC_1; // Increment the source address DmaDesc1_4[3].DESTINC = DESTINC_1; // Increment the destination address DmaDesc1_4[3].TRIG = DMATRIG_NONE; // Triggered by setting DMAREQ DmaDesc1_4[3].TMODE = TMODE_BLOCK; DmaDesc1_4[3].WORDSIZE = WORDSIZE_BYTE; // One byte is transferred each time. return; }
UINT32 ali_otp_read(UINT16 addr) { SET_WORD(REG_ADDR, addr&0xfffc); SET_DWORD(REG_CTRL, GET_DWORD(REG_CTRL)|OTP_READ_TRIG); while(GET_DWORD(REG_CTRL) & OTP_READ_BUSY); return GET_DWORD(REG_RDATA); }
void Processor::script_close() { h_flags &= ~SCRIPTING_FLAG; SET_WORD(H_FLAGS, h_flags); glk_stream_close(sfp); ostream_script = false; }
void dmaFromRadio(WORD length, WORD dstAddr){ SET_WORD(DmaDesc1_4[0].SRCADDRH, DmaDesc1_4[0].SRCADDRL, &X_RFD); // Set RFD register as source SET_WORD(DmaDesc1_4[0].DESTADDRH, DmaDesc1_4[0].DESTADDRL, dstAddr); // RX buffer address SET_WORD(DmaDesc1_4[0].LENH, DmaDesc1_4[0].LENL, length); // Set the length of the transfer (bytes) DmaDesc1_4[0].VLEN = VLEN_USE_LEN; // Use the length field DmaDesc1_4[0].PRIORITY = PRI_GUARANTEED; DmaDesc1_4[0].M8 = M8_USE_8_BITS; DmaDesc1_4[0].IRQMASK = IRQMASK_ENABLE; // Raise IRCON.DMAIF upon DMA completion. DmaDesc1_4[0].DESTINC = DESTINC_1; // The increment the destination address DmaDesc1_4[0].SRCINC = SRCINC_0; // The source address is constant DmaDesc1_4[0].TRIG = DMATRIG_RADIO; // DMA is started by the radio receiver. DmaDesc1_4[0].TMODE = TMODE_SINGLE; // One byte is transferred at each DMA trigger. DmaDesc1_4[0].WORDSIZE = WORDSIZE_BYTE; // Byte transfer. return; }
//----------------------------------------------------------------------------- // See cul.h for a description of this function. //----------------------------------------------------------------------------- void culDmaToRadio(DMA_DESC* pDmaChannel, WORD length, BYTE* pSrcAddr, BOOL generateInterrupt){ SET_WORD(pDmaChannel->SRCADDRH, pDmaChannel->SRCADDRL, pSrcAddr); // The start address of the segment SET_WORD(pDmaChannel->DESTADDRH, pDmaChannel->DESTADDRL, &X_RFD); // Tx FIFO address SET_WORD(pDmaChannel->LENH, pDmaChannel->LENL, length); // Setting the length of the transfer (bytes) pDmaChannel->VLEN = VLEN_USE_LEN; // Using the length field pDmaChannel->PRIORITY = PRI_HIGH; // High priority pDmaChannel->M8 = M8_USE_8_BITS; // Transferring all 8 bits in each byte. pDmaChannel->IRQMASK = generateInterrupt; // The DMA complete interrupt flag is set at completion. pDmaChannel->DESTINC = DESTINC_0; // The destination address is constant pDmaChannel->SRCINC = SRCINC_1; // The address for data fetch is inremented by 1 byte // after each transfer. pDmaChannel->TRIG = DMATRIG_NONE; // DMA is started by writing the DMAREQ register. pDmaChannel->TMODE = TMODE_BLOCK; // The whole block is transferred. pDmaChannel->WORDSIZE = WORDSIZE_BYTE; // One byte is transferred each time. return; }
//----------------------------------------------------------------------------- // See cul.h for a description of this function. //----------------------------------------------------------------------------- void culDmaFromRadio(DMA_DESC* pDmaChannel, BYTE *pDstAddr, BOOL generateInterrupt) { SET_WORD(pDmaChannel->SRCADDRH, pDmaChannel->SRCADDRL, &X_RFD); // The start address of the segment SET_WORD(pDmaChannel->DESTADDRH, pDmaChannel->DESTADDRL, pDstAddr); // Tx FiFo address SET_WORD(pDmaChannel->LENH, pDmaChannel->LENL, 255); // Maximum of the Tx FiFo. pDmaChannel->VLEN = VLEN_1_P_VALOFFIRST_P_2;// The first byte indicates transfer length pDmaChannel->PRIORITY = PRI_LOW; pDmaChannel->M8 = M8_USE_8_BITS; pDmaChannel->IRQMASK = generateInterrupt; // The DMA complete interrupt flag is set at completion. pDmaChannel->DESTINC = DESTINC_1; // The destination is constant pDmaChannel->SRCINC = SRCINC_0; // The address for data fetch is incremented by 1 byte after each transfer. pDmaChannel->TRIG = DMATRIG_RADIO; // DMA is started by the radio receiver. pDmaChannel->TMODE = TMODE_SINGLE; // One byte is transferred at each DMA trigger. pDmaChannel->WORDSIZE = WORDSIZE_BYTE; // Byte transfer. return; }
void script_close (void) { h_flags &= ~SCRIPTING_FLAG; SET_WORD (H_FLAGS, h_flags); fclose (sfp); ostream_script = FALSE; }/* script_close */
void script_close (void) { z_header.h_flags &= ~SCRIPTING_FLAG; SET_WORD (H_FLAGS, z_header.h_flags) fclose (sfp); ostream_script = FALSE; }/* script_close */
void Mem::set_header_extension(int entry, zword val) { zword addr; if (h_extension_table == 0 || entry > hx_table_size) return; addr = h_extension_table + 2 * entry; SET_WORD(addr, val); }
void dmaToAudioIn(){ SET_WORD(DmaDesc1_4[2].DESTADDRH, DmaDesc1_4[2].DESTADDRL, audioIn); // Set the audioIn buffer as the destination DmaDesc1_4[2].LENL = 192; // Set the length of the transfer (bytes) DmaDesc1_4[2].LENH = 0; DmaDesc1_4[2].VLEN = VLEN_FIXED; DmaDesc1_4[2].PRIORITY = PRI_LOW; DmaDesc1_4[2].M8 = M8_USE_8_BITS; // Transferring all 8 bits in each byte. DmaDesc1_4[2].IRQMASK = IRQMASK_DISABLE; // No interrupt on DMA completion. DmaDesc1_4[2].DESTINC = DESTINC_1; // Increment the destination address by 1 DmaDesc1_4[2].TRIG = DMATRIG_NONE; // Triggered by setting DMAREQ DmaDesc1_4[2].TMODE = TMODE_BLOCK; DmaDesc1_4[2].WORDSIZE = WORDSIZE_BYTE; // One byte is transferred each time. return; }
void dmaToUSBfifo(){ SET_WORD(DmaDesc0.DESTADDRH, DmaDesc0.DESTADDRL, &USBF4); DmaDesc0.DESTINC = DESTINC_0; // The destination address is constant DmaDesc0.VLEN = VLEN_FIXED; DmaDesc0.LENH = 0; DmaDesc0.LENL = 96; DmaDesc0.WORDSIZE = WORDSIZE_BYTE; DmaDesc0.TMODE = TMODE_BLOCK; DmaDesc0.TRIG = DMATRIG_NONE; // Triggered by setting DMAREQ DmaDesc0.IRQMASK = IRQMASK_DISABLE; DmaDesc0.PRIORITY = PRI_LOW; return; }
void Processor::script_open() { h_flags &= ~SCRIPTING_FLAG; frefid_t fref = glk_fileref_create_by_prompt(fileusage_Transcript, filemode_WriteAppend); sfp = glk_stream_open_file(fref, filemode_WriteAppend); if (sfp != nullptr) { sfp->setPosition(0, seekmode_End); h_flags |= SCRIPTING_FLAG; script_valid = true; ostream_script = true; script_width = 0; } else { print_string("Cannot open file\n"); } SET_WORD(H_FLAGS, h_flags); }
void script_open (void) { static bool script_valid = FALSE; char new_name[MAX_FILE_NAME + 1]; h_flags &= ~SCRIPTING_FLAG; if (h_version >= V5 || !script_valid) { if (!os_read_file_name (new_name, f_setup.script_name, FILE_SCRIPT)) goto done; strcpy (f_setup.script_name, new_name); } /* Opening in "at" mode doesn't work for script_erase_input... */ if ((sfp = fopen (f_setup.script_name, "r+t")) != NULL || (sfp = fopen (f_setup.script_name, "w+t")) != NULL) { fseek (sfp, 0, SEEK_END); h_flags |= SCRIPTING_FLAG; script_valid = TRUE; ostream_script = TRUE; script_width = 0; } else print_string ("Cannot open file\n"); done: SET_WORD (H_FLAGS, h_flags); }/* script_open */
//////////////////////////////////////////////////////////////////////////////// /// @brief Application main function. //////////////////////////////////////////////////////////////////////////////// void main(void) { // Initializations SET_MAIN_CLOCK_SOURCE(CRYSTAL); SET_MAIN_CLOCK_SPEED(MHZ_26); CLKCON = (CLKCON & 0xC7); init_peripherals(); P0 &= ~0x40; // Pulse the Codec Reset line (high to low, low to high) P0 |= 0x40; init_codec(); // Initilize the Codec INT_SETFLAG(INUM_DMA, INT_CLR); // clear the DMA interrupt flag I2SCFG0 |= 0x01; // Enable the I2S interface DMA_SET_ADDR_DESC0(&DmaDesc0); // Set up DMA configuration table for channel 0 DMA_SET_ADDR_DESC1234(&DmaDesc1_4[0]); // Set up DMA configuration table for channels 1 - 4 dmaMemtoMem(AF_BUF_SIZE); // Set up DMA Channel 0 for memmory to memory data transfers initRf(); // Set radio base frequency and reserve DMA channels 1 and 2 for RX/TX buffers dmaAudio(); // Set up DMA channels 3 and 4 for the Audio In/Out buffers DMAIRQ = 0; DMA_ARM_CHANNEL(4); // Arm DMA channel 4 macTimer3Init(); INT_ENABLE(INUM_T1, INT_ON); // Enable Timer 1 interrupts INT_ENABLE(INUM_DMA, INT_ON); // Enable DMA interrupts INT_GLOBAL_ENABLE(INT_ON); // Enable Global interrupts MAStxData.macPayloadLen = TX_PAYLOAD_LEN; MAStxData.macField = MAC_ADDR; while (1) { // main program loop setChannel(channel[band][ActiveChIdx]); // SetChannel will set the MARCSTATE to IDLE ActiveChIdx = (ActiveChIdx + 1) & 0x03; SCAL(); // Start PLL calibration at new channel if ((P1 & 0x08) != aux_option_status) { // if the 'SEL AUX IN' option bit has changed state if ((P1 & 0x08) == 0) { // SEL AUX IN has changed state to true I2Cwrite(MIC1LP_LEFTADC, 0xFC); // Disconnect MIC1LP/M from the Left ADC, Leave Left DAC enabled I2Cwrite(MIC2L_MIC2R_LEFTADC, 0x2F); // Connect AUX In (MIC2L) to Left ADC I2Cwrite(LEFT_ADC_PGA_GAIN, 0x00); // Set PGA gain to 0 dB aux_option_status &= ~0x08; } else { // SEL AUX IN has changed state to false I2Cwrite(MIC2L_MIC2R_LEFTADC, 0xFF); // Disconnect AUX In (MIC2L) from Left ADC I2Cwrite(MIC1LP_LEFTADC, 0x84); // Connect the internal microphone to the Left ADC using differential inputs (gain = 0 dB); Power Up the Left ADC I2Cwrite(LEFT_ADC_PGA_GAIN, 0x3C); // Enable PGA and set gain to 30 dB aux_option_status |= 0x08; } } if ((P1 & 0x04) != agc_option_status) { // if the 'ENA AGC' option bit has changed state if ((P1 & 0x04) == 0) { // ENA AGC has changed state to true I2Cwrite(LEFT_AGC_CNTRL_A, 0x90); // Left AGC Control Register A - Enable, set target level to -8 dB I2Cwrite(LEFT_AGC_CNTRL_B, 0xC8); // Left AGC Control Register B - Set maximum gain to to 50 dB I2Cwrite(LEFT_AGC_CNTRL_C, 0x00); // Left AGC Control Register C - Disable Silence Detection agc_option_status &= ~0x04; } else { // SEL AUX IN has changed state to false I2Cwrite(LEFT_AGC_CNTRL_A, 0x10); // Left AGC Control Register A - Disable agc_option_status |= 0x04; } } // Check the band selection bits band = 2; // if the switch is not in position 1 or 2, in must be in position 3 if ((P1 & 0x10) == 0) // check if switch is in position 1 band = 0; else if ((P0 & 0x04) == 0) // check if switch is in position 2 band = 1; // Now wait for the "audio frame ready" signal while (audioFrameReady == FALSE); // Wait until an audioframe is ready to be transmitted audioFrameReady = FALSE; // Reset the flag // Move data from the CODEC (audioOut) buffer to the TX buffer using DMA Channel 0 SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut[activeOut]); SET_WORD(DmaDesc0.DESTADDRH, DmaDesc0.DESTADDRL, MAStxData.payload); DmaDesc0.SRCINC = SRCINC_1; // Increment Source address DMAARM |= DMA_CHANNEL_0; DMAREQ |= DMA_CHANNEL_0; // Enable memory-to-memory transfer using DMA channel 0 while ((DMAARM & DMA_CHANNEL_0) > 0); // Wait for transfer to complete while (MARCSTATE != 0x01); // Wait for calibration to complete P2 |= 0x08; // Debug - Set P2_3 (TP2) rfSendPacket(MASTER_TX_TIMEOUT_WO_CALIB); P2 &= ~0x08; // Debug - Reset P2_3 (TP2) } // end of 'while (1)' loop }
void dma_main(void){ #else void main(void){ #endif DMA_DESC dmaChannel; char sourceString[56] = "This is a test string used to demonstrate DMA transfer."; //56 bytes char destString[56]; INT8 i; INT8 errors = 0; initDma(); //Clearing the destination memset(destString,0,sizeof(destString)); // Setting up the DMA channel. SET_WORD(dmaChannel.SRCADDRH, dmaChannel.SRCADDRL, &sourceString); // The start address of the data to be transmitted SET_WORD(dmaChannel.DESTADDRH, dmaChannel.DESTADDRL, &destString); // The start address of the destination. SET_WORD(dmaChannel.LENH, dmaChannel.LENL, sizeof(sourceString)); // Setting the number of bytes to transfer. dmaChannel.VLEN = VLEN_USE_LEN; // Using the length field to determine how many bytes to transfer. dmaChannel.PRIORITY = PRI_HIGH; // High priority. dmaChannel.M8 = M8_USE_8_BITS; // Irrelevant since length is determined by the LENH and LENL. dmaChannel.IRQMASK = FALSE; // The DMA shall not issue an IRQ upon completion. dmaChannel.DESTINC = DESTINC_1; // The destination address is to be incremented by 1 after each transfer. dmaChannel.SRCINC = SRCINC_1; // The source address inremented by 1 byte after each transfer. dmaChannel.TRIG = DMATRIG_NONE; // The DMA channel will be started manually. dmaChannel.TMODE = TMODE_BLOCK; // The number of bytes specified by LENH and LENL is transferred. dmaChannel.WORDSIZE = WORDSIZE_BYTE; // One byte is transferred each time. // Using DMA channel 0. // Setting where the DMA channel is to read the desciptor and arming the DMA channel. DMA_SET_ADDR_DESC0(&dmaChannel); DMA_ABORT_CHANNEL(0); DMA_ARM_CHANNEL(0); //Waiting for the user to start the transfer. lcdUpdate((char*)"Press S1",(char*)"to start DMA."); while(!buttonPushed()); // Clearing all DMA complete flags and starting the transfer. DMAIRQ = 0x00; DMA_START_CHANNEL(0); // Waiting for the DMA to finish. while(!(DMAIRQ & DMA_CHANNEL_0)); // Verifying that data is transferred correctly for(i=0;i<sizeof(sourceString);i++) { if(sourceString[i] != destString[i]) errors++; } //Displaying the result if(errors == 0) {lcdUpdate((char*)"Dma transfer",(char*)"correct!");} else {lcdUpdate((char*)"Error in DMA",(char*)"Transfer");} haltApplicationWithLED(); return; }
// ************************ USB interrupt event processing ******************************** void usbirqHookProcessEvents(void) { // Handle events that require immediate processing here P0 |= 0x04; // Set P0_2 (P4 pin 6) if (usbirqData.eventMask & USBIRQ_EVENT_START_OF_FRAME) { oldEndpoint = USBINDEX; if (failed_to_send != 0) { // Transfer nulls into the USB audio buffer using DMA SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, &null); DmaDesc0.SRCINC = SRCINC_0; // The source address is constant DMAARM |= DMA_CHANNEL_0; DMAREQ |= DMA_CHANNEL_0; // Enable memory-to-memory transfer using DMA channel 0 while ((DMAARM & DMA_CHANNEL_0) > 0); // Wait for transfer to complete } failed_to_send = 1; // This flag should be cleard by a subsequent EP4IN interrupt usbirqData.eventMask &= ~USBIRQ_EVENT_START_OF_FRAME; USBCSIL |= USBCSIL_INPKT_RDY; USBINDEX = oldEndpoint; } if (usbirqData.eventMask & USBIRQ_EVENT_EP4IN) { oldEndpoint = USBINDEX; USBINDEX = 4; // Change to endpoint 4 // Transfer audio data from the audioIn buffer to the USB audio buffer using DMA // SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, SINE_TABLE); switch (whichbuffer) { case 0: if (activeOut == 0) SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.A.fifoA); else SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.B.fifoA); break; case 1: if (activeOut == 0) SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.A.fifoB); else SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.B.fifoB); break; case 2: if (activeOut == 0) SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.A.fifoC); else SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.B.fifoC); break; case 3: if (activeOut == 0) SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.A.fifoD); else SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.B.fifoD); break; case 4: if (activeOut == 0) SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.A.fifoE); else SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.B.fifoE); break; case 5: if (activeOut == 0) SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.A.fifoF); else SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, audioOut.B.fifoF); break; } // SET_WORD(DmaDesc0.SRCADDRH, DmaDesc0.SRCADDRL, SINE_TABLE); DmaDesc0.SRCINC = SRCINC_1; // The incrment the source address DMAARM |= DMA_CHANNEL_0; DMAREQ |= DMA_CHANNEL_0; // Enable memory-to-memory transfer using DMA channel 0 while ((DMAARM & DMA_CHANNEL_0) > 0); // Wait for transfer to complete whichbuffer++; if (whichbuffer > 5) { activeOut++; activeOut &= 0x01; whichbuffer = 0; } usbirqData.eventMask &= ~USBIRQ_EVENT_EP4IN; USBCSIL |= USBCSIL_INPKT_RDY; USBINDEX = oldEndpoint; failed_to_send = 0; } }
/****************************************************************************** * @fn writeFlashUsingDMA * * @brief * Writes data to flash using DMA. Erases the page in advance if told to. * * Parameters: * * @param BYTE* pSrcAddr * The start of the data to be written to flash. * * INT16 length * The number of bytes to be written to flash. * * WORD flashAddress * The address in flash the data is to be written to. * * BOOL erase * Indicating whether the flash is to be erased or not. * * @return void * ******************************************************************************/ void writeFlashUsingDMA(BYTE* pSrcAddr, INT16 length, WORD flashAddress, BOOL erase) { BYTE buffer[10]; INT_GLOBAL_ENABLE(INT_OFF); // Setting up the flash address, // erasing the page if required. SET_WORD(FADDRH, FADDRL, (int)(flashAddress >> 1)); if(erase == TRUE) { halFlashErasePage(buffer, PAGE_NUMBER); } halWait(0xFF); // Making sure a multiplum of 4 bytes is transferred. while(length & 0x0003){ length++; } SET_WORD(dmaChannel.SRCADDRH, dmaChannel.SRCADDRL, pSrcAddr); // The start address of the segment SET_WORD(dmaChannel.DESTADDRH, dmaChannel.DESTADDRL, &X_FWDATA); // Input of the AES module SET_WORD(dmaChannel.LENH, dmaChannel.LENL, length); // Setting the length of the transfer (bytes) dmaChannel.VLEN = VLEN_USE_LEN; // Using the length field dmaChannel.PRIORITY = PRI_LOW; // High priority dmaChannel.M8 = M8_USE_8_BITS; // Transferring all 8 bits in each byte. dmaChannel.IRQMASK = FALSE; // The DMA complete interrupt flag is set at completion. dmaChannel.DESTINC = DESTINC_0; // The destination address is constant dmaChannel.SRCINC = SRCINC_1; // The address for data fetch is inremented by 1 byte dmaChannel.TRIG = DMATRIG_FLASH; // Setting the FLASH module to generate the DMA trigger dmaChannel.TMODE = TMODE_SINGLE; // A single byte is transferred each time. dmaChannel.WORDSIZE = WORDSIZE_BYTE; // Set to count bytes. // Setting up the DMA. // Clearing all DMA complete flags and arming the channel. DMA_SET_ADDR_DESC0(&dmaChannel); DMA_ABORT_CHANNEL(0); DMAIRQ &= ~DMA_CHANNEL_0; DMA_ARM_CHANNEL(0); asm("NOP"); // Starting to write FLASH_CONFIG(WRITE); // Waiting for the DMA to finish. while(!(DMAIRQ & DMA_CHANNEL_0)); DMAIRQ &= ~DMA_CHANNEL_0; return; }