/**************************************************************************//** * @brief get average distance from noSamples measurements * @return distance *****************************************************************************/ uint16_t getAvgDistance( uint8_t noSamples ) { uint32_t dist; // used for return value uint8_t i; // internal counter uint8_t destPos = 0; for( i = 0; i < DIST_BUF_SIZE; i++) // clear the buffer { Dist_buf[destPos] = 0; } if(noSamples > DIST_BUF_SIZE) noSamples = DIST_BUF_SIZE; // ButtonsDisable(); // disable user buttons RTC_tick = false; while( !RTC_tick ) // wait for tick { EMU_EnterEM1(); } #define MAX_DIST_READINGS 2*DIST_BUF_SIZE // max number of trials for( i = 0; destPos < noSamples && i < 2*noSamples; i++ ) { RTC_tick = false; TX_Start_Burst(); RX_Measure(); if ( out_of_range ) { // do nothing } else { Dist_buf[destPos] = MaxCount; // store uncalibrated distance into buffer destPos++; } while( !RTC_tick ) // wait for tick { EMU_EnterEM1(); } } // caluclations dist = c_air / 10; dist *= average_Dist_buf(destPos); dist /= 32000; dist += offset_val; // ButtonsEnable(); // enable user buttons return (uint16_t)dist; } // getDistance()
/****************************************************************************** * @brief * Main function *****************************************************************************/ int main(void) { /* Initialize chip - handle erratas */ CHIP_Init(); /* Setup RTC for periodic wake-ups */ startRTCTick(); /* Start LFXO. Do not wait until it is stable */ CMU_OscillatorEnable(cmuOsc_LFXO, true, false); /* Wait in EM2 until LFXO is ready */ while (!(CMU->STATUS & CMU_STATUS_LFXORDY)) { EMU_EnterEM2(false); } /* Stop the RTC */ stopRTCTick(); while (1) { /* Go to sleep */ EMU_EnterEM1(); } }
void hw_enter_lowpower_mode(uint8_t mode) { switch(mode) { case 0: { EMU_EnterEM1(); break; } case 1: { EMU_EnterEM2(true); break; } case 2: { EMU_EnterEM3(true); break; } case 4: { EMU_EnterEM4(); break; } default: { assert(0); } } }
/**************************************************************************//** * @brief Sleep in EM1 until SPI transfers are done *****************************************************************************/ void sleepUntilTransferDone(void) { /* Enter EM1 while DMA transfer is active to save power. Note that * interrupts are disabled to prevent the ISR from being triggered * after checking the transferActive flag, but before entering * sleep. If this were to happen, there would be no interrupt to wake * the core again and the MCU would be stuck in EM1. While the * core is in sleep, pending interrupts will still wake up the * core and the ISR will be triggered after interrupts are enabled * again. */ bool isActive = false; while(1) { INT_Disable(); isActive = spiIsActive(); if ( isActive ) { EMU_EnterEM1(); } INT_Enable(); /* Exit the loop if transfer has completed */ if ( !isActive ) { break; } } }
enum lpm_mode lpm_arch_set(enum lpm_mode target) { switch (target) { case LPM_ON: /* nothing to do */ break; case LPM_IDLE: /* wait for next event or interrupt */ EMU_EnterEM1(); break; case LPM_SLEEP: /* after exiting EM2, clocks are restored */ EMU_EnterEM2(true); break; case LPM_POWERDOWN: /* after exiting EM3, clocks are restored */ EMU_EnterEM3(true); break; case LPM_OFF: /* only a reset can wake up from EM4 */ EMU_EnterEM4(); break; /* do nothing here */ case LPM_UNKNOWN: default: break; } /* no matter which case was selected, instructions executed in EM0 only */ return LPM_ON; }
/**************************************************************************//** * @brief Main function * Main is called from __iar_program_start, see assembly startup file *****************************************************************************/ int main(void) { /* Align different chip revisions */ CHIP_Init(); /* Enable clock for PRS */ CMU_ClockEnable(cmuClock_PRS, true); /* Initialize DAC */ DAC_setup(); /* Calculate output to 0.5 V. */ uint32_t dacValue; dacValue = (uint32_t)((0.5 * 4096) / 3.3); /* Write the new value to DAC register This value will not be output immediately, only when the PRS pulse is generated by software */ DAC_WriteData(DAC0, dacValue, 0); /* Generate PRS pulse on channel 5 by writing 1 to bit 5 (0x20) in PRS_SWPULSE register This will trigger the DAC conversion and 0.5V can be probed on PB11 */ PRS_PulseTrigger(0x20); while(1) { /* Enter EM1 */ EMU_EnterEM1(); } }
void dmaStartFrameTransfer(int firstLine, int lastLine) { /* Wait until previous transfer is done */ while (DMA->CHENS & DMA_CHENS_CH0ENS) { EMU_EnterEM1(); } /* 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 */ }
/****************************************************************************** * @brief Main function * The main file starts a timer and uses PRS to trigger an ADC conversion. * It waits in EM1 until the ADC conversion is complete, then prints the * result on the lcd. *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); SegmentLCD_Init(false); /* Enable clocks required */ CMU_ClockEnable(cmuClock_ADC0, true); CMU_ClockEnable(cmuClock_PRS, true); CMU_ClockEnable(cmuClock_TIMER0, true); /* Select TIMER0 as source and TIMER0OF (Timer0 overflow) as signal (rising edge) */ PRS_SourceSignalSet(0, PRS_CH_CTRL_SOURCESEL_TIMER0, PRS_CH_CTRL_SIGSEL_TIMER0OF, prsEdgePos); ADCConfig(); TimerConfig(); /* Stay in this loop forever */ while (1) { /* Enter EM1 and wait for timer triggered adc conversion */ EMU_EnterEM1(); /* Write result to LCD */ SegmentLCD_Number(adcResult); /* Do other stuff */ int i; for (i = 0; i < 10000; i++) ; } }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { /* Chip revision alignment and errata fixes */ CHIP_Init(); /* Set system frequency to 1 MHz */ CMU_HFRCOBandSet(cmuHFRCOBand_1MHz); /* Initialize LCD */ SegmentLCD_Init(false); /* Initialize TIMER0 */ initTimer(); /* Enable Sleep-om-Exit */ SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; /* Initialize interrupt count */ interruptCount = 0; /* Enter EM1 until all TIMER0 interrupts are done * Notice that we only enter sleep once, as the MCU will fall asleep * immediately when the ISR is done without returning to main as long as * SLEEPONEXIT is set */ EMU_EnterEM1(); /* Signal that program is done */ SegmentLCD_Write("DONE"); while(1); }
/***************************************************************************** * @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 */ }
/**************************************************************************//** * @brief Sleeps in EM1 in given time unless some other IRQ sources has been * enabled * @param msec Time in milliseconds *****************************************************************************/ void EM1Sleep(uint32_t msec) { /* Wake us up after msec (or joystick pressed) */ NVIC_DisableIRQ(LCD_IRQn); /* Tell AEM we're in EM1 */ RTCDRV_Trigger(msec, RtcTrigger); EMU_EnterEM1(); NVIC_EnableIRQ(LCD_IRQn); }
void os_idle_demon (void) { /* The idle demon is a system thread, running when no other thread is */ /* ready to run. */ for (;;) { /* HERE: include optional user code to be executed when no thread runs.*/ /* Enter EM1. This is always safe to do, independently of which peripherals are active. */ EMU_EnterEM1(); } }
/****************************************************************************** * @brief Main function * *****************************************************************************/ int main(void) { /* Initialize chip - handle erratas */ CHIP_Init( ); /* Initialize clocks and oscillators */ cmuSetup( ); /* Initialize UART peripheral */ uartSetup( ); /* Initialize Development Kit in EBI mode */ BSP_Init(BSP_INIT_DEFAULT); /* Enable RS-232 transceiver on Development Kit */ BSP_PeripheralAccess(BSP_RS232_UART, true); /* When DVK is configured, and no more DVK access is needed, the interface can safely be disabled to save current */ BSP_Disable(); /* Write welcome message to UART */ uartPutData((uint8_t*) welcomeString, welLen); /* Eternal while loop * CPU will sleep during Rx and Tx. When a byte is transmitted, an interrupt * wakes the CPU which copies the next byte in the txBuf queue to the * UART TXDATA register. * * When the predefined termiation character is received, the all pending * data in rxBuf is copied to txBuf and echoed back on the UART */ while (1) { /* Wait in EM1 while UART transmits */ EMU_EnterEM1(); /* Check if RX buffer has overflowed */ if (rxBuf.overflow) { rxBuf.overflow = false; uartPutData((uint8_t*) overflowString, ofsLen); } /* Check if termination character is received */ if (rxBuf.data[(rxBuf.wrI - 1) % BUFFERSIZE] == TERMINATION_CHAR) { /* Copy received data to UART transmit queue */ uint8_t tmpBuf[BUFFERSIZE]; int len = uartGetData(tmpBuf, 0); uartPutData(tmpBuf, len); } } }
/***************************************************************************//** * @brief * SPI transfer function * * @details * Performs one SPI transaction. Fundamentally SPI does a write and read of the * same length (byte count) at the same time. Often only a few bytes are to be * written, and the data returned while those bytes are written is to be * discarded. This can be done using the "half_duplex" flag. The data to be * written may optionally be split into two separate buffers in order to handle * discontiguous data. Set tx_len or tx_len2 to 0 if the corresponding buffer * is not used. Will block if NULL passed for completion function; otherwise * will call completion function passing ref argument. Note that completion * function may be called either before or after the function returns. * * @param[in] tx_len * Number of bytes to transfer from tx buffer * @param[in] *tx_data * Pointer to data to be transferred/TX'd * @param[in] tx2_len * Number of bytes to transfer from tx2 buffer * @param[in] *tx2_data * Pointer to data to be transferred from tx2 buffer. * @param[in] hold_cs_active * TRUE/FALSE, Determines whether to hold CS active * @param[in] *completion * Completion state machine callback function * @param[in] *completion_ref * Argument to be passed to completion callback * ******************************************************************************/ void spi_xfer(size_t tx_len, const uint8_t *tx_data, size_t tx2_len, const uint8_t *tx2_data, bool half_duplex, size_t rx_len, uint8_t *rx_data, bool hold_cs_active, spi_completion_fn_t *completion, void *completion_ref) { spi_rx_len = rx_len; spi_rx_data = rx_data; spi_tx_len = tx_len; spi_tx_data = tx_data; spi_tx2_len = tx2_len; spi_tx2_data = tx2_data; spi_tx_post_padding_len = 0; spi_rx_pre_padding_len = 0; spi_rx_post_padding_len = 0; spi_hold_cs_active = hold_cs_active; if (half_duplex) { spi_rx_pre_padding_len = tx_len + tx2_len; spi_tx_post_padding_len = spi_rx_len; } else if ((tx_len + tx2_len) < rx_len) spi_tx_post_padding_len = rx_len - (tx_len + tx2_len); else spi_rx_post_padding_len = (tx_len + tx2_len) - rx_len; //printf("tx: %d, tx2: %d, tx_post: %d\r\n", tx_len, tx2_len, spi_tx_post_padding_len); //printf("rx_pre: %d, rx: %d, rx_post: %d\r\n", spi_rx_pre_padding_len, rx_len, spi_rx_post_padding_len); spi_completion = completion; spi_completion_ref = completion_ref; spi_busy = true; GPIO_PinOutClear(CS_PORT, CS_PIN); // assert CS // enable interrupts to start transfer SPI_PORT->IEN |= (USART_IEN_TXBL | USART_IEN_RXDATAV); if (! completion) while (spi_busy) EMU_EnterEM1(); }
/**************************************************************************//** * @brief Sleeps in EM2 in given time * @param msec Time in milliseconds *****************************************************************************/ void EM2Sleep(uint32_t msec) { /* Wake us up after msec */ NVIC_DisableIRQ(LCD_IRQn); rtcFlag = true; RTCDRV_Trigger(msec, RTC_TimeOutHandler); /* The rtcFlag variable is set in the RTC interrupt routine using the callback * RTC_TimeOutHandler. This makes sure that the elapsed time is correct. */ while (rtcFlag) { EMU_EnterEM1(); } NVIC_EnableIRQ(LCD_IRQn); }
ERROR_CODE Statemachine::startApplication( STATUS_BLOCK *statusBlock ) { callingStatusBlock = currentStatusBlock; currentStatusBlock = statusBlock; if(!setupDone) return FSM_NotInitialized; // Run the FSM until the execution is stopped by the Application-Code. // The State-Function is called within the WHILE-STATEMENT !!!! while( ( *(stateDefinition)[statusBlock->nextState] )() ) { // Is the State-Function, which is selected for execution in the next step a valid one? if( currentStatusBlock->nextState < maxNumberOfStates ) { // Does the MCU have to enter a sleep-mode? if( currentStatusBlock->wantToSleep ) { // Which sleep-mode has to be entered? switch( currentStatusBlock->sleepMode ) { case 0: break; case 1: EMU_EnterEM1(); break; case 2: EMU_EnterEM2( currentStatusBlock->restoreClockSetting ); break; case 3: EMU_EnterEM3( currentStatusBlock->restoreClockSetting ); break; case 4: EMU_EnterEM4(); default: return EM_invalid; // Invalid sleep-mode!!! } } } else return StateID_Invalid; // Invalid State-Function number!!! } currentStatusBlock = callingStatusBlock; return FSM_finalized; // FSM-execution successfully finalized!!! }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); setupSWO(); BSP_LedsInit(); /* Enable clock for GPIO module */ CMU_ClockEnable(cmuClock_GPIO, true); /* Configure interrupt for Push Button 0 */ GPIO_PinModeSet(PB0_PORT, PB0_PIN, gpioModeInput, 1); #if defined(_EFM32_GIANT_FAMILY) NVIC_EnableIRQ(GPIO_ODD_IRQn); #else NVIC_EnableIRQ(GPIO_EVEN_IRQn); #endif GPIO_IntConfig(PB0_PORT, PB0_PIN, false, true, true); /* By turning on retention in EM4, the state of the GPIO pins * can be retained in all energy modes */ GPIO->CTRL = GPIO_CTRL_EM4RET; /* Uncomment to drive LED in all energy modes */ /* BSP_LedSet(0);*/ while (1) { switch (STATE) { case EM0: break; case EM1: EMU_EnterEM1(); break; case EM2: EMU_EnterEM2(true); break; case EM3: EMU_EnterEM3(true); case EM4: EMU_EnterEM4(); break; } } }
/**************************************************************************//** * @brief Main function * Main is called from __iar_program_start, see assembly startup file *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); /* Configuring clocks in the Clock Management Unit (CMU) */ setupCmu(); /* Configure DMA scatter-gather transfer */ configureDmaTransfer(); /* Starting the scatter-gather DMA operation */ DMA_ActivateScatterGather(DMA_CHANNEL_SCATTERGATHER, false, &dmaScatterCfgBlock[0], SCATTER_GATHER_TRANSFERS); /* Enter EM1 while DMA transfer is active to save power. Note that * interrupts are disabled to prevent the ISR from being triggered * after checking the transferActive flag, but before entering * sleep. If this were to happen, there would be no interrupt to wake * the core again and the MCU would be stuck in EM1. While the * core is in sleep, pending interrupts will still wake up the * core and the ISR will be triggered after interrupts are enabled * again. */ while(1) { INT_Disable(); if ( transferActive ) { EMU_EnterEM1(); } INT_Enable(); /* Exit the loop if transfer has completed */ if ( !transferActive ) { break; } } /* Cleaning up after DMA transfers */ DMA_Reset(); /* Done */ while (1); }
int main(void) { /* Chip errata */ CHIP_Init(); /* Enable HFXO */ CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO); /* Enable deboug output over UART */ RETARGET_SerialInit(); RETARGET_SerialCrLf(1); /* Enable the segment LCD */ SegmentLCD_Init(false); SegmentLCD_Write("USB"); printf("\nStarting USB Device...\n"); /* Set up GPIO interrupts */ gpioInit(); /* Start USB stack. Callback routines in callbacks.c will be called * when connected to a host. */ USBD_Init(&initstruct);; /* * When using a debugger it is pratical to uncomment the following three * lines to force host to re-enumerate the device. */ /* USBD_Disconnect(); */ /* USBTIMER_DelayMs( 1000 ); */ /* USBD_Connect(); */ while(1) { if ( USBD_SafeToEnterEM2() ) { /* Enter EM2 when in suspend or disconnected */ EMU_EnterEM2(true); } else { /* When USB is active we can sleep in EM1. */ EMU_EnterEM1(); } } }
/**************************************************************************//** * @brief Main function * Main is called from __iar_program_start, see assembly startup file *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); /* Enable clock for GPIO module */ CMU_ClockEnable(cmuClock_GPIO, true); /* Enable clock for ADC0 module */ CMU_ClockEnable(cmuClock_ADC0, true); /* Enable clock for PRS module */ CMU_ClockEnable(cmuClock_PRS, true); /* Configure PD8 as an input for PB0 button with filter enable (out = 1)*/ GPIO_PinModeSet(gpioPortD, 8, gpioModeInput, 1); /* Select PD8 as PRS output */ GPIO->EXTIPSELH = (GPIO->EXTIPSELH & !_GPIO_EXTIPSELH_EXTIPSEL8_MASK ) | GPIO_EXTIPSELH_EXTIPSEL8_PORTD; /* Enable PRS sense */ GPIO->INSENSE = GPIO->INSENSE | GPIO_INSENSE_PRS; /* Select GPIO as source and GPIOPIN8 as signal (falling edge) */ PRS_SourceSignalSet(0, PRS_CH_CTRL_SOURCESEL_GPIOH, PRS_CH_CTRL_SIGSEL_GPIOPIN8, prsEdgeNeg); /* Initialize ADC common parts for both single conversion and scan sequence */ ADC_Init(ADC0, &ADCInit); /* Initialize ADC single sample conversion */ ADC_InitSingle(ADC0, &ADCInitSingle); /* Enable ADC Interrupt when Single Conversion Complete */ ADC0->IEN = ADC_IEN_SINGLE; /* Enable ADC interrupt vector in NVIC*/ NVIC_EnableIRQ(ADC0_IRQn); while(1) { /* Enter EM1 */ EMU_EnterEM1(); /* After ADC Single conversion wake up -> Delay 1000mS */ Delay(1000); } }
/***************************************************************************//** * @brief * Call the callbacks and enter the requested energy mode. * * @details * This function is not part of the API, therefore it shall not be called by * the user directly as it doesn not have any checks if the system is ready * for sleep! * * @note * The EM4 wakeup callback is not being called from this function because * waking up from EM4 causes a reset. * If SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to true, SLEEP_Init() function * checks for the cause of the reset and calls the wakeup callback if the * reset was a wakeup from EM4. ******************************************************************************/ static void SLEEP_EnterEMx(SLEEP_EnergyMode_t eMode) { EFM_ASSERT((eMode > sleepEM0) && (eMode <= sleepEM4)); /* Call sleepCallback() before going to sleep. */ if (NULL != sleepCallback) { /* Call the callback before going to sleep. */ sleepCallback(eMode); } /* Enter the requested energy mode. */ switch (eMode) { case sleepEM1: { EMU_EnterEM1(); } break; case sleepEM2: { EMU_EnterEM2(true); } break; case sleepEM3: { EMU_EnterEM3(true); } break; case sleepEM4: { EMU_EnterEM4(); } break; default: { /* Don't do anything, stay in EM0. */ } break; } /* Call the callback after waking up from sleep. */ if (NULL != wakeUpCallback) { wakeUpCallback(eMode); } }
/** * Sleep mode. * Enter the lowest possible sleep mode that is not blocked by ongoing activity. */ void sleep(void) { if (sleep_block_counter[0] > 0) { /* Blocked everything below EM0, so just return */ return; } else if (sleep_block_counter[1] > 0) { /* Blocked everything below EM1, enter EM1 */ EMU_EnterEM1(); } else if (sleep_block_counter[2] > 0) { /* Blocked everything below EM2, enter EM2 */ EMU_EnterEM2(true); } else { /* Blocked everything below EM3, enter EM3 */ EMU_EnterEM3(true); } /* Never enter EM4, as mbed has no way of configuring EM4 wakeup */ return; }
/**************************************************************************//** * @brief Main function * This exmaple sets up the TIMER to trigger the ADC through PRS at a set * interval. The ADC then sets a DMA request and the DMA fetches each sample * until the a set number of samples have been received. *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); /* Configuring clocks in the Clock Management Unit (CMU) */ setupCmu(); /* Configure DMA transfer from ADC to RAM */ setupDma(); /* Configure ADC Sampling and TIMER trigger through PRS. Start TIMER as well */ setupAdc(); /* Enter EM1 while DMA transfer is active to save power. Note that * interrupts are disabled to prevent the ISR from being triggered * after checking the transferActive flag, but before entering * sleep. If this were to happen, there would be no interrupt to wake * the core again and the MCU would be stuck in EM1. While the * core is in sleep, pending interrupts will still wake up the * core and the ISR will be triggered after interrupts are enabled * again. */ while(1) { INT_Disable(); if ( transferActive ) { EMU_EnterEM1(); } INT_Enable(); /* Exit the loop if transfer has completed */ if ( !transferActive ) { break; } } /* Cleaning up after DMA transfers */ DMA_Reset(); /* Done */ while (1); }
/**************************************************************************//** * @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(); } }
/**************************************************************************//** * @brief Enter a Energy Mode for a given number of seconds. * * @param[in] mode Energy Mode to enter (0..3). * @param[in] secs Time to stay in Energy Mode <mode>. *****************************************************************************/ static void EnterEMode( int mode, uint32_t secs ) { if ( secs ) { uint32_t startTime = seconds; if ( mode == 0 ) { int cnt = 0; while ((seconds - startTime) < secs) { if ( cnt == 0 ) printf( "\r - - EM0 - -" ); else if ( cnt == 1 ) printf( "\r \\ \\ EM0 / /" ); else if ( cnt == 2 ) printf( "\r | | EM0 | |" ); else if ( cnt == 3 ) printf( "\r / / EM0 \\ \\" ); cnt = (cnt + 1) % 4; if ( enterEM4 ) { printf( "\r EM0 " ); return; } } printf( "\r EM0 " ); } else { while ((seconds - startTime) < secs) { switch ( mode ) { case 1: EMU_EnterEM1(); break; case 2: EMU_EnterEM2( true ); break; case 3: EMU_EnterEM3( true ); break; } if ( enterEM4 ) { return; } } } } }
/**************************************************************************//** * @brief main - the entrypoint after reset. *****************************************************************************/ int main( void ) { #if !defined(BUSPOWERED) BSP_Init(BSP_INIT_DEFAULT); /* Initialize DK board register access */ /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); #endif CMU_ClockSelectSet( cmuClock_HF, cmuSelect_HFXO ); CMU_OscillatorEnable(cmuOsc_LFXO, true, false); #if !defined(BUSPOWERED) RETARGET_SerialInit(); /* Initialize DK UART port */ RETARGET_SerialCrLf( 1 ); /* Map LF to CRLF */ printf( "\nEFM32 Mass Storage Device example\n" ); #endif if ( !MSDDMEDIA_Init() ) { #if !defined(BUSPOWERED) printf( "\nMedia error !\n" ); #endif EFM_ASSERT( false ); for( ;; ){} } MSDD_Init(gpioPortE, 1); for (;;) { if ( MSDD_Handler() ) { /* There is no pending activity in the MSDD handler. */ /* Enter sleep mode to conserve energy. */ if ( USBD_SafeToEnterEM2() ) EMU_EnterEM2(true); else EMU_EnterEM1(); } } }
/**************************************************************************//** * @brief This function iterates through all the capsensors and reads and * initiates a reading. Uses EM1 while waiting for the result from * each sensor. *****************************************************************************/ void CAPSENSE_Sense(void) { /* Use the default STK capacative sensing setup and enable it */ ACMP_Enable(ACMP_CAPSENSE); uint8_t ch; /* Iterate trough all channels */ for (currentChannel = 0; currentChannel < ACMP_CHANNELS; currentChannel++) { /* If this channel is not in use, skip to the next one */ if (!channelsInUse[currentChannel]) { continue; } /* Set up this channel in the ACMP. */ ch = currentChannel; ACMP_CapsenseChannelSet(ACMP_CAPSENSE, (ACMP_Channel_TypeDef) ch); /* Reset timers */ TIMER0->CNT = 0; TIMER1->CNT = 0; measurementComplete = false; /* Start timers */ TIMER0->CMD = TIMER_CMD_START; TIMER1->CMD = TIMER_CMD_START; /* Wait for measurement to complete */ while ( measurementComplete == false ) { EMU_EnterEM1(); } } /* Disable ACMP while not sensing to reduce power consumption */ ACMP_Disable(ACMP_CAPSENSE); }
/**************************************************************************//** * @brief Energy Mode 1 demonstration, no active peripherals * @param[in] clock Select oscillator to use * @param[in] HFRCO band *****************************************************************************/ void Demo_EM1(CMU_Select_TypeDef clock, CMU_HFRCOBand_TypeDef band) { /* Disable systick timer */ SysTick->CTRL = 0; /* Set HF clock */ CMU_ClockSelectSet(cmuClock_HF, clock); /* If HFRCO, select band */ if(clock == cmuSelect_HFRCO) { CMU_HFRCOBandSet(band); } /* Disable HFRCO, LFRCO and all unwanted clocks */ if(clock != cmuSelect_HFXO) { CMU->OSCENCMD = CMU_OSCENCMD_HFXODIS; } if(clock != cmuSelect_HFRCO) { CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS; } if(clock != cmuSelect_LFRCO) { CMU->OSCENCMD = CMU_OSCENCMD_LFRCODIS; } if(clock != cmuSelect_LFXO) { CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS; } CMU->HFPERCLKEN0 = 0x00000000; CMU->HFCORECLKEN0 = 0x00000000; CMU->LFACLKEN0 = 0x00000000; CMU->LFBCLKEN0 = 0x00000000; /* Enter Energy Mode 1, no active peripherals */ EMU_EnterEM1(); }
int main(void) { CHIP_Init(); initOscillators(); //init_uart_interface(); #ifdef DEBUG //init_uart_interface_for_debuging(); //uart_sendText("GPS module Startup\n"); init_leuart_interface(); LeUart_SendText("GPS module Startup\n"); #endif //RTC initialization RTC_init(); RTC_setTime(1000); RTC_enableInt(); while(1) { EMU_EnterEM1(); } }
uint16_t adc_get_value(uint8_t u8_adc_channel, ADC_Ref_TypeDef adcref) { ADC_InitSingle_TypeDef sInit = ADC_INITSINGLE_DEFAULT; uint32_t rawvalue = 0; /* Set reference */ sInit.reference = adcref; sInit.input = u8_adc_channel; ADC_InitSingle(ADC0, &sInit); _u8_conv_complete = 0; ADC_Start(ADC0, adcStartSingle); /* Wait in EM1 for ADC to complete */ EMU_EnterEM1(); // Make sure it's ADC interrupt // TODO : timeout while(_u8_conv_complete == 0); rawvalue = ADC_DataSingleGet(ADC0); return (uint16_t) rawvalue; }