コード例 #1
0
ファイル: usart2.c プロジェクト: Spike0/Contiki_my
/**
 * @brief  SPI DMA Transfer
 * NULL can be input as txBuffer if tx data to transmit dummy data
 * If only sending data, set rxBuffer as NULL to skip DMA activation on RX
 */
void spiDmaTransfer(void *txBuffer, void *rxBuffer,  int bytes)
{
  /* Only activate RX DMA if a receive buffer is specified */
  if (rxBuffer != NULL)
  {
    /* Setting flag to indicate that RX is in progress
     * will be cleared by call-back function */
    rxActive = true;

    /* Clear RX regiters */
    USART2->CMD = USART_CMD_CLEARRX;

    /* Activate RX channel */
    DMA_ActivateBasic(DMA_CHANNEL_RX,
                      true,
                      false,
                      rxBuffer,
                      (void *)&(USART2->RXDATA),
                      bytes - 1);
  }
  /* Setting flag to indicate that TX is in progress
   * will be cleared by call-back function */
  txActive = true;

  /* Clear TX regsiters */
  USART2->CMD = USART_CMD_CLEARTX;

  /* Activate TX channel */
  DMA_ActivateBasic(DMA_CHANNEL_TX,
                    true,
                    false,
                    (void *)&(USART2->TXDATA),
                    txBuffer,
                    bytes - 1);
}
コード例 #2
0
/*
 *Function name: LEUART0_IRQHandler
 *Description : Interrupt Service Routine for LEUART0.
 */
void LEUART0_IRQHandler(void)
{
	leuartif = LEUART_IntGet(LEUART0); 	// Store the interrupt flag

	LEUART_IntClear(LEUART0, leuartif); //Clear interrupts

	if (leuartif & LEUART_IF_SIGF)
	{
		int temp = 0, i = 0;
		char tempChar[7];						// To store the Value of Temperature in char to transmit
		char temp_string[TX_bufferSize];	// Concatenated string for Message and Temperature, this will be transfered
		char copyCmp[sizeof(commandString)/sizeof(char)];							// string to store the Received string from Buffer to compare

		// Stop the LEUART reception and DMA Transfers
		for (i = 0; i < (strlen(commandString)); i++)		// Run loop till the return message (RetTemp!) length and copy RX buffer to copyCmp for comparing

		{
			copyCmp[i] = RX_Buffer[i];
		}

		copyCmp[8]='\0';

    	/* To extract the digits of the temperature variable and put in tempChar. A basic digit extraction algorithm is used and then each digit is passed one by one. */
		if (!strcmp(commandString,copyCmp)) 			// If valid Command is Received ie RetTemp!
		{
			temp = temperature*10;
			tempChar[0] = (temp/100)+48;
			temp = temp%100;
			tempChar[1] = (temp/10)+48;
			temp  = temp%10;
			tempChar[2] = '.';
			tempChar[3] = (temp)+48;
			tempChar[4] = 'C';
			tempChar[5] = '\r';
			tempChar[6] = '\n';

			strcpy(temp_string,returnMsg);					//Copy the returnMsg message in the temporary string
			strcat(temp_string,tempChar);					// Concatenate with tempChar to get the final message to be transfered

			// Enable DMA wake-up from LEUART0 TX
			LEUART0->CTRL = LEUART_CTRL_TXDMAWU;				// Enable DMA wake up for LEUART TX in EM2
			// Activate DMA for LEUART TX transfers
			DMA_ActivateBasic(DMA_CHANNEL_TX, true, false, (void *)&(LEUART0->TXDATA), (void *)temp_string, strlen(temp_string)- 1);	// -1 for the Null character which we wont transmit
		}
		else
		{
			LEUART0->CTRL = LEUART_CTRL_TXDMAWU;				// Enable DMA wake up for LEUART0 TX in EM2
			// Activate DMA for LEUART TX transfers
			DMA_ActivateBasic(DMA_CHANNEL_TX, true, false, (void *)&(LEUART0->TXDATA), (void *)errorMsg, strlen(errorMsg)-2);	// -1 for the Null character which we wont transmit
		}
		LEUART_IntEnable(LEUART0, LEUART_IF_RXDATAV); //Enable RXDATA Interrupt to check for received characters
		DMA_ActivateBasic(DMA_CHANNEL_RX, true, false, NULL, NULL, LEUART0_BUFFER-1);
	}
	else if (leuartif & LEUART_IF_RXDATAV)
	{
		LEUART_IntDisable(LEUART0, LEUART_IF_RXDATAV);	// Disable after receiving
	}

}
コード例 #3
0
/**************************************************************************//**
 * @brief  SPI DMA Transfer
 * NULL can be input as txBuffer if tx data to transmit dummy data
 * If only sending data, set rxBuffer as NULL to skip DMA activation on RX.
 * AUTOTX is used instead of DMA TX channel if txBuffer is NULL
 *****************************************************************************/
