//----------------------------------------------------------------------------- // See cul.h for a description of this function. //----------------------------------------------------------------------------- void culDmaInit(void){ // Clearing all channels memset((void*)dmaChannel1to4, 0, sizeof(dmaChannel1to4)); // Clearing the DMA table memset((void*)dmaTable, 0, sizeof(dmaTable)); // Clearing any arming of channels 1 to 4, but leaving staus of channel 0. DMAARM &= DMA_CHANNEL_0; // Clearing all starting of DMA channels 1 to 4, but leaving status of channel 0. DMAREQ &= DMA_CHANNEL_0; // Clearing all DMA interrupt flags of channels 1 to 4, but leaving status of channel 0. DMAIRQ &= DMA_CHANNEL_0; // Clearing the interrupt flag of the DMA and enabling DMA interrupt. INT_SETFLAG(INUM_DMA, INT_CLR); INT_ENABLE(INUM_DMA, INT_ON); // Setting the address of the DMA descriptors DMA_SET_ADDR_DESC1234(dmaChannel1to4); } // ends culDmaInit()
__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); }
//////////////////////////////////////////////////////////////////////////////// /// @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
//----------------------------------------------------------------------------- // See cul.h for a description of this function. //----------------------------------------------------------------------------- BOOL sppInit(UINT32 frequency, BYTE address){ BYTE res = 0; BOOL status = TRUE; sppSetAddress(address); // Clearing the states of the spp. sppTxStatus = TX_IDLE; sppRxStatus = RX_IDLE; retransmissionCounter = 0; ackTimerNumber = 0; pAckData = 0; // Clearing the RF interrupt flags and enable mask and enabling RF interrupts RFIF = 0; RFIM = 0; INT_SETFLAG(INUM_RF,INT_CLR); INT_ENABLE(INUM_RF,INT_ON); // Setting the frequency and initialising the radio res = halRfConfig(FREQUENCY_4_CC1110); if(res == FALSE){ status = FALSE; } // Always in RX unless sending. //debug: MCSM1 = 0x2F; // MCSM1 = 0x3F; SRX(); // Using the timer 4 administrator to generate interrupt to check if a message is unacked... culTimer4AdmInit(); // Initialising the DMA administrator culDmaInit(); // Requesting a DMA channel for transmit data. No callback function is used. Instead the TX_DONE // interrupt is used to determine when a transfer is finished. Configuring the DMA channel for // transmit. The data address and length will be set prior to each specific transmission. dmaTx = culDmaAllocChannel(&dmaNumberTx, 0); if((dmaNumberTx == 0) || (dmaNumberTx > 4)){ status = FALSE; } culDmaToRadio(dmaTx, SPP_MAX_PAYLOAD_LENGTH + SPP_HEADER_AND_FOOTER_LENGTH, 0, FALSE); // Requesting a DMA channel for receiving data. Giving the address of the callback function. // Configuring the DMA channel for receive. The data address will be set prior to each specific // reception. dmaRx = culDmaAllocChannel(&dmaNumberRx, &rxCallBack); if((dmaNumberRx == 0) || (dmaNumberRx > 4)){ status = FALSE; } culDmaFromRadio(dmaRx, 0, TRUE); // Making sure that none of the channels are armed. DMA_ABORT_CHANNEL(dmaNumberRx); DMA_ABORT_CHANNEL(dmaNumberTx); INT_ENABLE(INUM_DMA, INT_ON); return status; } // ends sppInit