/*----------------------------------------------------------------------------* * NAME * InitAlertTagHardware - initialize application hardware * * DESCRIPTION * This function is called upon a power reset to initialize the PIOs * and configure their initial states. * * RETURNS * Nothing. * *----------------------------------------------------------------------------*/ extern void InitAlertTagHardware(void) { #ifndef DEBUG_THRU_UART /* Don't wakeup on UART RX line */ SleepWakeOnUartRX(FALSE); #endif /* Setup PIOs * PIO3 - Buzzer - BUZZER_PIO * PIO4 - LED 1 - LED_PIO * PIO11 - Button - BUTTON_PIO */ PioSetModes(PIO_BIT_MASK(BUTTON_PIO), pio_mode_user); PioSetDir(BUTTON_PIO, PIO_DIRECTION_INPUT); /* input */ PioSetPullModes(PIO_BIT_MASK(BUTTON_PIO), pio_mode_strong_pull_up); /* Setup button on PIO11 */ PioSetEventMask(PIO_BIT_MASK(BUTTON_PIO), pio_event_mode_both); #ifdef ENABLE_LEDBLINK /* PWM is being used for LED glowing.*/ PioSetModes(PIO_BIT_MASK(LED_PIO), pio_mode_pwm1); /* Advertising parameters are being configured for PWM right now. When * application moves to connection state, we change PWM parameters to * the ones for connection */ PioConfigPWM(LED_PWM_INDEX_1, pio_pwm_mode_push_pull, DULL_LED_ON_TIME_ADV, DULL_LED_OFF_TIME_ADV, DULL_LED_HOLD_TIME_ADV, BRIGHT_LED_OFF_TIME_ADV, BRIGHT_LED_ON_TIME_ADV, BRIGHT_LED_HOLD_TIME_ADV, LED_RAMP_RATE); PioEnablePWM(LED_PWM_INDEX_1, FALSE); #endif /* ENABLE_LEDBLINK */ #ifdef ENABLE_BUZZER PioSetModes(PIO_BIT_MASK(BUZZER_PIO), pio_mode_pwm0); /* Configure the buzzer on PIO3 */ PioConfigPWM(BUZZER_PWM_INDEX_0, pio_pwm_mode_push_pull, DULL_BUZZ_ON_TIME, DULL_BUZZ_OFF_TIME, DULL_BUZZ_HOLD_TIME, BRIGHT_BUZZ_ON_TIME, BRIGHT_BUZZ_OFF_TIME, BRIGHT_BUZZ_HOLD_TIME, BUZZ_RAMP_RATE); PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); #endif /* ENABLE_BUZZER */ /* Set the I2C pins to pull down */ PioSetI2CPullMode(pio_i2c_pull_mode_strong_pull_down); }
/*----------------------------------------------------------------------------* * NAME * SetIndication * * DESCRIPTION * This function indicates the app state through LED blinking * * RETURNS/MODIFIES * Nothing. * *----------------------------------------------------------------------------*/ extern void SetIndication(app_indication state) { #ifdef ENABLE_LEDBLINK if(state == app_ind_stop) { /*Stop LED glowing */ PioEnablePWM(LED_PWM_INDEX_1, FALSE); /* Reconfigure LED to pio_mode_user. This reconfiguration has been done * because When PWM is disabled, LED pio value remains same as it was at * the exact time of disabling. So if LED was on, it may remain ON even * after PWM disabling. So it is better to reconfigure it to user mode. * It will reconfigured to PWM mode while enabling. */ PioSetModes(PIO_BIT_MASK(LED_PIO), pio_mode_user); PioSet(LED_PIO, FALSE); } else { if(state == app_ind_adv) { /* Fast Blinking for advertising */ PioConfigPWM(LED_PWM_INDEX_1, pio_pwm_mode_push_pull, DULL_LED_ON_TIME_ADV, DULL_LED_OFF_TIME_ADV, DULL_LED_HOLD_TIME_ADV, BRIGHT_LED_ON_TIME_ADV, BRIGHT_LED_OFF_TIME_ADV, BRIGHT_LED_HOLD_TIME_ADV, LED_RAMP_RATE); } else if(state == app_ind_conn) { /* slow blinking for connected state */ PioConfigPWM(LED_PWM_INDEX_1, pio_pwm_mode_push_pull, DULL_LED_ON_TIME_CONN, DULL_LED_OFF_TIME_CONN, DULL_LED_HOLD_TIME_CONN, BRIGHT_LED_ON_TIME_CONN, BRIGHT_LED_OFF_TIME_CONN, BRIGHT_LED_HOLD_TIME_CONN, LED_RAMP_RATE); } PioSetModes(PIO_BIT_MASK(LED_PIO), pio_mode_pwm1); /*Start LED glowing */ PioEnablePWM(LED_PWM_INDEX_1, TRUE); PioSet(LED_PIO, TRUE); } #endif /* ENABLE_LEDBLINK */ }
void LcdDisplayInitPwm(void) { PioSetMode(PIO_LED, pio_mode_user); PioSetDir(PIO_LED, TRUE); /* Output */ PioSet(PIO_LED, FALSE); PioSetMode(PIO_LED, pio_mode_pwm0); /* PIO is controlled by PWM. */ LcdDisplayBacklight(10, 10); /* Start with dim light. */ PioEnablePWM(PWM_ID_LED, TRUE); } /* LcdDisplayInitPwm */
/*----------------------------------------------------------------------------* * NAME * BuzzerInitHardware * * DESCRIPTION * This function initialises the buzzer hardware. * * PARAMETERS * None * * RETURNS * Nothing *----------------------------------------------------------------------------*/ extern void BuzzerInitHardware(void) { /* Configure the buzzer PIO to use PWM. */ PioSetModes(BUZZER_PIO_MASK, pio_mode_pwm0); /* Configure the PWM for buzzer ON OFF values */ PioConfigPWM(BUZZER_PWM_INDEX_0, pio_pwm_mode_push_pull, DULL_BUZZ_ON_TIME, DULL_BUZZ_OFF_TIME, DULL_BUZZ_HOLD_TIME, BRIGHT_BUZZ_ON_TIME, BRIGHT_BUZZ_OFF_TIME, BRIGHT_BUZZ_HOLD_TIME, BUZZ_RAMP_RATE); /* Disable buzzer for the time being. */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); }
/*----------------------------------------------------------------------------* * NAME * InitTimeClientHardware-initialize application hardware * * DESCRIPTION * This function is called upon a power reset to initialize the PIOs * and configure their initial states. * * RETURNS * Nothing. * *----------------------------------------------------------------------------*/ extern void InitTimeClientHardware(void) { /* Setup PIOs * PIO3 - Buzzer - BUZZER_PIO * PIO4 - LED 1 - LED_PIO * PIO11 - Button - BUTTON_PIO */ PioSetModes(PIO_BIT_MASK(BUTTON_PIO), pio_mode_user); PioSetDir(BUTTON_PIO, PIO_DIRECTION_INPUT); /* input */ PioSetPullModes(PIO_BIT_MASK(BUTTON_PIO), pio_mode_strong_pull_up); /* Setup button on PIO11 */ PioSetEventMask(PIO_BIT_MASK(BUTTON_PIO), pio_event_mode_both); /* Initialize Buzzer Hardware */ BuzzerInitHardware(); #ifdef ENABLE_LEDBLINK /* PWM is being used for LED glowing.*/ PioSetModes(PIO_BIT_MASK(LED_PIO), pio_mode_pwm1); /* Advertising parameters are being configured for PWM right now. When * application moves to connection state, we change PWM parameters to * the ones for connection */ PioConfigPWM(LED_PWM_INDEX_1, pio_pwm_mode_push_pull, DULL_LED_ON_TIME_ADV, DULL_LED_OFF_TIME_ADV, DULL_LED_HOLD_TIME_ADV, BRIGHT_LED_OFF_TIME_ADV, BRIGHT_LED_ON_TIME_ADV, BRIGHT_LED_HOLD_TIME_ADV, LED_RAMP_RATE); PioEnablePWM(LED_PWM_INDEX_1, FALSE); #endif /* ENABLE_LEDBLINK */ /* Set the I2C pins to pull down */ PioSetI2CPullMode(pio_i2c_pull_mode_strong_pull_down); }
/*----------------------------------------------------------------------------* * NAME * appBuzzerTimerHandler * * DESCRIPTION * This function is used to stop the Buzzer at the expiry of * timer. * * RETURNS * Nothing. * *----------------------------------------------------------------------------*/ static void appBuzzerTimerHandler(timer_id tid) { uint32 beep_timer = SHORT_BEEP_TIMER_VALUE; g_app_hw_data.buzzer_tid = TIMER_INVALID; switch(g_app_hw_data.beep_type) { case beep_short: /* FALLTHROUGH */ case beep_long: { g_app_hw_data.beep_type = beep_off; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); } break; case beep_twice: { if(g_app_hw_data.beep_count == 0) { /* First beep sounded. Start the silent gap*/ g_app_hw_data.beep_count = 1; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); /* Time gap between two beeps */ beep_timer = BEEP_GAP_TIMER_VALUE; } else if(g_app_hw_data.beep_count == 1) { g_app_hw_data.beep_count = 2; /* Enable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE); /* Start beep */ beep_timer = SHORT_BEEP_TIMER_VALUE; } else { /* Two beeps have been sounded. Stop buzzer now*/ g_app_hw_data.beep_count = 0; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); g_app_hw_data.beep_type = beep_off; } } break; case beep_thrice: { if(g_app_hw_data.beep_count == 0 || g_app_hw_data.beep_count == 2) { /* First beep sounded. Start the silent gap*/ g_app_hw_data.beep_count++; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); /* Time gap between two beeps */ beep_timer = BEEP_GAP_TIMER_VALUE; } else if(g_app_hw_data.beep_count == 1 || g_app_hw_data.beep_count == 3) { g_app_hw_data.beep_count++; /* Enable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE); beep_timer = SHORT_BEEP_TIMER_VALUE; } else { /* Two beeps have been sounded. Stop buzzer now*/ g_app_hw_data.beep_count = 0; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); g_app_hw_data.beep_type = beep_off; } } break; default: { /* No such beep type */ ReportPanic(app_panic_unexpected_beep_type); /* Though break statement will not be executed after panic but this * has been kept to avoid any confusion for default case. */ } break; } if(g_app_hw_data.beep_type != beep_off) { /* start the timer */ g_app_hw_data.buzzer_tid = TimerCreate(beep_timer, TRUE, appBuzzerTimerHandler); } }
/*----------------------------------------------------------------------------* * NAME * SoundBuzzer * * DESCRIPTION * Function for sounding beeps. * * RETURNS * Nothing. * *----------------------------------------------------------------------------*/ extern void SoundBuzzer(buzzer_beep_type beep_type) { #ifdef ENABLE_BUZZER uint32 beep_timer = SHORT_BEEP_TIMER_VALUE; PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); TimerDelete(g_app_hw_data.buzzer_tid); g_app_hw_data.buzzer_tid = TIMER_INVALID; g_app_hw_data.beep_count = 0; /* Store the beep type in some global variable. It will used on timer expiry * to check the type of beeps being sounded. */ g_app_hw_data.beep_type = beep_type; switch(g_app_hw_data.beep_type) { case beep_off: { /* Don't do anything */ } break; case beep_short: /* FALLTHROUGH */ case beep_twice: /* Two short beeps will be sounded */ /* FALLTHROUGH */ case beep_thrice: /* Three short beeps will be sounded */ { /* One short beep will be sounded */ beep_timer = SHORT_BEEP_TIMER_VALUE; } break; case beep_long: { /* One long beep will be sounded */ beep_timer = LONG_BEEP_TIMER_VALUE; } break; break; default: { /* No such beep type defined */ ReportPanic(app_panic_unexpected_beep_type); /* Though break statement will not be executed after panic but this * has been kept to avoid any confusion for default case. */ } break; } if(g_app_hw_data.beep_type != beep_off) { /* Initialize beep count to zero */ g_app_hw_data.beep_count = 0; /* Enable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE); TimerDelete(g_app_hw_data.buzzer_tid); g_app_hw_data.buzzer_tid = TimerCreate(beep_timer, TRUE, appBuzzerTimerHandler); } #endif /* ENABLE_BUZZER */ }
/*----------------------------------------------------------------------------* * NAME * SoundBuzzer * * DESCRIPTION * This function is called to trigger beeps of different types, enumerated * by 'buzzer_beep_type'. * * PARAMETERS * beep_type [in] Type of beep required * * RETURNS * Nothing *----------------------------------------------------------------------------*/ extern void SoundBuzzer(buzzer_beep_type beep_type) { /* Duration of beep */ uint32 beep_timer = SHORT_BEEP_TIMER_VALUE; /* Disable the buzzer and stop the buzzer timer. */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); if (g_buzz_data.buzzer_tid != TIMER_INVALID) { TimerDelete(g_buzz_data.buzzer_tid); g_buzz_data.buzzer_tid = TIMER_INVALID; } /* Reset the beeper state */ g_buzz_data.beep_count = 0; /* Store the beep type. It will be used on timer expiry to check the type of * beep being sounded. */ g_buzz_data.beep_type = beep_type; switch(g_buzz_data.beep_type) { case buzzer_beep_off: { /* Don't do anything */ } break; case buzzer_beep_short: /* One short beep will be sounded */ /* FALLTHROUGH */ case buzzer_beep_twice: /* Two short beeps will be sounded */ /* FALLTHROUGH */ case buzzer_beep_thrice: /* Three short beeps will be sounded */ { beep_timer = SHORT_BEEP_TIMER_VALUE; } break; case buzzer_beep_long: { /* One long beep will be sounded */ beep_timer = LONG_BEEP_TIMER_VALUE; } break; default: { /* No such beep type defined */ ReportPanic(app_panic_unexpected_beep_type); } break; } if(g_buzz_data.beep_type != buzzer_beep_off) { /* Enable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE); /* Start the buzzer timer */ g_buzz_data.buzzer_tid = TimerCreate(beep_timer, TRUE, appBuzzerTimerHandler); } }
/*----------------------------------------------------------------------------* * NAME * appBuzzerTimerHandler * * DESCRIPTION * This function is used to stop the Buzzer at the expiry of timer. * * PARAMETERS * tid [in] ID of expired timer (unused) * * RETURNS * Nothing *----------------------------------------------------------------------------*/ static void appBuzzerTimerHandler(timer_id tid) { /* Duration of next timer */ uint32 beep_timer = SHORT_BEEP_TIMER_VALUE; /* The buzzer timer has just expired, so reset the timer ID */ g_buzz_data.buzzer_tid = TIMER_INVALID; switch(g_buzz_data.beep_type) { case buzzer_beep_short: /* FALLTHROUGH */ case buzzer_beep_long: { g_buzz_data.beep_type = buzzer_beep_off; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); } break; case buzzer_beep_twice: { if(g_buzz_data.beep_count == 0) { /* First beep sounded. Increment the beep count and start the * silent gap. */ g_buzz_data.beep_count = 1; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); /* Time gap between two beeps */ beep_timer = BEEP_GAP_TIMER_VALUE; } else if(g_buzz_data.beep_count == 1) { /* Sound the second beep and increment the beep count. */ g_buzz_data.beep_count = 2; /* Enable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE); /* Start another short beep */ beep_timer = SHORT_BEEP_TIMER_VALUE; } else { /* Two beeps have been sounded. Stop buzzer now and reset the * beep count. */ g_buzz_data.beep_count = 0; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); g_buzz_data.beep_type = buzzer_beep_off; } } break; case buzzer_beep_thrice: { if(g_buzz_data.beep_count == 0 || g_buzz_data.beep_count == 2) { /* Start the silent gap*/ ++g_buzz_data.beep_count; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); /* Time gap between two beeps */ beep_timer = BEEP_GAP_TIMER_VALUE; } else if(g_buzz_data.beep_count == 1 || g_buzz_data.beep_count == 3) { /* Start the beep sounding part. */ ++g_buzz_data.beep_count; /* Enable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE); beep_timer = SHORT_BEEP_TIMER_VALUE; } else { /* Three beeps have been sounded. Stop the buzzer. */ g_buzz_data.beep_count = 0; /* Disable buzzer */ PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE); g_buzz_data.beep_type = buzzer_beep_off; } } break; default: { /* No such beep type */ ReportPanic(app_panic_unexpected_beep_type); } break; } if(g_buzz_data.beep_type != buzzer_beep_off) { /* Start the timer */ g_buzz_data.buzzer_tid = TimerCreate(beep_timer, TRUE, appBuzzerTimerHandler); } }
/*----------------------------------------------------------------------------* * NAME * AppInit * * DESCRIPTION * This user application function is called after a power-on reset * (including after a firmware panic), after a wakeup from Hibernate or * Dormant sleep states, or after an HCI Reset has been requested. * * NOTE: In the case of a power-on reset, this function is called * after AppPowerOnReset(). * * PARAMETERS * last_sleep_state [in] Last sleep state * * RETURNS * Nothing *----------------------------------------------------------------------------*/ void AppInit(sleep_state last_sleep_state) { /* Initialise UART communications */ DebugInit(1, NULL, NULL); DebugWriteString("Configuring PWM Modes\r\n"); /* Configure the output PIO on which the slow flashing LED signal is * generated */ PioSetDir(PIO_LED, PIO_DIR_OUTPUT); /* SLOW FLASHING WITH PWM: * Configure PWM 0 to have the following characteristics * DULL LED Light is generated by having pulses of 0ms ON and * 6ms OFF (~0% duty cycle) * BRIGHT LED Light is generated by having pulses of 6ms ON and * 0ms OFF (~100% duty cycle) * Dullest and Brightest level are held for ~1s * * The brightness level ramps for ~1s when going from dullest to * brightest and vice-versa */ if (PioConfigPWM(0, pio_pwm_mode_push_pull, /* Pulse timings for the dullest part of the sequence: * dullest part of the sequence has the pulse off for the whole * period, in effect the line stays low for the duration for which * the dullest part of the sequence lasts. */ 0, /* ON time for the pulse is 0us */ 255, /* OFF time for the pulse is (255 * 30)us */ 62, /* Dullest part of the sequence lasts for ( 62 * 16 )ms before ramping up to the brightest part of the sequence */ /* Pulse timings for the brightest part of the sequence: * brightest part of the sequence has the pulse ON for the whole * period, in effect the line stays high for the duration for which * the brightest part of the sequence lasts. */ 255, /* ON time for the pulse is (255 * 30)us */ 0, /* OFF time for the pulse is 0us */ 62, /* Brightest part of the sequence lasts for ( 62 * 16 )ms before ramping down to the dullest part of the sequence */ /* Ramping between dullest and brightest parts of the sequence * This parameter determines the duration for which the ramping * lasts when going from dullest to the brightest (and vice-versa). * * The total duration for which the ramping lasts is determined by * multiplying this value with one less than the difference between * the on_time or off_time of the two states, whichever is bigger; * in the units of 30us * */ 132 /* Ramping lasts for ((255-1) * 132 * 30)us */ )) { DebugWriteString("PWM0 was set to ramp between brightest and dullest " "levels\r\n"); /* Connect PWM0 output to LED */ PioSetMode(PIO_LED, pio_mode_pwm0); /* Enable the PWM0 */ PioEnablePWM(0, TRUE); } else { DebugWriteString("PWM0 couldn't be configured\r\n"); } /* Set both outputs to have strong internal pull ups */ PioSetPullModes((1UL << PIO_MOTOR) | (1UL << PIO_LED), pio_mode_strong_pull_up); /* Configure motor PIO to be output */ PioSetDir(PIO_MOTOR, PIO_DIR_OUTPUT); /* Connect PWM1 output to motor PIO */ PioSetMode(PIO_MOTOR, pio_mode_pwm1); /* Initialise timers */ TimerInit(MAX_APP_TIMERS, app_timers); /* Call the function (with a dummy timer ID to start with) to configure * the PWM1 with initial duty cycle and start a timer. When the timer * expires the same function gets called again and the duty cycle for * PWM1 gets updated. It takes care of restarting the timer and ensuring * that duty cycle alternates between 0% and 100% back and forth. */ dutyCycleTask(TIMER_INVALID); /* Enable the PWM1 */ PioEnablePWM(1, TRUE); }