void spiDmaTransfer(uint8_t *txBuffer, uint8_t *rxBuffer,  int bytes)
{ 
  /* Use AUTOTX if MOSI data is irrelevant (reading from slave) */
  autoTx = (txBuffer == NULL);
  
  /* Only activate RX DMA if a receive buffer is specified */  
  if (rxBuffer != NULL)
  {
    /* Setting flag to indicate that RX is in progress
     * will be cleared by call-back function */
    rxActive = true;
    
    /* Clear RX registers */
    USART1->CMD = USART_CMD_CLEARRX;
    
    /* Activate RX channel */
    DMA_ActivateBasic(DMA_CHANNEL_RX,
                      true,
                      false,
                      rxBuffer,
                      (void *)&(USART1->RXDATA),
                      bytes - (autoTx ? 4 : 1)); /* Skip last 3 bytes if AUTOTX is used */
  }
  
  /* Clear TX registers */
  USART1->CMD = USART_CMD_CLEARTX;
  
  /* Setting flag to indicate that TX is in progress
   * will be cleared by callback function or USART RX interrupt (if using AUTOTX) */
  txActive = true;
  
  /* Activate AUTOTX when only reading from slave. If using TX data from a 
   * buffer use a TX DMA channel */
  if (autoTx)
  { 
    rxBufferG = (uint8_t *) rxBuffer; /* Copy buffer pointer to global variable */
    
    /* Setting AUTOTX will start TX as long as there is room in RX registers */
    USART1->CTRL |= USART_CTRL_AUTOTX; 
  }
  else
  {
    /* Activate TX channel */
    DMA_ActivateBasic(DMA_CHANNEL_TX,
                      true,
                      false,
                      (void *)&(USART1->TXDATA),
                      txBuffer,
                      bytes - 1); 
  }

}
コード例 #4
0
ファイル: dma.c プロジェクト: AndreMiras/EFM32-Library
void dmaStartFrameTransfer(int firstLine, int lastLine)
{
  /* Get address of first line */
  uint16_t *startAddr = FB_getActiveBuffer();
  startAddr += firstLine * 10;
  
  /* Create update command and address of first line */
  uint16_t cmd = MEMLCD_CMD_UPDATE | ((firstLine+1) << 8); 
  
  /* Enable chip select */
  GPIO_PinOutSet( pConf->scs.port, pConf->scs.pin );
  
  /* Set number of lines to copy */
  DMA->RECT0 = (DMA->RECT0 & ~_DMA_RECT0_HEIGHT_MASK) | (lastLine - firstLine);
  
  /* Indicate to the rest of the program that SPI transfer is in progress */
  spiTransferActive = true;
  
  /* Send the update command */
  USART_TxDouble(pConf->usart, cmd);
    
  /* Start the transfer */
  DMA_ActivateBasic(DMA_CHANNEL,
                    true,                               /* Use primary channel */
                    false,                              /* No burst */
                    (void *)&(pConf->usart->TXDOUBLE),  /* Write to USART */
                    startAddr,                          /* Start address */
                    FRAME_BUFFER_WIDTH/16-1);           /* Width -1 */  
  
}
コード例 #5
0
ファイル: i2c_master.c プロジェクト: AndreMiras/EFM32-Library
/*****************************************************************************
 * @brief  Reads from I2C EEPROM using DMA. 
 * 
 * @param deviceAddress 
 *      I2C address of EEPROM
 * 
 * @param offset
 *      The offset (address) to start reading from
 * 
 * @param data
 *      Pointer to the data buffer
 * 
 * @param length
 *      Number of bytes to read
 *****************************************************************************/
void i2cDmaRead(uint8_t deviceAddress, uint8_t offset, uint8_t *data, uint8_t length)
{ 
  /* Wait for any previous transfer to finish */
  while ( transferActive )
  {
    EMU_EnterEM1();
  }
  
  /* Abort if an error has occured */
  if ( i2cError )
  {
    return;
  }
 
  /* Clear all pending interrupts prior to starting transfer. */
  I2C0->IFC = _I2C_IFC_MASK;

  /* Write address to read from. Note that this is specific to the EEPROM on the 
   * EFM32GG-DK3750 and may need to be changed when using a different device. */
  i2cWriteByte(deviceAddress, offset);
    
  /* Send the device address. I2C_CMD_START must be written before
   * TXDATA since this is a repeated start.  */
  I2C0->CMD        = I2C_CMD_START;
  I2C0->TXDATA     = deviceAddress | I2C_READ_BIT;
  
  /* Wait for ACK on the address */
  if ( !i2cWaitForAckNack() )
  {
    i2cErrorAbort();
    return;
  }
  
  /* Do not start DMA if an error has occured */
  if ( i2cError )
  {
    return;
  }
  
  /* Automatically ACK received bytes */
  I2C0->CTRL |= I2C_CTRL_AUTOACK;
  
  /* These are used by the RX interrupt handler
   * to fetch the last two bytes of the transaction */
  rxPointer = data + length - 2;
  bytesLeft = 2;
  
  /* Set transfer active flag. Cleared by interrupt handler
   * when STOP condition has been sent. */
  transferActive = true;
  
  /* Activate DMA */
  DMA_ActivateBasic(DMA_CHANNEL_I2C_RX,         /* RX DMA channel */
                    true,                       /* Primary descriptor */
                    false,                      /* No burst */
                    (void *)data,               /* Write to rx buffer */        
                    (void *)&(I2C0->RXDATA),    /* Read from RXDATA */
                    length - 3 );               /* Number of transfers */
}
コード例 #6
0
/*
 * Function Name: main();
 * Description: All the function calls are done in main(). The CPU goes to sleep while in main(); until Interupt is generated.
 */
