1
0
mirror of https://github.com/peterantypas/maiana.git synced 2025-05-15 15:00:08 -07:00

Merge pull request #127 from rszemeti/master

Support for 10.0.1
This commit is contained in:
Peter Antypas 2023-03-01 06:42:28 -08:00 committed by GitHub
commit 1aaf9695ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 861 additions and 1 deletions

View File

@ -109,6 +109,8 @@ extern const char *BSP_HW_REV;
#include <bsp_9_3.hpp>
#elif BOARD_REV == 100
#include <bsp_10_0.hpp>
#elif BOARD_REV == 101
#include <bsp_10_1.hpp>
#elif BOARD_REV == 105
#include <bsp_10_5.hpp>
#elif BOARD_REV == 109

View File

@ -0,0 +1,98 @@
/*
Copyright (c) 2016-2020 Peter Antypas
This file is part of the MAIANA transponder firmware.
The firmware is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
*/
#ifndef INC_BSP_10_1_HPP_
#define INC_BSP_10_1_HPP_
// GPIO Pin definitions
#define GNSS_EN_PORT GPIOC
#define GNSS_EN_PIN GPIO_PIN_14
#define TRX_IC_CLK_PORT GPIOC
#define TRX_IC_CLK_PIN GPIO_PIN_15
#define CS2_PORT GPIOA
#define CS2_PIN GPIO_PIN_0
#define RX_EVT_PORT GPIOA
#define RX_EVT_PIN GPIO_PIN_1
#define GNSS_1PPS_PORT GPIOA
#define GNSS_1PPS_PIN GPIO_PIN_2
#define GNSS_NMEA_RX_PORT GPIOA
#define GNSS_NMEA_RX_PIN GPIO_PIN_3
#define CS1_PORT GPIOA
#define CS1_PIN GPIO_PIN_4
#define SCK_PORT GPIOA
#define SCK_PIN GPIO_PIN_5
#define MISO_PORT GPIOA
#define MISO_PIN GPIO_PIN_6
#define MOSI_PORT GPIOA
#define MOSI_PIN GPIO_PIN_7
#define SDN1_PORT GPIOB
#define SDN1_PIN GPIO_PIN_0
#define TRX_IC_DATA_PORT GPIOB
#define TRX_IC_DATA_PIN GPIO_PIN_1
#define PA_BIAS_PORT GPIOA
#define PA_BIAS_PIN GPIO_PIN_8
#define UART_TX_PORT GPIOA
#define UART_TX_PIN GPIO_PIN_9
#define UART_RX_PORT GPIOA
#define UART_RX_PIN GPIO_PIN_10
#define GNSS_STATE_PORT GPIOA
#define GNSS_STATE_PIN GPIO_PIN_11
#define TX_DISABLE_PORT GPIOA
#define TX_DISABLE_PIN GPIO_PIN_12
#define SDN2_PORT GPIOA
#define SDN2_PIN GPIO_PIN_15
#define RX_IC_CLK_PORT GPIOB
#define RX_IC_CLK_PIN GPIO_PIN_3
#define RX_IC_DATA_PORT GPIOB
#define RX_IC_DATA_PIN GPIO_PIN_4
#define TX_EVT_PORT GPIOB
#define TX_EVT_PIN GPIO_PIN_5
#define I2C_SCL_PORT GPIOB
#define I2C_SCL_PIN GPIO_PIN_6
#define I2C_SDA_PORT GPIOB
#define I2C_SDA_PIN GPIO_PIN_7
#endif /* INC_BSP_5_0_HPP_ */

View File

@ -157,7 +157,11 @@ void Transceiver::configureGPIOsForTX()
gpiocfg.GPIO0 = 0x00; // No change
gpiocfg.GPIO1 = 0x04; // RX/TX bit data
gpiocfg.GPIO2 = 0x1F; // RX/TX bit clock
gpiocfg.GPIO3 = 0x20; // RX_STATE; high in TX, low in RX
#if BOARD_REV < 105
gpiocfg.GPIO3 = 0x21; // RX_STATE; low during TX and high during RX
#else
gpiocfg.GPIO3 = 0x20; // RX_STATE; high during TX and low during RX
#endif
gpiocfg.NIRQ = 0x00; // No change
gpiocfg.SDO = 0x00; // No change
gpiocfg.GENCFG = 0x00; // No change
@ -328,7 +332,11 @@ void Transceiver::configureGPIOsForRX()
gpiocfg.GPIO0 = 0x00; // No change
gpiocfg.GPIO1 = 0x14; // RX data bits
gpiocfg.GPIO2 = 0x1F; // RX/TX data clock
#if BOARD_REV < 105
gpiocfg.GPIO3 = 0x21; // RX_STATE; high during TX and low during RX
#else
gpiocfg.GPIO3 = 0x20; // RX_STATE; high during TX and low during RX
#endif
gpiocfg.NIRQ = 0x00; // No change
gpiocfg.SDO = 0x00; // No change
gpiocfg.GENCFG = 0x00; // No change

