/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { /* Chip errata */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); /* Initialize SLEEP driver, no calbacks are used */ SLEEP_Init(NULL, NULL); #if (configSLEEP_MODE < 3) /* do not let to sleep deeper than define */ SLEEP_SleepBlockBegin((SLEEP_EnergyMode_t)(configSLEEP_MODE+1)); #endif /* Initialize the LCD driver */ SegmentLCD_Init(false); /* Create standard binary semaphore */ vSemaphoreCreateBinary(sem); /* Create two task to show numbers from 0 to 15 */ xTaskCreate(Count, (const signed char *) "Count", STACK_SIZE_FOR_TASK, NULL, TASK_PRIORITY, NULL); xTaskCreate(LcdPrint, (const signed char *) "LcdPrint", STACK_SIZE_FOR_TASK, NULL, TASK_PRIORITY, NULL); /* Start FreeRTOS Scheduler */ vTaskStartScheduler(); return 0; }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { /* Chip errata */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); /* Initialize LED driver */ BSP_LedsInit(); /* Setting state of leds*/ BSP_LedSet(0); BSP_LedSet(1); /* Initialize SLEEP driver, no calbacks are used */ SLEEP_Init(NULL, NULL); #if (configSLEEP_MODE < 3) /* do not let to sleep deeper than define */ SLEEP_SleepBlockBegin((SLEEP_EnergyMode_t)(configSLEEP_MODE+1)); #endif /* Parameters value for taks*/ static TaskParams_t parametersToTask1 = { pdMS_TO_TICKS(1000), 0 }; static TaskParams_t parametersToTask2 = { pdMS_TO_TICKS(500), 1 }; /*Create two task for blinking leds*/ xTaskCreate( LedBlink, (const char *) "LedBlink1", STACK_SIZE_FOR_TASK, ¶metersToTask1, TASK_PRIORITY, NULL); xTaskCreate( LedBlink, (const char *) "LedBlink2", STACK_SIZE_FOR_TASK, ¶metersToTask2, TASK_PRIORITY, NULL); /*Start FreeRTOS Scheduler*/ vTaskStartScheduler(); return 0; }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { /* Chip errata */ CHIP_Init(); /* Enable clock for GPIO */ CMU_ClockEnable(cmuClock_GPIO, true); /* Configure LED_PORT pin LED_PIN (User LED) as push/pull outputs */ GPIO_PinModeSet(LED_PORT, /* Port */ LED_PIN, /* Pin */ gpioModePushPull, /* Mode */ 0 ); /* Output value */ /* Initialize SLEEP driver, no calbacks are used */ SLEEP_Init(NULL, NULL); #if (configSLEEP_MODE < 3) /* do not let to sleep deeper than define */ SLEEP_SleepBlockBegin((SLEEP_EnergyMode_t)(configSLEEP_MODE+1)); #endif /*Create two task for blinking leds*/ xTaskCreate( LedBlink, (const char *) "LedBlink", STACK_SIZE_FOR_TASK, NULL, TASK_PRIORITY, NULL); /* Start FreeRTOS Scheduler */ vTaskStartScheduler(); return 0; }
static void prvSetupHardware( void ) { /* Library initialisation routines. */ CHIP_Init(); BSP_TraceProfilerSetup(); SLEEP_Init( NULL, NULL ); BSP_LedsInit(); SLEEP_SleepBlockBegin( configENERGY_MODE ); }
/**************************************************************************//** * @brief main - the entrypoint after reset. *****************************************************************************/ int main( void ) { CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); CMU_ClockSelectSet( cmuClock_HF, cmuSelect_HFXO ); CMU_OscillatorEnable(cmuOsc_LFXO, true, false); /* Initialize LCD driver */ SegmentLCD_Init(false); SegmentLCD_Write("usbcomp"); SegmentLCD_Symbol(LCD_SYMBOL_GECKO, true); /* Initialize LED driver */ BSP_LedsInit(); /* Initialize SLEEP driver, no calbacks are used */ SLEEP_Init(NULL, NULL); #if (configSLEEP_MODE < 3) /* do not let to sleep deeper than define */ SLEEP_SleepBlockBegin((SLEEP_EnergyMode_t)(configSLEEP_MODE + 1)); #endif /* Parameters value for taks*/ static LedTaskParams_t parametersToTask1 = { 1000 / portTICK_RATE_MS, 0 }; static LedTaskParams_t parametersToTask2 = { 500 / portTICK_RATE_MS, 1 }; static AdcTaskParams_t parametersToAdc = { .adcChannelsMask = 0x32, .uPrsChannel = 5, .uSampleRate = 1, .uTimer = 3 }; /*Create two task for blinking leds*/ xTaskCreate( UsbCDCTask, "UsbCDC", STACK_SIZE_FOR_TASK, NULL, TASK_PRIORITY, NULL); // xTaskCreate( LedTask, (const char *) "LedBlink1", STACK_SIZE_FOR_TASK, ¶metersToTask1, TASK_PRIORITY, NULL); // xTaskCreate( LedTask, (const char *) "LedBlink2", STACK_SIZE_FOR_TASK, ¶metersToTask2, TASK_PRIORITY, NULL); xTaskCreate( vAdcTask, "ADC", STACK_SIZE_FOR_TASK, ¶metersToAdc, TASK_PRIORITY + 1, NULL); xTaskCreate( vDacTask, "DAC", STACK_SIZE_FOR_TASK, NULL, TASK_PRIORITY, NULL); xTaskCreate( vEchoTask, "echo", STACK_SIZE_FOR_TASK, NULL, TASK_PRIORITY, NULL); NVIC_SetPriority(USB_IRQn, 7); NVIC_SetPriority(ADC0_IRQn, 7); vTaskStartScheduler(); }
static void rescheduleRtc( uint32_t rtcCnt ) { int i; uint64_t min = UINT64_MAX; // Find the timer with shortest timeout. for ( i = 0; i < EMDRV_RTCDRV_NUM_TIMERS; i++ ) { if ( ( timer[ i ].running == true ) && ( timer[ i ].remaining < min ) ) { min = timer[ i ].remaining; } } rtcRunning = false; if ( min != UINT64_MAX ) { min = SL_MIN( min, RTC_CLOSE_TO_MAX_VALUE ); #if defined( RTCDRV_USE_RTC ) if ( inTimerIRQ == false ) { lastStart = ( rtcCnt ) & RTC_COUNTER_MASK; } else #endif { lastStart = rtcCnt; } RTC_INTCLEAR( RTC_COMP_INT ); RTC_COMPARESET( rtcCnt + min ); #if defined( EMODE_DYNAMIC ) // When RTC is running, we can not allow EM3 or EM4. if ( sleepBlocked == false ) { sleepBlocked = true; SLEEP_SleepBlockBegin( sleepEM3 ); } #endif rtcRunning = true; // Reenable compare IRQ. RTC_INTENABLE( RTC_COMP_INT ); } }
/***************************************************************************//** * @brief * Start a timer. * * @note * It is legal to start an already running timer. * * @param[in] id The id of the timer to start. * @param[in] type Timer type, oneshot or periodic. See @ref RTCDRV_TimerType_t. * @param[in] timeout Timeout expressed in milliseconds. If the timeout value * is 0, the callback function will be called immediately and * the timer will not be started. * @param[in] callback Function to call on timer expiry. See @ref * RTCDRV_Callback_t. NULL is a legal value. * @param[in] user Extra callback function parameter for user application. * * @return * @ref ECODE_EMDRV_RTCDRV_OK on success.@n * @ref ECODE_EMDRV_RTCDRV_ILLEGAL_TIMER_ID if id has an illegal value.@n * @ref ECODE_EMDRV_RTCDRV_TIMER_NOT_ALLOCATED if the timer is not reserved. ******************************************************************************/ Ecode_t RTCDRV_StartTimer( RTCDRV_TimerID_t id, RTCDRV_TimerType_t type, uint32_t timeout, RTCDRV_Callback_t callback, void *user ) { uint32_t timeElapsed, cnt, compVal, loopCnt = 0; uint32_t timeToNextTimerCompletion; // Check if valid timer ID. if ( id >= EMDRV_RTCDRV_NUM_TIMERS ) { return ECODE_EMDRV_RTCDRV_ILLEGAL_TIMER_ID; } INT_Disable(); if ( ! timer[ id ].allocated ) { INT_Enable(); return ECODE_EMDRV_RTCDRV_TIMER_NOT_ALLOCATED; } if ( timeout == 0 ) { if ( callback != NULL ) { callback( id, user ); } INT_Enable(); return ECODE_EMDRV_RTCDRV_OK; } cnt = RTC_COUNTERGET(); timer[ id ].callback = callback; timer[ id ].ticks = MSEC_TO_TICKS( timeout ); if (rtcdrvTimerTypePeriodic == type) { // Calculate compensation value for periodic timers. timer[ id ].periodicCompensationUsec = 1000 * timeout - (timer[ id ].ticks * TICK_TIME_USEC); timer[ id ].periodicDriftUsec = TICK_TIME_USEC/2; } else { // Compensate for the fact that CNT is normally COMP0+1 after a // compare match event on some devices. timer[ id ].ticks -= RTC_ONESHOT_TICK_ADJUST; } // Add one tick in order to compensate if RTC is close to an increment event. timer[ id ].remaining = timer[ id ].ticks + 1; timer[ id ].running = true; timer[ id ].timerType = type; timer[ id ].user = user; if ( inTimerIRQ == true ) { // Exit now, remaining processing will be done in IRQ handler. INT_Enable(); return ECODE_EMDRV_RTCDRV_OK; } // StartTimer() may recurse, keep track of recursion level. if ( startTimerNestingLevel < UINT32_MAX ) { startTimerNestingLevel++; } if ( rtcRunning == false ) { #if defined( RTCDRV_USE_RTC ) lastStart = ( cnt ) & RTC_COUNTER_MASK; #elif defined( RTCDRV_USE_RTCC ) lastStart = cnt; #endif RTC_INTCLEAR( RTC_COMP_INT ); compVal = SL_MIN( timer[ id ].remaining, RTC_CLOSE_TO_MAX_VALUE ); RTC_COMPARESET( cnt + compVal ); // Start the timer system by enabling the compare interrupt. RTC_INTENABLE( RTC_COMP_INT ); #if defined( EMODE_DYNAMIC ) // When RTC is running, we can not allow EM3 or EM4. if ( sleepBlocked == false ) { sleepBlocked = true; SLEEP_SleepBlockBegin( sleepEM3 ); } #endif rtcRunning = true; } else { // The timer system is running. We must stop, update timers with the time // elapsed so far, find the timer with the shortest timeout and then restart. // As StartTimer() may be called from the callbacks we only do this // processing at the first nesting level. if ( startTimerNestingLevel == 1 ) { timer[ id ].running = false; // This loop is repeated if CNT is incremented while processing. do { RTC_INTDISABLE( RTC_COMP_INT ); timeElapsed = TIMEDIFF( cnt, lastStart ); #if defined( RTCDRV_USE_RTC ) // Compensate for the fact that CNT is normally COMP0+1 after a // compare match event. if ( timeElapsed == RTC_MAX_VALUE ) { timeElapsed = 0; } #endif // Update all timers with elapsed time. checkAllTimers( timeElapsed ); // Execute timer callbacks. executeTimerCallbacks(); // Set timer to running only after checkAllTimers() is called once. if ( loopCnt == 0 ) { timer[ id ].running = true; } loopCnt++; // Restart RTC according to next timeout. rescheduleRtc( cnt ); cnt = RTC_COUNTERGET(); timeElapsed = TIMEDIFF( cnt, lastStart ); timeToNextTimerCompletion = TIMEDIFF( RTC_COMPAREGET(), lastStart ); /* If the counter has passed the COMP(ARE) register value since we checked the timers, then we should recheck the timers and reschedule again. */ } while ( rtcRunning && (timeElapsed > timeToNextTimerCompletion)); } } if ( startTimerNestingLevel > 0 ) { startTimerNestingLevel--; } INT_Enable(); return ECODE_EMDRV_RTCDRV_OK; }
/***************************************************************************//** * @brief * Initialize RTCDRV driver. * * @details * Will enable all necessary clocks. Initializes internal datastructures * and configures the underlying hardware timer. * * @return * @ref ECODE_EMDRV_RTCDRV_OK. ******************************************************************************/ Ecode_t RTCDRV_Init( void ) { if ( rtcdrvIsInitialized == true ) { return ECODE_EMDRV_RTCDRV_OK; } rtcdrvIsInitialized = true; // Ensure LE modules are clocked. CMU_ClockEnable( cmuClock_CORELE, true ); #if defined( CMU_LFECLKEN0_RTCC ) // Enable LFECLK in CMU (will also enable oscillator if not enabled). CMU_ClockSelectSet( cmuClock_LFE, RTCDRV_OSC ); #else // Enable LFACLK in CMU (will also enable oscillator if not enabled). CMU_ClockSelectSet( cmuClock_LFA, RTCDRV_OSC ); #endif #if defined( RTCDRV_USE_RTC ) // Set clock divider. CMU_ClockDivSet( cmuClock_RTC, RTC_DIVIDER ); // Enable RTC module clock. CMU_ClockEnable( cmuClock_RTC, true ); // Initialize RTC. RTC_Init( &initRTC ); #elif defined( RTCDRV_USE_RTCC ) // Set clock divider. initRTCC.presc = (RTCC_CntPresc_TypeDef)CMU_DivToLog2( RTC_DIVIDER ); // Enable RTCC module clock. CMU_ClockEnable( cmuClock_RTCC, true ); // Initialize RTCC. RTCC_Init( &initRTCC ); // Set up Compare channel. RTCC_ChannelInit( 1, &initRTCCCompareChannel ); #endif // Disable RTC/RTCC interrupt generation. RTC_INTDISABLE( RTC_ALL_INTS ); RTC_INTCLEAR( RTC_ALL_INTS ); RTC_COUNTERRESET(); // Clear and then enable RTC interrupts in NVIC. NVIC_CLEARPENDINGIRQ(); NVIC_ENABLEIRQ(); #if defined( EMDRV_RTCDRV_WALLCLOCK_CONFIG ) // Enable overflow interrupt for wallclock. RTC_INTENABLE( RTC_OF_INT ); #endif // Reset RTCDRV internal data structures/variables. memset( timer, 0, sizeof( timer ) ); inTimerIRQ = false; rtcRunning = false; startTimerNestingLevel = 0; #if defined( EMODE_DYNAMIC ) sleepBlocked = false; #endif #if defined( EMDRV_RTCDRV_WALLCLOCK_CONFIG ) wallClockOverflowCnt = 0; wallClockTimeBase = 0; #if defined( EMODE_NEVER_ALLOW_EM3EM4 ) // Always block EM3 and EM4 if wallclock is running. SLEEP_SleepBlockBegin( sleepEM3 ); #endif #endif return ECODE_EMDRV_RTCDRV_OK; }