int main(void)
{

    CHIP_Init();

    CMU_HFRCOBandSet(cmuHFRCOBand_14MHz);
    CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
    CMU_OscillatorEnable(cmuOsc_HFXO, false, false);

    blockSleepMode(EM2); //Prevents the CPU to go below EM3 mode.

#if DEBUG_ON
    BSP_TraceSwoSetup(); //For simplicity studio Energy profiler code correlation.
#endif
    LETIMER_setup(); //Initialize LETIMER.

    ADC_Setup(); //Initialize the ADC

    DMA_Init();	//Initialize DMA.

    DMA_Setup(); //Setup DMA.

    LEUART_Setup(); //Initialize LEUART.

    GPIO_Init(); //Initialize GPOIs.

    LETIMER_IntEnable(LETIMER0, LETIMER_IF_UF); //Enable underflow UF interrupt.

    LEUART_IntEnable(LEUART0, LEUART_IF_SIGF);	// Enable SF RXDATAV

    NVIC_EnableIRQ(LETIMER0_IRQn); //Enable LETIMER0 interrupt vector in NVIC (Nested Vector Interrupt Controller)

    NVIC_EnableIRQ(LEUART0_IRQn); //Enable LETIMER0 interrupt vector in NVIC (Nested Vector Interrupt Controller)

	LEUART0->SIGFRAME = '!';							// Set LEUART signal frame to '!'

	LEUART0->CTRL |= LEUART_CTRL_RXDMAWU;				// Enable DMA wake up for LEUART RX in EM2
    DMA_ActivateBasic(DMA_CHANNEL_RX, true, false, (void *)RX_Buffer, (void *)&(LEUART0->RXDATA), LEUART0_BUFFER-1);

    // Enable Sleep-on-Exit
#if SLEEPONEXIT
    SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;	// Setting the corresponding bit for SleepOnExit
#endif

    while(1)
    {
        sleep(); //CPU goes to EM3 Mode to save energy, waits there until Interrupt is generated.
    }

}
コード例 #7
0
/*
 * Function Name: ADC_setup
 * Description: Configures ADC0
 */
void LEUART_Setup(void)
{
	/* Enabling the required clocks */
	CMU_ClockEnable(cmuClock_LFB, true);           //Enable the clock input to LETIMER
	CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO); //Selecting the ULFRCO as the source clock
	CMU_ClockEnable(cmuClock_LEUART0, true);           //Enable the clock input to LETIMER
	/* Defining the LEUART1 initialization data */
		LEUART_Init_TypeDef leuart0Init =
		{
		  .enable   = leuartEnable,        // Activate data reception on LEUn_TX pin.
		  .refFreq  = 0,                   // Inherit the clock frequency from the LEUART clock source
		  .baudrate = LEUART0_BAUD,    // Baudrate = 9600 bps
		  .databits = LEUART0_Databits,    // Each LEUART frame contains 8 databits
		  .parity   = LEUART0_Parity,      // No parity bits in use
		  .stopbits = LEUART0_Stopbits,    // Setting the number of stop bits in a frame to 2 bitperiods
		};

		LEUART_Init(LEUART0, &leuart0Init);

		// Route LEUART1 TX,RX pin to DMA location 0
		LEUART0->ROUTE = LEUART_ROUTE_TXPEN | LEUART_ROUTE_RXPEN | LEUART_ROUTE_LOCATION_LOC0;

		// Enable GPIO for LEUART1. TX is on D4
		GPIO_PinModeSet(gpioPortD, 4, gpioModePushPull, 0);
		// Enable GPIO for LEUART1. RX is on D5
		GPIO_PinModeSet(gpioPortD, 5, gpioModeInputPull, 0);
		// Pull PD15(CTS pin of BLE module) to GRND
		GPIO_PinModeSet(gpioPortD, 15, gpioModePushPull, 0);

}

/*
 *Function name: LETIMER0_IRQHandler
 *Description : Interrupt Service Routine for LETIMER.
 */
void LETIMER0_IRQHandler(void)
{
    LETIMER_IntClear(LETIMER0, LETIMER_IF_UF); //Clear LETIMER0 underflow (UF) and COMP1 flag.
    DMA_ActivateBasic(DMA_CHANNEL_ADC, true, false, (void *)ADC_Buffer, (void *)&(ADC0->SINGLEDATA), ADC_SAMPLES - 1);
    ADC_Setup();
    // ADC start
    ADC_Start(ADC0, adcStartSingle);
    unblockSleepMode(EM2);
    blockSleepMode(EM1);
    trfComplete=false;
}
コード例 #8
0
/**************************************************************************//**
 * @brief Flash transfer function
 * This function sets up the DMA transfer
 *****************************************************************************/
