Fix USB connection/battery charging issue.

fsk9600 v1.0.1
Rob Riggs 2019-01-13 13:17:54 -06:00
rodzic e00cb3d8ba
commit f87873d26a
5 zmienionych plików z 100 dodań i 65 usunięć

Wyświetl plik

@ -379,6 +379,7 @@ HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
hpcd->battery_charging_active = 0U; hpcd->battery_charging_active = 0U;
USBx->BCDR &= ~(USB_BCDR_BCDEN); USBx->BCDR &= ~(USB_BCDR_BCDEN);
USBx->BCDR &= ~(USB_BCDR_DCDEN);
return HAL_OK; return HAL_OK;
} }

Wyświetl plik

@ -161,6 +161,7 @@ extern uint8_t mac_address[6];
extern char error_message[80]; extern char error_message[80];
extern int go_back_to_sleep; extern int go_back_to_sleep;
extern int usb_wake_state; extern int usb_wake_state;
extern int charging_enabled;
#define CxxErrorHandler() _Error_Handler(const_cast<char*>(__FILE__), __LINE__) #define CxxErrorHandler() _Error_Handler(const_cast<char*>(__FILE__), __LINE__)

Wyświetl plik

@ -154,8 +154,8 @@ char error_message[80] __attribute__((section(".bss3"))) = {0};
// USB power control -- need to renegotiate USB charging in STOP mode. // USB power control -- need to renegotiate USB charging in STOP mode.
int go_back_to_sleep __attribute__((section(".bss3"))); int go_back_to_sleep __attribute__((section(".bss3")));
int stop_now __attribute__((section(".bss3"))); int stop_now __attribute__((section(".bss3")));
int usb_wake_state; int charging_enabled __attribute__((section(".bss3")));
int usb_stop_state; int usb_wake_state __attribute__((section(".bss3")));
/* USER CODE END PV */ /* USER CODE END PV */
@ -182,6 +182,7 @@ extern void startAudioInputTask(void const * argument);
extern void startModulatorTask(void const * argument); extern void startModulatorTask(void const * argument);
extern void beacon(void const * argument); extern void beacon(void const * argument);
extern void shutdown(void const * argument); extern void shutdown(void const * argument);
void encode_serial_number(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
@ -247,14 +248,13 @@ void configure_gpio_for_stop()
HAL_GPIO_DeInit(BAT_LEVEL_GPIO_Port, BAT_LEVEL_Pin); HAL_GPIO_DeInit(BAT_LEVEL_GPIO_Port, BAT_LEVEL_Pin);
HAL_GPIO_DeInit(BAT_DIVIDER_GPIO_Port, BAT_DIVIDER_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 (charging_enabled)
if (HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin) == GPIO_PIN_RESET)
{ {
HAL_GPIO_WritePin(GPIOB, USB_CE_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, USB_CE_Pin, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = USB_CE_Pin; }
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; else
GPIO_InitStruct.Pull = GPIO_PULLUP; // CE active low. {
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_DeInit(USB_CE_GPIO_Port, USB_CE_Pin); // Hi-Z
} }
// Bluetooth module // Bluetooth module
@ -340,6 +340,14 @@ void enable_debug_gpio()
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
} }
/**
* Shutdown is used to enter stop mode in a clean state. This ensures that
* all IP have been reset & re-initialized to their default state when
* entering low-power stop mode. This is a work-around until we can
* determine what causes a high-discharge state after USB is enabled.
*
* @param argument is unused.
*/
void shutdown(void const * argument) void shutdown(void const * argument)
{ {
UNUSED(argument); UNUSED(argument);
@ -387,6 +395,7 @@ int main(void)
if (!(RCC->CSR & RCC_CSR_SFTRSTF)) { if (!(RCC->CSR & RCC_CSR_SFTRSTF)) {
go_back_to_sleep = 0; go_back_to_sleep = 0;
stop_now = 0; stop_now = 0;
usb_wake_state = 0;
} }
/* USER CODE END 1 */ /* USER CODE END 1 */
@ -438,45 +447,47 @@ int main(void)
encode_serial_number(); encode_serial_number();
// The Bluetooth module is powered on during MX_GPIO_Init(). BT_CMD if (!go_back_to_sleep) {
// has a weak pull-up on the BT module and is in OD mode. Pull the // The Bluetooth module is powered on during MX_GPIO_Init(). BT_CMD
// pin low during boot to enter Bluetooth programming mode. Here the // has a weak pull-up on the BT module and is in OD mode. Pull the
// BT_CMD pin is switched to input mode to detect the state. The // pin low during boot to enter Bluetooth programming mode. Here the
// TNC must be reset to exit programming mode. // BT_CMD pin is switched to input mode to detect the state. The
// TNC must be reset to exit programming mode.
// Wait for BT module to settle. // Wait for BT module to settle.
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = BT_CMD_Pin; GPIO_InitStructure.Pin = BT_CMD_Pin;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Pull = GPIO_PULLUP;
HAL_GPIO_Init(BT_CMD_GPIO_Port, &GPIO_InitStructure); HAL_GPIO_Init(BT_CMD_GPIO_Port, &GPIO_InitStructure);
HAL_Delay(10); HAL_Delay(10);
if (HAL_GPIO_ReadPin(BT_CMD_GPIO_Port, BT_CMD_Pin) == GPIO_PIN_RESET) { if (HAL_GPIO_ReadPin(BT_CMD_GPIO_Port, BT_CMD_Pin) == GPIO_PIN_RESET) {
// Special test mode for programming the Bluetooth module. The TNC // Special test mode for programming the Bluetooth module. The TNC
// has the BT_CMD pin actively being pulled low. In this case we // has the BT_CMD pin actively being pulled low. In this case we
// power on the BT module with BT_CMD held low and wait here without // power on the BT module with BT_CMD held low and wait here without
// initializing the UART. We only exit via reset. // initializing the UART. We only exit via reset.
HAL_UART_MspDeInit(&huart3); HAL_UART_MspDeInit(&huart3);
HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_RESET);
HAL_Delay(1); HAL_Delay(1);
HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_SET);
HAL_Delay(200); HAL_Delay(200);
printf("Bluetooth programming mode\r\n"); printf("Bluetooth programming mode\r\n");
while (1); while (1);
}
// Not in BT programming mode. Switch BT_CMD back to OD mode.
HAL_GPIO_WritePin(BT_CMD_GPIO_Port, BT_CMD_Pin, GPIO_PIN_SET);
GPIO_InitStructure.Pin = BT_CMD_Pin;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Pull = GPIO_PULLUP;
HAL_GPIO_Init(BT_CMD_GPIO_Port, &GPIO_InitStructure);
} }
// Not in BT programming mode. Switch BT_CMD back to OD mode.
HAL_GPIO_WritePin(BT_CMD_GPIO_Port, BT_CMD_Pin, GPIO_PIN_SET);
GPIO_InitStructure.Pin = BT_CMD_Pin;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Pull = GPIO_PULLUP;
HAL_GPIO_Init(BT_CMD_GPIO_Port, &GPIO_InitStructure);
/* USER CODE END 2 */ /* USER CODE END 2 */
/* USER CODE BEGIN RTOS_MUTEX */ /* USER CODE BEGIN RTOS_MUTEX */
@ -581,13 +592,16 @@ int main(void)
if (HAL_OPAMP_Start(&hopamp1) != HAL_OK) Error_Handler(); if (HAL_OPAMP_Start(&hopamp1) != HAL_OK) Error_Handler();
if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK) Error_Handler(); if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK) Error_Handler();
// Initialize the BM78 Bluetooth module and the RTC date/time the first time we boot. if (!go_back_to_sleep) {
if (!bm78_initialized()) {
bm78_initialize(); // Initialize the BM78 Bluetooth module and the RTC date/time the first time we boot.
memset(error_message, 0, sizeof(error_message)); if (!bm78_initialized()) {
// init_rtc_date_time(); bm78_initialize();
memset(error_message, 0, sizeof(error_message));
// init_rtc_date_time();
}
else bm78_wait_until_ready();
} }
else bm78_wait_until_ready();
init_ioport(); init_ioport();
initCDC(); initCDC();
@ -1269,7 +1283,7 @@ void stop2()
{ {
osThreadSuspendAll(); osThreadSuspendAll();
GPIO_PinState usb = HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin); int usb_stop_state = HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin);
HAL_OPAMP_DeInit(&hopamp1); HAL_OPAMP_DeInit(&hopamp1);
HAL_TIM_PWM_DeInit(&htim1); HAL_TIM_PWM_DeInit(&htim1);
@ -1279,10 +1293,11 @@ void stop2()
HAL_UART_DeInit(&huart3); HAL_UART_DeInit(&huart3);
HAL_PWR_DisablePVD(); HAL_PWR_DisablePVD();
USB->BCDR = 0;
HAL_PWREx_DisableVddUSB(); HAL_PWREx_DisableVddUSB();
HAL_ADCEx_EnterADCDeepPowerDownMode(&hadc1); HAL_ADCEx_EnterADCDeepPowerDownMode(&hadc1);
configure_gpio_for_stop(); configure_gpio_for_stop();
power_down_vdd(); if (!usb_stop_state) power_down_vdd();
HAL_RCCEx_DisableLSCO(); HAL_RCCEx_DisableLSCO();
@ -1310,6 +1325,8 @@ void stop2()
if (powerOnViaUSB()) { if (powerOnViaUSB()) {
go_back_to_sleep = 0; go_back_to_sleep = 0;
} }
} else {
charging_enabled = 0;
} }
HAL_NVIC_SystemReset(); HAL_NVIC_SystemReset();
} }
@ -1412,20 +1429,22 @@ void init_rtc_alarm()
/* USER CODE END Header_StartDefaultTask */ /* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument) void StartDefaultTask(void const * argument)
{ {
/* init code for USB_DEVICE */
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 5 */ /* USER CODE BEGIN 5 */
printf("startDefaultTask\r\n");
UNUSED(argument); UNUSED(argument);
if (HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin) == GPIO_PIN_SET) if (HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin) == GPIO_PIN_SET)
{ {
#ifdef KISS_LOGGING
printf("VBUS detected\r\n"); printf("VBUS detected\r\n");
#endif
MX_USB_DEVICE_Init();
HAL_PCD_MspInit(&hpcd_USB_FS); HAL_PCD_MspInit(&hpcd_USB_FS);
HAL_PCDEx_ActivateBCD(&hpcd_USB_FS);
HAL_PCDEx_BCD_VBUSDetect(&hpcd_USB_FS); HAL_PCDEx_BCD_VBUSDetect(&hpcd_USB_FS);
} else { } else {
#ifdef KISS_LOGGING
printf("VBUS not detected\r\n"); printf("VBUS not detected\r\n");
#endif
} }
/* Infinite loop */ /* Infinite loop */
for(;;) for(;;)
@ -1474,6 +1493,8 @@ void _Error_Handler(char *file, int line)
#endif #endif
snprintf(error_message, sizeof(error_message), "Error: %s:%d", file, line); snprintf(error_message, sizeof(error_message), "Error: %s:%d", file, line);
stop_now = 0;
go_back_to_sleep = 0;
NVIC_SystemReset(); NVIC_SystemReset();
/* USER CODE END Error_Handler_Debug */ /* USER CODE END Error_Handler_Debug */
} }

