kopia lustrzana https://github.com/mobilinkd/tnc3-firmware
Negotiate battery charging when turned off and plugged in. Fixed #7.
rodzic
de457d00fc
commit
5ba4233871
|
@ -160,6 +160,8 @@ extern char serial_number[25];
|
|||
extern char serial_number_64[17];
|
||||
extern uint8_t mac_address[6];
|
||||
extern char error_message[80];
|
||||
extern int go_back_to_sleep;
|
||||
extern int usb_wake_state;
|
||||
|
||||
#define CxxErrorHandler() _Error_Handler(const_cast<char*>(__FILE__), __LINE__)
|
||||
|
||||
|
|
82
Src/main.c
82
Src/main.c
|
@ -139,6 +139,8 @@ osTimerId beaconTimer3Handle;
|
|||
osStaticTimerDef_t beaconTimer3ControlBlock;
|
||||
osTimerId beaconTimer4Handle;
|
||||
osStaticTimerDef_t beaconTimer4ControlBlock;
|
||||
osTimerId usbShutdownTimerHandle;
|
||||
osStaticTimerDef_t usbShutdownTimerControlBlock;
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
@ -150,6 +152,11 @@ char serial_number_64[17] = {0};
|
|||
// Make sure it is not overwritten during resets (bss3).
|
||||
uint8_t mac_address[6] __attribute__((section(".bss3"))) = {0};
|
||||
char error_message[80] __attribute__((section(".bss3"))) = {0};
|
||||
// USB power control -- need to renegotiate USB charging in STOP mode.
|
||||
int go_back_to_sleep __attribute__((section(".bss3")));
|
||||
int stop_now __attribute__((section(".bss3")));
|
||||
int usb_wake_state;
|
||||
int usb_stop_state;
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
|
@ -175,6 +182,7 @@ extern void startLedBlinkerTask(void const * argument);
|
|||
extern void startAudioInputTask(void const * argument);
|
||||
extern void startModulatorTask(void const * argument);
|
||||
extern void beacon(void const * argument);
|
||||
extern void shutdown(void const * argument);
|
||||
|
||||
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
|
||||
|
||||
|
@ -184,6 +192,7 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
|
|||
void stop2(void) __attribute__((noinline));
|
||||
void configure_gpio_for_stop(void) __attribute__((noinline));
|
||||
void power_down_vdd(void);
|
||||
void power_up_vdd(void);
|
||||
void configure_wakeup_gpio(void);
|
||||
void enable_debug_gpio(void);
|
||||
void init_rtc_date_time(void);
|
||||
|
@ -239,17 +248,16 @@ void configure_gpio_for_stop()
|
|||
HAL_GPIO_DeInit(BAT_LEVEL_GPIO_Port, BAT_LEVEL_Pin);
|
||||
HAL_GPIO_DeInit(BAT_DIVIDER_GPIO_Port, BAT_DIVIDER_Pin);
|
||||
|
||||
usb_stop_state = HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin);
|
||||
if (HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin) == GPIO_PIN_RESET)
|
||||
{
|
||||
HAL_GPIO_WritePin(GPIOB, USB_CE_Pin, GPIO_PIN_SET);
|
||||
// Pull-down required for these.
|
||||
GPIO_InitStruct.Pin = USB_CE_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP; // CE active low.
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
|
||||
// Bluetooth module
|
||||
HAL_GPIO_DeInit(GPIOC, BT_WAKE_Pin);
|
||||
HAL_GPIO_DeInit(GPIOB, BT_RESET_Pin|BT_CMD_Pin);
|
||||
|
@ -272,6 +280,20 @@ void power_down_vdd()
|
|||
for (int i = 0; i < 4800; ++i) asm volatile("nop");
|
||||
}
|
||||
|
||||
void power_up_vdd()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
GPIO_InitStruct.Pin = VDD_EN_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(VDD_EN_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
HAL_GPIO_WritePin(VDD_EN_GPIO_Port, VDD_EN_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void configure_wakeup_gpio()
|
||||
{
|
||||
if (!__HAL_RCC_GPIOH_IS_CLK_ENABLED()) Error_Handler();
|
||||
|
@ -283,13 +305,11 @@ void configure_wakeup_gpio()
|
|||
HAL_NVIC_DisableIRQ(EXTI1_IRQn);
|
||||
HAL_GPIO_DeInit(GPIOH, USB_POWER_Pin|SW_POWER_Pin);
|
||||
|
||||
// Wake up whenever there is a change in VUSB to handle connect events.
|
||||
if (powerOnViaUSB()) {
|
||||
GPIO_InitStruct.Pin = USB_POWER_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL; // Pulled down on PCB.
|
||||
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
|
||||
}
|
||||
// Wake up whenever there is a change in VUSB to handle connect/disconnect events.
|
||||
GPIO_InitStruct.Pin = USB_POWER_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING_FALLING;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN; // needed to act as a voltage divider
|
||||
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
|
||||
|
||||
// Only wake up after the button has been released. This avoids the case
|
||||
// where the TNC is woken up on button down and then immediately put back
|
||||
|
@ -321,6 +341,13 @@ void enable_debug_gpio()
|
|||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
void shutdown(void const * argument)
|
||||
{
|
||||
UNUSED(argument);
|
||||
stop_now = 1;
|
||||
HAL_NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
|
@ -331,7 +358,13 @@ void enable_debug_gpio()
|
|||
int main(void)
|
||||
{
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
// If not a software reset, reset the flags. This prevents odd behavior
|
||||
// during initial power on and hardware resets where SRAM2 may be in an
|
||||
// inconsistent state. During a soft reset, it should be initialized.
|
||||
if (!(RCC->CSR & RCC_CSR_SFTRSTF)) {
|
||||
go_back_to_sleep = 0;
|
||||
stop_now = 0;
|
||||
}
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration----------------------------------------------------------*/
|
||||
|
@ -372,10 +405,13 @@ int main(void)
|
|||
MX_TIM7_Init();
|
||||
MX_OPAMP1_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
if (stop_now) stop2();
|
||||
|
||||
MX_TIM1_Init(); // Initialize the LED PWM timer and GPIOs.
|
||||
SCB->SHCSR |= 0x70000; // Enable fault handlers;
|
||||
indicate_turning_on(); // LEDs on during boot.
|
||||
if (!go_back_to_sleep) {
|
||||
indicate_turning_on(); // LEDs on during boot.
|
||||
}
|
||||
|
||||
// Fetch the device serial number.
|
||||
uint32_t* uid = (uint32_t*) UID_BASE;
|
||||
|
@ -452,6 +488,10 @@ int main(void)
|
|||
osTimerStaticDef(beaconTimer4, beacon, &beaconTimer4ControlBlock);
|
||||
beaconTimer4Handle = osTimerCreate(osTimer(beaconTimer4), osTimerPeriodic, NULL);
|
||||
|
||||
/* definition and creation of usbShutdownTimer */
|
||||
osTimerStaticDef(usbShutdownTimer, shutdown, &usbShutdownTimerControlBlock);
|
||||
usbShutdownTimerHandle = osTimerCreate(osTimer(usbShutdownTimer), osTimerOnce, NULL);
|
||||
|
||||
/* USER CODE BEGIN RTOS_TIMERS */
|
||||
/* start timers, add new ones, ... */
|
||||
/* USER CODE END RTOS_TIMERS */
|
||||
|
@ -546,7 +586,7 @@ int main(void)
|
|||
Error_Handler();
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
// Do not erase SRAM2 during reset.
|
||||
if ((obInit.USERConfig & FLASH_OPTR_SRAM2_RST) == RESET) {
|
||||
obInit.OptionType = OPTIONBYTE_USER;
|
||||
|
@ -1236,9 +1276,25 @@ void stop2()
|
|||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "isb" );
|
||||
|
||||
go_back_to_sleep = 0;
|
||||
stop_now = 0;
|
||||
|
||||
HAL_PWREx_DisableLowPowerRunMode();
|
||||
HAL_DBGMCU_DisableDBGStopMode();
|
||||
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFE);
|
||||
|
||||
// Powered off state
|
||||
// When awakened by USB_POWER pin change:
|
||||
// If unplugged, re-init IO, disabling charging, then go back to STOP.
|
||||
// If plugged, re-init IO, do charger detection then,
|
||||
// If powerOnViaUSB(), stay awake, otherwise go back to STOP.
|
||||
usb_wake_state = HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin);
|
||||
go_back_to_sleep = (usb_stop_state != usb_wake_state);
|
||||
if (usb_wake_state) {
|
||||
if (powerOnViaUSB()) {
|
||||
go_back_to_sleep = 0;
|
||||
}
|
||||
}
|
||||
HAL_NVIC_SystemReset();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,10 @@
|
|||
|
||||
extern osMessageQId hdlcOutputQueueHandle;
|
||||
extern PCD_HandleTypeDef hpcd_USB_FS;
|
||||
extern osTimerId usbShutdownTimerHandle;
|
||||
|
||||
extern "C" void stop2(void);
|
||||
extern "C" void shutdown(void);
|
||||
extern "C" void shutdown(void const * argument);
|
||||
extern "C" void startLedBlinkerTask(void const*);
|
||||
|
||||
static PTT getPttStyle(const mobilinkd::tnc::kiss::Hardware& hardware)
|
||||
|
@ -40,62 +41,70 @@ void startIOEventTask(void const*)
|
|||
{
|
||||
using namespace mobilinkd::tnc;
|
||||
|
||||
indicate_on();
|
||||
if (!go_back_to_sleep) {
|
||||
indicate_on();
|
||||
|
||||
print_startup_banner();
|
||||
print_startup_banner();
|
||||
|
||||
auto& hardware = kiss::settings();
|
||||
auto& hardware = kiss::settings();
|
||||
|
||||
if (! hardware.load() or reset_requested or !hardware.crc_ok())
|
||||
{
|
||||
if (reset_requested) {
|
||||
INFO("Hardware reset requested.");
|
||||
if (! hardware.load() or reset_requested or !hardware.crc_ok())
|
||||
{
|
||||
if (reset_requested) {
|
||||
INFO("Hardware reset requested.");
|
||||
}
|
||||
|
||||
hardware.init();
|
||||
hardware.store();
|
||||
}
|
||||
hardware.debug();
|
||||
|
||||
audio::init_log_volume();
|
||||
audio::setAudioOutputLevel();
|
||||
audio::setAudioInputLevels();
|
||||
setPtt(getPttStyle(hardware));
|
||||
|
||||
// Cannot enable these interrupts until we start the io loop because
|
||||
// they send messages on the queue.
|
||||
HAL_NVIC_SetPriority(SW_POWER_EXTI_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(SW_POWER_EXTI_IRQn);
|
||||
|
||||
HAL_NVIC_SetPriority(SW_BOOT_EXTI_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(SW_BOOT_EXTI_IRQn);
|
||||
|
||||
HAL_NVIC_SetPriority(EXTI4_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
|
||||
|
||||
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||
|
||||
if (reset_requested)
|
||||
{
|
||||
}
|
||||
|
||||
hardware.init();
|
||||
hardware.store();
|
||||
// FIXME: this is probably not right
|
||||
if (HAL_GPIO_ReadPin(BT_STATE2_GPIO_Port, BT_STATE2_Pin) == GPIO_PIN_RESET)
|
||||
{
|
||||
DEBUG("BT Connected at start");
|
||||
openSerial();
|
||||
INFO("BT Opened");
|
||||
indicate_connected_via_ble();
|
||||
}
|
||||
else
|
||||
{
|
||||
indicate_waiting_to_connect();
|
||||
}
|
||||
} else {
|
||||
if (!usb_wake_state) {
|
||||
shutdown(0);
|
||||
} else {
|
||||
osTimerStart(usbShutdownTimerHandle, 2000);
|
||||
}
|
||||
}
|
||||
hardware.debug();
|
||||
|
||||
audio::init_log_volume();
|
||||
audio::setAudioOutputLevel();
|
||||
audio::setAudioInputLevels();
|
||||
setPtt(getPttStyle(hardware));
|
||||
|
||||
// Cannot enable these interrupts until we start the io loop because
|
||||
// they send messages on the queue.
|
||||
HAL_NVIC_SetPriority(USB_POWER_EXTI_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(USB_POWER_EXTI_IRQn);
|
||||
|
||||
HAL_NVIC_SetPriority(SW_POWER_EXTI_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(SW_POWER_EXTI_IRQn);
|
||||
|
||||
HAL_NVIC_SetPriority(SW_BOOT_EXTI_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(SW_BOOT_EXTI_IRQn);
|
||||
|
||||
HAL_NVIC_SetPriority(EXTI4_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
|
||||
|
||||
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||
|
||||
if (reset_requested)
|
||||
{
|
||||
}
|
||||
|
||||
// FIXME: this is probably not right
|
||||
if (HAL_GPIO_ReadPin(BT_STATE2_GPIO_Port, BT_STATE2_Pin) == GPIO_PIN_RESET)
|
||||
{
|
||||
DEBUG("BT Connected at start");
|
||||
openSerial();
|
||||
INFO("BT Opened");
|
||||
indicate_connected_via_ble();
|
||||
}
|
||||
else
|
||||
{
|
||||
indicate_waiting_to_connect();
|
||||
}
|
||||
|
||||
uint32_t power_button_counter{0};
|
||||
uint32_t power_button_duration{0};
|
||||
|
||||
|
@ -127,7 +136,7 @@ void startIOEventTask(void const*)
|
|||
case CMD_USB_DISCONNECTED:
|
||||
INFO("VBUS Lost");
|
||||
if (powerOffViaUSB()) {
|
||||
stop2(); // ***NO RETURN***
|
||||
shutdown(0); // ***NO RETURN***
|
||||
} else {
|
||||
HAL_PCD_MspDeInit(&hpcd_USB_FS);
|
||||
HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_SET);
|
||||
|
@ -165,7 +174,7 @@ void startIOEventTask(void const*)
|
|||
DEBUG("Power Up");
|
||||
power_button_duration = osKernelSysTick() - power_button_counter;
|
||||
DEBUG("Button pressed for %lums", power_button_duration);
|
||||
stop2(); // ***NO RETURN***
|
||||
shutdown(0); // ***NO RETURN***
|
||||
break;
|
||||
case CMD_BOOT_BUTTON_DOWN:
|
||||
DEBUG("BOOT Down");
|
||||
|
@ -223,7 +232,7 @@ void startIOEventTask(void const*)
|
|||
break;
|
||||
case CMD_SHUTDOWN:
|
||||
INFO("STOP mode");
|
||||
stop2();
|
||||
shutdown(0);
|
||||
INFO("RUN mode");
|
||||
HAL_GPIO_WritePin(BT_SLEEP_GPIO_Port, BT_SLEEP_Pin, GPIO_PIN_SET);
|
||||
audio::setAudioOutputLevel();
|
||||
|
@ -259,14 +268,22 @@ void startIOEventTask(void const*)
|
|||
break;
|
||||
case CMD_USB_DISCOVERY_COMPLETE:
|
||||
INFO("USB discovery complete");
|
||||
osTimerStop(usbShutdownTimerHandle);
|
||||
if (go_back_to_sleep) shutdown(0);
|
||||
USBD_Start(&hUsbDeviceFS);
|
||||
initCDC();
|
||||
break;
|
||||
case CMD_USB_DISCOVERY_ERROR:
|
||||
// This happens when powering VBUS from a bench supply.
|
||||
INFO("Not a recognized USB charging device");
|
||||
INFO("USB charging enabled");
|
||||
HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_RESET);
|
||||
osTimerStop(usbShutdownTimerHandle);
|
||||
if (HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin) == GPIO_PIN_SET)
|
||||
{
|
||||
INFO("Not a recognized USB charging device");
|
||||
INFO("USB charging enabled");
|
||||
HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
hpcd_USB_FS.Instance->BCDR = 0;
|
||||
if (go_back_to_sleep) shutdown(0);
|
||||
break;
|
||||
case CMD_BT_DEEP_SLEEP:
|
||||
INFO("BT deep sleep");
|
||||
|
|
|
@ -57,7 +57,7 @@ const uint8_t* get_rtc_datetime()
|
|||
return buffer;
|
||||
}
|
||||
|
||||
// @TODO: determine why this is now necessary.
|
||||
// TODO: determine why this is now necessary.
|
||||
void set_rtc_datetime(const uint8_t* buffer) __attribute__((optimize("-O0")));
|
||||
|
||||
void set_rtc_datetime(const uint8_t* buffer)
|
||||
|
|
Ładowanie…
Reference in New Issue