void performFlashTransfer(void)
{
  /* Setting call-back function */
  DMA_CB_TypeDef cb[DMA_CHAN_COUNT];
  cb[DMA_CHANNEL_FLASH].cbFunc = flashTransferComplete;

  /* usrPtr can be used to send data to the callback function,
   * but this is not used here, which is indicated by the NULL pointer */
  cb[DMA_CHANNEL_FLASH].userPtr = NULL;

  /* Setting up channel */
  DMA_CfgChannel_TypeDef chnlCfg;
  chnlCfg.highPri   = false;
  chnlCfg.enableInt = true;
  chnlCfg.select    = 0;
  chnlCfg.cb        = &(cb[DMA_CHANNEL_FLASH]);
  DMA_CfgChannel(DMA_CHANNEL_FLASH, &chnlCfg);

  /* Setting up channel descriptor */
  DMA_CfgDescr_TypeDef descrCfg;
  descrCfg.dstInc  = dmaDataInc1;
  descrCfg.srcInc  = dmaDataInc1;
  descrCfg.size    = dmaDataSize1;
  descrCfg.arbRate = dmaArbitrate1;
  descrCfg.hprot   = 0;
  DMA_CfgDescr(DMA_CHANNEL_FLASH, true, &descrCfg);

  /* Setting flag to indicate that transfer is in progress
   * will be cleared by call-back function */
  flashTransferActive = true;

  DMA_ActivateBasic(DMA_CHANNEL_FLASH,
                    true,
                    false,
                    (void *) &ramBuffer,
                    (void *) &flashData,
                    FLASHDATA_SIZE - 1);

  /* Entering EM1 to wait for completion (the DMA requires EM1) */
  while (flashTransferActive)
  {
    EMU_EnterEM1();
  }
}
コード例 #9
0
ファイル: adc_basic.c プロジェクト: AndreMiras/EFM32-Library
/**************************************************************************//**
 * @brief Configure DMA for ADC RAM Transfer
 *****************************************************************************/
void setupDma(void)
{
  DMA_Init_TypeDef        dmaInit;
  DMA_CfgChannel_TypeDef  chnlCfg;
  DMA_CfgDescr_TypeDef    descrCfg;
  
  /* Initializing the DMA */
  dmaInit.hprot        = 0;
  dmaInit.controlBlock = dmaControlBlock;
  DMA_Init(&dmaInit);
    
  /* Setting up call-back function */  
  cb.cbFunc  = transferComplete;
  cb.userPtr = NULL;

  /* Setting up channel */
  chnlCfg.highPri   = false;
  chnlCfg.enableInt = true;
  chnlCfg.select    = DMAREQ_ADC0_SINGLE;
  chnlCfg.cb        = &cb;
  DMA_CfgChannel(DMA_CHANNEL_ADC, &chnlCfg);

  /* Setting up channel descriptor */
  descrCfg.dstInc  = dmaDataInc2;
  descrCfg.srcInc  = dmaDataIncNone;
  descrCfg.size    = dmaDataSize2;
  descrCfg.arbRate = dmaArbitrate1;
  descrCfg.hprot   = 0;
  DMA_CfgDescr(DMA_CHANNEL_ADC, true, &descrCfg);
    
  /* Setting flag to indicate that transfer is in progress
   * will be cleared by call-back function. */
  transferActive = true;
  
  /* Starting transfer. Using Basic since every transfer must be initiated
   * by the ADC. */
  DMA_ActivateBasic(DMA_CHANNEL_ADC,
                    true,
                    false,
                    (void *)ramBufferAdcData,
                    (void *)&(ADC0->SINGLEDATA),
                    ADCSAMPLES - 1);
}
コード例 #10
0
ファイル: i2c_master.c プロジェクト: AndreMiras/EFM32-Library
/*****************************************************************************
 * @brief  Writes bytes to I2C EEPROM using DMA. 
 * 
 * @param deviceAddress 
 *      I2C address of EEPROM
 * 
 * @param offset
 *      The offset (address) to start writing from
 * 
 * @param data
 *      Pointer to the data buffer
 * 
 * @param length
 *      Number of bytes to write
 *****************************************************************************/
void i2cDmaWrite(uint8_t deviceAddress, uint8_t offset, uint8_t *data, uint8_t length)
{ 
  /* Abort if an error has been detected */
  if ( i2cError )
  {
    return;
  }
  
  /* Send address to write to. Note that this is specific to the EEPROM on the 
   * EFM32GG-DK3750 and may need to be changed when using a different device. */
  i2cWriteByte(deviceAddress, offset);  
  
  /* Abort if an error has been detected */
  if ( i2cError )
  {
    return;
  }

  /* Automatically generate a STOP condition when there is no
   * more data to send. The DMA must be fast enough to 
   * keep up (normally not a problem unless the DMA is
   * been prescaled). */
  I2C0->CTRL |= I2C_CTRL_AUTOSE;
   
  /* Set transfer active flag. Cleared by interrupt handler
   * when STOP condition has been sent. */
  transferActive = true;
  
  /* Activate DMA */
  DMA_ActivateBasic(DMA_CHANNEL_I2C_TX,         /* TX DMA channel */
                    true,                       /* Primary descriptor */
                    false,                      /* No burst */
                    (void *)&(I2C0->TXDATA),    /* Write to TXDATA */
                    (void *)data,               /* Read from txBuffer */
                    length - 1 );               /* Number of transfers */
  
}
コード例 #11
0
/*
 *Function name: DMA_CallBack()
 *Description :  Call back function of the DMA
 */