Wyświetl plik

@ -45,18 +45,21 @@ void startIOEventTask(void const*)
indicate_on(); 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 (! hardware.load() or reset_requested or !hardware.crc_ok())
{ {
if (reset_requested) { if (reset_requested) {
INFO("Hardware reset requested."); INFO("Hardware reset requested.");
}
hardware.init();
hardware.store();
} }
hardware.init();
hardware.store();
}
if (!go_back_to_sleep) {
hardware.debug(); hardware.debug();
audio::init_log_volume(); audio::init_log_volume();
@ -96,9 +99,13 @@ void startIOEventTask(void const*)
} }
} else { } else {
if (!usb_wake_state) { if (!usb_wake_state) {
DEBUG("USB disconnected -- shutdown");
shutdown(0); shutdown(0);
} else { } else {
osTimerStart(usbShutdownTimerHandle, 2000); DEBUG("USB connected -- negotiate");
HAL_GPIO_WritePin(BT_SLEEP_GPIO_Port, BT_SLEEP_Pin,
GPIO_PIN_RESET);
osTimerStart(usbShutdownTimerHandle, 5000);
} }
} }
@ -135,9 +142,11 @@ void startIOEventTask(void const*)
break; break;
case CMD_USB_DISCONNECTED: case CMD_USB_DISCONNECTED:
INFO("VBUS Lost"); INFO("VBUS Lost");
charging_enabled = 0;
if (powerOffViaUSB()) { if (powerOffViaUSB()) {
shutdown(0); // ***NO RETURN*** shutdown(0); // ***NO RETURN***
} else { } else {
hpcd_USB_FS.Instance->BCDR = 0;
HAL_PCD_MspDeInit(&hpcd_USB_FS); HAL_PCD_MspDeInit(&hpcd_USB_FS);
HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_SET);
if (ioport != getUsbPort()) if (ioport != getUsbPort())
@ -257,6 +266,7 @@ void startIOEventTask(void const*)
break; break;
case CMD_USB_CONNECTED: case CMD_USB_CONNECTED:
INFO("VBUS Detected"); INFO("VBUS Detected");
MX_USB_DEVICE_Init();
HAL_PCD_MspInit(&hpcd_USB_FS); HAL_PCD_MspInit(&hpcd_USB_FS);
hpcd_USB_FS.Instance->BCDR = 0; hpcd_USB_FS.Instance->BCDR = 0;
HAL_PCDEx_ActivateBCD(&hpcd_USB_FS); HAL_PCDEx_ActivateBCD(&hpcd_USB_FS);
@ -265,24 +275,26 @@ void startIOEventTask(void const*)
case CMD_USB_CHARGE_ENABLE: case CMD_USB_CHARGE_ENABLE:
INFO("USB charging enabled"); INFO("USB charging enabled");
HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_RESET);
charging_enabled = 1;
if (go_back_to_sleep) shutdown(0);
break; break;
case CMD_USB_DISCOVERY_COMPLETE: case CMD_USB_DISCOVERY_COMPLETE:
INFO("USB discovery complete"); INFO("USB discovery complete");
osTimerStop(usbShutdownTimerHandle); osTimerStop(usbShutdownTimerHandle);
if (go_back_to_sleep) shutdown(0);
USBD_Start(&hUsbDeviceFS); USBD_Start(&hUsbDeviceFS);
initCDC(); initCDC();
break; break;
case CMD_USB_DISCOVERY_ERROR: case CMD_USB_DISCOVERY_ERROR:
// This happens when powering VBUS from a bench supply. // This happens when powering VBUS from a bench supply.
osTimerStop(usbShutdownTimerHandle); osTimerStop(usbShutdownTimerHandle);
HAL_PCDEx_DeActivateBCD(&hpcd_USB_FS);
if (HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin) == GPIO_PIN_SET) if (HAL_GPIO_ReadPin(USB_POWER_GPIO_Port, USB_POWER_Pin) == GPIO_PIN_SET)
{ {
INFO("Not a recognized USB charging device"); INFO("Not a recognized USB charging device");
INFO("USB charging enabled"); INFO("USB charging enabled");
HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_RESET);
charging_enabled = 1;
} }
hpcd_USB_FS.Instance->BCDR = 0;
if (go_back_to_sleep) shutdown(0); if (go_back_to_sleep) shutdown(0);
break; break;
case CMD_BT_DEEP_SLEEP: case CMD_BT_DEEP_SLEEP:

Wyświetl plik

@ -26,7 +26,7 @@ int powerOffViaUSB(void)
namespace mobilinkd { namespace tnc { namespace kiss { namespace mobilinkd { namespace tnc { namespace kiss {
const char FIRMWARE_VERSION[] = "1.0.0"; const char FIRMWARE_VERSION[] = "1.0.1";
const char HARDWARE_VERSION[] = "Mobilinkd TNC3 2.1.1"; const char HARDWARE_VERSION[] = "Mobilinkd TNC3 2.1.1";
Hardware& settings() Hardware& settings()