__interrupt void dma_IRQ (void){ INT_GLOBAL_ENABLE(INT_OFF); // Stop all other interrupts DMAIF = 0; // Clear the main CPU interrupt flag INT_SETFLAG(INUM_DMA, INT_CLR); // Clear the DMA IRQ flag INT_GLOBAL_ENABLE(INT_ON); // Re-enable interrupts }
__interrupt void dma_IRQ (void){ BYTE clearedFlags = 0x00; INT_GLOBAL_ENABLE(INT_OFF); // Handle each channel if ((DMAIRQ & DMA_CHANNEL_0) && dmaTable[0].callBackFunction) { clearedFlags |= DMA_CHANNEL_0; dmaTable[0].callBackFunction(); } if ((DMAIRQ & DMA_CHANNEL_1) && dmaTable[1].callBackFunction) { clearedFlags |= DMA_CHANNEL_1; dmaTable[1].callBackFunction(); } if ((DMAIRQ & DMA_CHANNEL_2) && dmaTable[2].callBackFunction) { clearedFlags |= DMA_CHANNEL_2; dmaTable[2].callBackFunction(); } if ((DMAIRQ & DMA_CHANNEL_3) && dmaTable[3].callBackFunction) { clearedFlags |= DMA_CHANNEL_3; dmaTable[3].callBackFunction(); } if ((DMAIRQ & DMA_CHANNEL_4) && dmaTable[4].callBackFunction) { clearedFlags |= DMA_CHANNEL_4; dmaTable[4].callBackFunction(); } // Clear the flags INT_SETFLAG(INUM_DMA, INT_CLR); DMAIRQ = ~clearedFlags; INT_GLOBAL_ENABLE(INT_ON); }
__interrupt void spp_rf_IRQ(void) { BYTE enabledAndActiveInterrupt; INT_GLOBAL_ENABLE(INT_OFF); enabledAndActiveInterrupt = RFIF; RFIF = 0x00; // Clear all interrupt flags INT_SETFLAG(INUM_RF, INT_CLR); // Clear MCU interrupt flag enabledAndActiveInterrupt &= RFIM; // Start of frame delimiter (SFD) if(enabledAndActiveInterrupt & IRQ_SFD) { if(sppRxStatus == RX_WAIT) { sppRxStatus = RX_IN_PROGRESS; RFIM &= ~IRQ_SFD; } } // Transmission of a packet is finished. Enabling reception of ACK if required. if(enabledAndActiveInterrupt & IRQ_DONE) { if(sppTxStatus == TX_IN_PROGRESS) { if(pAckData == NULL) { sppTxStatus = TX_SUCCESSFUL; } else { DMA_ARM_CHANNEL(dmaNumberRx); } } // Clearing the tx done interrupt enable RFIM &= ~IRQ_DONE; } INT_GLOBAL_ENABLE(INT_ON); }
//----------------------------------------------------------------------------- // See cul.h for a description of this function. //----------------------------------------------------------------------------- void culTimer4AdmReset(BYTE entry){ BYTE status; // Storing the interrupt enable register, and turning off interrupts status = IEN0; INT_GLOBAL_ENABLE(INT_OFF); // Setting up the table. timer4Table[entry].counter = 0; // Restoring the interrupt enable status. IEN0 = status; return; } // ends culTimer4AdmClear(...)
/****************************************************************************** * @fn initStopWatch * * @brief * Initializes components for the stopwatch application example. * * Parameters: * * @param void * * @return void * ******************************************************************************/ void initStopWatch(void) { //interrupts[INUM_T3] = stop_watch_T3_IRQ; INIT_GLED(); SET_MAIN_CLOCK_SOURCE(CRYSTAL); CLKCON &= ~0x38; // Enabling overflow interrupt from timer 3 TIMER34_INIT(3); halSetTimer34Period(3, 1000); INT_ENABLE(INUM_T3, INT_ON); TIMER34_ENABLE_OVERFLOW_INT(3,INT_ON); INT_GLOBAL_ENABLE(INT_ON); }
//----------------------------------------------------------------------------- // See cul.h for a description of this function. //----------------------------------------------------------------------------- DMA_DESC* culDmaAllocChannel(UINT8* pDmaChannelNumber, FUNCTION* callBackFunction) { DMA_DESC* dmaDesc; BYTE savedIntEnable = 0x00; INT8 i; // Checking for an unassigned DMA channel for(i = 1; i <= DMA_ADM_NUMBER_OF_CHANNELS; i++) { if(dmaTable[i].assigned == FALSE) { break; } } // If no channel is available, the function returns. if(i > DMA_ADM_NUMBER_OF_CHANNELS) { *pDmaChannelNumber = 0x00; dmaDesc = NULL; } // An available table entry was found else { // Deactivating the channel and erasing old interrupt flag DMA_ABORT_CHANNEL(i); DMAIRQ &= ~(1 << i); // Storing interrupt enable register and turning off interrupts. savedIntEnable = IEN0; INT_GLOBAL_ENABLE(INT_OFF); // Reserving the DMA channel. dmaTable[i].assigned = TRUE; dmaTable[i].callBackFunction = callBackFunction; *pDmaChannelNumber = i; // Restoring old interrupt enable register. IEN0 = savedIntEnable; dmaDesc = &dmaChannel1to4[i-1]; } // Returning pointer to the DMA descriptor return dmaDesc; } // ends culDmaAlloc()
//----------------------------------------------------------------------------- // See cul.h for a description of this function. //----------------------------------------------------------------------------- BYTE culTimer4AdmSet(DWORD timeout, FUNCTION* callBackFunction){ BYTE status = 0x00; BYTE i = 0x00; // Checking the arguments... if((timeout == 0) || (callBackFunction == NULL)){ return 0xFF; } status = IEN0; INT_GLOBAL_ENABLE(INT_OFF); // Searching for an available entry in the table. for(i = 0; i < TIMER_ADM_TABLE_LENGTH; i++){ if(timer4Table[i].timeout == 0){ // Storing the interrupt enable register, and turning off interrupts // Setting up the table. timer4Table[i].timeout = timeout; timer4Table[i].counter = 0; timer4Table[i].callBackFunction = callBackFunction; break; } } // Restoring the interrupt enable status. IEN0 = status; if(i < TIMER_ADM_TABLE_LENGTH ) { return i; } else { // No available entry in the table, returning error value return 0xFF; } } // ends culTimer4AdmSet(...)
//////////////////////////////////////////////////////////////////////////////// /// @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 }
//----------------------------------------------------------------------------- // See cul.h for a description of this function. //----------------------------------------------------------------------------- BYTE sppSend(SPP_STRUCT* pPacketPointer){ BYTE res = TRUE; // Checking that length is not too long if (pPacketPointer->payloadLength > SPP_MAX_PAYLOAD_LENGTH) { res = TOO_LONG; sppTxStatus = TX_IDLE; } // Flipping the sequence bit, writing total packet length and address if the transfer is not a retransmission. // If it is a retransmission, the fields are correct if(!(pPacketPointer->flags & RETRANSMISSION)) { pPacketPointer->flags ^= SEQUENCE_BIT; pPacketPointer->payloadLength += SPP_HEADER_AND_FOOTER_LENGTH; pPacketPointer->srcAddress = myAddress; } // Setting up the DMA DMA_ABORT_CHANNEL(dmaNumberTx); SET_DMA_SOURCE(dmaTx,pPacketPointer); // Proceed if the packet length is OK. if (res == TRUE) { // Clearing RF interrupt flags and enabling RF interrupts. RFIF &= ~IRQ_DONE; RFIM &= ~IRQ_SFD; INT_SETFLAG(INUM_RF, INT_CLR); #ifdef CCA_ENABLE if(!CCA) { SRX(); // Turning on Rx and waiting to make the RSSI value become valid. halWait(1); } if(CCA) #endif { // Setting up radio DMA_ABORT_CHANNEL(dmaNumberRx); SIDLE(); RFTXRXIF = 0; INT_GLOBAL_ENABLE(FALSE); DMA_ARM_CHANNEL(dmaNumberTx); STX(); INT_GLOBAL_ENABLE(TRUE); sppTxStatus = TX_IN_PROGRESS; if(pPacketPointer->flags & DO_ACK) { pAckData = pPacketPointer; waitForAck(); } else { pAckData = NULL; } RFIM |= IRQ_DONE; } #ifdef CCA_ENABLE // The "air" is busy else { res = CHANNEL_BUSY; RFIM &= ~IRQ_DONE; // De-flipping the sequence bit. if(!(pPacketPointer->flags & RETRANSMISSION)) { pPacketPointer->flags ^= SEQUENCE_BIT; } } #endif } return res; } // ends sppSend
void stop_watch_main(void){ #else void main(void){ #endif STATE state = START_STATE; initStopWatch(); TIMER3_RUN(FALSE); ClearScreen(); Print(0,5,"--STOP WATCH--",1); Rectangle(2 , 4 , 108 , 7); while(!stopApplication()){ switch (state) { case START_STATE: { t.h = t.m = t.s = 0; overflow = 0; printTime(); if(LanguageSel == 1) { Print6(2,10," OK for START ",1); } else { Print(2,8,"按OK键开始:",1); } if(ScanKey() == K_OK) { while(ScanKey() != 0xff); halWait(5); TIMER3_RUN(TRUE); state = RUN_STATE; if(LanguageSel == 1) { Print6(2,10," OK for STOP ",1); } else { Print(2,8,"按OK键停止:",1); } } }break; case RUN_STATE: { INT_GLOBAL_ENABLE(INT_OFF); if(overflow > 0 && overflow < 0x09) { GLED = LED_ON; } else if(overflow > (UINT16)1000) { //overflow = 0; overflow -= 1000; incrementTime(); printTime(); } else { GLED = LED_OFF; } if(ScanKey() == K_OK) { while(ScanKey() != 0xff); halWait(5); TIMER3_RUN(FALSE); state = STOP_STATE; GLED = LED_OFF; } INT_GLOBAL_ENABLE(INT_ON); }break; case STOP_STATE: { printTime(); if(LanguageSel == 1) { Print6(2,10," Total time is:",1); } else { Print(2,8,"总计时间为:",1); } if(ScanKey() == K_OK) { while(ScanKey() != 0xff); halWait(5); state = START_STATE; } }break; default: break; } } while(ScanKey() != 0xff); halWait(5); INT_GLOBAL_ENABLE(INT_OFF); return; }
void flash_main(void){ #else void main(void){ #endif BYTE buffer[30]; char inputBuffer[STRING_LENGTH]; INT8 pointer = 0; BOOL stop = FALSE; BOOL write = FALSE; char c; char *menuText[] = {(char*)" CPU write?", (char*)" DMA write?"}; BYTE command; BOOL unUsed; initFlash(); // Clearing buffers memset(buffer,0,sizeof(buffer)); memset(inputBuffer,0,sizeof(inputBuffer)); // Setting up UART UART_SETUP(0,57600,HIGH_STOP); UTX0IF = 1; // Set UART 0 TX interrupt flag while(getJoystickDirection() != CENTRED); //Displaying the stored flash message. lcdUpdateLine(LINE1,(char*)"Last written:"); if((unUsed = flashUnused((BYTE*)testData, STRING_LENGTH))) { lcdUpdateLine(LINE2,(char*)"Unused"); } else { scrollText((char*) testData, STRING_LENGTH); } while(getJoystickDirection() != CENTRED); while(getJoystickDirection() == CENTRED); while(getJoystickDirection() != CENTRED); // User decides whether to use CPU or DMA to write flash or to abort. command = lcdMenu(menuText,2); if(command == ABORT_MENU) { return; } // Uart communication lcdUpdate((char*)"Enter UART", (char*)"data"); printf((char*)"\n\nFlash Programming\n"); printf((char*)"Press a key\n\n"); uartGetkey (); // wait for a key to be pressed or the application to be ended if (stopApplication() ) return; else { inputBuffer[0] = U0DBUF; halWait(5); USART0_FLUSH(); inputBuffer[1] = U0DBUF; } // Printing the previously written data printf((char*)"\nLast written:\n"); if(unUsed) { printf((char*)"Unused\n"); } else { printf((char*)"%s\n",&testData); } //Aquiring new data: printf((char*)"\n\nType data to be written.\nWill be printed to the LCD next time."); printf((char*)"\n(ENTER: store in flash, ESC: abort)\n\n"); memset(inputBuffer,0,STRING_LENGTH); while(!stop) { c = getkey(); U0DBUF = c; switch (c){ case ENTER: inputBuffer[pointer] = 0; printf((char*)"\n\nTo write: %s\nENTER if OK.\n",inputBuffer); if(getkey() == ENTER) { // Write data to flash; stop = TRUE; write = TRUE; } else { // Reaquire data. printf((char*)"\nEnter text:\n"); pointer = 0; } break; case BACK_SPACE: // Erasing the last typed data. if (pointer > 0) { pointer--; inputBuffer[pointer] = ' '; } break; case ESC: // Abort Flash write. stop = TRUE; write = FALSE; break; default: // Add typed data to buffer. if (pointer < STRING_LENGTH-1) { inputBuffer[pointer] = c; pointer++; } break; } } INT_GLOBAL_ENABLE(INT_OFF); // Updating the flash if asked to. if(write == TRUE) { if(command == 0) { halFlashWritePage((BYTE*) &inputBuffer, buffer, PAGE_NUMBER); } else { writeFlashUsingDMA((BYTE*) &inputBuffer, STRING_LENGTH, PAGE_ADDRESS, TRUE); } printf((char*)"\nUpdated:"); printf((char*)" %s\n",(char __code*) (PAGE_NUMBER << 10)); lcdUpdateLine(LINE1,(char*)"Updated"); } else { printf((char*)"\nNot updated\n"); lcdUpdateLine(LINE1,(char*)"Not updated"); } lcdUpdateLine(LINE2,(char*)"LEFT to continue"); // Done haltApplicationWithLED(); return; }
/****************************************************************************** * @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; }