void DMA_CallBack(unsigned int channel, bool primary, void *user)
{
    unblockSleepMode(EM1);
    blockSleepMode(EM2);

	if(!trfComplete)
	{
		ADC_Reset(ADC0);		// Reset the ADC; Turn it off
	    //ADC0->CMD = ADC_CMD_SINGLESTOP;

		int temp = 0, i = 0;
		    char tempChar[7];			//To store the temperature in char, for transmitting
		    char temp_string[TX_bufferSize];

		    (void) channel;
		    (void) primary;
		    (void) user;

		    for (i = 0; i < ADC_SAMPLES; i++)
		    {
		        temp += (ADC_Buffer[i]);
		    }
		    temperature = temp / ADC_SAMPLES;
		    temperature = convertToCelsius(temperature); //Get value of Temperature in deg C


		    if (temperature > HIGHTEMP)
		    {
		        //GPIO_PinOutClear(gpioPortE,2);
		        //GPIO_PinOutSet(gpioPortE,3);
		    	/* To extract the digits of the temperature variable and put in tempChar. A basic digit extraction algorithm is used and then each digit is passed one by one. */
		        temp 		= temperature*10;
				tempChar[0] = (temp/100)+48;
				temp 	    = temp%100;
				tempChar[1] = (temp/10)+48;
				temp 		= temp%10;
				tempChar[2] = '.';
				tempChar[3] = (temp)+48;
				tempChar[4] = 'C';			// Pad the 4th position of charTemp as C
				tempChar[5] = '\r';			// Pad carriage return
				tempChar[6] = '\n';			// Pad line feed

				strcpy(temp_string,HighTemp);					// Copy the HighTemp message in the temporary string
				strcat(temp_string,tempChar);					// Concatenate with the tempChar to get the final message

    			LEUART0->CTRL |= LEUART_CTRL_TXDMAWU;				// Enable DMA wake up for LEUART TX in EM2
    			// Activate DMA transfers for LEUART TX
		        DMA_ActivateBasic(DMA_CHANNEL_TX, true, false, (void *)&(LEUART0->TXDATA), (void *)temp_string, strlen(temp_string) - 1);

		    }
		    else if (temperature < LOWTEMP)
		    {
		        //GPIO_PinOutSet(gpioPortE,2);
		        //GPIO_PinOutClear(gpioPortE,3);

		        temp 		= temperature*10;
				tempChar[0] = (temp/100)+48;
				temp 	    = temp%100;
				tempChar[1] = (temp/10)+48;
				temp 		= temp%10;
				tempChar[2] = '.';
				tempChar[3] = (temp)+48;
				tempChar[4] = 'C';
				tempChar[5] = '\r';
				tempChar[6] = '\n';

				strcpy(temp_string,LowTemp);					// Copy the LowTemp message in the temporary string
				strcat(temp_string,tempChar);					// Concatenate with the tempChar to get the final message

				LEUART0->CTRL |= LEUART_CTRL_TXDMAWU;				// Enable DMA wake up for LEUART TX in EM2
				// Activate DMA transfers for LEUART TX
				DMA_ActivateBasic(DMA_CHANNEL_TX, true, false, (void *)&(LEUART0->TXDATA), (void *)temp_string, strlen(temp_string) -1);

		    }
		   trfComplete=true;
	}

	else
	{
		(void) channel;
		(void) primary;
		(void) user;

		// Disable DMA wake-up from LEUART1 TX
		LEUART0->CTRL &= ~LEUART_CTRL_TXDMAWU;
	}
}
コード例 #12
0
/*
 * Function Name: DMA_setup
 * Description: Setup DMA channels for ADC,TX,RX
 */
