F2 F3 deprecate (#267)
* move f3-1 to f4, remove f3 * remove f2 * remove firmware F3 for pipeline * remove patch for F4 makefile * fix fw makefile * migrate bootloader to f4
This commit is contained in:
13
firmware/targets/f4/api-hal/api-hal-boot.c
Normal file
13
firmware/targets/f4/api-hal/api-hal-boot.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <api-hal-boot.h>
|
||||
#include <stm32wbxx_ll_rtc.h>
|
||||
|
||||
#define BOOT_REQUEST_NONE 0x00000000
|
||||
#define BOOT_REQUEST_DFU 0xDF00B000
|
||||
|
||||
void api_hal_boot_set_mode(ApiHalBootMode mode) {
|
||||
if (mode == ApiHalBootModeNormal) {
|
||||
LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_NONE);
|
||||
} else if (mode == ApiHalBootModeDFU) {
|
||||
LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU);
|
||||
}
|
||||
}
|
37
firmware/targets/f4/api-hal/api-hal-bt.c
Normal file
37
firmware/targets/f4/api-hal/api-hal-bt.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <api-hal-bt.h>
|
||||
#include <app_entry.h>
|
||||
#include <ble.h>
|
||||
|
||||
void api_hal_bt_init() {
|
||||
// Explicitly tell that we are in charge of CLK48 domain
|
||||
HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID);
|
||||
// Start Core2, init HCI and start GAP/GATT
|
||||
APPE_Init();
|
||||
}
|
||||
|
||||
void api_hal_bt_dump_state(string_t buffer) {
|
||||
BleGlueStatus status = APPE_Status();
|
||||
if (status == BleGlueStatusStarted) {
|
||||
uint8_t HCI_Version;
|
||||
uint16_t HCI_Revision;
|
||||
uint8_t LMP_PAL_Version;
|
||||
uint16_t Manufacturer_Name;
|
||||
uint16_t LMP_PAL_Subversion;
|
||||
|
||||
tBleStatus ret = hci_read_local_version_information(
|
||||
&HCI_Version, &HCI_Revision, &LMP_PAL_Version, &Manufacturer_Name, &LMP_PAL_Subversion
|
||||
);
|
||||
|
||||
string_cat_printf(buffer,
|
||||
"Ret: %d, HCI_Version: %d, HCI_Revision: %d, LMP_PAL_Version: %d, Manufacturer_Name: %d, LMP_PAL_Subversion: %d",
|
||||
ret, HCI_Version, HCI_Revision, LMP_PAL_Version, Manufacturer_Name, LMP_PAL_Subversion
|
||||
);
|
||||
} else {
|
||||
string_cat_printf(buffer, "BLE not ready");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool api_hal_bt_is_alive() {
|
||||
return APPE_Status() == BleGlueStatusStarted;
|
||||
}
|
27
firmware/targets/f4/api-hal/api-hal-delay.c
Normal file
27
firmware/targets/f4/api-hal/api-hal-delay.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "api-hal-delay.h"
|
||||
#include "assert.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
static uint32_t clk_per_microsecond;
|
||||
|
||||
void delay_us_init_DWT(void) {
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
||||
DWT->CYCCNT = 0U;
|
||||
clk_per_microsecond = SystemCoreClock / 1000000.0f;
|
||||
}
|
||||
|
||||
void delay_us(float microseconds) {
|
||||
uint32_t start = DWT->CYCCNT;
|
||||
uint32_t time_ticks = microseconds * clk_per_microsecond;
|
||||
while((DWT->CYCCNT - start) < time_ticks) {
|
||||
};
|
||||
}
|
||||
|
||||
// cannot be used in ISR
|
||||
// TODO add delay_ISR variant
|
||||
void delay(float milliseconds) {
|
||||
uint32_t ticks = milliseconds / (1000.0f / osKernelGetTickFreq());
|
||||
osStatus_t result = osDelay(ticks);
|
||||
assert(result == osOK);
|
||||
}
|
44
firmware/targets/f4/api-hal/api-hal-gpio.c
Normal file
44
firmware/targets/f4/api-hal/api-hal-gpio.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "api-hal-gpio.h"
|
||||
#include "api-hal-resources.h"
|
||||
|
||||
// init GPIO
|
||||
void hal_gpio_init(
|
||||
const GpioPin* gpio,
|
||||
const GpioMode mode,
|
||||
const GpioPull pull,
|
||||
const GpioSpeed speed) {
|
||||
// TODO: Alternate Functions
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
GPIO_InitStruct.Pin = gpio->pin;
|
||||
GPIO_InitStruct.Mode = mode;
|
||||
GPIO_InitStruct.Pull = pull;
|
||||
GPIO_InitStruct.Speed = speed;
|
||||
|
||||
HAL_GPIO_Init(gpio->port, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
bool hal_gpio_read_sd_detect(void) {
|
||||
bool result = false;
|
||||
|
||||
// TODO open record
|
||||
const GpioPin* sd_cs_record = &sd_cs_gpio;
|
||||
|
||||
// configure pin as input
|
||||
gpio_init_ex(sd_cs_record, GpioModeInput, GpioPullUp, GpioSpeedVeryHigh);
|
||||
delay(50);
|
||||
|
||||
// if gpio_read == 0 return true else return false
|
||||
result = !gpio_read(sd_cs_record);
|
||||
|
||||
// configure pin back
|
||||
gpio_init_ex(sd_cs_record, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
|
||||
delay(50);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void enable_cc1101_irq() {
|
||||
HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
|
||||
}
|
77
firmware/targets/f4/api-hal/api-hal-gpio.h
Normal file
77
firmware/targets/f4/api-hal/api-hal-gpio.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
#include "main.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// this defined in xx_hal_gpio.c, so...
|
||||
#define GPIO_NUMBER (16U)
|
||||
|
||||
typedef enum {
|
||||
GpioModeInput = GPIO_MODE_INPUT,
|
||||
GpioModeOutputPushPull = GPIO_MODE_OUTPUT_PP,
|
||||
GpioModeOutputOpenDrain = GPIO_MODE_OUTPUT_OD,
|
||||
GpioModeAltFunctionPushPull = GPIO_MODE_AF_PP,
|
||||
GpioModeAltFunctionOpenDrain = GPIO_MODE_AF_OD,
|
||||
GpioModeAnalog = GPIO_MODE_ANALOG,
|
||||
GpioModeInterruptRise = GPIO_MODE_IT_RISING,
|
||||
GpioModeInterruptFall = GPIO_MODE_IT_FALLING,
|
||||
GpioModeInterruptRiseFall = GPIO_MODE_IT_RISING_FALLING,
|
||||
GpioModeEventRise = GPIO_MODE_EVT_RISING,
|
||||
GpioModeEventFall = GPIO_MODE_EVT_FALLING,
|
||||
GpioModeEventRiseFall = GPIO_MODE_EVT_RISING_FALLING,
|
||||
} GpioMode;
|
||||
|
||||
typedef enum {
|
||||
GpioSpeedLow = GPIO_SPEED_FREQ_LOW,
|
||||
GpioSpeedMedium = GPIO_SPEED_FREQ_MEDIUM,
|
||||
GpioSpeedHigh = GPIO_SPEED_FREQ_HIGH,
|
||||
GpioSpeedVeryHigh = GPIO_SPEED_FREQ_VERY_HIGH,
|
||||
} GpioSpeed;
|
||||
|
||||
typedef enum {
|
||||
GpioPullNo = GPIO_NOPULL,
|
||||
GpioPullUp = GPIO_PULLUP,
|
||||
GpioPullDown = GPIO_PULLDOWN,
|
||||
} GpioPull;
|
||||
|
||||
typedef struct {
|
||||
GPIO_TypeDef* port;
|
||||
uint16_t pin;
|
||||
} GpioPin;
|
||||
|
||||
// init GPIO
|
||||
void hal_gpio_init(
|
||||
const GpioPin* gpio,
|
||||
const GpioMode mode,
|
||||
const GpioPull pull,
|
||||
const GpioSpeed speed);
|
||||
|
||||
// write value to GPIO, false = LOW, true = HIGH
|
||||
static inline void hal_gpio_write(const GpioPin* gpio, const bool state) {
|
||||
// writing to BSSR is an atomic operation
|
||||
if(state == true) {
|
||||
gpio->port->BSRR = gpio->pin;
|
||||
} else {
|
||||
gpio->port->BSRR = (uint32_t)gpio->pin << GPIO_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
// read value from GPIO, false = LOW, true = HIGH
|
||||
static inline bool hal_gpio_read(const GpioPin* gpio) {
|
||||
if((gpio->port->IDR & gpio->pin) != 0x00U) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool hal_gpio_read_sd_detect(void);
|
||||
|
||||
void enable_cc1101_irq();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
90
firmware/targets/f4/api-hal/api-hal-power.c
Normal file
90
firmware/targets/f4/api-hal/api-hal-power.c
Normal file
@@ -0,0 +1,90 @@
|
||||
#include <api-hal-power.h>
|
||||
#include <main.h>
|
||||
#include <bq27220.h>
|
||||
#include <bq25896.h>
|
||||
|
||||
void HAL_RCC_CSSCallback(void) {
|
||||
LL_RCC_ForceBackupDomainReset();
|
||||
LL_RCC_ReleaseBackupDomainReset();
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void api_hal_power_init() {
|
||||
bq27220_init();
|
||||
bq25896_init();
|
||||
}
|
||||
|
||||
uint8_t api_hal_power_get_pct() {
|
||||
return bq27220_get_state_of_charge();
|
||||
}
|
||||
|
||||
bool api_hal_power_is_charging() {
|
||||
return bq25896_is_charging();
|
||||
}
|
||||
|
||||
void api_hal_power_off() {
|
||||
bq25896_poweroff();
|
||||
}
|
||||
|
||||
void api_hal_power_enable_otg() {
|
||||
bq25896_enable_otg();
|
||||
}
|
||||
|
||||
void api_hal_power_disable_otg() {
|
||||
bq25896_disable_otg();
|
||||
}
|
||||
|
||||
float api_hal_power_get_battery_voltage() {
|
||||
return (float)bq27220_get_voltage() / 1000.0f;
|
||||
}
|
||||
|
||||
float api_hal_power_get_battery_current() {
|
||||
return (float)bq27220_get_current() / 1000.0f;
|
||||
}
|
||||
|
||||
void api_hal_power_dump_state(string_t buffer) {
|
||||
BatteryStatus battery_status;
|
||||
OperationStatus operation_status;
|
||||
if (bq27220_get_battery_status(&battery_status) == BQ27220_ERROR
|
||||
|| bq27220_get_operation_status(&operation_status) == BQ27220_ERROR) {
|
||||
string_cat_printf(buffer, "Failed to get bq27220 status. Communication error.\r\n");
|
||||
} else {
|
||||
string_cat_printf(buffer,
|
||||
"bq27220: CALMD: %d, SEC0: %d, SEC1: %d, EDV2: %d, VDQ: %d, INITCOMP: %d, SMTH: %d, BTPINT: %d, CFGUPDATE: %d\r\n",
|
||||
operation_status.CALMD, operation_status.SEC0, operation_status.SEC1,
|
||||
operation_status.EDV2, operation_status.VDQ, operation_status.INITCOMP,
|
||||
operation_status.SMTH, operation_status.BTPINT, operation_status.CFGUPDATE
|
||||
);
|
||||
// Battery status register, part 1
|
||||
string_cat_printf(buffer,
|
||||
"bq27220: CHGINH: %d, FC: %d, OTD: %d, OTC: %d, SLEEP: %d, OCVFAIL: %d, OCVCOMP: %d, FD: %d\r\n",
|
||||
battery_status.CHGINH, battery_status.FC, battery_status.OTD,
|
||||
battery_status.OTC, battery_status.SLEEP, battery_status.OCVFAIL,
|
||||
battery_status.OCVCOMP, battery_status.FD
|
||||
);
|
||||
// Battery status register, part 2
|
||||
string_cat_printf(buffer,
|
||||
"bq27220: DSG: %d, SYSDWN: %d, TDA: %d, BATTPRES: %d, AUTH_GD: %d, OCVGD: %d, TCA: %d, RSVD: %d\r\n",
|
||||
battery_status.DSG, battery_status.SYSDWN, battery_status.TDA,
|
||||
battery_status.BATTPRES, battery_status.AUTH_GD, battery_status.OCVGD,
|
||||
battery_status.TCA, battery_status.RSVD
|
||||
);
|
||||
// Voltage and current info
|
||||
string_cat_printf(buffer,
|
||||
"bq27220: Full capacity: %dmAh, Remaining capacity: %dmAh, State of Charge: %d%%\r\n",
|
||||
bq27220_get_full_charge_capacity(), bq27220_get_remaining_capacity(),
|
||||
bq27220_get_state_of_charge()
|
||||
);
|
||||
string_cat_printf(buffer,
|
||||
"bq27220: Voltage: %dmV, Current: %dmA, Temperature: %dC\r\n",
|
||||
bq27220_get_voltage(), bq27220_get_current(), (bq27220_get_temperature() - 2731)/10
|
||||
);
|
||||
}
|
||||
|
||||
string_cat_printf(buffer,
|
||||
"bq25896: VBUS: %d, VSYS: %d, VBAT: %d, Current: %d, NTC: %dm%%\r\n",
|
||||
bq25896_get_vbus_voltage(), bq25896_get_vsys_voltage(),
|
||||
bq25896_get_vbat_voltage(), bq25896_get_vbat_current(),
|
||||
bq25896_get_ntc_mpct()
|
||||
);
|
||||
}
|
57
firmware/targets/f4/api-hal/api-hal-pwm.c
Normal file
57
firmware/targets/f4/api-hal/api-hal-pwm.c
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "api-hal-pwm.h"
|
||||
|
||||
void hal_pwm_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel) {
|
||||
tim->Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
tim->Init.Period = (uint32_t)((SystemCoreClock / (tim->Init.Prescaler + 1)) / freq);
|
||||
tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
HAL_TIM_PWM_Init(tim);
|
||||
|
||||
TIM_OC_InitTypeDef sConfigOC;
|
||||
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = (uint16_t)(tim->Init.Period * value);
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
|
||||
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
|
||||
HAL_TIM_PWM_ConfigChannel(tim, &sConfigOC, channel);
|
||||
HAL_TIM_PWM_Start(tim, channel);
|
||||
}
|
||||
|
||||
void hal_pwmn_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel) {
|
||||
tim->Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
tim->Init.Period = (uint32_t)((SystemCoreClock / (tim->Init.Prescaler + 1)) / freq - 1);
|
||||
tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
HAL_TIM_PWM_Init(tim);
|
||||
|
||||
TIM_OC_InitTypeDef sConfigOC;
|
||||
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = (uint16_t)(tim->Init.Period * value);
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
|
||||
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
|
||||
HAL_TIM_PWM_ConfigChannel(tim, &sConfigOC, channel);
|
||||
HAL_TIMEx_PWMN_Start(tim, channel);
|
||||
}
|
||||
|
||||
void hal_pwm_stop(TIM_HandleTypeDef* tim, uint32_t channel) {
|
||||
HAL_TIM_PWM_Stop(tim, channel);
|
||||
}
|
||||
|
||||
void hal_pwmn_stop(TIM_HandleTypeDef* tim, uint32_t channel) {
|
||||
HAL_TIMEx_PWMN_Stop(tim, channel);
|
||||
}
|
||||
|
||||
void irda_pwm_set(float value, float freq){
|
||||
hal_pwmn_set(value, freq, &IRDA_TX_TIM, IRDA_TX_CH);
|
||||
}
|
||||
|
||||
void irda_pwm_stop(){
|
||||
hal_pwmn_stop(&IRDA_TX_TIM, IRDA_TX_CH);
|
||||
}
|
11
firmware/targets/f4/api-hal/api-hal-pwm.h
Normal file
11
firmware/targets/f4/api-hal/api-hal-pwm.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "main.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
void hal_pwm_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel);
|
||||
void hal_pwmn_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel);
|
||||
void hal_pwm_stop(TIM_HandleTypeDef* tim, uint32_t channel);
|
||||
void hal_pwmn_stop(TIM_HandleTypeDef* tim, uint32_t channel);
|
||||
|
||||
void irda_pwm_set(float value, float freq);
|
||||
void irda_pwm_stop();
|
22
firmware/targets/f4/api-hal/api-hal-resources.c
Normal file
22
firmware/targets/f4/api-hal/api-hal-resources.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "main.h"
|
||||
#include "flipper_v2.h"
|
||||
|
||||
const GpioPin input_gpio[GPIO_INPUT_PINS_COUNT] = {
|
||||
{BUTTON_UP_GPIO_Port, BUTTON_UP_Pin},
|
||||
{BUTTON_DOWN_GPIO_Port, BUTTON_DOWN_Pin},
|
||||
{BUTTON_RIGHT_GPIO_Port, BUTTON_RIGHT_Pin},
|
||||
{BUTTON_LEFT_GPIO_Port, BUTTON_LEFT_Pin},
|
||||
{BUTTON_OK_GPIO_Port, BUTTON_OK_Pin},
|
||||
{BUTTON_BACK_GPIO_Port, BUTTON_BACK_Pin},
|
||||
};
|
||||
|
||||
const GpioPin led_gpio[3] = {
|
||||
{LED_RED_GPIO_Port, LED_RED_Pin},
|
||||
{LED_GREEN_GPIO_Port, LED_GREEN_Pin},
|
||||
{LED_BLUE_GPIO_Port, LED_BLUE_Pin}};
|
||||
|
||||
const GpioPin backlight_gpio = {DISPLAY_BACKLIGHT_GPIO_Port, DISPLAY_BACKLIGHT_Pin};
|
||||
const GpioPin sd_cs_gpio = {SD_CS_GPIO_Port, SD_CS_Pin};
|
||||
const GpioPin vibro_gpio = {VIBRO_GPIO_Port, VIBRO_Pin};
|
||||
const GpioPin ibutton_gpio = {iBTN_GPIO_Port, iBTN_Pin};
|
||||
const GpioPin cc1101_g0_gpio = {CC1101_G0_GPIO_Port, CC1101_G0_Pin};
|
16
firmware/targets/f4/api-hal/api-hal-resources.h
Normal file
16
firmware/targets/f4/api-hal/api-hal-resources.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "main.h"
|
||||
#include "flipper_v2.h"
|
||||
|
||||
#define DEBOUNCE_TICKS 10
|
||||
#define GPIO_INPUT_PINS_COUNT 6
|
||||
|
||||
extern const GpioPin input_gpio[GPIO_INPUT_PINS_COUNT];
|
||||
extern const bool input_invert[GPIO_INPUT_PINS_COUNT];
|
||||
|
||||
extern const GpioPin led_gpio[3];
|
||||
extern const GpioPin backlight_gpio;
|
||||
extern const GpioPin sd_cs_gpio;
|
||||
extern const GpioPin vibro_gpio;
|
||||
extern const GpioPin ibutton_gpio;
|
||||
extern const GpioPin cc1101_g0_gpio;
|
59
firmware/targets/f4/api-hal/api-hal-task.c
Normal file
59
firmware/targets/f4/api-hal/api-hal-task.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "cmsis_os.h"
|
||||
#include "api-hal-task.h"
|
||||
|
||||
//-----------------------------cmsis_os2.c-------------------------------
|
||||
// helpers to get isr context
|
||||
// get arch
|
||||
#ifndef __ARM_ARCH_6M__
|
||||
#define __ARM_ARCH_6M__ 0
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_7M__
|
||||
#define __ARM_ARCH_7M__ 0
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_7EM__
|
||||
#define __ARM_ARCH_7EM__ 0
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_8M_MAIN__
|
||||
#define __ARM_ARCH_8M_MAIN__ 0
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_7A__
|
||||
#define __ARM_ARCH_7A__ 0
|
||||
#endif
|
||||
|
||||
// get masks
|
||||
#if((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M_MAIN__ == 1U))
|
||||
#define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U))
|
||||
#elif(__ARM_ARCH_6M__ == 1U)
|
||||
#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
|
||||
#elif(__ARM_ARCH_7A__ == 1U)
|
||||
/* CPSR mask bits */
|
||||
#define CPSR_MASKBIT_I 0x80U
|
||||
|
||||
#define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U)
|
||||
#else
|
||||
#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
|
||||
#endif
|
||||
|
||||
// get is irq mode
|
||||
#if(__ARM_ARCH_7A__ == 1U)
|
||||
/* CPSR mode bitmasks */
|
||||
#define CPSR_MODE_USER 0x10U
|
||||
#define CPSR_MODE_SYSTEM 0x1FU
|
||||
|
||||
#define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
|
||||
#else
|
||||
#define IS_IRQ_MODE() (__get_IPSR() != 0U)
|
||||
#endif
|
||||
|
||||
// added osKernelGetState(), because KernelState is a static var
|
||||
#define IS_IRQ() (IS_IRQ_MODE() || (IS_IRQ_MASKED() && (osKernelGetState() == osKernelRunning)))
|
||||
//-------------------------end of cmsis_os2.c----------------------------
|
||||
|
||||
bool task_is_isr_context(void) {
|
||||
return IS_IRQ();
|
||||
}
|
||||
|
||||
bool task_equal(TaskHandle_t a, TaskHandle_t b) {
|
||||
if(a == NULL || b == NULL) return false;
|
||||
return a == b;
|
||||
}
|
13
firmware/targets/f4/api-hal/api-hal-task.h
Normal file
13
firmware/targets/f4/api-hal/api-hal-task.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "main.h"
|
||||
#include <cmsis_os.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Task stack size in bytes
|
||||
#define DEFAULT_STACK_SIZE 4096
|
||||
|
||||
// Max system tasks count
|
||||
#define MAX_TASK_COUNT 14
|
||||
|
||||
bool task_equal(TaskHandle_t a, TaskHandle_t b);
|
||||
bool task_is_isr_context(void);
|
8
firmware/targets/f4/api-hal/api-hal-tim.c
Normal file
8
firmware/targets/f4/api-hal/api-hal-tim.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "cmsis_os.h"
|
||||
#include "api-hal-tim.h"
|
||||
|
||||
void tim_irda_rx_init(void) {
|
||||
HAL_NVIC_SetPriority(TIM2_IRQn, 5, 0);
|
||||
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
|
||||
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
|
||||
}
|
4
firmware/targets/f4/api-hal/api-hal-tim.h
Normal file
4
firmware/targets/f4/api-hal/api-hal-tim.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "main.h"
|
||||
|
||||
void tim_irda_rx_init(void);
|
10
firmware/targets/f4/api-hal/api-hal-uuid.c
Normal file
10
firmware/targets/f4/api-hal/api-hal-uuid.c
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <api-hal-uid.h>
|
||||
#include <stm32wbxx.h>
|
||||
|
||||
size_t api_hal_uid_size() {
|
||||
return 64/8;
|
||||
}
|
||||
|
||||
const uint8_t* api_hal_uid() {
|
||||
return (const uint8_t *)UID64_BASE;
|
||||
}
|
92
firmware/targets/f4/api-hal/api-hal-vcp.c
Normal file
92
firmware/targets/f4/api-hal/api-hal-vcp.c
Normal file
@@ -0,0 +1,92 @@
|
||||
#include <api-hal-vcp.h>
|
||||
#include <usbd_cdc_if.h>
|
||||
#include <flipper_v2.h>
|
||||
#include <stream_buffer.h>
|
||||
|
||||
#define API_HAL_VCP_RX_BUFFER_SIZE 600
|
||||
|
||||
typedef struct {
|
||||
StreamBufferHandle_t rx_stream;
|
||||
osSemaphoreId_t tx_semaphore;
|
||||
volatile bool alive;
|
||||
volatile bool underrun;
|
||||
} ApiHalVcp;
|
||||
|
||||
ApiHalVcp api_hal_vcp;
|
||||
|
||||
static const uint8_t ascii_soh = 0x01;
|
||||
static const uint8_t ascii_eot = 0x04;
|
||||
|
||||
void _api_hal_vcp_init();
|
||||
void _api_hal_vcp_deinit();
|
||||
void _api_hal_vcp_control_line(uint8_t state);
|
||||
void _api_hal_vcp_rx_callback(const uint8_t* buffer, size_t size);
|
||||
void _api_hal_vcp_tx_complete(size_t size);
|
||||
|
||||
void api_hal_vcp_init() {
|
||||
api_hal_vcp.rx_stream = xStreamBufferCreate(API_HAL_VCP_RX_BUFFER_SIZE, 1);
|
||||
api_hal_vcp.tx_semaphore = osSemaphoreNew(1, 1, NULL);
|
||||
api_hal_vcp.alive = false;
|
||||
api_hal_vcp.underrun = false;
|
||||
}
|
||||
|
||||
void _api_hal_vcp_init() {
|
||||
osSemaphoreRelease(api_hal_vcp.tx_semaphore);
|
||||
}
|
||||
|
||||
void _api_hal_vcp_deinit() {
|
||||
api_hal_vcp.alive = false;
|
||||
osSemaphoreRelease(api_hal_vcp.tx_semaphore);
|
||||
}
|
||||
|
||||
void _api_hal_vcp_control_line(uint8_t state) {
|
||||
// bit 0: DTR state, bit 1: RTS state
|
||||
// bool dtr = state & 0b01;
|
||||
bool rts = state & 0b10;
|
||||
|
||||
if (rts) {
|
||||
api_hal_vcp.alive = true;
|
||||
_api_hal_vcp_rx_callback(&ascii_soh, 1); // SOH
|
||||
} else {
|
||||
api_hal_vcp.alive = false;
|
||||
_api_hal_vcp_rx_callback(&ascii_eot, 1); // EOT
|
||||
}
|
||||
|
||||
osSemaphoreRelease(api_hal_vcp.tx_semaphore);
|
||||
}
|
||||
|
||||
void _api_hal_vcp_rx_callback(const uint8_t* buffer, size_t size) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
size_t ret = xStreamBufferSendFromISR(api_hal_vcp.rx_stream, buffer, size, &xHigherPriorityTaskWoken);
|
||||
if (ret != size) {
|
||||
api_hal_vcp.underrun = true;
|
||||
}
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
void _api_hal_vcp_tx_complete(size_t size) {
|
||||
osSemaphoreRelease(api_hal_vcp.tx_semaphore);
|
||||
}
|
||||
|
||||
size_t api_hal_vcp_rx(uint8_t* buffer, size_t size) {
|
||||
return xStreamBufferReceive(api_hal_vcp.rx_stream, buffer, size, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void api_hal_vcp_tx(uint8_t* buffer, size_t size) {
|
||||
while (size > 0 && api_hal_vcp.alive) {
|
||||
furi_check(osSemaphoreAcquire(api_hal_vcp.tx_semaphore, osWaitForever) == osOK);
|
||||
|
||||
size_t batch_size = size;
|
||||
if (batch_size > APP_TX_DATA_SIZE) {
|
||||
batch_size = APP_TX_DATA_SIZE;
|
||||
}
|
||||
|
||||
if (CDC_Transmit_FS(buffer, batch_size) == USBD_OK) {
|
||||
size -= batch_size;
|
||||
buffer += batch_size;
|
||||
} else {
|
||||
// Shouldn't be there
|
||||
osDelay(100);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user