Added 'platform_pwrButtonStatus' API function, which returns the current status of the power button/knob. Implemented power on/off mechanism on MD-9600

replace/ff7515918fc8555ec6df355c0569fce3a57706d9
Silvano Seva 2021-04-11 12:38:20 +02:00
rodzic a42354a204
commit 4b30a66735
8 zmienionych plików z 121 dodań i 9 usunięć

Wyświetl plik

@ -108,6 +108,13 @@ int8_t platform_getChSelector();
*/
bool platform_getPttStatus();
/**
* This function reads and returns the current status of the power on/power off
* button or switch.
* @return true if power is enabled, false otherwise.
*/
bool platform_pwrButtonStatus();
/**
* This function turns on the selected led.
* @param led: which led to control

Wyświetl plik

@ -32,6 +32,19 @@ extern void *ui_task(void *arg);
int main(void)
{
// MD-9600 does not have a proper power on/off mechanism and the MCU is
// always powered on. We thus need to place a busy wait on the power on
// button to manage the on/off mechanism.
// A do-while block is used to avoid re-powering on after a power off due to
// MCU rebooting before user stops pressing the power button.
#ifdef PLATFORM_MD9600
do
{
sleepFor(1, 0);
}
while(!platform_pwrButtonStatus());
#endif
// Initialize platform drivers
platform_init();

Wyświetl plik

@ -695,15 +695,14 @@ void ui_saveState()
void ui_updateFSM(event_t event, bool *sync_rtx)
{
#ifndef BAT_NONE
// The volume knob has been set to OFF, shutdown the radio
if(state.v_bat <= 0)
// User wants to power off the radio, so shutdown.
if(!platform_pwrButtonStatus())
{
state_terminate();
platform_terminate();
return;
}
#endif
// Check if battery has enough charge to operate.
// Check is skipped if there is an ongoing transmission, since the voltage
// drop caused by the RF PA power absorption causes spurious triggers of

Wyświetl plik

@ -140,6 +140,14 @@ bool platform_getPttStatus()
return (gpio_readPin(PTT_SW) == 0) ? true : false;
}
bool platform_pwrButtonStatus()
{
/*
* When power knob is set to off, battery voltage measurement returns 0V.
*/
return (platform_getVbat() > 0.0f) ? true : false:
}
void platform_ledOn(led_t led)
{
switch(led)

Wyświetl plik

@ -139,6 +139,14 @@ bool platform_getPttStatus()
return (gpio_readPin(PTT_SW) == 0) ? true : false;
}
bool platform_pwrButtonStatus()
{
/*
* When power knob is set to off, battery voltage measurement returns 0V.
*/
return (platform_getVbat() > 0.0f) ? true : false:
}
void platform_ledOn(led_t led)
{
switch(led)

Wyświetl plik

@ -122,6 +122,14 @@ bool platform_getPttStatus()
return (gpio_readPin(PTT_SW) == 0) ? true : false;
}
bool platform_pwrButtonStatus()
{
/*
* When power knob is set to off, battery voltage measurement returns 0V.
*/
return (adc1_getMeasurement(ADC_VBAT_CH) > 0.0f) ? true : false;
}
void platform_ledOn(led_t led)
{
switch(led)

Wyświetl plik

@ -20,6 +20,7 @@
#include <interfaces/gpio.h>
#include <interfaces/nvmem.h>
#include <interfaces/platform.h>
#include <interfaces/delays.h>
#include <hwconfig.h>
#include <string.h>
#include <backlight.h>
@ -34,14 +35,12 @@ hwInfo_t hwInfo;
void platform_init()
{
gpio_setMode(CH_SELECTOR_0, INPUT_PULL_UP);
gpio_setMode(CH_SELECTOR_1, INPUT_PULL_UP);
gpio_setMode(PTT_SW, INPUT);
/* Enable 8V power supply rail */
gpio_setMode(PWR_SW, OUTPUT);
gpio_setPin(PWR_SW);
gpio_setMode(PTT_SW, INPUT);
/*
* Initialise ADC1, for vbat, RSSI, ...
* Configuration of corresponding GPIOs in analog input mode is done inside
@ -93,6 +92,13 @@ void platform_terminate()
/* Finally, remove power supply */
gpio_clearPin(PWR_SW);
/*
* MD-9600 does not have a proper power on/off mechanism and the MCU is
* always powered. Thus, for turn off, perform a system reset.
*/
NVIC_SystemReset();
while(1) ;
}
float platform_getVbat()
@ -121,6 +127,61 @@ bool platform_getPttStatus()
return (gpio_readPin(PTT_SW) == 0) ? true : false;
}
bool platform_pwrButtonStatus()
{
/*
* The power on/off button, when pressed, connects keyboard coloumn 3 to
* row 3. Here we set coloumn to input with pull up mode and row to output
* mode, consistently with keyboard driver.
*/
gpio_setMode(KB_COL3, INPUT_PULL_UP);
gpio_setMode(KB_ROW3, OUTPUT);
/*
* Critical section to avoid stomping the keyboard driver.
* Also, working at register level to keep it as short as possible
*/
__disable_irq();
uint32_t prevRowState = GPIOD->ODR & (1 << 4); /* Row 3 is PD4 */
GPIOD->BSRRH = 1 << 4; /* PD4 low */
delayUs(10);
uint32_t btnStatus = GPIOE->IDR & 0x01; /* Col 3 is PE0 */
GPIOD->ODR |= prevRowState; /* Restore PD4 */
__enable_irq();
/*
* Power button API requires this function to return true if power is
* enabled. To comply to the requirement this function behaves in this way:
* - if button is not pressed, return current status of PWR_SW.
* - if button is pressed and PWR_SW is low, return true as user wants to
* turn the radio on.
* - if button is pressed and PWR_SW is high, return false as user wants to
* turn the radio off.
*/
/*
* Power button follows an active-low logic: btnStatus is low when button
* is pressed
*/
if(btnStatus == 0)
{
if(gpio_readPin(PWR_SW))
{
/* Power switch high and button pressed: request to turn off */
return false;
}
else
{
/* Power switch low and button pressed: request to turn on */
return true;
}
}
/* We get here if power button is not pressed, just return PWR_SW status */
return gpio_readPin(PWR_SW) ? true : false;
}
void platform_ledOn(led_t led)
{
/* No LEDs on this platform */

Wyświetl plik

@ -116,6 +116,14 @@ bool platform_getPttStatus()
return (gpio_readPin(PTT_SW) == 0) ? true : false;
}
bool platform_pwrButtonStatus()
{
/*
* When power knob is set to off, battery voltage measurement returns 0V.
*/
return (adc1_getMeasurement(ADC_VBAT_CH) > 0.0f) ? true : false;
}
void platform_ledOn(led_t led)
{
switch(led)