void DMA_Setup(void)
{

    DMA_CfgChannel_TypeDef  chnlCfg_adc;
    DMA_CfgDescr_TypeDef    descrCfg_adc;
    DMA_CfgChannel_TypeDef  chnlCfg_rx;
    DMA_CfgDescr_TypeDef    descrCfg_rx;
    DMA_CfgChannel_TypeDef  chnlCfg_tx;
    DMA_CfgDescr_TypeDef    descrCfg_tx;

    /* Setting up call-back function */
    cb.cbFunc  = DMA_CallBack;
    cb.userPtr = NULL;

    /* Setting up ADC channel */
    chnlCfg_adc.highPri   = DMA_PRIORITY_ADC;
    chnlCfg_adc.enableInt = true;
    chnlCfg_adc.select    = DMAREQ_ADC0_SINGLE;
    chnlCfg_adc.cb        = &cb;
    DMA_CfgChannel(DMA_CHANNEL_ADC, &chnlCfg_adc);

    /* Setting up ADC channel descriptor */
    descrCfg_adc.dstInc  = dmaDataInc2;
    descrCfg_adc.srcInc  = dmaDataIncNone;
    descrCfg_adc.size    = dmaDataSize2;
    descrCfg_adc.arbRate = DMA_ARBITRATE_ADC;
    descrCfg_adc.hprot   = 0;
    DMA_CfgDescr(DMA_CHANNEL_ADC, true, &descrCfg_adc);

    /* Starting DMA transfer using Basic since every transfer must be initiated by the ADC. */
       DMA_ActivateBasic(DMA_CHANNEL_ADC, true, false, (void *)ADC_Buffer, (void *)&(ADC0->SINGLEDATA), ADC_SAMPLES - 1);

    /* Setting up Rx channel */
    chnlCfg_rx.highPri   = DMA_PRIORITY_RX;
    chnlCfg_rx.enableInt = true;
    chnlCfg_rx.select    = DMAREQ_LEUART0_RXDATAV;
    chnlCfg_rx.cb        = &cb;
    DMA_CfgChannel(DMA_CHANNEL_RX, &chnlCfg_rx);

    /* Setting up Rx channel descriptor */
    descrCfg_rx.dstInc  = dmaDataInc1;
    descrCfg_rx.srcInc  = dmaDataIncNone;
    descrCfg_rx.size    = dmaDataSize1;
    descrCfg_rx.arbRate = DMA_ARBITRATE_RX;
    descrCfg_rx.hprot   = 0;
    DMA_CfgDescr(DMA_CHANNEL_RX, true, &descrCfg_rx);

    /* Setting up Tx channel */
    chnlCfg_tx.highPri   = DMA_PRIORITY_TX;
    chnlCfg_tx.enableInt = true;
    chnlCfg_tx.select    = DMAREQ_LEUART0_TXBL;
    chnlCfg_tx.cb        = &cb;
    DMA_CfgChannel(DMA_CHANNEL_TX, &chnlCfg_tx);

    /* Setting up Tx channel descriptor */
    descrCfg_tx.dstInc  = dmaDataIncNone;
    descrCfg_tx.srcInc  = dmaDataInc1;
    descrCfg_tx.size    = dmaDataSize1;
    descrCfg_tx.arbRate = DMA_ARBITRATE_TX;
    descrCfg_tx.hprot   = 0;
    DMA_CfgDescr(DMA_CHANNEL_TX, true, &descrCfg_tx);

}
コード例 #13
0
ファイル: accel.c プロジェクト: havardh/bitless
int main(void)
{
  /** Number of samples/channels taken from accelerometer. */
  #define ACCEL_SAMPLES               3

  /** X axis sample index. */
  #define ACCEL_X                     0
  /** Y axis sample index. */
  #define ACCEL_Y                     1
  /** Z axis sample index. */
  #define ACCEL_Z                     2

  /*
   * Tilt levels: Midpoint is theoretically half value of max sampling value
   * (ie 0x800 for 12 bit sampling). In real world, some sort of calibration
   * is required if more accurate sensing is required. We just use set some
   * fixed limit, that should be sufficient for this basic example.
   */

  /** Tilt left limit */
  #define TILT_LEFT                   0x750
  /** Tilt right limit */
  #define TILT_RIGHT                  0x8b0

  SYSTEM_ChipRevision_TypeDef chipRev;
  uint32_t leds;
  uint32_t samples[ACCEL_SAMPLES];
  int errataShift = 0;
  int i;

  /* Chip revision alignment and errata fixes */
  CHIP_Init();

  /* ADC errata for rev B when using VDD as reference, need to multiply */
  /* result by 2 */
  SYSTEM_ChipRevisionGet(&chipRev);
  if ((chipRev.major == 1) && (chipRev.minor == 1))
  {
    errataShift = 1;
  }

  /* Initialize DK board register access */
  BSP_Init(BSP_INIT_DEFAULT);

  /* If first word of user data page is non-zero, enable eA Profiler trace */
  BSP_TraceProfilerSetup();

  /* Connect accelerometer to EFM32. */
  BSP_PeripheralAccess(BSP_ACCEL, true);

  /* Enable clocks required */
  CMU_ClockEnable(cmuClock_HFPER, true);
  CMU_ClockEnable(cmuClock_ADC0, true);
  CMU_ClockEnable(cmuClock_DMA, true);

  /* Configure ADC and DMA used for scanning accelerometer */
  accelADCConfig();
  accelDMAConfig();

  /* Main loop, keep polling accelerometer */
  leds = 0x0180;
  while (1)
  {
    DMA_ActivateBasic(ACCEL_DMA_CHANNEL,
                      true,
                      false,
                      samples,
                      (void *)((uint32_t)&(ADC0->SCANDATA)),
                      ACCEL_SAMPLES - 1);

    /* Scan all axis', even though this app only use the X axis */
    ADC_IntClear(ADC0, ADC_IF_SCAN);
    ADC_Start(ADC0, adcStartScan);

    /* Poll for completion, entering EM2 when waiting for next poll */
    while (!(ADC_IntGet(ADC0) & ADC_IF_SCAN))
    {
      RTCDRV_Trigger(5, NULL);
      EMU_EnterEM2(true);
    }

    if (errataShift)
    {
      for (i = 0; i < ACCEL_SAMPLES; i++)
      {
        samples[i] <<= errataShift;
      }
    }

    if (samples[ACCEL_X] < TILT_LEFT)
    {
      if (leds < 0xc000)
      {
        leds <<= 1;
      }
    }
    else if (samples[ACCEL_X] > TILT_RIGHT)
    {
      if (leds > 0x0003)
      {
        leds >>= 1;
      }
    }
    else
    {
      if (leds > 0x0180)
コード例 #14
0
ファイル: dmadrv.c プロジェクト: PW-Sat2/PWSat2OBC
/***************************************************************************//**
 * @brief
 *  Start a UDMA transfer.
 ******************************************************************************/
static Ecode_t StartTransfer( DmaMode_t             mode,
                              DmaDirection_t        direction,
                              unsigned int          channelId,
                              DMADRV_PeripheralSignal_t
                                                    peripheralSignal,
                              void                  *buf0,
                              void                  *buf1,
                              void                  *buf2,
                              bool                  bufInc,
                              int                   len,
                              DMADRV_DataSize_t     size,
                              DMADRV_Callback_t     callback,
                              void                  *cbUserParam )
{
  ChTable_t *ch;
  DMA_CfgChannel_TypeDef chCfg;
  DMA_CfgDescr_TypeDef   descrCfg;

  if ( !initialized )
  {
    return ECODE_EMDRV_DMADRV_NOT_INITIALIZED;
  }

  if ( ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
       || ( buf0 == NULL )
       || ( buf1 == NULL )
       || ( len > DMADRV_MAX_XFER_COUNT )
       || ( ( mode == dmaModePingPong ) && ( buf2 == NULL ) ) )
  {
    return ECODE_EMDRV_DMADRV_PARAM_ERROR;
  }

  ch = &chTable[ channelId ];
  if ( ch->allocated == false )
  {
    return ECODE_EMDRV_DMADRV_CH_NOT_ALLOCATED;
  }

  /* Setup the interrupt callback routine. */
  if ( mode == dmaModeBasic )
  {
    dmaCallBack[ channelId ].cbFunc  = DmaBasicCallback;
  }
  else
  {
    dmaCallBack[ channelId ].cbFunc  = DmaPingPongCallback;
  }
  dmaCallBack[ channelId ].userPtr = NULL;

  /* Setup the channel */
  chCfg.highPri = false;              /* Can't use hi pri with peripherals. */

  /* Interrupt needed ? */
  if ( ( callback != NULL ) || ( mode == dmaModePingPong ) )
  {
    chCfg.enableInt = true;
  }
  else
  {
    chCfg.enableInt = false;
  }
  chCfg.select = peripheralSignal;
  chCfg.cb     = &dmaCallBack[ channelId ];
  DMA_CfgChannel( channelId, &chCfg );

  /* Setup channel descriptor. */
  if ( direction == dmaDirectionMemToPeripheral )
  {
    if ( bufInc )
    {
      if ( size == dmadrvDataSize1 )
      {
        descrCfg.srcInc = dmaDataInc1;
      }
      else if ( size == dmadrvDataSize2 )
      {
        descrCfg.srcInc = dmaDataInc2;
      }
      else /* dmadrvDataSize4 */
      {
        descrCfg.srcInc = dmaDataInc4;
      }
    }
    else
    {
      descrCfg.srcInc = dmaDataIncNone;
    }
    descrCfg.dstInc = dmaDataIncNone;
  }
  else
  {
    if ( bufInc )
    {
      if ( size == dmadrvDataSize1 )
      {
        descrCfg.dstInc = dmaDataInc1;
      }
      else if ( size == dmadrvDataSize2 )
      {
        descrCfg.dstInc = dmaDataInc2;
      }
      else /* dmadrvDataSize4 */
      {
        descrCfg.dstInc = dmaDataInc4;
      }
    }
    else
    {
      descrCfg.dstInc = dmaDataIncNone;
    }
    descrCfg.srcInc = dmaDataIncNone;
  }
  descrCfg.size    = (DMA_DataSize_TypeDef)size;
  descrCfg.arbRate = dmaArbitrate1;
  descrCfg.hprot   = 0;
  DMA_CfgDescr( channelId, true, &descrCfg );
  if ( mode == dmaModePingPong )
  {
    DMA_CfgDescr( channelId, false, &descrCfg );
  }

  ch->callback      = callback;
  ch->userParam     = cbUserParam;
  ch->callbackCount = 0;
  ch->length        = len;

  DMA->IFC = 1 << channelId;

  /* Start DMA cycle. */
  if ( mode == dmaModeBasic )
  {
    DMA_ActivateBasic( channelId, true, false, buf0, buf1, len - 1 );
  }
  else
  {
    if ( direction == dmaDirectionMemToPeripheral )
    {
      DMA_ActivatePingPong( channelId,
                            false,
                            buf0,                             /* dest */
                            buf1,                             /* src  */
                            len - 1,
                            buf0,                             /* dest */
                            buf2,                             /* src  */
                            len - 1);
    }
    else
    {
      DMA_ActivatePingPong( channelId,
                            false,
                            buf0,                             /* dest */
                            buf2,                             /* src  */
                            len - 1,
                            buf1,                             /* dest */
                            buf2,                             /* src  */
                            len - 1);
    }
  }

  return ECODE_EMDRV_DMADRV_OK;
}
コード例 #15
0
ファイル: drv_usart.c プロジェクト: hduffddybz/rt-thread
/***************************************************************************//**
 * @brief
 *   Write to USART device
 *
 * @details
 *
 * @note
 *
 * @param[in] dev
 *   Pointer to device descriptor
 *
 * @param[in] pos
 *   Offset
 *
 * @param[in] buffer
 *   Poniter to the buffer
 *
 * @param[in] size
 *   Buffer size in byte
 *
 * @return
 *   Number of written bytes
 ******************************************************************************/
static rt_size_t rt_usart_write (
    rt_device_t     dev,
    rt_off_t        pos,
    const void*     buffer,
    rt_size_t       size)
{
    rt_err_t err_code;
    struct efm32_usart_device_t* usart = (struct efm32_usart_device_t*)(dev->user_data);
    rt_size_t   read_len, len;
    rt_uint8_t  *ptr;
    rt_size_t   write_size = 0;
    rt_uint32_t tx_flag, b8_flag;

#if defined(UART_PRESENT)
    if (usart->state & USART_STATE_ASYNC_ONLY)
    {
        tx_flag = UART_STATUS_TXBL;
        b8_flag = UART_CTRL_BIT8DV;
    }
    else
#endif
    {
        tx_flag = USART_STATUS_TXBL;
        b8_flag = USART_CTRL_BIT8DV;
    }

    /* Lock device */
    if (rt_hw_interrupt_check())
    {
        err_code = rt_sem_take(usart->lock, RT_WAITING_NO);
    }
    else
    {
        err_code = rt_sem_take(usart->lock, RT_WAITING_FOREVER);
    }
    if (err_code != RT_EOK)
    {
        rt_set_errno(err_code);
        return 0;
    }

    if (usart->state & USART_STATE_SYNC)
    {   /* SPI write */
        rt_uint8_t inst_len     = *((rt_uint8_t *)buffer);
        rt_uint8_t *inst_ptr    = (rt_uint8_t *)(buffer + 1);
        rt_uint8_t *tx_buf      = *((rt_uint8_t **)(buffer + inst_len + 1));

        ptr = inst_ptr;
        len = inst_len;
        /* Write instructions */
        if (len)
        {
            if (usart->state & USART_STATE_9BIT)
            {
                usart->usart_device->CTRL &= ~b8_flag;
            }
            if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (len > 2))
            {   /* DMA mode Tx */
                struct efm32_usart_dma_mode_t *dma_tx;

                usart_debug("USART: DMA TX INS (%d)\n", len);
                dma_tx = (struct efm32_usart_dma_mode_t *)(usart->tx_mode);
                dma_tx->data_ptr = (rt_uint32_t *)ptr;
                dma_tx->data_size = len;

                usart->state |= USART_STATE_TX_BUSY;
                DMA_ActivateBasic(
                    dma_tx->dma_channel,
                    true,
                    false,
                    (void *)&(usart->usart_device->TXDATA),
                    (void *)ptr,
                    (rt_uint32_t)(len - 1));
                /* Wait, otherwise the TX buffer is overwrite */
                // TODO: This function blocks the process => goto low power mode?
                //      if (usart->state & USART_STATE_CONSOLE)
                //      {
                while(usart->state & USART_STATE_TX_BUSY);
                //      }
                //      else
                //      {
                //          while(usart->state & USART_STATE_TX_BUSY)
                //          {
                //              rt_thread_sleep(USART_WAIT_TIME_TX);
                //          }
                //      }
            }
            else
            {   /* polling mode */
                usart_debug("USART: Polling TX INS (%d)\n", len);
                while (len)
                {
                    while (!(usart->usart_device->STATUS & tx_flag));
                    usart->usart_device->TXDATA = (rt_uint32_t)*(ptr++);
                    len--;
                }
            }
            if (usart->state & USART_STATE_9BIT)
            {
                usart->usart_device->CTRL |= b8_flag;
            }
        }

        ptr = tx_buf;
    }
    else
    {
        ptr = (rt_uint8_t *)buffer;
    }

    len = size;
    /* Write data */
    if (dev->flag & RT_DEVICE_FLAG_STREAM)
    {
        if (*(ptr + len - 1) == '\n')
        {
            *(ptr + len - 1) = '\r';
            *(ptr + len++) = '\n';
            *(ptr + len) = 0;
        }
    }
    if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (len > 2))
    {   /* DMA mode Tx */
        struct efm32_usart_dma_mode_t *dma_tx;

        usart_debug("USART: DMA TX data (%d)\n", len);
        dma_tx = (struct efm32_usart_dma_mode_t *)(usart->tx_mode);
        dma_tx->data_ptr = (rt_uint32_t *)ptr;
        dma_tx->data_size = len;

        usart->state |= USART_STATE_TX_BUSY;
        DMA_ActivateBasic(
            dma_tx->dma_channel,
            true,
            false,
            (void *)&(usart->usart_device->TXDATA),
            (void *)ptr,
            (rt_uint32_t)(len - 1));

        /* Wait, otherwise the TX buffer is overwrite */
        // TODO: This function blocks the process => goto low power mode?
//      if (usart->state & USART_STATE_CONSOLE)
//      {
        while(usart->state & USART_STATE_TX_BUSY);
//      }
//      else
//      {
//          while(usart->state & USART_STATE_TX_BUSY)
//          {
//              rt_thread_sleep(USART_WAIT_TIME_TX);
//          }
//      }
        write_size = size;
    }
    else
    {   /* polling mode */
        usart_debug("USART: Polling TX data (%d)\n", len);
        while (len)
        {
            while (!(usart->usart_device->STATUS & tx_flag));
            usart->usart_device->TXDATA = (rt_uint32_t)*(ptr++);
            len--;
        }

        write_size = size - len;
    }

    /* Unlock device */
    rt_sem_release(usart->lock);

    /* set error code */
    rt_set_errno(err_code);

    return write_size;
}