Example #1
0
void sendAck(SPP_STRUCT* receivedPacket)
{
   SIDLE();
   // Debug:
   halWait(1);
   DMA_ABORT_CHANNEL(dmaNumberTx);

   RFTXRXIF = 0;
   STX();
   RFIF &= ~IRQ_DONE;
   while(RFTXRXIF == 0);
   RFD = SPP_HEADER_AND_FOOTER_LENGTH + SPP_ACK_LENGTH;
   RFTXRXIF = 0;
   while(RFTXRXIF == 0);
   RFTXRXIF = 0;
   RFD = receivedPacket->srcAddress;
   while(RFTXRXIF == 0);
   RFTXRXIF = 0;
   RFD = myAddress;
   while(RFTXRXIF == 0);
   RFTXRXIF = 0;
   RFD = ACK;
   while(!(RFIF & IRQ_DONE));
   RFIF &= ~IRQ_DONE;

   return;
}
Example #2
0
//-----------------------------------------------------------------------------
// 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()
Example #3
0
//-----------------------------------------------------------------------------
// See cul.h for a description of this function.
//-----------------------------------------------------------------------------
void sppReceive(SPP_STRUCT* pReceiveData){

   sppRxStatus = RX_WAIT;

   DMA_ABORT_CHANNEL(dmaNumberRx);
   // Setting the address to where the received data are to be written. // Setting max number of bytes to receive
   SET_DMA_DEST(dmaRx,pReceiveData);
   SET_DMA_LENGTH(dmaRx,255);

   // Arming the DMA channel. The receiver will initate the transfer when a packet is received.
   DMA_ARM_CHANNEL(dmaNumberRx);

   // Debug:
   SIDLE();

   RFIF &= ~IRQ_SFD;
   RFIM |= IRQ_SFD;
   // Turning on the receiver
   SRX();

   return;
}
Example #4
0
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;
}
Example #5
0
//-----------------------------------------------------------------------------
// 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
Example #6
0
//-----------------------------------------------------------------------------
// 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
Example #7
-1
/******************************************************************************
* @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;
}