View File

@ -0,0 +1,752 @@
/*
Copyright (c) 2016-2020 Peter Antypas
This file is part of the MAIANA transponder firmware.
The firmware is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
*/
#include "bsp.hpp"
#include <stm32l4xx_hal.h>
#include "printf_serial.h"
#include <string.h>
#if BOARD_REV==101
#define EEPROM_ADDRESS (0x50 << 1)
#define EEPROM_STATION_ADDRESS 0x00
#define EEPROM_CONFIG_ADDRESS 0x40
#define STATION_DATA_FLASH_ADDRESS 0x0800F800
const char *BSP_HW_REV = "10.0.1";
I2C_HandleTypeDef hi2c1;
SPI_HandleTypeDef hspi1;
IWDG_HandleTypeDef hiwdg;
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart1;
TIM_HandleTypeDef htim2;
void SystemClock_Config();
char_input_cb gnssInputCallback = nullptr;
char_input_cb terminalInputCallback = nullptr;
irq_callback ppsCallback = nullptr;
irq_callback sotdmaCallback = nullptr;
irq_callback trxClockCallback = nullptr;
irq_callback rxClockCallback = nullptr;
irq_callback tickCallback = nullptr;
// This should be plenty big (no need to be a whole flash page)
typedef union
{
StationData station;
uint64_t dw[32];
} StationDataPage;
StationData __station = {0};
typedef struct
{
GPIO_TypeDef *port;
GPIO_InitTypeDef gpio;
GPIO_PinState init;
} GPIO;
static const GPIO __gpios[] = {
{GNSS_EN_PORT, {GNSS_EN_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_SET},
{TRX_IC_CLK_PORT, {TRX_IC_CLK_PIN, GPIO_MODE_IT_RISING, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
{TX_DISABLE_PORT, {TX_DISABLE_PIN, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_SPEED_LOW, 0}, GPIO_PIN_SET},
{CS2_PORT, {CS2_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, 0}, GPIO_PIN_SET},
{RX_EVT_PORT, {RX_EVT_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
{GNSS_1PPS_PORT, {GNSS_1PPS_PIN, GPIO_MODE_IT_RISING, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
{GNSS_NMEA_RX_PORT, {GNSS_NMEA_RX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_SPEED_LOW, GPIO_AF7_USART2}, GPIO_PIN_RESET},
{CS1_PORT, {CS1_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, 0}, GPIO_PIN_SET},
{SCK_PORT, {SCK_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, GPIO_AF5_SPI1}, GPIO_PIN_SET},
{MISO_PORT, {MISO_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, GPIO_AF5_SPI1}, GPIO_PIN_SET},
{MOSI_PORT, {MOSI_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, GPIO_AF5_SPI1}, GPIO_PIN_SET},
{SDN1_PORT, {SDN1_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_SET},
{TRX_IC_DATA_PORT, {TRX_IC_DATA_PIN, GPIO_MODE_INPUT, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
{TX_EVT_PORT, {TX_EVT_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
{UART_TX_PORT, {UART_TX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_SPEED_LOW, GPIO_AF7_USART1}, GPIO_PIN_RESET},
{UART_RX_PORT, {UART_RX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_SPEED_LOW, GPIO_AF7_USART1}, GPIO_PIN_RESET},
{GNSS_STATE_PORT, {GNSS_STATE_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
{SDN2_PORT, {SDN2_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_SET},
{RX_IC_CLK_PORT, {RX_IC_CLK_PIN, GPIO_MODE_IT_RISING, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
{RX_IC_DATA_PORT, {RX_IC_DATA_PIN, GPIO_MODE_INPUT, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
{PA_BIAS_PORT, {PA_BIAS_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
{I2C_SCL_PORT, {I2C_SCL_PIN, GPIO_MODE_AF_OD, GPIO_PULLUP, GPIO_SPEED_HIGH, GPIO_AF4_I2C1}, GPIO_PIN_SET},
{I2C_SDA_PORT, {I2C_SDA_PIN, GPIO_MODE_AF_OD, GPIO_PULLUP, GPIO_SPEED_HIGH, GPIO_AF4_I2C1}, GPIO_PIN_SET},
};
extern "C"
{
void Error_Handler(uint8_t i)
{
asm("BKPT 0");
printf_serial_now("[ERROR %d]\r\n", i);
//printf_serial_now("[ERROR] ***** System error handler resetting *****\r\n");
//NVIC_SystemReset();
}
}
void gpio_pin_init();
void bsp_hw_init()
{
HAL_Init();
SystemClock_Config();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_TIM2_CLK_ENABLE();
__HAL_RCC_I2C1_CLK_ENABLE();
gpio_pin_init();
// USART1 (main UART)
huart1.Instance = USART1;
huart1.Init.BaudRate = 38400;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
HAL_UART_Init(&huart1);
HAL_NVIC_SetPriority(USART1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
// SPI
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler(0);
}
__HAL_SPI_ENABLE(&hspi1);
// I2C
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00702991;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler(0);
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler(0);
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler(0);
}
// USART2 (GNSS, RX only)
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
HAL_UART_Init(&huart2);
HAL_NVIC_SetPriority(USART2_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
// TIM2 for SOTDMA (37.5Hz)
uint32_t period = (SystemCoreClock / 37.5) - 1;
__HAL_RCC_TIM2_CLK_ENABLE();
htim2.Instance = TIM2;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = period;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&htim2);
// 1PPS signal
HAL_NVIC_SetPriority(EXTI2_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
// SOTDMA
HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
// RF IC clock interrupts
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
HAL_NVIC_SetPriority(EXTI3_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
bsp_read_station_data(&__station);
}
void SystemClock_Config()
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
/**Initializes the CPU, AHB and APB bus clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 10; // 80 MHz
#if defined(STM32L432xx) || defined(STM32L431xx)
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
#endif
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler(0);
}
/**Initializes the CPU, AHB and APB bus clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler(0);
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_HSI;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler(0);
}
/**Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler(0);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
void gpio_pin_init()
{
for ( unsigned i = 0; i < sizeof __gpios / sizeof(GPIO); ++i )
{
const GPIO* io = &__gpios[i];
if ( io->gpio.Mode == GPIO_MODE_OUTPUT_PP || io->gpio.Mode == GPIO_MODE_OUTPUT_OD )
{
HAL_GPIO_WritePin(io->port, io->gpio.Pin, io->init);
}
HAL_GPIO_Init(io->port, (GPIO_InitTypeDef*)&io->gpio);
}
}
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/**
* Some of these interrupts will be managed and configured in FreeRTOS
*/
/* System interrupt init*/
/* MemoryManagement_IRQn interrupt configuration */
HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
/* BusFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
/* UsageFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
/* SVCall_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SVCall_IRQn, 10, 0);
/* DebugMonitor_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
/* PendSV_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PendSV_IRQn, 10, 0);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
bool bsp_is_tx_hardwired()
{
// Always true for this board. It will get more involved later. Or maybe never ...
return true;
}
void bsp_erase_flash_station_data()
{
uint32_t page = (STATION_DATA_FLASH_ADDRESS - FLASH_BASE) / FLASH_PAGE_SIZE;
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
if ( HAL_FLASH_Unlock() != HAL_OK )
return;
FLASH_EraseInitTypeDef erase;
erase.TypeErase = FLASH_TYPEERASE_PAGES;
erase.Banks = FLASH_BANK_1;
erase.Page = page;
erase.NbPages = 1;
uint32_t errPage;
HAL_FLASHEx_Erase(&erase, &errPage);
HAL_FLASH_Lock();
}
void bsp_read_station_data(StationData *data)
{
/**
* If there is legacy data in MCU flash, migrate it automatically to EEPROM!!!
*/
StationData *__d = (StationData*)STATION_DATA_FLASH_ADDRESS;
if ( __d->magic == STATION_DATA_MAGIC )
{
bsp_write_station_data(*__d);
bsp_erase_flash_station_data();
}
uint8_t *d = (uint8_t*)data;
for ( uint8_t i = 0; i < sizeof (StationData); ++i, ++d )
{
HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS|1, i+EEPROM_STATION_ADDRESS, 1, d, 1, 5);
}
}
void bsp_write_station_data(const StationData &data)
{
__station = data;
uint8_t *d = (uint8_t*)&__station;
for ( uint8_t i = 0; i < sizeof (StationData); ++i, ++d )
{
HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, i+EEPROM_STATION_ADDRESS, 1, d, 1, 5);
HAL_Delay(5);
}
}
void bsp_erase_station_data()
{
bsp_write_station_data({0});
}
bool bsp_is_station_data_provisioned()
{
return __station.magic == STATION_DATA_MAGIC;
}
void bsp_read_config_flags(ConfigFlags *flags)
{
uint8_t *d = (uint8_t*)flags;
for ( uint8_t i = 0; i < sizeof (ConfigFlags); ++i, ++d )
{
HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS|1, i+EEPROM_CONFIG_ADDRESS, 1, d, 1, 5);
}
}
void bsp_write_config_flags(const ConfigFlags &flags)
{
ConfigFlags __f = flags;
uint8_t *d = (uint8_t*)&__f;
for ( uint8_t i = 0; i < sizeof (ConfigFlags); ++i, ++d )
{
HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, i+EEPROM_CONFIG_ADDRESS, 1, d, 1, 5);
HAL_Delay(5);
}
}
void bsp_erase_config_flags()
{
bsp_write_config_flags({0});
}
void bsp_set_rx_mode()
{
HAL_GPIO_WritePin(PA_BIAS_PORT, PA_BIAS_PIN, GPIO_PIN_RESET); // Kill the RF MOSFET bias voltage
GPIO_InitTypeDef gpio;
gpio.Pin = TRX_IC_DATA_PIN;
gpio.Mode = GPIO_MODE_INPUT;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
gpio.Pull = GPIO_NOPULL;
HAL_GPIO_Init(TRX_IC_DATA_PORT, &gpio);
}
void bsp_rx_led_on()
{
HAL_GPIO_WritePin(RX_EVT_PORT, RX_EVT_PIN, GPIO_PIN_SET);
}
void bsp_rx_led_off()
{
HAL_GPIO_WritePin(RX_EVT_PORT, RX_EVT_PIN, GPIO_PIN_RESET);
}
void bsp_tx_led_on()
{
#if LEGACY_BREAKOUTS
HAL_GPIO_WritePin(TX_EVT_PORT, TX_EVT_PIN, GPIO_PIN_RESET);
#else
HAL_GPIO_WritePin(TX_EVT_PORT, TX_EVT_PIN, GPIO_PIN_SET);
#endif
}
void bsp_tx_led_off()
{
#if LEGACY_BREAKOUTS
HAL_GPIO_WritePin(TX_EVT_PORT, TX_EVT_PIN, GPIO_PIN_SET);
#else
HAL_GPIO_WritePin(TX_EVT_PORT, TX_EVT_PIN, GPIO_PIN_RESET);
#endif
}
void bsp_gps_led_on()
{
HAL_GPIO_WritePin(GNSS_STATE_PORT, GNSS_STATE_PIN, GPIO_PIN_SET);
}
void bsp_gps_led_off()
{
HAL_GPIO_WritePin(GNSS_STATE_PORT, GNSS_STATE_PIN, GPIO_PIN_RESET);
}
void bsp_set_tx_mode()
{
GPIO_InitTypeDef gpio;
gpio.Pin = TRX_IC_DATA_PIN;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
gpio.Pull = GPIO_NOPULL;
HAL_GPIO_Init(TRX_IC_DATA_PORT, &gpio);
HAL_GPIO_WritePin(PA_BIAS_PORT, PA_BIAS_PIN, GPIO_PIN_SET); // RF MOSFET bias voltage
}
void bsp_gnss_on()
{
HAL_GPIO_WritePin(GNSS_EN_PORT, GNSS_EN_PIN, GPIO_PIN_SET);
}
void bsp_gnss_off()
{
HAL_GPIO_WritePin(GNSS_EN_PORT, GNSS_EN_PIN, GPIO_PIN_RESET);
}
bool bsp_is_gnss_on()
{
return HAL_GPIO_ReadPin(GNSS_EN_PORT, GNSS_EN_PIN) == GPIO_PIN_RESET;
}
void USART_putc(USART_TypeDef* USARTx, char c)
{
while ( !(USARTx->ISR & USART_ISR_TXE) )
;
USARTx->TDR = c;
}
void bsp_write_char(char c)
{
USART_putc(USART1, c);
}
void bsp_write_string(const char *s)
{
for ( int i = 0; s[i] != 0; ++i )
USART_putc(USART1, s[i]);
}
void bsp_start_wdt()
{
IWDG_InitTypeDef iwdg;
iwdg.Prescaler = IWDG_PRESCALER_16;
iwdg.Reload = 0x0fff;
iwdg.Window = 0x0fff;
hiwdg.Instance = IWDG;
hiwdg.Init = iwdg;
HAL_IWDG_Init(&hiwdg);
}
void bsp_refresh_wdt()
{
HAL_IWDG_Refresh(&hiwdg);
}
void bsp_set_gnss_input_callback(char_input_cb cb)
{
gnssInputCallback = cb;
}
void bsp_set_terminal_input_callback(char_input_cb cb)
{
terminalInputCallback = cb;
}
void bsp_set_tick_callback(irq_callback cb)
{
tickCallback = cb;
}
void bsp_start_sotdma_timer()
{
HAL_TIM_Base_Start_IT(&htim2);
}
void bsp_stop_sotdma_timer()
{
HAL_TIM_Base_Stop_IT(&htim2);
}
void bsp_set_gnss_1pps_callback(irq_callback cb)
{
ppsCallback = cb;
}
void bsp_set_trx_clk_callback(irq_callback cb)
{
trxClockCallback = cb;
}
void bsp_set_rx_clk_callback(irq_callback cb)
{
rxClockCallback = cb;
}
void bsp_set_gnss_sotdma_timer_callback(irq_callback cb)
{
sotdmaCallback = cb;
}
uint32_t bsp_get_sotdma_timer_value()
{
return TIM2->CNT;
}
void bsp_set_sotdma_timer_value(uint32_t v)
{
TIM2->CNT = v;
}
uint32_t bsp_get_system_clock()
{
return SystemCoreClock;
}
uint8_t bsp_tx_spi_byte(uint8_t data)
{
uint8_t result = 0;
HAL_SPI_TransmitReceive(&hspi1, &data, &result, 1, 2);
return result;
}
void bsp_reboot()
{
NVIC_SystemReset();
}
bool bsp_is_tx_disabled()
{
return HAL_GPIO_ReadPin(TX_DISABLE_PORT, TX_DISABLE_PIN) == GPIO_PIN_RESET;
}
void bsp_enter_dfu()
{
// Cut off the GPS signals immediately to prevent its UART from transmitting and hijacking the bootloader upon reset
bsp_gnss_off();
HAL_Delay(1000);
// This flag simply tells main() to jump to the ROM bootloader immediately upon reset, before initializing anything
*(uint32_t*)BOOTMODE_ADDRESS = DFU_FLAG_MAGIC;
bsp_reboot();
}
void bsp_signal_rx_event()
{
HAL_GPIO_WritePin(RX_EVT_PORT, RX_EVT_PIN, GPIO_PIN_SET);
}
void bsp_signal_gps_status(bool tracking)
{
HAL_GPIO_WritePin(GNSS_STATE_PORT, GNSS_STATE_PIN, tracking ? GPIO_PIN_SET: GPIO_PIN_RESET);
}
extern "C"
{
void USART1_IRQHandler(void)
{
if ( __HAL_UART_GET_IT(&huart1, UART_IT_RXNE) )
{
__HAL_UART_CLEAR_IT(&huart1, UART_IT_RXNE);
char c = USART1->RDR;
if ( terminalInputCallback )
terminalInputCallback(c);
}
}
void EXTI2_IRQHandler(void)
{
if ( __HAL_GPIO_EXTI_GET_IT(GNSS_1PPS_PIN) != RESET )
{
__HAL_GPIO_EXTI_CLEAR_IT(GNSS_1PPS_PIN);
if ( ppsCallback )
ppsCallback();
}
}
void USART2_IRQHandler()
{
if ( __HAL_UART_GET_IT(&huart2, UART_IT_RXNE) )
{
__HAL_UART_CLEAR_IT(&huart2, UART_IT_RXNE);
char c = (char)USART2->RDR;
if ( gnssInputCallback )
gnssInputCallback(c);
}
}
void TIM2_IRQHandler(void)
{
if(__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_UPDATE) !=RESET)
{
__HAL_TIM_CLEAR_IT(&htim2, TIM_IT_UPDATE);
if ( sotdmaCallback )
sotdmaCallback();
}
}
}
void EXTI3_IRQHandler(void)
{
if ( __HAL_GPIO_EXTI_GET_IT(RX_IC_CLK_PIN) != RESET )
{
__HAL_GPIO_EXTI_CLEAR_IT(RX_IC_CLK_PIN);
if ( rxClockCallback )
rxClockCallback();
}
}
void EXTI15_10_IRQHandler(void)
{
if ( __HAL_GPIO_EXTI_GET_IT(TRX_IC_CLK_PIN) != RESET )
{
__HAL_GPIO_EXTI_CLEAR_IT(TRX_IC_CLK_PIN);
if ( trxClockCallback )
trxClockCallback();
}
}
void HAL_SYSTICK_Callback()
{
if ( tickCallback )
tickCallback();
}
}
#endif