[FL-1196] Targets: add F6 (#427)

* Targets: add F6
* F6: Update linker script for use with internal storage
* F6: synchronize with F5, add all changes arriving in V9 board, update cube project. Github workflow: add multi-target build, add F6 to build targets.
* CI: fix full assembly
* CI: better artifact naming scheme
* CI: fix artifacts wildcard
* F6: Swap C10 - A15, vibro and sdcard detect pins
This commit is contained in:
あく 2021-05-18 12:23:14 +03:00 committed by GitHub
parent 618ddfcd04
commit 734820c137
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
171 changed files with 26370 additions and 25 deletions

View File

@ -7,7 +7,7 @@ on:
- 'wiki_static/**'
env:
TARGET_VERSION: f5
TARGETS: f5 f6
jobs:
build:
@ -42,62 +42,67 @@ jobs:
- name: Build bootloader in docker
uses: ./.github/actions/docker
with:
run: make -j$(nproc) -C bootloader TARGET=${TARGET_VERSION}
run: for TARGET in ${TARGETS}; do make -j$(nproc) -C bootloader TARGET=${TARGET}; done
- name: Generate dfu file for bootloader
uses: ./.github/actions/docker
with:
run: hex2dfu -i bootloader/.obj/${TARGET_VERSION}/bootloader.hex -o bootloader/.obj/${TARGET_VERSION}/bootloader.dfu
run: for TARGET in ${TARGETS}; do hex2dfu -i bootloader/.obj/${TARGET}/bootloader.hex -o bootloader/.obj/${TARGET}/bootloader.dfu; done
- name: Build firmware in docker
uses: ./.github/actions/docker
with:
run: make -j$(nproc) -C firmware TARGET=${TARGET_VERSION}
run: for TARGET in ${TARGETS}; do make -j$(nproc) -C firmware TARGET=${TARGET}; done
- name: Generate dfu file for firmware
uses: ./.github/actions/docker
with:
run: hex2dfu -i firmware/.obj/${TARGET_VERSION}/firmware.hex -o firmware/.obj/${TARGET_VERSION}/firmware.dfu
run: for TARGET in ${TARGETS}; do hex2dfu -i firmware/.obj/${TARGET}/firmware.hex -o firmware/.obj/${TARGET}/firmware.dfu; done
- name: Generate full hex file
uses: ./.github/actions/docker
with:
run: srec_cat bootloader/.obj/${TARGET_VERSION}/bootloader.hex -Intel firmware/.obj/${TARGET_VERSION}/firmware.hex -Intel -o full.hex -Intel
run: |
for TARGET in ${TARGETS}; do
srec_cat bootloader/.obj/${TARGET}/bootloader.hex -Intel firmware/.obj/${TARGET}/firmware.hex -Intel -o ${TARGET}_full.hex -Intel
done
- name: Move upload files
uses: ./.github/actions/docker
with:
run: |
mv bootloader/.obj/${TARGET_VERSION}/bootloader.dfu bootloader.dfu
mv bootloader/.obj/${TARGET_VERSION}/bootloader.bin bootloader.bin
mv bootloader/.obj/${TARGET_VERSION}/bootloader.elf bootloader.elf
mv firmware/.obj/${TARGET_VERSION}/firmware.dfu firmware.dfu
mv firmware/.obj/${TARGET_VERSION}/firmware.bin firmware.bin
mv firmware/.obj/${TARGET_VERSION}/firmware.elf firmware.elf
for TARGET in ${TARGETS}; do
mv bootloader/.obj/${TARGET}/bootloader.dfu ${TARGET}_bootloader.dfu
mv bootloader/.obj/${TARGET}/bootloader.bin ${TARGET}_bootloader.bin
mv bootloader/.obj/${TARGET}/bootloader.elf ${TARGET}_bootloader.elf
mv firmware/.obj/${TARGET}/firmware.dfu ${TARGET}_firmware.dfu
mv firmware/.obj/${TARGET}/firmware.bin ${TARGET}_firmware.bin
mv firmware/.obj/${TARGET}/firmware.elf ${TARGET}_firmware.elf
done
- name: Generate full dfu file
uses: ./.github/actions/docker
with:
run: hex2dfu -i full.hex -o full.dfu
run: for TARGET in ${TARGETS}; do hex2dfu -i ${TARGET}_full.hex -o ${TARGET}_full.dfu; done
- name: Copy bootloader for full.bin
run: cp bootloader.bin full.bin
run: for TARGET in ${TARGETS}; do cp ${TARGET}_bootloader.bin ${TARGET}_full.bin; done
- name: Truncate full.bin
run: truncate -s 32768 full.bin
run: for TARGET in ${TARGETS}; do truncate -s 32768 ${TARGET}_full.bin; done
- name: Add firmware.bin at full.bin
run: cat firmware.bin >> full.bin
run: for TARGET in ${TARGETS}; do cat ${TARGET}_firmware.bin >> ${TARGET}_full.bin; done
- name: Publish artifacts
uses: actions/upload-artifact@v2
with:
name: artifacts
path: |
bootloader.dfu
bootloader.bin
firmware.dfu
firmware.bin
full.dfu
full.bin
*_bootloader.dfu
*_bootloader.bin
*_firmware.dfu
*_firmware.bin
*_full.dfu
*_full.bin
if-no-files-found: error
retention-days: 7
@ -119,10 +124,10 @@ jobs:
remote_host: ${{ secrets.RSYNC_DEPLOY_HOST }}
remote_port: ${{ secrets.RSYNC_DEPLOY_PORT }}
remote_user: ${{ secrets.RSYNC_DEPLOY_USER }}
remote_key: ${{ secrets.RSYNC_DEPLOY_KEY }}
remote_key: ${{ secrets.RSYNC_DEPLOY_KEY }}
- name: Generate files list
run: ls bootloader.dfu firmware.dfu full.dfu bootloader.bin firmware.bin full.bin bootloader.elf firmware.elf > uploadlist.txt
run: ls *_bootloader.dfu *_firmware.dfu *_full.dfu *_bootloader.bin *_firmware.bin *_full.bin *_bootloader.elf *_firmware.elf > uploadlist.txt
- name: Upload artifacts
uses: burnett01/rsync-deployments@4.1
@ -150,7 +155,7 @@ jobs:
PREP_DATE=$(echo "${GET_DATE^^}")
echo "PREP_DATE=$PREP_DATE" >> $GITHUB_ENV
- name: Test output PREP_DATE
run: echo $PREP_DATE
run: echo $PREP_DATE
- name: Gen pic
uses: ./.github/actions/docker
with:

View File

@ -0,0 +1,137 @@
#include <api-hal-i2c.h>
#include <stm32wbxx_ll_bus.h>
#include <stm32wbxx_ll_i2c.h>
#include <stm32wbxx_ll_rcc.h>
#include <stm32wbxx_ll_gpio.h>
#include <stm32wbxx_ll_cortex.h>
void api_hal_i2c_init() {
LL_I2C_InitTypeDef I2C_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
GPIO_InitStruct.Pin = POWER_I2C_SCL_Pin | POWER_I2C_SDA_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
I2C_InitStruct.Timing = POWER_I2C_TIMINGS;
I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
I2C_InitStruct.DigitalFilter = 0;
I2C_InitStruct.OwnAddress1 = 0;
I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
LL_I2C_Init(I2C1, &I2C_InitStruct);
LL_I2C_EnableAutoEndMode(I2C1);
LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);
LL_I2C_DisableOwnAddress2(I2C1);
LL_I2C_DisableGeneralCall(I2C1);
LL_I2C_EnableClockStretching(I2C1);
}
bool api_hal_i2c_tx(
I2C_TypeDef* instance,
uint8_t address,
const uint8_t* data,
uint8_t size,
uint32_t timeout) {
uint32_t time_left = timeout;
bool ret = true;
while(LL_I2C_IsActiveFlag_BUSY(instance))
;
LL_I2C_HandleTransfer(
instance,
address,
LL_I2C_ADDRSLAVE_7BIT,
size,
LL_I2C_MODE_AUTOEND,
LL_I2C_GENERATE_START_WRITE);
while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) {
if(LL_I2C_IsActiveFlag_TXIS(instance)) {
LL_I2C_TransmitData8(instance, (*data));
data++;
size--;
time_left = timeout;
}
if(LL_SYSTICK_IsActiveCounterFlag()) {
if(--time_left == 0) {
ret = false;
break;
}
}
}
LL_I2C_ClearFlag_STOP(instance);
return ret;
}
bool api_hal_i2c_rx(
I2C_TypeDef* instance,
uint8_t address,
uint8_t* data,
uint8_t size,
uint32_t timeout) {
uint32_t time_left = timeout;
bool ret = true;
while(LL_I2C_IsActiveFlag_BUSY(instance))
;
LL_I2C_HandleTransfer(
instance,
address,
LL_I2C_ADDRSLAVE_7BIT,
size,
LL_I2C_MODE_AUTOEND,
LL_I2C_GENERATE_START_READ);
while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) {
if(LL_I2C_IsActiveFlag_RXNE(instance)) {
*data = LL_I2C_ReceiveData8(instance);
data++;
size--;
time_left = timeout;
}
if(LL_SYSTICK_IsActiveCounterFlag()) {
if(--time_left == 0) {
ret = false;
break;
}
}
}
LL_I2C_ClearFlag_STOP(instance);
return ret;
}
bool api_hal_i2c_trx(
I2C_TypeDef* instance,
uint8_t address,
const uint8_t* tx_data,
uint8_t tx_size,
uint8_t* rx_data,
uint8_t rx_size,
uint32_t timeout) {
if(api_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) &&
api_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) {
return true;
} else {
return false;
}
}

View File

@ -0,0 +1,43 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <api-hal-resources.h>
#ifdef __cplusplus
extern "C" {
#endif
void api_hal_i2c_init();
bool api_hal_i2c_tx(
I2C_TypeDef* instance,
const uint8_t address,
const uint8_t* data,
const uint8_t size,
uint32_t timeout);
bool api_hal_i2c_rx(
I2C_TypeDef* instance,
const uint8_t address,
uint8_t* data,
const uint8_t size,
uint32_t timeout);
bool api_hal_i2c_trx(
I2C_TypeDef* instance,
const uint8_t address,
const uint8_t* tx_data,
const uint8_t tx_size,
uint8_t* rx_data,
const uint8_t rx_size,
uint32_t timeout);
#define with_api_hal_i2c(type, pointer, function_body) \
{ \
*pointer = ({ type __fn__ function_body __fn__; })(); \
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,43 @@
#include <api-hal-light.h>
#include <lp5562.h>
#define LED_CURRENT_RED 50
#define LED_CURRENT_GREEN 50
#define LED_CURRENT_BLUE 50
#define LED_CURRENT_WHITE 150
void api_hal_light_init() {
lp5562_reset();
lp5562_set_channel_current(LP5562ChannelRed, LED_CURRENT_RED);
lp5562_set_channel_current(LP5562ChannelGreen, LED_CURRENT_GREEN);
lp5562_set_channel_current(LP5562ChannelBlue, LED_CURRENT_BLUE);
lp5562_set_channel_current(LP5562ChannelWhite, LED_CURRENT_WHITE);
lp5562_set_channel_value(LP5562ChannelRed, 0x00);
lp5562_set_channel_value(LP5562ChannelGreen, 0x00);
lp5562_set_channel_value(LP5562ChannelBlue, 0x00);
lp5562_set_channel_value(LP5562ChannelWhite, 0x00);
lp5562_enable();
lp5562_configure();
}
void api_hal_light_set(Light light, uint8_t value) {
switch(light) {
case LightRed:
lp5562_set_channel_value(LP5562ChannelRed, value);
break;
case LightGreen:
lp5562_set_channel_value(LP5562ChannelGreen, value);
break;
case LightBlue:
lp5562_set_channel_value(LP5562ChannelBlue, value);
break;
case LightBacklight:
lp5562_set_channel_value(LP5562ChannelWhite, value);
break;
default:
break;
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <api-hal-resources.h>
#ifdef __cplusplus
extern "C" {
#endif
void api_hal_light_init();
void api_hal_light_set(Light light, uint8_t value);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,42 @@
#pragma once
#include <stm32wbxx.h>
#include <stm32wbxx_ll_gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define POWER_I2C_SCL_Pin LL_GPIO_PIN_9
#define POWER_I2C_SCL_GPIO_Port GPIOA
#define POWER_I2C_SDA_Pin LL_GPIO_PIN_10
#define POWER_I2C_SDA_GPIO_Port GPIOA
#define POWER_I2C I2C1
/* Timing register value is computed with the STM32CubeMX Tool,
* Fast Mode @100kHz with I2CCLK = 64 MHz,
* rise time = 0ns, fall time = 0ns
*/
#define POWER_I2C_TIMINGS 0x10707DBC
/* Input Keys */
typedef enum {
InputKeyUp,
InputKeyDown,
InputKeyRight,
InputKeyLeft,
InputKeyOk,
InputKeyBack,
} InputKey;
/* Light */
typedef enum {
LightRed,
LightGreen,
LightBlue,
LightBacklight,
} Light;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,6 @@
#include <api-hal.h>
void api_hal_init() {
api_hal_i2c_init();
api_hal_light_init();
}

View File

@ -0,0 +1,6 @@
#pragma once
#include <api-hal-i2c.h>
#include <api-hal-light.h>
void api_hal_init();

View File

@ -0,0 +1,187 @@
/**
*****************************************************************************
**
** File : stm32wb55xx_flash_cm4.ld
**
** Abstract : System Workbench Minimal System calls file
**
** For more information about which c-functions
** need which of these lowlevel functions
** please consult the Newlib libc-manual
**
** Environment : System Workbench for MCU
**
** Distribution: The file is distributed “as is,” without any warranty
** of any kind.
**
*****************************************************************************
**
** <h2><center>&copy; COPYRIGHT(c) 2019 Ac6</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
** 1. Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** 3. Neither the name of Ac6 nor the names of its contributors
** may be used to endorse or promote products derived from this software
** without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20030000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K
RAM1 (xrw) : ORIGIN = 0x20000004, LENGTH = 0x2FFFC
RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM1 AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM1
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM1
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED
MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED
MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED
}

View File

@ -0,0 +1,171 @@
#include <target.h>
#include <stm32wbxx.h>
#include <stm32wbxx_ll_system.h>
#include <stm32wbxx_ll_bus.h>
#include <stm32wbxx_ll_utils.h>
#include <stm32wbxx_ll_rcc.h>
#include <stm32wbxx_ll_rtc.h>
#include <stm32wbxx_ll_pwr.h>
#include <stm32wbxx_ll_gpio.h>
#include <stm32wbxx_hal_flash.h>
#include <version.h>
#include <api-hal.h>
// Boot request enum
#define BOOT_REQUEST_NONE 0x00000000
#define BOOT_REQUEST_DFU 0xDF00B000
// Boot to DFU pin
#define BOOT_DFU_PORT GPIOB
#define BOOT_DFU_PIN LL_GPIO_PIN_11
// USB pins
#define BOOT_USB_PORT GPIOA
#define BOOT_USB_DM_PIN LL_GPIO_PIN_11
#define BOOT_USB_DP_PIN LL_GPIO_PIN_12
#define BOOT_USB_PIN (BOOT_USB_DM_PIN | BOOT_USB_DP_PIN)
#define RTC_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady())
void target_led_control(char* c) {
api_hal_light_set(LightRed, 0x00);
api_hal_light_set(LightGreen, 0x00);
api_hal_light_set(LightBlue, 0x00);
do {
if(*c == 'R') {
api_hal_light_set(LightRed, 0xFF);
} else if(*c == 'G') {
api_hal_light_set(LightGreen, 0xFF);
} else if(*c == 'B') {
api_hal_light_set(LightBlue, 0xFF);
} else if(*c == '.') {
LL_mDelay(125);
api_hal_light_set(LightRed, 0x00);
api_hal_light_set(LightGreen, 0x00);
api_hal_light_set(LightBlue, 0x00);
LL_mDelay(125);
} else if(*c == '-') {
LL_mDelay(250);
api_hal_light_set(LightRed, 0x00);
api_hal_light_set(LightGreen, 0x00);
api_hal_light_set(LightBlue, 0x00);
LL_mDelay(250);
} else if(*c == '|') {
api_hal_light_set(LightRed, 0x00);
api_hal_light_set(LightGreen, 0x00);
api_hal_light_set(LightBlue, 0x00);
}
c++;
} while(*c != 0);
}
void clock_init() {
LL_Init1msTick(4000000);
LL_SetSystemCoreClock(4000000);
}
void gpio_init() {
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
// USB D+
LL_GPIO_SetPinMode(BOOT_USB_PORT, BOOT_USB_DP_PIN, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinSpeed(BOOT_USB_PORT, BOOT_USB_DP_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
LL_GPIO_SetPinOutputType(BOOT_USB_PORT, BOOT_USB_DP_PIN, LL_GPIO_OUTPUT_OPENDRAIN);
// USB D-
LL_GPIO_SetPinMode(BOOT_USB_PORT, BOOT_USB_DM_PIN, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinSpeed(BOOT_USB_PORT, BOOT_USB_DM_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
LL_GPIO_SetPinOutputType(BOOT_USB_PORT, BOOT_USB_DM_PIN, LL_GPIO_OUTPUT_OPENDRAIN);
// Button: back
LL_GPIO_SetPinMode(BOOT_DFU_PORT, BOOT_DFU_PIN, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinPull(BOOT_DFU_PORT, BOOT_DFU_PIN, LL_GPIO_PULL_UP);
}
void rtc_init() {
// LSE and RTC
LL_PWR_EnableBkUpAccess();
if(!RTC_CLOCK_IS_READY()) {
// Start LSI1 needed for CSS
LL_RCC_LSI1_Enable();
// Try to start LSE normal way
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_MEDIUMLOW);
LL_RCC_LSE_Enable();
uint32_t c = 0;
while(!RTC_CLOCK_IS_READY() && c < 200) {
LL_mDelay(10);
c++;
}
// Plan B: reset backup domain
if(!RTC_CLOCK_IS_READY()) {
target_led_control("-R.R.R.");
LL_RCC_ForceBackupDomainReset();
LL_RCC_ReleaseBackupDomainReset();
NVIC_SystemReset();
}
// Set RTC domain clock to LSE
LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
// Enable LSE CSS
LL_RCC_LSE_EnableCSS();
}
// Enable clocking
LL_RCC_EnableRTC();
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
}
void version_save(void) {
LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR1, (uint32_t)version_get());
}
void usb_wire_reset() {
LL_GPIO_ResetOutputPin(BOOT_USB_PORT, BOOT_USB_PIN);
LL_mDelay(10);
LL_GPIO_SetOutputPin(BOOT_USB_PORT, BOOT_USB_PIN);
}
void target_init() {
clock_init();
gpio_init();
api_hal_init();
target_led_control("RGB");
rtc_init();
version_save();
usb_wire_reset();
// Errata 2.2.9, Flash OPTVERR flag is always set after system reset
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
}
int target_is_dfu_requested() {
if(LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR0) == BOOT_REQUEST_DFU) {
LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_NONE);
return 1;
}
LL_mDelay(100);
if(!LL_GPIO_IsInputPinSet(BOOT_DFU_PORT, BOOT_DFU_PIN)) {
return 1;
}
return 0;
}
void target_switch(void* offset) {
asm volatile("ldr r3, [%0] \n"
"msr msp, r3 \n"
"ldr r3, [%1] \n"
"mov pc, r3 \n"
:
: "r"(offset), "r"(offset + 0x4)
: "r3");
}
void target_switch2dfu() {
target_led_control("B");
// Remap memory to system bootloader
LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SYSTEMFLASH);
target_switch(0x0);
}
void target_switch2os() {
target_led_control("G");
SCB->VTOR = BOOT_ADDRESS + OS_OFFSET;
target_switch((void*)(BOOT_ADDRESS + OS_OFFSET));
}

View File

@ -0,0 +1,46 @@
TOOLCHAIN = arm
BOOT_ADDRESS = 0x08000000
FW_ADDRESS = 0x08008000
OS_OFFSET = 0x00008000
FLASH_ADDRESS = 0x08000000
OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "stm32wbx.cpu configure -rtos auto" -c "init"
BOOT_CFLAGS = -DBOOT_ADDRESS=$(BOOT_ADDRESS) -DFW_ADDRESS=$(FW_ADDRESS) -DOS_OFFSET=$(OS_OFFSET)
MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard
CFLAGS += $(MCU_FLAGS) $(BOOT_CFLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections
LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs
CUBE_DIR = ../lib/STM32CubeWB
# ST HAL
CFLAGS += -DUSE_FULL_LL_DRIVER
ASM_SOURCES += $(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Source/Templates/gcc/startup_stm32wb55xx_cm4.s
C_SOURCES += $(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Source/Templates/system_stm32wbxx.c
C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c
C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c
C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c
CFLAGS += -I$(CUBE_DIR)/Drivers/CMSIS/Include
CFLAGS += -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Include
CFLAGS += -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc
LDFLAGS += -T$(TARGET_DIR)/stm32wb55xx_flash_cm4.ld
# Drivers
DRIVERS_DIR = ../lib/drivers
CFLAGS += -I$(DRIVERS_DIR)
C_SOURCES += $(DRIVERS_DIR)/lp5562.c
# API-HAL
CFLAGS += -I$(TARGET_DIR)/api-hal
C_SOURCES += $(wildcard $(TARGET_DIR)/api-hal/*.c)
# Version generation
CFLAGS += -I../lib/version
C_SOURCES += ../lib/version/version.c
ASM_SOURCES += $(wildcard $(TARGET_DIR)/*.s)
C_SOURCES += $(wildcard $(TARGET_DIR)/*.c)
CPP_SOURCES += $(wildcard $(TARGET_DIR)/*.cpp)

View File

@ -0,0 +1,166 @@
/* USER CODE BEGIN Header */
/*
* FreeRTOS Kernel V10.2.1
* Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Portion Copyright (C) 2019 StMicroelectronics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* USER CODE END Header */
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* These parameters and more are described within the 'configuration' section of the
* FreeRTOS API documentation available on the FreeRTOS.org web site.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* Section where include file can be added */
/* USER CODE END Includes */
/* Ensure definitions are only used by the compiler, and not by the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
void xPortSysTickHandler(void);
/* USER CODE BEGIN 0 */
extern void configureTimerForRunTimeStats(void);
extern unsigned long getRunTimeCounterValue(void);
/* USER CODE END 0 */
#endif
#define configENABLE_FPU 1
#define configENABLE_MPU 1
#define configUSE_PREEMPTION 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ((TickType_t)1024)
#define configMAX_PRIORITIES ( 56 )
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
#define configTOTAL_HEAP_SIZE ((size_t)131072)
#define configMAX_TASK_NAME_LEN ( 16 )
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configENABLE_BACKWARD_COMPATIBILITY 0
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_TICKLESS_IDLE 2
#define configRECORD_STACK_HIGH_ADDRESS 1
#define configUSE_NEWLIB_REENTRANT 0
/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
/* Defaults to size_t for backward compatibility, but can be changed
if lengths will always be less than the number of bytes in a size_t. */
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 1
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 8
/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH 256
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xQueueGetMutexHolder 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_eTaskGetState 1
/*
* The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
* by the application thus the correct define need to be enabled below
*/
#define USE_FreeRTOS_HEAP_4
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); asm("bkpt 1"); for( ;; );}
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
/* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick,
to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
/* #define xPortSysTickHandler SysTick_Handler */
#endif /* FREERTOS_CONFIG_H */

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
* @file adc.h
* @brief This file contains all the function prototypes for
* the adc.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __ADC_H__
#define __ADC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_ADC1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __ADC_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,54 @@
/**
******************************************************************************
* @file aes.h
* @brief This file contains all the function prototypes for
* the aes.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __AES_H__
#define __AES_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern CRYP_HandleTypeDef hcryp1;
extern CRYP_HandleTypeDef hcryp2;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_AES1_Init(void);
void MX_AES2_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __AES_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
* @file comp.h
* @brief This file contains all the function prototypes for
* the comp.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __COMP_H__
#define __COMP_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern COMP_HandleTypeDef hcomp1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_COMP1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __COMP_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
* @file crc.h
* @brief This file contains all the function prototypes for
* the crc.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CRC_H__
#define __CRC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern CRC_HandleTypeDef hcrc;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_CRC_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __CRC_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,49 @@
/**
******************************************************************************
* @file gpio.h
* @brief This file contains all the function prototypes for
* the gpio.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __GPIO_H__
#define __GPIO_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_GPIO_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__ GPIO_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,153 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32wbxx_hal.h"
void Error_Handler(void);
#define BUTTON_BACK_EXTI_IRQn EXTI15_10_IRQn
#define BUTTON_BACK_GPIO_Port GPIOC
#define BUTTON_BACK_Pin GPIO_PIN_13
#define BUTTON_DOWN_EXTI_IRQn EXTI6_IRQn
#define BUTTON_DOWN_GPIO_Port GPIOC
#define BUTTON_DOWN_Pin GPIO_PIN_6
#define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn
#define BUTTON_LEFT_GPIO_Port GPIOB
#define BUTTON_LEFT_Pin GPIO_PIN_11
#define BUTTON_OK_EXTI_IRQn EXTI3_IRQn
#define BUTTON_OK_GPIO_Port GPIOH
#define BUTTON_OK_Pin GPIO_PIN_3
#define BUTTON_RIGHT_EXTI_IRQn EXTI15_10_IRQn
#define BUTTON_RIGHT_GPIO_Port GPIOB
#define BUTTON_RIGHT_Pin GPIO_PIN_12
#define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn
#define BUTTON_UP_GPIO_Port GPIOB
#define BUTTON_UP_Pin GPIO_PIN_10
#define CC1101_CS_GPIO_Port GPIOD
#define CC1101_CS_Pin GPIO_PIN_0
#define CC1101_G0_GPIO_Port GPIOA
#define CC1101_G0_Pin GPIO_PIN_1
#define DISPLAY_CS_GPIO_Port GPIOC
#define DISPLAY_CS_Pin GPIO_PIN_11
#define DISPLAY_DI_GPIO_Port GPIOB
#define DISPLAY_DI_Pin GPIO_PIN_1
#define DISPLAY_RST_GPIO_Port GPIOB
#define DISPLAY_RST_Pin GPIO_PIN_0
#define IR_RX_GPIO_Port GPIOA
#define IR_RX_Pin GPIO_PIN_0
#define IR_TX_GPIO_Port GPIOB
#define IR_TX_Pin GPIO_PIN_9
#define NFC_CS_GPIO_Port GPIOE
#define NFC_CS_Pin GPIO_PIN_4
#define PA4_GPIO_Port GPIOA
#define PA4_Pin GPIO_PIN_4
#define PA6_GPIO_Port GPIOA
#define PA6_Pin GPIO_PIN_6
#define PA7_GPIO_Port GPIOA
#define PA7_Pin GPIO_PIN_7
#define PB2_GPIO_Port GPIOB
#define PB2_Pin GPIO_PIN_2
#define PB3_GPIO_Port GPIOB
#define PB3_Pin GPIO_PIN_3
#define PC0_GPIO_Port GPIOC
#define PC0_Pin GPIO_PIN_0
#define PC1_GPIO_Port GPIOC
#define PC1_Pin GPIO_PIN_1
#define PC3_GPIO_Port GPIOC
#define PC3_Pin GPIO_PIN_3
#define PERIPH_POWER_GPIO_Port GPIOA
#define PERIPH_POWER_Pin GPIO_PIN_3
#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC
#define QUARTZ_32MHZ_IN_Pin GPIO_PIN_14
#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC
#define QUARTZ_32MHZ_OUT_Pin GPIO_PIN_15
#define RFID_OUT_GPIO_Port GPIOB
#define RFID_OUT_Pin GPIO_PIN_13
#define RFID_PULL_GPIO_Port GPIOA
#define RFID_PULL_Pin GPIO_PIN_2
#define RFID_RF_IN_GPIO_Port GPIOC
#define RFID_RF_IN_Pin GPIO_PIN_5
#define RFID_TUNE_GPIO_Port GPIOA
#define RFID_TUNE_Pin GPIO_PIN_8
#define RF_SW_0_GPIO_Port GPIOC
#define RF_SW_0_Pin GPIO_PIN_4
#define SD_CD_GPIO_Port GPIOC
#define SD_CD_Pin GPIO_PIN_10
#define SD_CS_GPIO_Port GPIOC
#define SD_CS_Pin GPIO_PIN_12
#define SPEAKER_GPIO_Port GPIOB
#define SPEAKER_Pin GPIO_PIN_8
#define VIBRO_GPIO_Port GPIOA
#define VIBRO_Pin GPIO_PIN_15
#define iBTN_GPIO_Port GPIOB
#define iBTN_Pin GPIO_PIN_14
#define USART1_TX_Pin GPIO_PIN_6
#define USART1_TX_Port GPIOB
#define USART1_RX_Pin GPIO_PIN_7
#define USART1_RX_Port GPIOB
#define SPI_D_MISO_GPIO_Port GPIOC
#define SPI_D_MISO_Pin GPIO_PIN_2
#define SPI_D_MOSI_GPIO_Port GPIOB
#define SPI_D_MOSI_Pin GPIO_PIN_15
#define SPI_D_SCK_GPIO_Port GPIOD
#define SPI_D_SCK_Pin GPIO_PIN_1
#define SPI_R_MISO_GPIO_Port GPIOB
#define SPI_R_MISO_Pin GPIO_PIN_4
#define SPI_R_MOSI_GPIO_Port GPIOB
#define SPI_R_MOSI_Pin GPIO_PIN_5
#define SPI_R_SCK_GPIO_Port GPIOA
#define SPI_R_SCK_Pin GPIO_PIN_5
#define SPI_R hspi1
#define SPI_D hspi2
#define SPI_SD_HANDLE SPI_D
extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim16;
#define TIM_A htim1
#define TIM_B htim2
#define TIM_C htim16
#define SPEAKER_TIM htim16
#define SPEAKER_CH TIM_CHANNEL_1
#define LFRFID_TIM htim1
#define LFRFID_CH TIM_CHANNEL_1
#define IRDA_TX_TIM htim1
#define IRDA_TX_CH TIM_CHANNEL_3
// only for reference
// IRDA RX timer dont exist in F2
// and timer need more data to init (NVIC IRQn to set priority)
#define IRDA_RX_TIM htim2
#define IRDA_RX_FALLING_CH TIM_CHANNEL_1
#define IRDA_RX_RISING_CH TIM_CHANNEL_2
#define NFC_IRQ_Pin RFID_PULL_Pin
#define NFC_IRQ_GPIO_Port RFID_PULL_GPIO_Port
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
* @file pka.h
* @brief This file contains all the function prototypes for
* the pka.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __PKA_H__
#define __PKA_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern PKA_HandleTypeDef hpka;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_PKA_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __PKA_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,50 @@
/**
******************************************************************************
* @file rf.h
* @brief This file contains all the function prototypes for
* the rf.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __RF_H__
#define __RF_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_RF_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __RF_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
* @file rng.h
* @brief This file contains all the function prototypes for
* the rng.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __RNG_H__
#define __RNG_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern RNG_HandleTypeDef hrng;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_RNG_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __RNG_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
* @file rtc.h
* @brief This file contains all the function prototypes for
* the rtc.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __RTC_H__
#define __RTC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern RTC_HandleTypeDef hrtc;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_RTC_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __RTC_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,59 @@
/**
******************************************************************************
* @file spi.h
* @brief This file contains all the function prototypes for
* the spi.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_H__
#define __SPI_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern SPI_HandleTypeDef hspi1;
extern SPI_HandleTypeDef hspi2;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_SPI1_Init(void);
void MX_SPI2_Init(void);
/* USER CODE BEGIN Prototypes */
void NFC_SPI_Reconfigure();
void SD_SPI_Reconfigure_Slow();
void SD_SPI_Reconfigure_Fast();
void CC1101_SPI_Reconfigure();
void SD_SPI_Bus_To_Down_State();
void SD_SPI_Bus_To_Normal_State();
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __SPI_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,353 @@
/**
******************************************************************************
* @file stm32wbxx_hal_conf.h
* @author MCD Application Team
* @brief HAL configuration file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32WBxx_HAL_CONF_H
#define __STM32WBxx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
#define HAL_ADC_MODULE_ENABLED
#define HAL_CRYP_MODULE_ENABLED
#define HAL_COMP_MODULE_ENABLED
#define HAL_CRC_MODULE_ENABLED
#define HAL_HSEM_MODULE_ENABLED
// #define HAL_I2C_MODULE_ENABLED
/*#define HAL_IPCC_MODULE_ENABLED */
/*#define HAL_IRDA_MODULE_ENABLED */
/*#define HAL_IWDG_MODULE_ENABLED */
/*#define HAL_LCD_MODULE_ENABLED */
/*#define HAL_LPTIM_MODULE_ENABLED */
#define HAL_PCD_MODULE_ENABLED
#define HAL_PKA_MODULE_ENABLED
/*#define HAL_QSPI_MODULE_ENABLED */
#define HAL_RNG_MODULE_ENABLED
#define HAL_RTC_MODULE_ENABLED
/*#define HAL_SAI_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
#define HAL_TIM_MODULE_ENABLED
/*#define HAL_TSC_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */
#define HAL_EXTI_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_GPIO_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define USE_HAL_ADC_REGISTER_CALLBACKS 0u
#define USE_HAL_COMP_REGISTER_CALLBACKS 0u
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u
#define USE_HAL_I2C_REGISTER_CALLBACKS 0u
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u
#define USE_HAL_PCD_REGISTER_CALLBACKS 0u
#define USE_HAL_PKA_REGISTER_CALLBACKS 0u
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0u
#define USE_HAL_RNG_REGISTER_CALLBACKS 0u
#define USE_HAL_RTC_REGISTER_CALLBACKS 0u
#define USE_HAL_SAI_REGISTER_CALLBACKS 0u
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u
#define USE_HAL_SPI_REGISTER_CALLBACKS 0u
#define USE_HAL_TIM_REGISTER_CALLBACKS 0u
#define USE_HAL_TSC_REGISTER_CALLBACKS 0u
#define USE_HAL_UART_REGISTER_CALLBACKS 0u
#define USE_HAL_USART_REGISTER_CALLBACKS 0u
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u
/* ########################## Oscillator Values adaptation ####################*/
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE 32000000U /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal Multiple Speed oscillator (MSI) default value.
* This value is the default MSI range value after Reset.
*/
#if !defined (MSI_VALUE)
#define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI1) value.
*/
#if !defined (LSI1_VALUE)
#define LSI1_VALUE ((uint32_t)32000) /*!< LSI1 Typical Value in Hz*/
#endif /* LSI1_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief Internal Low Speed oscillator (LSI2) value.
*/
#if !defined (LSI2_VALUE)
#define LSI2_VALUE ((uint32_t)32000) /*!< LSI2 Typical Value in Hz*/
#endif /* LSI2_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
* This value is used by the UART, RTC HAL module to compute the system frequency
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
/**
* @brief Internal Multiple Speed oscillator (HSI48) default value.
* This value is the default HSI48 range value after Reset.
*/
#if !defined (HSI48_VALUE)
#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI48_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT 1000U /*!< Time out for LSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for SAI1 peripheral
* This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
* frequency.
*/
#if !defined (EXTERNAL_SAI1_CLOCK_VALUE)
#define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)2097000) /*!< Value of the SAI1 External clock source in Hz*/
#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32wbxx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32wbxx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_COMP_MODULE_ENABLED
#include "stm32wbxx_hal_comp.h"
#endif /* HAL_COMP_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32wbxx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32wbxx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32wbxx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32wbxx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32wbxx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32wbxx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_HSEM_MODULE_ENABLED
#include "stm32wbxx_hal_hsem.h"
#endif /* HAL_HSEM_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32wbxx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_IPCC_MODULE_ENABLED
#include "stm32wbxx_hal_ipcc.h"
#endif /* HAL_IPCC_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32wbxx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32wbxx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LCD_MODULE_ENABLED
#include "stm32wbxx_hal_lcd.h"
#endif /* HAL_LCD_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32wbxx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32wbxx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_PKA_MODULE_ENABLED
#include "stm32wbxx_hal_pka.h"
#endif /* HAL_PKA_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32wbxx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
#include "stm32wbxx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32wbxx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32wbxx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32wbxx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32wbxx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32wbxx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32wbxx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32wbxx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32wbxx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_TSC_MODULE_ENABLED
#include "stm32wbxx_hal_tsc.h"
#endif /* HAL_TSC_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32wbxx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32wbxx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32wbxx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* __STM32WBxx_HAL_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,77 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32wbxx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32WBxx_IT_H
#define __STM32WBxx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void DebugMon_Handler(void);
void SysTick_Handler(void);
void TAMP_STAMP_LSECSS_IRQHandler(void);
void RCC_IRQHandler(void);
void ADC1_IRQHandler(void);
void USB_LP_IRQHandler(void);
void COMP_IRQHandler(void);
void TIM1_UP_TIM16_IRQHandler(void);
void TIM1_TRG_COM_TIM17_IRQHandler(void);
void TIM1_CC_IRQHandler(void);
void TIM2_IRQHandler(void);
void HSEM_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32WBxx_IT_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,58 @@
/**
******************************************************************************
* @file tim.h
* @brief This file contains all the function prototypes for
* the tim.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __TIM_H__
#define __TIM_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim16;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_TIM1_Init(void);
void MX_TIM2_Init(void);
void MX_TIM16_Init(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __TIM_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
* @file usart.h
* @brief This file contains all the function prototypes for
* the usart.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_USART1_UART_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __USART_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,105 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usb_device.h
* @version : v3.0_Cube
* @brief : Header for usb_device.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEVICE__H__
#define __USB_DEVICE__H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx.h"
#include "stm32wbxx_hal.h"
#include "usbd_def.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup USBD_OTG_DRIVER
* @{
*/
/** @defgroup USBD_DEVICE USBD_DEVICE
* @brief Device file for Usb otg low level driver.
* @{
*/
/** @defgroup USBD_DEVICE_Exported_Variables USBD_DEVICE_Exported_Variables
* @brief Public variables.
* @{
*/
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/*
* -- Insert your variables declaration here --
*/
/* USER CODE BEGIN VARIABLES */
/* USER CODE END VARIABLES */
/**
* @}
*/
/** @defgroup USBD_DEVICE_Exported_FunctionsPrototype USBD_DEVICE_Exported_FunctionsPrototype
* @brief Declaration of public functions for Usb device.
* @{
*/
/** USB Device initialization function. */
void MX_USB_Device_Init(void);
/*
* -- Insert functions declaration here --
*/
/* USER CODE BEGIN FD */
/* USER CODE END FD */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USB_DEVICE__H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,134 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_cdc_if.h
* @version : v3.0_Cube
* @brief : Header for usbd_cdc_if.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CDC_IF_H__
#define __USBD_CDC_IF_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @brief For Usb device.
* @{
*/
/** @defgroup USBD_CDC_IF USBD_CDC_IF
* @brief Usb VCP device module
* @{
*/
/** @defgroup USBD_CDC_IF_Exported_Defines USBD_CDC_IF_Exported_Defines
* @brief Defines.
* @{
*/
/* USER CODE BEGIN EXPORTED_DEFINES */
/* Define size for the receive and transmit buffer over CDC */
/* It's up to user to redefine and/or remove those define */
#define APP_RX_DATA_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define APP_TX_DATA_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
/* USER CODE END EXPORTED_DEFINES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_Types USBD_CDC_IF_Exported_Types
* @brief Types.
* @{
*/
/* USER CODE BEGIN EXPORTED_TYPES */
/* USER CODE END EXPORTED_TYPES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_Macros USBD_CDC_IF_Exported_Macros
* @brief Aliases.
* @{
*/
/* USER CODE BEGIN EXPORTED_MACRO */
/* USER CODE END EXPORTED_MACRO */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
* @brief Public variables.
* @{
*/
/** CDC Interface callback. */
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_FunctionsPrototype USBD_CDC_IF_Exported_FunctionsPrototype
* @brief Public functions declaration.
* @{
*/
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
/* USER CODE BEGIN EXPORTED_FUNCTIONS */
/* USER CODE END EXPORTED_FUNCTIONS */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CDC_IF_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,176 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_conf.h
* @version : v3.0_Cube
* @brief : Header for usbd_conf.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CONF__H__
#define __USBD_CONF__H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stm32wbxx.h"
#include "stm32wbxx_hal.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup USBD_OTG_DRIVER
* @brief Driver for Usb device.
* @{
*/
/** @defgroup USBD_CONF USBD_CONF
* @brief Configuration file for Usb otg low level driver.
* @{
*/
/** @defgroup USBD_CONF_Exported_Variables USBD_CONF_Exported_Variables
* @brief Public variables.
* @{
*/
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines
* @brief Defines for configuration of the Usb device.
* @{
*/
/*---------- -----------*/
#define USBD_MAX_NUM_INTERFACES 1U
/*---------- -----------*/
#define USBD_MAX_NUM_CONFIGURATION 1U
/*---------- -----------*/
#define USBD_MAX_STR_DESC_SIZ 512U
/*---------- -----------*/
#define USBD_DEBUG_LEVEL 0U
/*---------- -----------*/
#define USBD_LPM_ENABLED 1U
/*---------- -----------*/
#define USBD_SELF_POWERED 1U
/****************************************/
/* #define for FS and HS identification */
#define DEVICE_FS 0
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Macros USBD_CONF_Exported_Macros
* @brief Aliases.
* @{
*/
/* Memory management macros */
/** Alias for memory allocation. */
#define USBD_malloc (void *)USBD_static_malloc
/** Alias for memory release. */
#define USBD_free USBD_static_free
/** Alias for memory set. */
#define USBD_memset memset
/** Alias for memory copy. */
#define USBD_memcpy memcpy
/** Alias for delay. */
#define USBD_Delay HAL_Delay
/* DEBUG macros */
#if (USBD_DEBUG_LEVEL > 0)
#define USBD_UsrLog(...) printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_UsrLog(...)
#endif
#if (USBD_DEBUG_LEVEL > 1)
#define USBD_ErrLog(...) printf("ERROR: ") ;\
printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_ErrLog(...)
#endif
#if (USBD_DEBUG_LEVEL > 2)
#define USBD_DbgLog(...) printf("DEBUG : ") ;\
printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_DbgLog(...)
#endif
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Types USBD_CONF_Exported_Types
* @brief Types.
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_FunctionsPrototype USBD_CONF_Exported_FunctionsPrototype
* @brief Declaration of public functions for Usb device.
* @{
*/
/* Exported functions -------------------------------------------------------*/
void *USBD_static_malloc(uint32_t size);
void USBD_static_free(void *p);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CONF__H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,145 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_desc.c
* @version : v3.0_Cube
* @brief : Header for usbd_conf.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_DESC__C__
#define __USBD_DESC__C__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_DESC USBD_DESC
* @brief Usb device descriptors module.
* @{
*/
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
* @brief Constants.
* @{
*/
#define DEVICE_ID1 (UID_BASE)
#define DEVICE_ID2 (UID_BASE + 0x4)
#define DEVICE_ID3 (UID_BASE + 0x8)
#define USB_SIZ_STRING_SERIAL 0x1E
/* USER CODE BEGIN EXPORTED_CONSTANTS */
/* USER CODE END EXPORTED_CONSTANTS */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_Defines USBD_DESC_Exported_Defines
* @brief Defines.
* @{
*/
/* USER CODE BEGIN EXPORTED_DEFINES */
/* USER CODE END EXPORTED_DEFINES */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_TypesDefinitions USBD_DESC_Exported_TypesDefinitions
* @brief Types.
* @{
*/
/* USER CODE BEGIN EXPORTED_TYPES */
/* USER CODE END EXPORTED_TYPES */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_Macros USBD_DESC_Exported_Macros
* @brief Aliases.
* @{
*/
/* USER CODE BEGIN EXPORTED_MACRO */
/* USER CODE END EXPORTED_MACRO */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_Variables USBD_DESC_Exported_Variables
* @brief Public variables.
* @{
*/
extern USBD_DescriptorsTypeDef CDC_Desc;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_FunctionsPrototype USBD_DESC_Exported_FunctionsPrototype
* @brief Public functions declaration.
* @{
*/
/* USER CODE BEGIN EXPORTED_FUNCTIONS */
/* USER CODE END EXPORTED_FUNCTIONS */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_DESC__C__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,128 @@
/**
******************************************************************************
* @file adc.c
* @brief This file provides code for the configuration
* of the ADC instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "adc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
ADC_HandleTypeDef hadc1;
/* ADC1 init function */
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_14;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(adcHandle->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/* ADC1 clock enable */
__HAL_RCC_ADC_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**ADC1 GPIO Configuration
PC5 ------> ADC1_IN14
*/
GPIO_InitStruct.Pin = RFID_RF_IN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(RFID_RF_IN_GPIO_Port, &GPIO_InitStruct);
/* ADC1 interrupt Init */
HAL_NVIC_SetPriority(ADC1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(ADC1_IRQn);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{
if(adcHandle->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspDeInit 0 */
/* USER CODE END ADC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADC_CLK_DISABLE();
/**ADC1 GPIO Configuration
PC5 ------> ADC1_IN14
*/
HAL_GPIO_DeInit(RFID_RF_IN_GPIO_Port, RFID_RF_IN_Pin);
/* ADC1 interrupt Deinit */
HAL_NVIC_DisableIRQ(ADC1_IRQn);
/* USER CODE BEGIN ADC1_MspDeInit 1 */
/* USER CODE END ADC1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,127 @@
/**
******************************************************************************
* @file aes.c
* @brief This file provides code for the configuration
* of the AES instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "aes.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
CRYP_HandleTypeDef hcryp1;
__ALIGN_BEGIN static const uint32_t pKeyAES1[4] __ALIGN_END = {
0x00000000,0x00000000,0x00000000,0x00000000};
CRYP_HandleTypeDef hcryp2;
__ALIGN_BEGIN static const uint32_t pKeyAES2[4] __ALIGN_END = {
0x00000000,0x00000000,0x00000000,0x00000000};
/* AES1 init function */
void MX_AES1_Init(void)
{
hcryp1.Instance = AES1;
hcryp1.Init.DataType = CRYP_DATATYPE_32B;
hcryp1.Init.KeySize = CRYP_KEYSIZE_128B;
hcryp1.Init.pKey = (uint32_t *)pKeyAES1;
hcryp1.Init.Algorithm = CRYP_AES_ECB;
hcryp1.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
hcryp1.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
if (HAL_CRYP_Init(&hcryp1) != HAL_OK)
{
Error_Handler();
}
}
/* AES2 init function */
void MX_AES2_Init(void)
{
hcryp2.Instance = AES2;
hcryp2.Init.DataType = CRYP_DATATYPE_32B;
hcryp2.Init.KeySize = CRYP_KEYSIZE_128B;
hcryp2.Init.pKey = (uint32_t *)pKeyAES2;
hcryp2.Init.Algorithm = CRYP_AES_ECB;
hcryp2.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
hcryp2.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
if (HAL_CRYP_Init(&hcryp2) != HAL_OK)
{
Error_Handler();
}
}
void HAL_CRYP_MspInit(CRYP_HandleTypeDef* crypHandle)
{
if(crypHandle->Instance==AES1)
{
/* USER CODE BEGIN AES1_MspInit 0 */
/* USER CODE END AES1_MspInit 0 */
/* AES1 clock enable */
__HAL_RCC_AES1_CLK_ENABLE();
/* USER CODE BEGIN AES1_MspInit 1 */
/* USER CODE END AES1_MspInit 1 */
}
else if(crypHandle->Instance==AES2)
{
/* USER CODE BEGIN AES2_MspInit 0 */
/* USER CODE END AES2_MspInit 0 */
/* AES2 clock enable */
__HAL_RCC_AES2_CLK_ENABLE();
/* USER CODE BEGIN AES2_MspInit 1 */
/* USER CODE END AES2_MspInit 1 */
}
}
void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef* crypHandle)
{
if(crypHandle->Instance==AES1)
{
/* USER CODE BEGIN AES1_MspDeInit 0 */
/* USER CODE END AES1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_AES1_CLK_DISABLE();
/* USER CODE BEGIN AES1_MspDeInit 1 */
/* USER CODE END AES1_MspDeInit 1 */
}
else if(crypHandle->Instance==AES2)
{
/* USER CODE BEGIN AES2_MspDeInit 0 */
/* USER CODE END AES2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_AES2_CLK_DISABLE();
/* USER CODE BEGIN AES2_MspDeInit 1 */
/* USER CODE END AES2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,103 @@
/**
******************************************************************************
* @file comp.c
* @brief This file provides code for the configuration
* of the COMP instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "comp.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
COMP_HandleTypeDef hcomp1;
/* COMP1 init function */
void MX_COMP1_Init(void)
{
hcomp1.Instance = COMP1;
hcomp1.Init.InputMinus = COMP_INPUT_MINUS_1_4VREFINT;
hcomp1.Init.InputPlus = COMP_INPUT_PLUS_IO1;
hcomp1.Init.OutputPol = COMP_OUTPUTPOL_NONINVERTED;
hcomp1.Init.Hysteresis = COMP_HYSTERESIS_HIGH;
hcomp1.Init.BlankingSrce = COMP_BLANKINGSRC_NONE;
hcomp1.Init.Mode = COMP_POWERMODE_MEDIUMSPEED;
hcomp1.Init.WindowMode = COMP_WINDOWMODE_DISABLE;
hcomp1.Init.TriggerMode = COMP_TRIGGERMODE_IT_RISING_FALLING;
if (HAL_COMP_Init(&hcomp1) != HAL_OK)
{
Error_Handler();
}
}
void HAL_COMP_MspInit(COMP_HandleTypeDef* compHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(compHandle->Instance==COMP1)
{
/* USER CODE BEGIN COMP1_MspInit 0 */
/* USER CODE END COMP1_MspInit 0 */
__HAL_RCC_GPIOC_CLK_ENABLE();
/**COMP1 GPIO Configuration
PC5 ------> COMP1_INP
*/
GPIO_InitStruct.Pin = RFID_RF_IN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(RFID_RF_IN_GPIO_Port, &GPIO_InitStruct);
/* COMP1 interrupt Init */
HAL_NVIC_SetPriority(COMP_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(COMP_IRQn);
/* USER CODE BEGIN COMP1_MspInit 1 */
/* USER CODE END COMP1_MspInit 1 */
}
}
void HAL_COMP_MspDeInit(COMP_HandleTypeDef* compHandle)
{
if(compHandle->Instance==COMP1)
{
/* USER CODE BEGIN COMP1_MspDeInit 0 */
/* USER CODE END COMP1_MspDeInit 0 */
/**COMP1 GPIO Configuration
PC5 ------> COMP1_INP
*/
HAL_GPIO_DeInit(RFID_RF_IN_GPIO_Port, RFID_RF_IN_Pin);
/* COMP1 interrupt Deinit */
HAL_NVIC_DisableIRQ(COMP_IRQn);
/* USER CODE BEGIN COMP1_MspDeInit 1 */
/* USER CODE END COMP1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,82 @@
/**
******************************************************************************
* @file crc.c
* @brief This file provides code for the configuration
* of the CRC instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "crc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
CRC_HandleTypeDef hcrc;
/* CRC init function */
void MX_CRC_Init(void)
{
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
if (HAL_CRC_Init(&hcrc) != HAL_OK)
{
Error_Handler();
}
}
void HAL_CRC_MspInit(CRC_HandleTypeDef* crcHandle)
{
if(crcHandle->Instance==CRC)
{
/* USER CODE BEGIN CRC_MspInit 0 */
/* USER CODE END CRC_MspInit 0 */
/* CRC clock enable */
__HAL_RCC_CRC_CLK_ENABLE();
/* USER CODE BEGIN CRC_MspInit 1 */
/* USER CODE END CRC_MspInit 1 */
}
}
void HAL_CRC_MspDeInit(CRC_HandleTypeDef* crcHandle)
{
if(crcHandle->Instance==CRC)
{
/* USER CODE BEGIN CRC_MspDeInit 0 */
/* USER CODE END CRC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CRC_CLK_DISABLE();
/* USER CODE BEGIN CRC_MspDeInit 1 */
/* USER CODE END CRC_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,56 @@
/**
******************************************************************************
* @file fatfs.c
* @brief Code for fatfs applications
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "fatfs.h"
uint8_t retUSER; /* Return value for USER */
char USERPath[4]; /* USER logical drive path */
FATFS USERFatFS; /* File system object for USER logical drive */
FIL USERFile; /* File object for USER */
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
void MX_FATFS_Init(void)
{
/*## FatFS: Link the USER driver ###########################*/
retUSER = FATFS_LinkDriver(&USER_Driver, USERPath);
/* USER CODE BEGIN Init */
/* additional user code for init */
/* USER CODE END Init */
}
/**
* @brief Gets Time from RTC
* @param None
* @retval Time in DWORD
*/
DWORD get_fattime(void)
{
/* USER CODE BEGIN get_fattime */
return 0;
/* USER CODE END get_fattime */
}
/* USER CODE BEGIN Application */
/* USER CODE END Application */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,49 @@
/**
******************************************************************************
* @file fatfs.h
* @brief Header for fatfs applications
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __fatfs_H
#define __fatfs_H
#ifdef __cplusplus
extern "C" {
#endif
#include "fatfs/ff.h"
#include "fatfs/ff_gen_drv.h"
#include "user_diskio.h" /* defines USER_Driver as external */
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern uint8_t retUSER; /* Return value for USER */
extern char USERPath[4]; /* USER logical drive path */
extern FATFS USERFatFS; /* File system object for USER logical drive */
extern FIL USERFile; /* File object for USER */
void MX_FATFS_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__fatfs_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,270 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* FatFs - Generic FAT file system module R0.12c (C)ChaN, 2017
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
#ifndef _FFCONF
#define _FFCONF 68300 /* Revision ID */
/*-----------------------------------------------------------------------------/
/ Additional user header to be used
/-----------------------------------------------------------------------------*/
#include "main.h"
#include "stm32wbxx_hal.h"
#include "cmsis_os.h" /* _FS_REENTRANT set to 1 and CMSIS API chosen */
/*-----------------------------------------------------------------------------/
/ Function Configurations
/-----------------------------------------------------------------------------*/
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define _FS_MINIMIZE 0 /* 0 to 3 */
/* This option defines minimization level to remove some basic API functions.
/
/ 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define _USE_FIND 0
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define _USE_MKFS 1
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define _USE_FASTSEEK 1
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
#define _USE_EXPAND 0
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define _USE_CHMOD 1
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
#define _USE_LABEL 1
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define _USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*-----------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/-----------------------------------------------------------------------------*/
#define _CODE_PAGE 850
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
*/
#define _USE_LFN 2 /* 0 to 3 */
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
/* The _USE_LFN switches the support of long file name (LFN).
/
/ 0: Disable support of LFN. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
/ It should be set 255 to support full featured LFN operations.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
/ This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 3
/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/
/ 0: ANSI/OEM
/ 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
/
/ This option has no effect when _LFN_UNICODE == 0. */
#define _FS_RPATH 0 /* 0 to 2 */
/* This option configures support of relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
*/
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/----------------------------------------------------------------------------*/
#define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */
/* USER CODE BEGIN Volumes */
#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
/* _STR_VOLUME_ID switches string support of volume ID.
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
/* USER CODE END Volumes */
#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Multiple partition */
/* This option switches support of multi-partition on a physical drive.
/ By default (0), each logical drive number is bound to the same physical drive
/ number and only an FAT volume found on the physical drive will be mounted.
/ When multi-partition is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define _MIN_SS 512 /* 512, 1024, 2048 or 4096 */
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
/* These options configure the range of sector size to be supported. (512, 1024,
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_TRIM 0
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define _FS_NOFSINFO 0 /* 0,1,2 or 3 */
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/
/ System Configurations
/----------------------------------------------------------------------------*/
#define _FS_TINY 1 /* 0:Normal or 1:Tiny */
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the file system object (FATFS) is used for the file data transfer. */
#define _FS_EXFAT 1
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
/ Note that enabling exFAT discards C89 compatibility. */
#define _FS_NORTC 0
#define _NORTC_MON 6
#define _NORTC_MDAY 4
#define _NORTC_YEAR 2015
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to get current time form real-time clock. _NORTC_MON,
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
#define _FS_LOCK 2 /* 0:Disable or >=1:Enable */
/* The option _FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
#define _SYNC_t osMutexId_t
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/* define the ff_malloc ff_free macros as standard malloc free */
#if !defined(ff_malloc) && !defined(ff_free)
#include <stdlib.h>
#define ff_malloc malloc
#define ff_free free
#endif
#endif /* _FFCONF */

View File

@ -0,0 +1,124 @@
#include "main.h"
#define SD_DUMMY_BYTE 0xFF
#define SD_CS_LOW() HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_RESET)
#define SD_CS_HIGH() HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_SET)
const uint32_t SpiTimeout = 1000;
extern SPI_HandleTypeDef SPI_SD_HANDLE;
uint8_t SD_IO_WriteByte(uint8_t Data);
/******************************************************************************
BUS OPERATIONS
*******************************************************************************/
/**
* @brief SPI error treatment function
* @retval None
*/
static void SPIx_Error(void) {
/* De-initialize the SPI communication BUS */
HAL_SPI_DeInit(&SPI_SD_HANDLE);
/* Re-Initiaize the SPI communication BUS */
HAL_SPI_Init(&SPI_SD_HANDLE);
}
/**
* @brief SPI Write byte(s) to device
* @param DataIn: Pointer to data buffer to write
* @param DataOut: Pointer to data buffer for read data
* @param DataLength: number of bytes to write
* @retval None
*/
static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) {
HAL_StatusTypeDef status = HAL_OK;
status =
HAL_SPI_TransmitReceive(&SPI_SD_HANDLE, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout);
/* Check the communication status */
if(status != HAL_OK) {
/* Execute user timeout callback */
SPIx_Error();
}
}
/**
* @brief SPI Write a byte to device
* @param Value: value to be written
* @retval None
*/
__attribute__((unused)) static void SPIx_Write(uint8_t Value) {
HAL_StatusTypeDef status = HAL_OK;
uint8_t data;
status = HAL_SPI_TransmitReceive(&SPI_SD_HANDLE, (uint8_t*)&Value, &data, 1, SpiTimeout);
/* Check the communication status */
if(status != HAL_OK) {
/* Execute user timeout callback */
SPIx_Error();
}
}
/******************************************************************************
LINK OPERATIONS
*******************************************************************************/
/********************************* LINK SD ************************************/
/**
* @brief Initialize the SD Card and put it into StandBy State (Ready for
* data transfer).
* @retval None
*/
void SD_IO_Init(void) {
uint8_t counter = 0;
/* SD chip select high */
SD_CS_HIGH();
/* Send dummy byte 0xFF, 10 times with CS high */
/* Rise CS and MOSI for 80 clocks cycles */
for(counter = 0; counter <= 200; counter++) {
/* Send dummy byte 0xFF */
SD_IO_WriteByte(SD_DUMMY_BYTE);
}
}
/**
* @brief Set SD interface Chip Select state
* @param val: 0 (low) or 1 (high) state
* @retval None
*/
void SD_IO_CSState(uint8_t val) {
if(val == 1) {
SD_CS_HIGH();
} else {
SD_CS_LOW();
}
}
/**
* @brief Write byte(s) on the SD
* @param DataIn: Pointer to data buffer to write
* @param DataOut: Pointer to data buffer for read data
* @param DataLength: number of bytes to write
* @retval None
*/
void SD_IO_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) {
/* Send the byte */
SPIx_WriteReadData(DataIn, DataOut, DataLength);
}
/**
* @brief Write a byte on the SD.
* @param Data: byte to send.
* @retval Data written
*/
uint8_t SD_IO_WriteByte(uint8_t Data) {
uint8_t tmp;
/* Send the byte */
SPIx_WriteReadData(&Data, &tmp, 1);
return tmp;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,252 @@
/**
******************************************************************************
* @file stm32_adafruit_sd.h
* @author MCD Application Team
* @version V3.0.0
* @date 23-December-2016
* @brief This file contains the common defines and functions prototypes for
* the stm32_adafruit_sd.c driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_ADAFRUIT_SD_H
#define __STM32_ADAFRUIT_SD_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
/** @addtogroup BSP
* @{
*/
#define __IO volatile
/** @addtogroup STM32_ADAFRUIT
* @{
*/
/** @defgroup STM32_ADAFRUIT_SD
* @{
*/
/** @defgroup STM32_ADAFRUIT_SD_Exported_Types
* @{
*/
/**
* @brief SD status structure definition
*/
enum {
BSP_SD_OK = 0x00,
MSD_OK = 0x00,
BSP_SD_ERROR = 0x01,
BSP_SD_TIMEOUT
};
typedef struct
{
uint8_t Reserved1:2; /* Reserved */
uint16_t DeviceSize:12; /* Device Size */
uint8_t MaxRdCurrentVDDMin:3; /* Max. read current @ VDD min */
uint8_t MaxRdCurrentVDDMax:3; /* Max. read current @ VDD max */
uint8_t MaxWrCurrentVDDMin:3; /* Max. write current @ VDD min */
uint8_t MaxWrCurrentVDDMax:3; /* Max. write current @ VDD max */
uint8_t DeviceSizeMul:3; /* Device size multiplier */
} struct_v1;
typedef struct
{
uint8_t Reserved1:6; /* Reserved */
uint32_t DeviceSize:22; /* Device Size */
uint8_t Reserved2:1; /* Reserved */
} struct_v2;
/**
* @brief Card Specific Data: CSD Register
*/
typedef struct
{
/* Header part */
uint8_t CSDStruct:2; /* CSD structure */
uint8_t Reserved1:6; /* Reserved */
uint8_t TAAC:8; /* Data read access-time 1 */
uint8_t NSAC:8; /* Data read access-time 2 in CLK cycles */
uint8_t MaxBusClkFrec:8; /* Max. bus clock frequency */
uint16_t CardComdClasses:12; /* Card command classes */
uint8_t RdBlockLen:4; /* Max. read data block length */
uint8_t PartBlockRead:1; /* Partial blocks for read allowed */
uint8_t WrBlockMisalign:1; /* Write block misalignment */
uint8_t RdBlockMisalign:1; /* Read block misalignment */
uint8_t DSRImpl:1; /* DSR implemented */
/* v1 or v2 struct */
union csd_version {
struct_v1 v1;
struct_v2 v2;
} version;
uint8_t EraseSingleBlockEnable:1; /* Erase single block enable */
uint8_t EraseSectorSize:7; /* Erase group size multiplier */
uint8_t WrProtectGrSize:7; /* Write protect group size */
uint8_t WrProtectGrEnable:1; /* Write protect group enable */
uint8_t Reserved2:2; /* Reserved */
uint8_t WrSpeedFact:3; /* Write speed factor */
uint8_t MaxWrBlockLen:4; /* Max. write data block length */
uint8_t WriteBlockPartial:1; /* Partial blocks for write allowed */
uint8_t Reserved3:5; /* Reserved */
uint8_t FileFormatGrouop:1; /* File format group */
uint8_t CopyFlag:1; /* Copy flag (OTP) */
uint8_t PermWrProtect:1; /* Permanent write protection */
uint8_t TempWrProtect:1; /* Temporary write protection */
uint8_t FileFormat:2; /* File Format */
uint8_t Reserved4:2; /* Reserved */
uint8_t crc:7; /* Reserved */
uint8_t Reserved5:1; /* always 1*/
} SD_CSD;
/**
* @brief Card Identification Data: CID Register
*/
typedef struct
{
__IO uint8_t ManufacturerID; /* ManufacturerID */
__IO uint16_t OEM_AppliID; /* OEM/Application ID */
__IO uint32_t ProdName1; /* Product Name part1 */
__IO uint8_t ProdName2; /* Product Name part2*/
__IO uint8_t ProdRev; /* Product Revision */
__IO uint32_t ProdSN; /* Product Serial Number */
__IO uint8_t Reserved1; /* Reserved1 */
__IO uint16_t ManufactDate; /* Manufacturing Date */
__IO uint8_t CID_CRC; /* CID CRC */
__IO uint8_t Reserved2; /* always 1 */
} SD_CID;
/**
* @brief SD Card information
*/
typedef struct
{
SD_CSD Csd;
SD_CID Cid;
uint64_t CardCapacity; /*!< Card Capacity */
uint32_t CardBlockSize; /*!< Card Block Size */
uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */
uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */
} SD_CardInfo;
/**
* @}
*/
/** @defgroup STM32_ADAFRUIT_SPI_SD_Exported_Constants
* @{
*/
/**
* @brief Block Size
*/
#define SD_BLOCK_SIZE 0x200
/**
* @brief SD detection on its memory slot
*/
#define SD_PRESENT ((uint8_t)0x01)
#define SD_NOT_PRESENT ((uint8_t)0x00)
#define SD_DATATIMEOUT ((uint32_t)100000000)
/**
* @brief SD Card information structure
*/
#define BSP_SD_CardInfo SD_CardInfo
/**
* @}
*/
/** @defgroup STM32_ADAFRUIT_SD_Exported_Macro
* @{
*/
/**
* @}
*/
/** @defgroup STM32_ADAFRUIT_SD_Exported_Functions
* @{
*/
uint8_t BSP_SD_Init(bool reset_card);
uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
uint8_t BSP_SD_GetCardState(void);
uint8_t BSP_SD_GetCardInfo(SD_CardInfo *pCardInfo);
/* Link functions for SD Card peripheral*/
void SD_SPI_Slow_Init(void);
void SD_SPI_Fast_Init(void);
void SD_IO_Init(void);
void SD_IO_CSState(uint8_t state);
void SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength);
uint8_t SD_IO_WriteByte(uint8_t Data);
/* Link function for HAL delay */
void HAL_Delay(__IO uint32_t Delay);
#ifdef __cplusplus
}
#endif
#endif /* __STM32_ADAFRUIT_SD_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,138 @@
/*------------------------------------------------------------------------*/
/* Sample code of OS dependent controls for FatFs */
/* (C)ChaN, 2014 */
/* Portions COPYRIGHT 2017 STMicroelectronics */
/* Portions Copyright (C) 2014, ChaN, all right reserved */
/*------------------------------------------------------------------------*/
/**
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
**/
#include "fatfs/ff.h"
#if _FS_REENTRANT
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding volume (logical drive number) */
_SYNC_t *sobj /* Pointer to return the created sync object */
)
{
int ret;
//osSemaphoreDef(SEM);
//*sobj = osSemaphoreCreate(osSemaphore(SEM), 1);
*sobj = osMutexNew(NULL);
ret = (*sobj != NULL);
return ret;
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to any error */
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
)
{
osMutexDelete(sobj);
return 1;
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
_SYNC_t sobj /* Sync object to wait */
)
{
int ret = 0;
if(osMutexAcquire(sobj, _FS_TIMEOUT) == osOK) {
ret = 1;
}
return ret;
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant (
_SYNC_t sobj /* Sync object to be signaled */
)
{
osMutexRelease(sobj);
}
#endif
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
*/
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
UINT msize /* Number of bytes to allocate */
)
{
return ff_malloc(msize); /* Allocate a new memory block with POSIX API */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free */
)
{
ff_free(mblock); /* Discard the memory block with POSIX API */
}
#endif

View File

@ -0,0 +1,230 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file user_diskio.c
* @brief This file includes a diskio driver skeleton to be completed by the user.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
#ifdef USE_OBSOLETE_USER_CODE_SECTION_0
/*
* Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0)
* To be suppressed in the future.
* Kept to ensure backward compatibility with previous CubeMx versions when
* migrating projects.
* User code previously added there should be copied in the new user sections before
* the section contents can be deleted.
*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
#endif
/* USER CODE BEGIN DECL */
/* Includes ------------------------------------------------------------------*/
#include "user_diskio.h"
#include "spi.h"
#include "api-hal-spi.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Disk status */
static volatile DSTATUS Stat = STA_NOINIT;
static DSTATUS User_CheckStatus(BYTE lun) {
Stat = STA_NOINIT;
if(BSP_SD_GetCardState() == MSD_OK) {
Stat &= ~STA_NOINIT;
}
return Stat;
}
/* USER CODE END DECL */
/* Private function prototypes -----------------------------------------------*/
DSTATUS USER_initialize(BYTE pdrv);
DSTATUS USER_status(BYTE pdrv);
DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
#if _USE_WRITE == 1
DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff);
#endif /* _USE_IOCTL == 1 */
Diskio_drvTypeDef USER_Driver = {
USER_initialize,
USER_status,
USER_read,
#if _USE_WRITE
USER_write,
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
USER_ioctl,
#endif /* _USE_IOCTL == 1 */
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes a Drive
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS USER_initialize(BYTE pdrv) {
/* USER CODE BEGIN INIT */
// TODO: SPI manager
api_hal_spi_lock_device(&sd_fast_spi);
DSTATUS status = User_CheckStatus(pdrv);
// TODO: SPI manager
api_hal_spi_unlock_device(&sd_fast_spi);
return status;
/* USER CODE END INIT */
}
/**
* @brief Gets Disk Status
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS USER_status(BYTE pdrv) {
/* USER CODE BEGIN STATUS */
return Stat;
/* USER CODE END STATUS */
}
/**
* @brief Reads Sector(s)
* @param pdrv: Physical drive number (0..)
* @param *buff: Data buffer to store read data
* @param sector: Sector address (LBA)
* @param count: Number of sectors to read (1..128)
* @retval DRESULT: Operation result
*/
DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
/* USER CODE BEGIN READ */
DRESULT res = RES_ERROR;
// TODO: SPI manager
api_hal_spi_lock_device(&sd_fast_spi);
if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) {
/* wait until the read operation is finished */
while(BSP_SD_GetCardState() != MSD_OK) {
}
res = RES_OK;
}
// TODO: SPI manager
api_hal_spi_unlock_device(&sd_fast_spi);
return res;
/* USER CODE END READ */
}
/**
* @brief Writes Sector(s)
* @param pdrv: Physical drive number (0..)
* @param *buff: Data to be written
* @param sector: Sector address (LBA)
* @param count: Number of sectors to write (1..128)
* @retval DRESULT: Operation result
*/
#if _USE_WRITE == 1
DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
/* USER CODE BEGIN WRITE */
/* USER CODE HERE */
DRESULT res = RES_ERROR;
// TODO: SPI manager
api_hal_spi_lock_device(&sd_fast_spi);
if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) {
/* wait until the Write operation is finished */
while(BSP_SD_GetCardState() != MSD_OK) {
}
res = RES_OK;
}
// TODO: SPI manager
api_hal_spi_unlock_device(&sd_fast_spi);
return res;
/* USER CODE END WRITE */
}
#endif /* _USE_WRITE == 1 */
/**
* @brief I/O control operation
* @param pdrv: Physical drive number (0..)
* @param cmd: Control code
* @param *buff: Buffer to send/receive control data
* @retval DRESULT: Operation result
*/
#if _USE_IOCTL == 1
DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) {
/* USER CODE BEGIN IOCTL */
DRESULT res = RES_ERROR;
BSP_SD_CardInfo CardInfo;
if(Stat & STA_NOINIT) return RES_NOTRDY;
// TODO: SPI manager
api_hal_spi_lock_device(&sd_fast_spi);
switch(cmd) {
/* Make sure that no pending write process */
case CTRL_SYNC:
res = RES_OK;
break;
/* Get number of sectors on the disk (DWORD) */
case GET_SECTOR_COUNT:
BSP_SD_GetCardInfo(&CardInfo);
*(DWORD*)buff = CardInfo.LogBlockNbr;
res = RES_OK;
break;
/* Get R/W sector size (WORD) */
case GET_SECTOR_SIZE:
BSP_SD_GetCardInfo(&CardInfo);
*(WORD*)buff = CardInfo.LogBlockSize;
res = RES_OK;
break;
/* Get erase block size in unit of sector (DWORD) */
case GET_BLOCK_SIZE:
BSP_SD_GetCardInfo(&CardInfo);
*(DWORD*)buff = CardInfo.LogBlockSize;
res = RES_OK;
break;
default:
res = RES_PARERR;
}
// TODO: SPI manager
api_hal_spi_unlock_device(&sd_fast_spi);
return res;
/* USER CODE END IOCTL */
}
#endif /* _USE_IOCTL == 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,48 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file user_diskio.h
* @brief This file contains the common defines and functions prototypes for
* the user_diskio driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USER_DISKIO_H
#define __USER_DISKIO_H
#ifdef __cplusplus
extern "C" {
#endif
/* USER CODE BEGIN 0 */
/* Includes ------------------------------------------------------------------*/
#include "stm32_adafruit_sd.h"
#include "fatfs/ff_gen_drv.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
extern Diskio_drvTypeDef USER_Driver;
/* USER CODE END 0 */
#ifdef __cplusplus
}
#endif
#endif /* __USER_DISKIO_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,21 @@
/*
* Since at least FreeRTOS V7.5.3 uxTopUsedPriority is no longer
* present in the kernel, so it has to be supplied by other means for
* OpenOCD's threads awareness.
*
* Add this file to your project, and, if you're using --gc-sections,
* ``--undefined=uxTopUsedPriority'' (or
* ``-Wl,--undefined=uxTopUsedPriority'' when using gcc for final
* linking) to your LDFLAGS; same with all the other symbols you need.
*/
#include "FreeRTOS.h"
#ifdef __GNUC__
#define USED __attribute__((used))
#else
#define USED
#endif
const int USED uxTopUsedPriority = configMAX_PRIORITIES - 1;

View File

@ -0,0 +1,176 @@
#include "gpio.h"
void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Pin = BUTTON_BACK_Pin;
HAL_GPIO_Init(BUTTON_BACK_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = BUTTON_OK_Pin;
HAL_GPIO_Init(BUTTON_OK_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PCPin PCPin PCPin PCPin */
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = PC0_Pin;
HAL_GPIO_Init(PC0_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = PC1_Pin;
HAL_GPIO_Init(PC1_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = PC3_Pin;
HAL_GPIO_Init(PC3_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = VIBRO_Pin;
HAL_GPIO_Init(VIBRO_GPIO_Port, &GPIO_InitStruct);
/* RF_SW_0 */
HAL_GPIO_WritePin(RF_SW_0_GPIO_Port, RF_SW_0_Pin, GPIO_PIN_RESET);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = RF_SW_0_Pin;
HAL_GPIO_Init(RF_SW_0_GPIO_Port, &GPIO_InitStruct);
/* PERIPH_POWER */
HAL_GPIO_WritePin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin, GPIO_PIN_SET);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = PERIPH_POWER_Pin;
HAL_GPIO_Init(PERIPH_POWER_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PAPin PAPin PAPin */
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = PA4_Pin;
HAL_GPIO_Init(PA4_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = PA6_Pin;
HAL_GPIO_Init(PA6_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = PA7_Pin;
HAL_GPIO_Init(PA7_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = RFID_PULL_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(RFID_PULL_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = CC1101_G0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
// HAL_GPIO_Init(CC1101_G0_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PBPin PBPin PBPin */
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = PB2_Pin;
HAL_GPIO_Init(PB2_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = iBTN_Pin;
HAL_GPIO_Init(iBTN_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = PB3_Pin;
HAL_GPIO_Init(PB3_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PBPin PBPin PBPin PBPin */
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Pin = BUTTON_UP_Pin;
HAL_GPIO_Init(BUTTON_UP_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = BUTTON_LEFT_Pin;
HAL_GPIO_Init(BUTTON_LEFT_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = BUTTON_RIGHT_Pin;
HAL_GPIO_Init(BUTTON_RIGHT_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PBPin PBPin PBPin PBPin */
GPIO_InitStruct.Pin = BUTTON_DOWN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(BUTTON_DOWN_GPIO_Port, &GPIO_InitStruct);
/* DISPLAY_RST */
HAL_GPIO_WritePin(DISPLAY_RST_GPIO_Port, DISPLAY_RST_Pin, GPIO_PIN_RESET);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = DISPLAY_RST_Pin;
HAL_GPIO_Init(DISPLAY_RST_GPIO_Port, &GPIO_InitStruct);
/* NFC_CS */
HAL_GPIO_WritePin(NFC_CS_GPIO_Port, NFC_CS_Pin, GPIO_PIN_SET);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pin = NFC_CS_Pin;
HAL_GPIO_Init(NFC_CS_GPIO_Port, &GPIO_InitStruct);
/* DISPLAY_CS */
HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_SET);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = DISPLAY_CS_Pin;
HAL_GPIO_Init(DISPLAY_CS_GPIO_Port, &GPIO_InitStruct);
/* DISPLAY_DI */
HAL_GPIO_WritePin(DISPLAY_DI_GPIO_Port, DISPLAY_DI_Pin, GPIO_PIN_RESET);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = DISPLAY_DI_Pin;
HAL_GPIO_Init(DISPLAY_DI_GPIO_Port, &GPIO_InitStruct);
/* SD_CD */
GPIO_InitStruct.Pin = SD_CD_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SD_CD_GPIO_Port, &GPIO_InitStruct);
/* SD_CS */
GPIO_InitStruct.Pin = SD_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(SD_CS_GPIO_Port, &GPIO_InitStruct);
/* CC1101_CS */
HAL_GPIO_WritePin(CC1101_CS_GPIO_Port, CC1101_CS_Pin, GPIO_PIN_SET);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pin = CC1101_CS_Pin;
HAL_GPIO_Init(CC1101_CS_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
HAL_NVIC_SetPriority(EXTI1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI1_IRQn);
HAL_NVIC_SetPriority(EXTI2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
HAL_NVIC_SetPriority(EXTI3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

View File

@ -0,0 +1,178 @@
#include "main.h"
#include "cmsis_os2.h"
#include "adc.h"
#include "aes.h"
#include "comp.h"
#include "crc.h"
#include "pka.h"
#include "rf.h"
#include "rng.h"
#include "rtc.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"
#include "fatfs/fatfs.h"
#include <furi.h>
#include <api-hal.h>
#include <flipper.h>
void SystemClock_Config(void);
void MX_FREERTOS_Init(void);
int main(void) {
// Initialize FURI layer
furi_init();
// Initialize ST HAL hardware
HAL_Init();
SystemClock_Config();
MX_USART1_UART_Init();
FURI_LOG_I("HAL", "USART OK");
MX_RTC_Init();
FURI_LOG_I("HAL", "RTC OK");
MX_GPIO_Init();
FURI_LOG_I("HAL", "GPIO OK");
MX_ADC1_Init();
FURI_LOG_I("HAL", "ADC1 OK");
MX_SPI1_Init();
FURI_LOG_I("HAL", "SPI1 OK");
MX_SPI2_Init();
FURI_LOG_I("HAL", "SPI2 OK");
MX_USB_Device_Init();
FURI_LOG_I("HAL", "USB OK");
MX_TIM1_Init();
FURI_LOG_I("HAL", "TIM1 OK");
MX_TIM2_Init();
FURI_LOG_I("HAL", "TIM2 OK");
MX_TIM16_Init();
FURI_LOG_I("HAL", "TIM16 OK");
MX_COMP1_Init();
FURI_LOG_I("HAL", "COMP1 OK");
MX_RF_Init();
FURI_LOG_I("HAL", "RF OK");
MX_PKA_Init();
FURI_LOG_I("HAL", "PKA OK");
MX_RNG_Init();
FURI_LOG_I("HAL", "RNG OK");
MX_AES1_Init();
FURI_LOG_I("HAL", "AES1 OK");
MX_AES2_Init();
FURI_LOG_I("HAL", "AES2 OK");
MX_CRC_Init();
FURI_LOG_I("HAL", "CRC OK");
// Flipper API HAL
api_hal_init();
// 3rd party
MX_FATFS_Init();
FURI_LOG_I("HAL", "FATFS OK");
// CMSIS initialization
osKernelInitialize();
FURI_LOG_I("HAL", "KERNEL OK");
// Init flipper
flipper_init();
// Start kernel
osKernelStart();
while (1) {}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_MEDIUMLOW);
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
LL_RCC_HSE_SetCapacitorTuning(0x18);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE
| RCC_OSCILLATORTYPE_LSI1 | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
RCC_OscInitStruct.PLL.PLLN = 8;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4|RCC_CLOCKTYPE_HCLK2
|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;
RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV2;
RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) {
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS|RCC_PERIPHCLK_RFWAKEUP
|RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1
|RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_CLK48SEL
|RCC_PERIPHCLK_USB|RCC_PERIPHCLK_RNG
|RCC_PERIPHCLK_ADC;
PeriphClkInitStruct.PLLSAI1.PLLN = 6;
PeriphClkInitStruct.PLLSAI1.PLLP = RCC_PLLP_DIV2;
PeriphClkInitStruct.PLLSAI1.PLLQ = RCC_PLLQ_DIV2;
PeriphClkInitStruct.PLLSAI1.PLLR = RCC_PLLR_DIV2;
PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_USBCLK|RCC_PLLSAI1_ADCCLK;
PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_CLK48;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSE;
PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSE;
PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
Error_Handler();
}
// CSS for HSE
HAL_RCC_EnableCSS();
// CSS for LSE
HAL_RCCEx_EnableLSECSS();
HAL_RCCEx_EnableLSECSS_IT();
}
void Error_Handler(void) {
asm("bkpt 1");
while(1) {}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line) {
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

View File

@ -0,0 +1,77 @@
/**
******************************************************************************
* @file pka.c
* @brief This file provides code for the configuration
* of the PKA instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "pka.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
PKA_HandleTypeDef hpka;
/* PKA init function */
void MX_PKA_Init(void)
{
hpka.Instance = PKA;
if (HAL_PKA_Init(&hpka) != HAL_OK)
{
Error_Handler();
}
}
void HAL_PKA_MspInit(PKA_HandleTypeDef* pkaHandle)
{
if(pkaHandle->Instance==PKA)
{
/* USER CODE BEGIN PKA_MspInit 0 */
/* USER CODE END PKA_MspInit 0 */
/* PKA clock enable */
__HAL_RCC_PKA_CLK_ENABLE();
/* USER CODE BEGIN PKA_MspInit 1 */
/* USER CODE END PKA_MspInit 1 */
}
}
void HAL_PKA_MspDeInit(PKA_HandleTypeDef* pkaHandle)
{
if(pkaHandle->Instance==PKA)
{
/* USER CODE BEGIN PKA_MspDeInit 0 */
/* USER CODE END PKA_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_PKA_CLK_DISABLE();
/* USER CODE BEGIN PKA_MspDeInit 1 */
/* USER CODE END PKA_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,37 @@
/**
******************************************************************************
* @file rf.c
* @brief This file provides code for the configuration
* of the RF instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "rf.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* RF init function */
void MX_RF_Init(void)
{
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,77 @@
/**
******************************************************************************
* @file rng.c
* @brief This file provides code for the configuration
* of the RNG instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "rng.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
RNG_HandleTypeDef hrng;
/* RNG init function */
void MX_RNG_Init(void)
{
hrng.Instance = RNG;
if (HAL_RNG_Init(&hrng) != HAL_OK)
{
Error_Handler();
}
}
void HAL_RNG_MspInit(RNG_HandleTypeDef* rngHandle)
{
if(rngHandle->Instance==RNG)
{
/* USER CODE BEGIN RNG_MspInit 0 */
/* USER CODE END RNG_MspInit 0 */
/* RNG clock enable */
__HAL_RCC_RNG_CLK_ENABLE();
/* USER CODE BEGIN RNG_MspInit 1 */
/* USER CODE END RNG_MspInit 1 */
}
}
void HAL_RNG_MspDeInit(RNG_HandleTypeDef* rngHandle)
{
if(rngHandle->Instance==RNG)
{
/* USER CODE BEGIN RNG_MspDeInit 0 */
/* USER CODE END RNG_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_RNG_CLK_DISABLE();
/* USER CODE BEGIN RNG_MspDeInit 1 */
/* USER CODE END RNG_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,123 @@
/**
******************************************************************************
* @file rtc.c
* @brief This file provides code for the configuration
* of the RTC instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "rtc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
RTC_HandleTypeDef hrtc;
/* RTC init function */
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
return;
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 0x0;
sTime.Minutes = 0x0;
sTime.Seconds = 0x0;
sTime.SubSeconds = 0x0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 0x1;
sDate.Year = 0x0;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
}
void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */
/* RTC clock enable */
__HAL_RCC_RTC_ENABLE();
__HAL_RCC_RTCAPB_CLK_ENABLE();
/* RTC interrupt Init */
HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn);
/* USER CODE BEGIN RTC_MspInit 1 */
/* USER CODE END RTC_MspInit 1 */
}
}
void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
{
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspDeInit 0 */
/* USER CODE END RTC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_RTC_DISABLE();
__HAL_RCC_RTCAPB_CLK_DISABLE();
/* RTC interrupt Deinit */
HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_IRQn);
/* USER CODE BEGIN RTC_MspDeInit 1 */
/* USER CODE END RTC_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,374 @@
/**
******************************************************************************
* @file spi.c
* @brief This file provides code for the configuration
* of the SPI instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "spi.h"
#include <cmsis_os2.h>
/* USER CODE BEGIN 0 */
void Enable_SPI(SPI_HandleTypeDef* spi);
/* USER CODE END 0 */
SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi2;
/* SPI1 init function */
void MX_SPI1_Init(void)
{
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_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
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();
}
}
/* SPI2 init function */
void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PB4 ------> SPI1_MISO
PB5 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = SPI_R_SCK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(SPI_R_SCK_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_R_MISO_Pin|SPI_R_MOSI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
else if(spiHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/* SPI2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**SPI2 GPIO Configuration
PC2 ------> SPI2_MISO
PB15 ------> SPI2_MOSI
PD1 ------> SPI2_SCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_D_MOSI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(SPI_D_MOSI_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_D_SCK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(SPI_D_SCK_GPIO_Port, &GPIO_InitStruct);
/* USER CODE BEGIN SPI2_MspInit 1 */
// SD Card need faster spi gpio
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_D_MOSI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(SPI_D_MOSI_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_D_SCK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(SPI_D_SCK_GPIO_Port, &GPIO_InitStruct);
/* USER CODE END SPI2_MspInit 1 */
}
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspDeInit 0 */
/* USER CODE END SPI1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI1_CLK_DISABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PB4 ------> SPI1_MISO
PB5 ------> SPI1_MOSI
*/
HAL_GPIO_DeInit(SPI_R_SCK_GPIO_Port, SPI_R_SCK_Pin);
HAL_GPIO_DeInit(GPIOB, SPI_R_MISO_Pin|SPI_R_MOSI_Pin);
/* USER CODE BEGIN SPI1_MspDeInit 1 */
/* USER CODE END SPI1_MspDeInit 1 */
}
else if(spiHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspDeInit 0 */
/* USER CODE END SPI2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI2_CLK_DISABLE();
/**SPI2 GPIO Configuration
PC2 ------> SPI2_MISO
PB15 ------> SPI2_MOSI
PD1 ------> SPI2_SCK
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_2);
HAL_GPIO_DeInit(SPI_D_MOSI_GPIO_Port, SPI_D_MOSI_Pin);
HAL_GPIO_DeInit(SPI_D_SCK_GPIO_Port, SPI_D_SCK_Pin);
/* USER CODE BEGIN SPI2_MspDeInit 1 */
/* USER CODE END SPI2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
void NFC_SPI_Reconfigure() {
osKernelLock();
SPI_R.Init.Mode = SPI_MODE_MASTER;
SPI_R.Init.Direction = SPI_DIRECTION_2LINES;
SPI_R.Init.DataSize = SPI_DATASIZE_8BIT;
SPI_R.Init.CLKPolarity = SPI_POLARITY_LOW;
SPI_R.Init.CLKPhase = SPI_PHASE_2EDGE;
SPI_R.Init.NSS = SPI_NSS_SOFT;
SPI_R.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; // 8mhz, 10mhz is max
SPI_R.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPI_R.Init.TIMode = SPI_TIMODE_DISABLE;
SPI_R.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SPI_R.Init.CRCPolynomial = 7;
SPI_R.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
SPI_R.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&SPI_R) != HAL_OK) {
Error_Handler();
}
Enable_SPI(&SPI_R);
osKernelUnlock();
}
void SD_SPI_Reconfigure_Slow(void) {
osKernelLock();
SPI_SD_HANDLE.Init.Mode = SPI_MODE_MASTER;
SPI_SD_HANDLE.Init.Direction = SPI_DIRECTION_2LINES;
SPI_SD_HANDLE.Init.DataSize = SPI_DATASIZE_8BIT;
SPI_SD_HANDLE.Init.CLKPolarity = SPI_POLARITY_LOW;
SPI_SD_HANDLE.Init.CLKPhase = SPI_PHASE_1EDGE;
SPI_SD_HANDLE.Init.NSS = SPI_NSS_SOFT;
SPI_SD_HANDLE.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
SPI_SD_HANDLE.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPI_SD_HANDLE.Init.TIMode = SPI_TIMODE_DISABLE;
SPI_SD_HANDLE.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SPI_SD_HANDLE.Init.CRCPolynomial = 7;
SPI_SD_HANDLE.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
SPI_SD_HANDLE.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
if(HAL_SPI_Init(&SPI_SD_HANDLE) != HAL_OK) {
Error_Handler();
}
Enable_SPI(&SPI_SD_HANDLE);
osKernelUnlock();
}
void SD_SPI_Reconfigure_Fast(void) {
osKernelLock();
SPI_SD_HANDLE.Init.Mode = SPI_MODE_MASTER;
SPI_SD_HANDLE.Init.Direction = SPI_DIRECTION_2LINES;
SPI_SD_HANDLE.Init.DataSize = SPI_DATASIZE_8BIT;
SPI_SD_HANDLE.Init.CLKPolarity = SPI_POLARITY_LOW;
SPI_SD_HANDLE.Init.CLKPhase = SPI_PHASE_1EDGE;
SPI_SD_HANDLE.Init.NSS = SPI_NSS_SOFT;
SPI_SD_HANDLE.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
SPI_SD_HANDLE.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPI_SD_HANDLE.Init.TIMode = SPI_TIMODE_DISABLE;
SPI_SD_HANDLE.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SPI_SD_HANDLE.Init.CRCPolynomial = 7;
SPI_SD_HANDLE.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
SPI_SD_HANDLE.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
if(HAL_SPI_Init(&SPI_SD_HANDLE) != HAL_OK) {
Error_Handler();
}
Enable_SPI(&SPI_SD_HANDLE);
osKernelUnlock();
}
void CC1101_SPI_Reconfigure(void) {
osKernelLock();
SPI_R.Init.Mode = SPI_MODE_MASTER;
SPI_R.Init.Direction = SPI_DIRECTION_2LINES;
SPI_R.Init.DataSize = SPI_DATASIZE_8BIT;
SPI_R.Init.CLKPolarity = SPI_POLARITY_LOW;
SPI_R.Init.CLKPhase = SPI_PHASE_1EDGE;
SPI_R.Init.NSS = SPI_NSS_SOFT;
SPI_R.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
SPI_R.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPI_R.Init.TIMode = SPI_TIMODE_DISABLE;
SPI_R.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SPI_R.Init.CRCPolynomial = 7;
SPI_R.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
SPI_R.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if(HAL_SPI_Init(&SPI_R) != HAL_OK) {
Error_Handler();
}
Enable_SPI(&SPI_R);
osKernelUnlock();
}
void Enable_SPI(SPI_HandleTypeDef* spi_instance){
if((spi_instance->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) {
__HAL_SPI_ENABLE(spi_instance);
}
}
void SD_SPI_Bus_To_Down_State(){
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_D_MOSI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SPI_D_MOSI_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_D_SCK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SPI_D_SCK_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SPI_D_MOSI_GPIO_Port, SPI_D_MOSI_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SPI_D_SCK_GPIO_Port, SPI_D_SCK_Pin, GPIO_PIN_RESET);
}
void SD_SPI_Bus_To_Normal_State(){
HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_SET);
HAL_SPI_MspInit(&SPI_SD_HANDLE);
}
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,93 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : stm32wbxx_hal_msp.c
* Description : This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_HSEM_CLK_ENABLE();
/* System interrupt init*/
/* PendSV_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
/* Peripheral interrupt init */
/* RCC_IRQn interrupt configuration */
HAL_NVIC_SetPriority(RCC_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(RCC_IRQn);
/* HSEM_IRQn interrupt configuration */
HAL_NVIC_SetPriority(HSEM_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(HSEM_IRQn);
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,107 @@
#include "main.h"
#include "stm32wbxx_it.h"
#include "FreeRTOS.h"
#include "task.h"
extern PCD_HandleTypeDef hpcd_USB_FS;
extern ADC_HandleTypeDef hadc1;
extern COMP_HandleTypeDef hcomp1;
extern RTC_HandleTypeDef hrtc;
extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim16;
extern TIM_HandleTypeDef htim17;
extern void HW_TS_RTC_Wakeup_Handler();
extern void HW_IPCC_Tx_Handler();
extern void HW_IPCC_Rx_Handler();
void NMI_Handler(void) {
HAL_RCC_NMI_IRQHandler();
}
void HardFault_Handler(void) {
if ((*(volatile uint32_t *)CoreDebug_BASE) & (1 << 0)) {
__asm("bkpt 1");
}
while (1) {}
}
void MemManage_Handler(void) {
__asm("bkpt 1");
while (1) {}
}
void BusFault_Handler(void) {
__asm("bkpt 1");
while (1) {}
}
void UsageFault_Handler(void) {
__asm("bkpt 1");
while (1) {}
}
void DebugMon_Handler(void) {
}
void SysTick_Handler(void) {
HAL_IncTick();
}
void TAMP_STAMP_LSECSS_IRQHandler(void) {
if (!LL_RCC_LSE_IsReady()) {
// TODO: notify user about issue with LSE
LL_RCC_ForceBackupDomainReset();
LL_RCC_ReleaseBackupDomainReset();
NVIC_SystemReset();
}
}
void RCC_IRQHandler(void) {
}
void ADC1_IRQHandler(void) {
HAL_ADC_IRQHandler(&hadc1);
}
void USB_LP_IRQHandler(void) {
HAL_PCD_IRQHandler(&hpcd_USB_FS);
}
void COMP_IRQHandler(void) {
HAL_COMP_IRQHandler(&hcomp1);
}
void TIM1_UP_TIM16_IRQHandler(void) {
HAL_TIM_IRQHandler(&htim1);
HAL_TIM_IRQHandler(&htim16);
}
void TIM1_TRG_COM_TIM17_IRQHandler(void) {
HAL_TIM_IRQHandler(&htim1);
}
void TIM1_CC_IRQHandler(void) {
HAL_TIM_IRQHandler(&htim1);
}
void TIM2_IRQHandler(void) {
HAL_TIM_IRQHandler(&htim2);
}
void HSEM_IRQHandler(void) {
HAL_HSEM_IRQHandler();
}
void RTC_WKUP_IRQHandler(void){
HW_TS_RTC_Wakeup_Handler();
}
void IPCC_C1_TX_IRQHandler(void){
HW_IPCC_Tx_Handler();
}
void IPCC_C1_RX_IRQHandler(void){
HW_IPCC_Rx_Handler();
}

View File

@ -0,0 +1,357 @@
/**
******************************************************************************
* @file system_stm32wbxx.c
* @author MCD Application Team
* @brief CMSIS Cortex Device Peripheral Access Layer System Source File
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32wbxx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* After each device reset the MSI (4 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to
* configure the system clock before to branch to main program.
*
* This file configures the system clock as follows:
*=============================================================================
*-----------------------------------------------------------------------------
* System Clock source | MSI
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 1
*-----------------------------------------------------------------------------
* APB2 Prescaler | 1
*-----------------------------------------------------------------------------
* PLL_M | 1
*-----------------------------------------------------------------------------
* PLL_N | 8
*-----------------------------------------------------------------------------
* PLL_P | 7
*-----------------------------------------------------------------------------
* PLL_Q | 2
*-----------------------------------------------------------------------------
* PLL_R | 2
*-----------------------------------------------------------------------------
* PLLSAI1_P | NA
*-----------------------------------------------------------------------------
* PLLSAI1_Q | NA
*-----------------------------------------------------------------------------
* PLLSAI1_R | NA
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Disabled
* SDIO and RNG clock |
*-----------------------------------------------------------------------------
*=============================================================================
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32WBxx_system
* @{
*/
/** @addtogroup stm32WBxx_System_Private_Includes
* @{
*/
#include "stm32wbxx.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE (32000000UL) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (MSI_VALUE)
#define MSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
#if !defined (LSI_VALUE)
#define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/
#endif /* LSI_VALUE */
#if !defined (LSE_VALUE)
#define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/
#endif /* LSE_VALUE */
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Defines
* @{
*/
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET OS_OFFSET /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#define VECT_TAB_BASE_ADDRESS SRAM1_BASE /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Variables
* @{
*/
/* The SystemCoreClock variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 4000000UL ; /*CPU1: M4 on MSI clock after startup (4MHz)*/
const uint32_t AHBPrescTable[16UL] = {1UL, 3UL, 5UL, 1UL, 1UL, 6UL, 10UL, 32UL, 2UL, 4UL, 8UL, 16UL, 64UL, 128UL, 256UL, 512UL};
const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL};
const uint32_t MSIRangeTable[16UL] = {100000UL, 200000UL, 400000UL, 800000UL, 1000000UL, 2000000UL, \
4000000UL, 8000000UL, 16000000UL, 24000000UL, 32000000UL, 48000000UL, 0UL, 0UL, 0UL, 0UL}; /* 0UL values are incorrect cases */
#if defined(STM32WB55xx) || defined(STM32WB5Mxx) || defined(STM32WB35xx)
const uint32_t SmpsPrescalerTable[4UL][6UL]={{1UL,3UL,2UL,2UL,1UL,2UL}, \
{2UL,6UL,4UL,3UL,2UL,4UL}, \
{4UL,12UL,8UL,6UL,4UL,8UL}, \
{4UL,12UL,8UL,6UL,4UL,8UL}};
#endif
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system.
* @param None
* @retval None
*/
void SystemInit(void)
{
/* Configure the Vector Table location add offset address ------------------*/
#if defined(VECT_TAB_SRAM) && defined(VECT_TAB_BASE_ADDRESS)
/* program in SRAMx */
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAMx for CPU1 */
#else /* program in FLASH */
SCB->VTOR = VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << (10UL*2UL))|(3UL << (11UL*2UL))); /* set CP10 and CP11 Full Access */
#endif
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set MSION bit */
RCC->CR |= RCC_CR_MSION;
/* Reset CFGR register */
RCC->CFGR = 0x00070000U;
/* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */
RCC->CR &= (uint32_t)0xFAF6FEFBU;
/*!< Reset LSI1 and LSI2 bits */
RCC->CSR &= (uint32_t)0xFFFFFFFAU;
/*!< Reset HSI48ON bit */
RCC->CRRCR &= (uint32_t)0xFFFFFFFEU;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x22041000U;
#if defined(STM32WB55xx) || defined(STM32WB5Mxx)
/* Reset PLLSAI1CFGR register */
RCC->PLLSAI1CFGR = 0x22041000U;
#endif
/* Reset HSEBYP bit */
RCC->CR &= 0xFFFBFFFFU;
/* Disable all interrupts */
RCC->CIER = 0x00000000;
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
* or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value
* 4 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 32 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp, msirange, pllvco, pllr, pllsource , pllm;
/* Get MSI Range frequency--------------------------------------------------*/
/*MSI frequency range in Hz*/
msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos];
/* Get SYSCLK source -------------------------------------------------------*/
switch (RCC->CFGR & RCC_CFGR_SWS)
{
case 0x00: /* MSI used as system clock source */
SystemCoreClock = msirange;
break;
case 0x04: /* HSI used as system clock source */
/* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x08: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x0C: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
SYSCLK = PLL_VCO / PLLR
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL ;
if(pllsource == 0x02UL) /* HSI used as PLL clock source */
{
pllvco = (HSI_VALUE / pllm);
}
else if(pllsource == 0x03UL) /* HSE used as PLL clock source */
{
pllvco = (HSE_VALUE / pllm);
}
else /* MSI used as PLL clock source */
{
pllvco = (msirange / pllm);
}
pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL);
SystemCoreClock = pllvco/pllr;
break;
default:
SystemCoreClock = msirange;
break;
}
/* Compute HCLK clock frequency --------------------------------------------*/
/* Get HCLK1 prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
/* HCLK clock frequency */
SystemCoreClock = SystemCoreClock / tmp;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,361 @@
/**
******************************************************************************
* @file tim.c
* @brief This file provides code for the configuration
* of the TIM instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "tim.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim16;
/* TIM1 init function */
void MX_TIM1_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
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;
if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&htim1);
}
/* TIM2 init function */
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 64-1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 4294967295;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
}
/* TIM16 init function */
void MX_TIM16_Init(void)
{
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
htim16.Instance = TIM16;
htim16.Init.Prescaler = 500 - 1;
htim16.Init.CounterMode = TIM_COUNTERMODE_UP;
htim16.Init.Period = 291;
htim16.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim16.Init.RepetitionCounter = 0;
htim16.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim16) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim16) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 145;
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;
if (HAL_TIM_PWM_ConfigChannel(&htim16, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim16, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&htim16);
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(tim_baseHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspInit 0 */
/* USER CODE END TIM1_MspInit 0 */
/* TIM1 clock enable */
__HAL_RCC_TIM1_CLK_ENABLE();
/* TIM1 interrupt Init */
HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM17_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM17_IRQn);
/* USER CODE BEGIN TIM1_MspInit 1 */
/* USER CODE END TIM1_MspInit 1 */
}
else if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspInit 0 */
/* USER CODE END TIM2_MspInit 0 */
/* TIM2 clock enable */
__HAL_RCC_TIM2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM2 GPIO Configuration
PA0 ------> TIM2_CH1
*/
GPIO_InitStruct.Pin = IR_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(IR_RX_GPIO_Port, &GPIO_InitStruct);
/* TIM2 interrupt Init */
HAL_NVIC_SetPriority(TIM2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspInit 1 */
/* USER CODE END TIM2_MspInit 1 */
}
else if(tim_baseHandle->Instance==TIM16)
{
/* USER CODE BEGIN TIM16_MspInit 0 */
/* USER CODE END TIM16_MspInit 0 */
/* TIM16 clock enable */
__HAL_RCC_TIM16_CLK_ENABLE();
/* USER CODE BEGIN TIM16_MspInit 1 */
/* USER CODE END TIM16_MspInit 1 */
}
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(timHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspPostInit 0 */
/* USER CODE END TIM1_MspPostInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**TIM1 GPIO Configuration
PB9 ------> TIM1_CH3N
PB13 ------> TIM1_CH1N
*/
GPIO_InitStruct.Pin = IR_TX_Pin|RFID_OUT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN TIM1_MspPostInit 1 */
/* USER CODE END TIM1_MspPostInit 1 */
}
else if(timHandle->Instance==TIM16)
{
/* USER CODE BEGIN TIM16_MspPostInit 0 */
/* USER CODE END TIM16_MspPostInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**TIM16 GPIO Configuration
PB8 ------> TIM16_CH1
*/
GPIO_InitStruct.Pin = SPEAKER_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF14_TIM16;
HAL_GPIO_Init(SPEAKER_GPIO_Port, &GPIO_InitStruct);
/* USER CODE BEGIN TIM16_MspPostInit 1 */
/* USER CODE END TIM16_MspPostInit 1 */
}
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspDeInit 0 */
/* USER CODE END TIM1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM1_CLK_DISABLE();
/* TIM1 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM1_TRG_COM_TIM17_IRQn);
/* USER CODE BEGIN TIM1_MspDeInit 1 */
/* USER CODE END TIM1_MspDeInit 1 */
}
else if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspDeInit 0 */
/* USER CODE END TIM2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM2_CLK_DISABLE();
/**TIM2 GPIO Configuration
PA0 ------> TIM2_CH1
*/
HAL_GPIO_DeInit(IR_RX_GPIO_Port, IR_RX_Pin);
/* TIM2 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspDeInit 1 */
/* USER CODE END TIM2_MspDeInit 1 */
}
else if(tim_baseHandle->Instance==TIM16)
{
/* USER CODE BEGIN TIM16_MspDeInit 0 */
/* USER CODE END TIM16_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM16_CLK_DISABLE();
/* USER CODE BEGIN TIM16_MspDeInit 1 */
/* USER CODE END TIM16_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,55 @@
#include "usart.h"
UART_HandleTypeDef huart1;
void MX_USART1_UART_Init(void) {
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
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.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK) {
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) {
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) {
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK) {
Error_Handler();
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1) {
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = USART1_TX_Pin|USART1_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) {
if(uartHandle->Instance==USART1) {
__HAL_RCC_USART1_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOB, USART1_TX_Pin|USART1_RX_Pin);
}
}

View File

@ -0,0 +1,99 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usb_device.c
* @version : v3.0_Cube
* @brief : This file implements the USB Device
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usb_device.h"
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_cdc.h"
#include "usbd_cdc_if.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
extern void Error_Handler(void);
/* USB Device Core handle declaration. */
USBD_HandleTypeDef hUsbDeviceFS;
extern USBD_DescriptorsTypeDef CDC_Desc;
/*
* -- Insert your variables declaration here --
*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*
* -- Insert your external function declaration here --
*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Init USB device Library, add supported class and start the library
* @retval None
*/
void MX_USB_Device_Init(void)
{
/* USER CODE BEGIN USB_Device_Init_PreTreatment */
/* USER CODE END USB_Device_Init_PreTreatment */
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &CDC_Desc, DEVICE_FS) != USBD_OK) {
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) {
Error_Handler();
}
if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK) {
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
Error_Handler();
}
/* USER CODE BEGIN USB_Device_Init_PostTreatment */
/* USER CODE END USB_Device_Init_PostTreatment */
}
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,311 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_cdc_if.c
* @version : v3.0_Cube
* @brief : Usb device for Virtual Com Port.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc_if.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @brief Usb device library.
* @{
*/
/** @addtogroup USBD_CDC_IF
* @{
*/
/** @defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions
* @brief Private types.
* @{
*/
/* USER CODE BEGIN PRIVATE_TYPES */
extern void _api_hal_vcp_init();
extern void _api_hal_vcp_deinit();
extern void _api_hal_vcp_control_line(uint8_t state);
extern void _api_hal_vcp_rx_callback(char* buffer, size_t size);
extern void _api_hal_vcp_tx_complete(size_t size);
/* USER CODE END PRIVATE_TYPES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines
* @brief Private defines.
* @{
*/
/* USER CODE BEGIN PRIVATE_DEFINES */
/* USER CODE END PRIVATE_DEFINES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros
* @brief Private macros.
* @{
*/
/* USER CODE BEGIN PRIVATE_MACRO */
/* USER CODE END PRIVATE_MACRO */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables
* @brief Private variables.
* @{
*/
/* Create buffer for reception and transmission */
/* It's up to user to redefine and/or remove those define */
/** Received data over USB are stored in this buffer */
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
/** Data to send over USB CDC are stored in this buffer */
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
/* USER CODE BEGIN PRIVATE_VARIABLES */
/* USER CODE END PRIVATE_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
* @brief Public variables.
* @{
*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static int8_t CDC_Init_FS(void);
static int8_t CDC_DeInit_FS(void);
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length);
static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
/**
* @}
*/
USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
{
CDC_Init_FS,
CDC_DeInit_FS,
CDC_Control_FS,
CDC_Receive_FS,
CDC_TransmitCplt_FS
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the CDC media low layer over the FS USB IP
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Init_FS(void)
{
/* USER CODE BEGIN 3 */
/* Set Application Buffers */
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
_api_hal_vcp_init();
return (USBD_OK);
/* USER CODE END 3 */
}
/**
* @brief DeInitializes the CDC media low layer
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_DeInit_FS(void)
{
/* USER CODE BEGIN 4 */
_api_hal_vcp_deinit();
return (USBD_OK);
/* USER CODE END 4 */
}
/**
* @brief Manage the CDC class requests
* @param cmd: Command code
* @param pbuf: Buffer containing command data (request parameters)
* @param length: Number of data to be sent (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)
{
/* USER CODE BEGIN 5 */
if (cmd == CDC_SEND_ENCAPSULATED_COMMAND) {
} else if (cmd == CDC_GET_ENCAPSULATED_RESPONSE) {
} else if (cmd == CDC_SET_COMM_FEATURE) {
} else if (cmd == CDC_GET_COMM_FEATURE) {
} else if (cmd == CDC_CLEAR_COMM_FEATURE) {
} else if (cmd == CDC_SET_LINE_CODING) {
/*******************************************************************************/
/* Line Coding Structure */
/*-----------------------------------------------------------------------------*/
/* Offset | Field | Size | Value | Description */
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
/* 4 | bCharFormat | 1 | Number | Stop bits */
/* 0 - 1 Stop bit */
/* 1 - 1.5 Stop bits */
/* 2 - 2 Stop bits */
/* 5 | bParityType | 1 | Number | Parity */
/* 0 - None */
/* 1 - Odd */
/* 2 - Even */
/* 3 - Mark */
/* 4 - Space */
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
/*******************************************************************************/
} else if (cmd == CDC_GET_LINE_CODING) {
} else if (cmd == CDC_SET_CONTROL_LINE_STATE) {
_api_hal_vcp_control_line(((USBD_SetupReqTypedef*)pbuf)->wValue);
} else if (cmd == CDC_SEND_BREAK) {
} else {
}
return (USBD_OK);
/* USER CODE END 5 */
}
/**
* @brief Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* @note
* This function will issue a NAK packet on any OUT packet received on
* USB endpoint until exiting this function. If you exit this function
* before transfer is complete on CDC interface (ie. using DMA controller)
* it will result in receiving more data while previous ones are still
* not sent.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
_api_hal_vcp_rx_callback((char*)Buf, *Len);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
/**
* @brief CDC_Transmit_FS
* Data to send over USB IN endpoint are sent over CDC interface
* through this function.
* @note
*
*
* @param Buf: Buffer of data to be sent
* @param Len: Number of data to be sent (in bytes)
* @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
*/
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 7 */
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
if (hcdc->TxState != 0){
return USBD_BUSY;
}
memcpy(UserTxBufferFS, Buf, Len);
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
/* USER CODE END 7 */
return result;
}
/**
* @brief CDC_TransmitCplt_FS
* Data transmited callback
*
* @note
* This function is IN transfer complete callback used to inform user that
* the submitted Data is successfully sent over USB.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 13 */
UNUSED(Buf);
UNUSED(epnum);
_api_hal_vcp_tx_complete(*Len);
/* USER CODE END 13 */
return result;
}
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,810 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_conf.c
* @version : v3.0_Cube
* @brief : This file implements the board support package for the USB device library
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx.h"
#include "stm32wbxx_hal.h"
#include "usbd_def.h"
#include "usbd_core.h"
#include "usbd_cdc.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
PCD_HandleTypeDef hpcd_USB_FS;
void Error_Handler(void);
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* Exported function prototypes ----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* Private functions ---------------------------------------------------------*/
static USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status);
/* USER CODE BEGIN 1 */
static void SystemClockConfig_Resume(void);
/* USER CODE END 1 */
extern void SystemClock_Config(void);
/*******************************************************************************
LL Driver Callbacks (PCD -> USB Device Library)
*******************************************************************************/
/* MSP Init */
#if (USE_HAL_PCD_REGISTER_CALLBACK == 1U)
static void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
#else
void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
#endif /* USE_HAL_PCD_REGISTER_CALLBACK */
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(pcdHandle->Instance==USB)
{
/* USER CODE BEGIN USB_MspInit 0 */
/* USER CODE END USB_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USB GPIO Configuration
PA11 ------> USB_DM
PA12 ------> USB_DP
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_USB;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_USB_CLK_ENABLE();
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(USB_LP_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USB_LP_IRQn);
/* USER CODE BEGIN USB_MspInit 1 */
/* USER CODE END USB_MspInit 1 */
}
}
#if (USE_HAL_PCD_REGISTER_CALLBACK == 1U)
static void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
#else
void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
#endif /* USE_HAL_PCD_REGISTER_CALLBACK */
{
if(pcdHandle->Instance==USB)
{
/* USER CODE BEGIN USB_MspDeInit 0 */
/* USER CODE END USB_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USB_CLK_DISABLE();
/**USB GPIO Configuration
PA11 ------> USB_DM
PA12 ------> USB_DP
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* Peripheral interrupt Deinit*/
HAL_NVIC_DisableIRQ(USB_LP_IRQn);
/* USER CODE BEGIN USB_MspDeInit 1 */
/* USER CODE END USB_MspDeInit 1 */
}
}
/**
* @brief Setup stage callback
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_SetupStageCallback_PreTreatment */
/* USER CODE END HAL_PCD_SetupStageCallback_PreTreatment */
USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup);
/* USER CODE BEGIN HAL_PCD_SetupStageCallback_PostTreatment */
/* USER CODE END HAL_PCD_SetupStageCallback_PostTreatment */
}
/**
* @brief Data Out stage callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#else
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_DataOutStageCallback_PreTreatment */
/* USER CODE END HAL_PCD_DataOutStageCallback_PreTreatment */
USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
/* USER CODE BEGIN HAL_PCD_DataOutStageCallback_PostTreatment */
/* USER CODE END HAL_PCD_DataOutStageCallback_PostTreatment */
}
/**
* @brief Data In stage callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#else
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_DataInStageCallback_PreTreatment */
/* USER CODE END HAL_PCD_DataInStageCallback_PreTreatment */
USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
/* USER CODE BEGIN HAL_PCD_DataInStageCallback_PostTreatment */
/* USER CODE END HAL_PCD_DataInStageCallback_PostTreatment */
}
/**
* @brief SOF callback.
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_SOFCallback_PreTreatment */
/* USER CODE END HAL_PCD_SOFCallback_PreTreatment */
USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_SOFCallback_PostTreatment */
/* USER CODE END HAL_PCD_SOFCallback_PostTreatment */
}
/**
* @brief Reset callback.
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ResetCallback_PreTreatment */
/* USER CODE END HAL_PCD_ResetCallback_PreTreatment */
USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
if ( hpcd->Init.speed != PCD_SPEED_FULL)
{
Error_Handler();
}
/* Set Speed. */
USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed);
/* Reset Device. */
USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_ResetCallback_PostTreatment */
/* USER CODE END HAL_PCD_ResetCallback_PostTreatment */
}
/**
* @brief Suspend callback.
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_SuspendCallback_PreTreatment */
/* USER CODE END HAL_PCD_SuspendCallback_PreTreatment */
/* Inform USB library that core enters in suspend Mode. */
USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData);
/* Enter in STOP mode. */
/* USER CODE BEGIN 2 */
if (hpcd->Init.low_power_enable)
{
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
}
/* USER CODE END 2 */
/* USER CODE BEGIN HAL_PCD_SuspendCallback_PostTreatment */
/* USER CODE END HAL_PCD_SuspendCallback_PostTreatment */
}
/**
* @brief Resume callback.
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ResumeCallback_PreTreatment */
/* USER CODE END HAL_PCD_ResumeCallback_PreTreatment */
/* USER CODE BEGIN 3 */
if (hpcd->Init.low_power_enable)
{
/* Reset SLEEPDEEP bit of Cortex System Control Register. */
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
SystemClockConfig_Resume();
}
/* USER CODE END 3 */
USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_ResumeCallback_PostTreatment */
/* USER CODE END HAL_PCD_ResumeCallback_PostTreatment */
}
/**
* @brief ISOOUTIncomplete callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#else
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ISOOUTIncompleteCallback_PreTreatment */
/* USER CODE END HAL_PCD_ISOOUTIncompleteCallback_PreTreatment */
USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
/* USER CODE BEGIN HAL_PCD_ISOOUTIncompleteCallback_PostTreatment */
/* USER CODE END HAL_PCD_ISOOUTIncompleteCallback_PostTreatment */
}
/**
* @brief ISOINIncomplete callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#else
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ISOINIncompleteCallback_PreTreatment */
/* USER CODE END HAL_PCD_ISOINIncompleteCallback_PreTreatment */
USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
/* USER CODE BEGIN HAL_PCD_ISOINIncompleteCallback_PostTreatment */
/* USER CODE END HAL_PCD_ISOINIncompleteCallback_PostTreatment */
}
/**
* @brief Connect callback.
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ConnectCallback_PreTreatment */
/* USER CODE END HAL_PCD_ConnectCallback_PreTreatment */
USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_ConnectCallback_PostTreatment */
/* USER CODE END HAL_PCD_ConnectCallback_PostTreatment */
}
/**
* @brief Disconnect callback.
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_DisconnectCallback_PreTreatment */
/* USER CODE END HAL_PCD_DisconnectCallback_PreTreatment */
USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_DisconnectCallback_PostTreatment */
/* USER CODE END HAL_PCD_DisconnectCallback_PostTreatment */
}
/* USER CODE BEGIN LowLevelInterface */
/* USER CODE END LowLevelInterface */
/*******************************************************************************
LL Driver Interface (USB Device Library --> PCD)
*******************************************************************************/
/**
* @brief Initializes the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
{
/* Init USB Ip. */
hpcd_USB_FS.pData = pdev;
/* Link the driver to the stack. */
pdev->pData = &hpcd_USB_FS;
/* Enable USB power on Pwrctrl CR2 register. */
HAL_PWREx_EnableVddUSB();
hpcd_USB_FS.Instance = USB;
hpcd_USB_FS.Init.dev_endpoints = 8;
hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;
hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
hpcd_USB_FS.Init.Sof_enable = DISABLE;
hpcd_USB_FS.Init.low_power_enable = DISABLE;
hpcd_USB_FS.Init.lpm_enable = DISABLE;
hpcd_USB_FS.Init.battery_charging_enable = DISABLE;
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
/* register Msp Callbacks (before the Init) */
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_MSPINIT_CB_ID, PCD_MspInit);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_MSPDEINIT_CB_ID, PCD_MspDeInit);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK)
{
Error_Handler( );
}
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
/* Register USB PCD CallBacks */
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SOF_CB_ID, PCD_SOFCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SETUPSTAGE_CB_ID, PCD_SetupStageCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_RESET_CB_ID, PCD_ResetCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SUSPEND_CB_ID, PCD_SuspendCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_RESUME_CB_ID, PCD_ResumeCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_CONNECT_CB_ID, PCD_ConnectCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_DISCONNECT_CB_ID, PCD_DisconnectCallback);
/* USER CODE BEGIN RegisterCallBackFirstPart */
/* USER CODE END RegisterCallBackFirstPart */
HAL_PCD_RegisterLpmCallback(&hpcd_USB_FS, PCDEx_LPM_Callback);
HAL_PCD_RegisterDataOutStageCallback(&hpcd_USB_FS, PCD_DataOutStageCallback);
HAL_PCD_RegisterDataInStageCallback(&hpcd_USB_FS, PCD_DataInStageCallback);
HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_FS, PCD_ISOOUTIncompleteCallback);
HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_FS, PCD_ISOINIncompleteCallback);
/* USER CODE BEGIN RegisterCallBackSecondPart */
/* USER CODE END RegisterCallBackSecondPart */
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
/* USER CODE BEGIN EndPoint_Configuration */
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
/* USER CODE END EndPoint_Configuration */
/* USER CODE BEGIN EndPoint_Configuration_CDC */
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100);
/* USER CODE END EndPoint_Configuration_CDC */
return USBD_OK;
}
/**
* @brief De-Initializes the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_DeInit(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Starts the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_Start(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Stops the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_Stop(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Opens an endpoint of the low level driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @param ep_type: Endpoint type
* @param ep_mps: Endpoint max packet size
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Closes an endpoint of the low level driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Flushes an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Sets a Stall condition on an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Clears a Stall condition on an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Returns Stall condition.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval Stall (1: Yes, 0: No)
*/
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData;
if((ep_addr & 0x80) == 0x80)
{
return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
}
else
{
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
}
}
/**
* @brief Assigns a USB address to the device.
* @param pdev: Device handle
* @param dev_addr: Device address
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Transmits data over an endpoint.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @param pbuf: Pointer to data to be sent
* @param size: Data size
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Prepares an endpoint for reception.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @param pbuf: Pointer to data to be received
* @param size: Data size
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Returns the last transfered packet size.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval Recived Data Size
*/
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr);
}
/**
* @brief Send LPM message to user layer
* @param hpcd: PCD handle
* @param msg: LPM message
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
#else
void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN LPM_Callback */
switch (msg)
{
case PCD_LPM_L0_ACTIVE:
if (hpcd->Init.low_power_enable)
{
SystemClockConfig_Resume();
/* Reset SLEEPDEEP bit of Cortex System Control Register. */
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
}
USBD_LL_Resume(hpcd->pData);
break;
case PCD_LPM_L1_ACTIVE:
USBD_LL_Suspend(hpcd->pData);
/* Enter in STOP mode. */
if (hpcd->Init.low_power_enable)
{
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
}
break;
}
/* USER CODE END LPM_Callback */
}
/**
* @brief Delays routine for the USB Device Library.
* @param Delay: Delay in ms
* @retval None
*/
void USBD_LL_Delay(uint32_t Delay)
{
HAL_Delay(Delay);
}
/**
* @brief Static single allocation.
* @param size: Size of allocated memory
* @retval None
*/
void *USBD_static_malloc(uint32_t size)
{
static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
return mem;
}
/**
* @brief Dummy memory free
* @param p: Pointer to allocated memory address
* @retval None
*/
void USBD_static_free(void *p)
{
}
/* USER CODE BEGIN 5 */
/**
* @brief Configures system clock after wake-up from USB resume callBack:
* enable HSI, PLL and select PLL as system clock source.
* @retval None
*/
static void SystemClockConfig_Resume(void)
{
SystemClock_Config();
}
/* USER CODE END 5 */
/**
* @brief Retuns the USB status depending on the HAL status:
* @param hal_status: HAL status
* @retval USB status
*/
USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status)
{
USBD_StatusTypeDef usb_status = USBD_OK;
switch (hal_status)
{
case HAL_OK :
usb_status = USBD_OK;
break;
case HAL_ERROR :
usb_status = USBD_FAIL;
break;
case HAL_BUSY :
usb_status = USBD_BUSY;
break;
case HAL_TIMEOUT :
usb_status = USBD_FAIL;
break;
default :
usb_status = USBD_FAIL;
break;
}
return usb_status;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,400 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_desc.c
* @version : v3.0_Cube
* @brief : This file implements the USB device descriptors.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_conf.h"
#include "api-hal-version.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @addtogroup USBD_DESC
* @{
*/
/** @defgroup USBD_DESC_Private_TypesDefinitions USBD_DESC_Private_TypesDefinitions
* @brief Private types.
* @{
*/
/* USER CODE BEGIN PRIVATE_TYPES */
/* USER CODE END PRIVATE_TYPES */
/**
* @}
*/
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
* @brief Private defines.
* @{
*/
#define USBD_VID 1155
#define USBD_LANGID_STRING 1033
#define USBD_MANUFACTURER_STRING "Flipper Devices Inc."
#define USBD_PID 22336
#define USBD_PRODUCT_STRING "Flipper Control Virtual ComPort"
#define USBD_CONFIGURATION_STRING "CDC Config"
#define USBD_INTERFACE_STRING "CDC Interface"
/* USER CODE BEGIN PRIVATE_DEFINES */
/* USER CODE END PRIVATE_DEFINES */
/**
* @}
*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/** @defgroup USBD_DESC_Private_Macros USBD_DESC_Private_Macros
* @brief Private macros.
* @{
*/
/* USER CODE BEGIN PRIVATE_MACRO */
/* USER CODE END PRIVATE_MACRO */
/**
* @}
*/
/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static void Get_SerialNum(void);
static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len);
/**
* @}
*/
/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
uint8_t * USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
/**
* @}
*/
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
USBD_DescriptorsTypeDef CDC_Desc =
{
USBD_CDC_DeviceDescriptor,
USBD_CDC_LangIDStrDescriptor,
USBD_CDC_ManufacturerStrDescriptor,
USBD_CDC_ProductStrDescriptor,
USBD_CDC_SerialStrDescriptor,
USBD_CDC_ConfigStrDescriptor,
USBD_CDC_InterfaceStrDescriptor
};
#if defined ( __ICCARM__ ) /* IAR Compiler */
#pragma data_alignment=4
#endif /* defined ( __ICCARM__ ) */
/** USB standard device descriptor. */
__ALIGN_BEGIN uint8_t USBD_CDC_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
0x00, /*bcdUSB */
0x02,
0x02, /*bDeviceClass*/
0x02, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID), /*idProduct*/
HIBYTE(USBD_PID), /*idProduct*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
};
/* USB_DeviceDescriptor */
/**
* @}
*/
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
#if defined ( __ICCARM__ ) /* IAR Compiler */
#pragma data_alignment=4
#endif /* defined ( __ICCARM__ ) */
/** USB lang indentifier descriptor. */
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END =
{
USB_LEN_LANGID_STR_DESC,
USB_DESC_TYPE_STRING,
LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING)
};
#if defined ( __ICCARM__ ) /* IAR Compiler */
#pragma data_alignment=4
#endif /* defined ( __ICCARM__ ) */
/* Internal string descriptor. */
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
USB_SIZ_STRING_SERIAL,
USB_DESC_TYPE_STRING,
};
/**
* @}
*/
/** @defgroup USBD_DESC_Private_Functions USBD_DESC_Private_Functions
* @brief Private functions.
* @{
*/
/**
* @brief Return the device descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_CDC_DeviceDesc);
return USBD_CDC_DeviceDesc;
}
/**
* @brief Return the LangID string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_LangIDDesc);
return USBD_LangIDDesc;
}
/**
* @brief Return the product string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if(speed == 0)
{
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING, USBD_StrDesc, length);
}
else
{
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Return the manufacturer string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief Return the serial number string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = USB_SIZ_STRING_SERIAL;
/* Update the serial number string descriptor with the data from the unique
* ID */
if(api_hal_version_get_name_ptr()){
char buffer[14] = "flip_";
strncat(buffer, api_hal_version_get_name_ptr(), 8);
USBD_GetString((uint8_t*) buffer, USBD_StringSerial, length);
} else {
Get_SerialNum();
}
/* USER CODE BEGIN USBD_CDC_SerialStrDescriptor */
/* USER CODE END USBD_CDC_SerialStrDescriptor */
return (uint8_t *) USBD_StringSerial;
}
/**
* @brief Return the configuration string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if(speed == USBD_SPEED_HIGH)
{
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length);
}
else
{
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Return the interface string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if(speed == 0)
{
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length);
}
else
{
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Create the serial number string descriptor
* @param None
* @retval None
*/
static void Get_SerialNum(void)
{
uint32_t deviceserial0, deviceserial1, deviceserial2;
deviceserial0 = *(uint32_t *) DEVICE_ID1;
deviceserial1 = *(uint32_t *) DEVICE_ID2;
deviceserial2 = *(uint32_t *) DEVICE_ID3;
deviceserial0 += deviceserial2;
if (deviceserial0 != 0)
{
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
}
/**
* @brief Convert Hex 32Bits value into char
* @param value: value to convert
* @param pbuf: pointer to the buffer
* @param len: buffer length
* @retval None
*/
static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len)
{
uint8_t idx = 0;
for (idx = 0; idx < len; idx++)
{
if (((value >> 28)) < 0xA)
{
pbuf[2 * idx] = (value >> 28) + '0';
}
else
{
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
}
value = value << 4;
pbuf[2 * idx + 1] = 0;
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,14 @@
#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);
}
}

View File

@ -0,0 +1,109 @@
#include <api-hal-bt.h>
#include <app_entry.h>
#include <ble.h>
#include <stm32wbxx.h>
#include <shci.h>
#include <cmsis_os2.h>
#include <app_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();
}
bool api_hal_bt_start_app() {
return APP_BLE_Start();
}
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;
}
bool api_hal_bt_wait_transition() {
uint8_t counter = 0;
while (APPE_Status() == BleGlueStatusStartup) {
osDelay(10);
counter++;
if (counter > 1000) {
return false;
}
}
return true;
}
bool api_hal_bt_lock_flash() {
if (!api_hal_bt_wait_transition()) {
return false;
}
if (APPE_Status() == BleGlueStatusUninitialized) {
HAL_FLASH_Unlock();
} else {
while (HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) {
osDelay(1);
}
SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
HAL_FLASH_Unlock();
while(LL_FLASH_IsOperationSuspended()) {};
}
return true;
}
void api_hal_bt_unlock_flash() {
if (APPE_Status() == BleGlueStatusUninitialized) {
HAL_FLASH_Lock();
} else {
SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF);
HAL_FLASH_Lock();
HAL_HSEM_Release(CFG_HW_FLASH_SEMID, HSEM_CPU1_COREID);
}
}
void api_hal_bt_start_tone_tx(uint8_t tx_channel, uint8_t power) {
aci_hal_set_tx_power_level(0, power);
aci_hal_tone_start(tx_channel, 0);
}
void api_hal_bt_stop_tone_tx() {
aci_hal_tone_stop();
}
void api_hal_bt_start_packet_tx(uint8_t frequency, uint8_t datarate) {
hci_le_enhanced_transmitter_test(frequency, 0x25, 2, datarate);
}
void api_hal_bt_stop_packet_tx() {
uint16_t num_of_packets;
hci_le_test_end(&num_of_packets);
}
void api_hal_bt_start_rx(uint8_t frequency) {
aci_hal_rx_start(frequency);
}
void api_hal_bt_stop_rx() {
aci_hal_rx_stop();
}

View File

@ -0,0 +1,27 @@
#include <api-hal-clock.h>
#include <stm32wbxx_ll_rcc.h>
void api_hal_clock_switch_to_hsi() {
LL_RCC_HSI_Enable( );
while(!LL_RCC_HSI_IsReady());
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSI);
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI);
}
void api_hal_clock_switch_to_pll() {
LL_RCC_HSE_Enable();
LL_RCC_PLL_Enable();
while(!LL_RCC_HSE_IsReady());
while(!LL_RCC_PLL_IsReady());
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE);
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL);
}

View File

@ -0,0 +1,7 @@
#pragma once
/* Switch to HSI clock */
void api_hal_clock_switch_to_hsi();
/* Switch to PLL clock */
void api_hal_clock_switch_to_pll();

View File

@ -0,0 +1,29 @@
#include "api-hal-delay.h"
#include <furi.h>
#include <cmsis_os2.h>
static uint32_t clk_per_microsecond;
void api_hal_delay_init(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);
(void)result;
furi_assert(result == osOK);
}

View File

@ -0,0 +1,88 @@
#include <api-hal-flash.h>
#include <api-hal-bt.h>
#include <stm32wbxx.h>
#include <furi.h>
/* Free flash space borders, exported by linker */
extern const void __free_flash_start__;
extern const void __free_flash_end__;
#define API_HAL_FLASH_READ_BLOCK 8
#define API_HAL_FLASH_WRITE_BLOCK 8
#define API_HAL_FLASH_PAGE_SIZE 4096
#define API_HAL_FLASH_CYCLES_COUNT 10000
size_t api_hal_flash_get_base() {
return FLASH_BASE;
}
size_t api_hal_flash_get_read_block_size() {
return API_HAL_FLASH_READ_BLOCK;
}
size_t api_hal_flash_get_write_block_size() {
return API_HAL_FLASH_WRITE_BLOCK;
}
size_t api_hal_flash_get_page_size() {
return API_HAL_FLASH_PAGE_SIZE;
}
size_t api_hal_flash_get_cycles_count() {
return API_HAL_FLASH_CYCLES_COUNT;
}
const void* api_hal_flash_get_free_start_address() {
return &__free_flash_start__;
}
const void* api_hal_flash_get_free_end_address() {
return &__free_flash_end__;
}
size_t api_hal_flash_get_free_page_start_address() {
size_t start = (size_t)api_hal_flash_get_free_start_address();
size_t page_start = start - start % API_HAL_FLASH_PAGE_SIZE;
if (page_start != start) {
page_start += API_HAL_FLASH_PAGE_SIZE;
}
return page_start;
}
size_t api_hal_flash_get_free_page_count() {
size_t end = (size_t)api_hal_flash_get_free_end_address();
size_t page_start = (size_t)api_hal_flash_get_free_page_start_address();
return (end-page_start) / API_HAL_FLASH_PAGE_SIZE;
}
bool api_hal_flash_erase(uint8_t page, uint8_t count) {
if (!api_hal_bt_lock_flash()) {
return false;
}
FLASH_EraseInitTypeDef erase;
erase.TypeErase = FLASH_TYPEERASE_PAGES;
erase.Page = page;
erase.NbPages = count;
uint32_t error;
HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &error);
api_hal_bt_unlock_flash();
return status == HAL_OK;
}
bool api_hal_flash_write_dword(size_t address, uint64_t data) {
if (!api_hal_bt_lock_flash()) {
return false;
}
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data);
api_hal_bt_unlock_flash();
return status == HAL_OK;
}
bool api_hal_flash_write_dword_from(size_t address, size_t source_address) {
if (!api_hal_bt_lock_flash()) {
return false;
}
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address);
api_hal_bt_unlock_flash();
return status == HAL_OK;
}

View File

@ -0,0 +1,74 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
/** Get flash base address
* @return pointer to flash base
*/
size_t api_hal_flash_get_base();
/** Get flash read block size
* @return size in bytes
*/
size_t api_hal_flash_get_read_block_size();
/** Get flash write block size
* @return size in bytes
*/
size_t api_hal_flash_get_write_block_size();
/** Get flash page size
* @return size in bytes
*/
size_t api_hal_flash_get_page_size();
/** Get expected flash cycles count
* @return count of erase-write operations
*/
size_t api_hal_flash_get_cycles_count();
/** Get free flash start address
* @return pointer to free region start
*/
const void* api_hal_flash_get_free_start_address();
/** Get free flash end address
* @return pointer to free region end
*/
const void* api_hal_flash_get_free_end_address();
/** Get first free page start address
* @return first free page memory address
*/
size_t api_hal_flash_get_free_page_start_address();
/** Get free page count
* @return free page count
*/
size_t api_hal_flash_get_free_page_count();
/*
* Erase Flash
* Locking operation, uses HSEM to manage shared access.
* @param page, page number
* @param count, page count to erase
*/
bool api_hal_flash_erase(uint8_t page, uint8_t count);
/*
* Write double word (64 bits)
* Locking operation, uses HSEM to manage shared access.
* @param address - destination address, must be double word aligned.
* @param data - data to write
*/
bool api_hal_flash_write_dword(size_t address, uint64_t data);
/*
* Write double word (64 bits) from address
* Locking operation, uses HSEM to manage shared access.
* @param address - destination address, must be block aligned
* @param source_address - source address
*/
bool api_hal_flash_write_dword_from(size_t address, size_t source_address);

View File

@ -0,0 +1,289 @@
#include <furi.h>
#include <api-hal-gpio.h>
#include <api-hal-version.h>
#define GET_SYSCFG_EXTI_PORT(gpio) \
(((gpio) == (GPIOA)) ? LL_SYSCFG_EXTI_PORTA : \
((gpio) == (GPIOB)) ? LL_SYSCFG_EXTI_PORTB : \
((gpio) == (GPIOC)) ? LL_SYSCFG_EXTI_PORTC : \
((gpio) == (GPIOD)) ? LL_SYSCFG_EXTI_PORTD : \
((gpio) == (GPIOE)) ? LL_SYSCFG_EXTI_PORTE : \
LL_SYSCFG_EXTI_PORTH)
#define GPIO_PIN_MAP(pin, prefix) \
(((pin) == (LL_GPIO_PIN_0)) ? prefix##0 : \
((pin) == (LL_GPIO_PIN_1)) ? prefix##1 : \
((pin) == (LL_GPIO_PIN_2)) ? prefix##2 : \
((pin) == (LL_GPIO_PIN_3)) ? prefix##3 : \
((pin) == (LL_GPIO_PIN_4)) ? prefix##4 : \
((pin) == (LL_GPIO_PIN_5)) ? prefix##5 : \
((pin) == (LL_GPIO_PIN_6)) ? prefix##6 : \
((pin) == (LL_GPIO_PIN_7)) ? prefix##7 : \
((pin) == (LL_GPIO_PIN_8)) ? prefix##8 : \
((pin) == (LL_GPIO_PIN_9)) ? prefix##9 : \
((pin) == (LL_GPIO_PIN_10)) ? prefix##10 : \
((pin) == (LL_GPIO_PIN_11)) ? prefix##11 : \
((pin) == (LL_GPIO_PIN_12)) ? prefix##12 : \
((pin) == (LL_GPIO_PIN_13)) ? prefix##13 : \
((pin) == (LL_GPIO_PIN_14)) ? prefix##14 : \
prefix##15)
#define GET_SYSCFG_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_SYSCFG_EXTI_LINE)
#define GET_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_EXTI_LINE_)
static volatile GpioInterrupt gpio_interrupt[GPIO_NUMBER];
static uint8_t hal_gpio_get_pin_num(const GpioPin* gpio) {
uint8_t pin_num = 0;
for(pin_num = 0; pin_num < GPIO_NUMBER; pin_num++) {
if(gpio->pin & (1 << pin_num)) break;
}
return pin_num;
}
void hal_gpio_init(
const GpioPin* gpio,
const GpioMode mode,
const GpioPull pull,
const GpioSpeed speed) {
uint32_t sys_exti_port = GET_SYSCFG_EXTI_PORT(gpio->port);
uint32_t sys_exti_line = GET_SYSCFG_EXTI_LINE(gpio->pin);
uint32_t exti_line = GET_EXTI_LINE(gpio->pin);
// Configure gpio with interrupts disabled
__disable_irq();
// Set gpio speed
if(speed == GpioSpeedLow) {
LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_LOW);
} else if(speed == GpioSpeedMedium) {
LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_MEDIUM);
} else if(speed == GpioSpeedHigh) {
LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_HIGH);
} else {
LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_VERY_HIGH);
}
// Set gpio pull mode
if(pull == GpioPullNo) {
LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_NO);
} else if(pull == GpioPullUp) {
LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_UP);
} else {
LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_DOWN);
}
// Set gpio mode
if(mode >= GpioModeInterruptRise) {
// Set pin in interrupt mode
LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_INPUT);
LL_SYSCFG_SetEXTISource(sys_exti_port, sys_exti_line);
if(mode == GpioModeInterruptRise || mode == GpioModeInterruptRiseFall) {
LL_EXTI_EnableIT_0_31(exti_line);
LL_EXTI_EnableRisingTrig_0_31(exti_line);
}
if(mode == GpioModeInterruptFall || mode == GpioModeInterruptRiseFall) {
LL_EXTI_EnableIT_0_31(exti_line);
LL_EXTI_EnableFallingTrig_0_31(exti_line);
}
if(mode == GpioModeEventRise || mode == GpioModeInterruptRiseFall) {
LL_EXTI_EnableEvent_0_31(exti_line);
LL_EXTI_EnableRisingTrig_0_31(exti_line);
}
if(mode == GpioModeEventFall || mode == GpioModeInterruptRiseFall) {
LL_EXTI_EnableEvent_0_31(exti_line);
LL_EXTI_EnableFallingTrig_0_31(exti_line);
}
} else {
// Disable interrupt if it was set
if(LL_SYSCFG_GetEXTISource(sys_exti_line) == sys_exti_port &&
LL_EXTI_IsEnabledIT_0_31(exti_line)) {
LL_EXTI_DisableIT_0_31(exti_line);
LL_EXTI_DisableRisingTrig_0_31(exti_line);
LL_EXTI_DisableFallingTrig_0_31(exti_line);
}
// Set not interrupt pin modes
if(mode == GpioModeInput) {
LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_INPUT);
} else if(mode == GpioModeOutputPushPull || mode == GpioModeAltFunctionPushPull) {
LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_PUSHPULL);
} else if(mode == GpioModeOutputOpenDrain || mode == GpioModeAltFunctionOpenDrain) {
LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_OPENDRAIN);
} else if(mode == GpioModeAnalog) {
LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ANALOG);
}
}
__enable_irq();
}
void hal_gpio_init_alt(
const GpioPin* gpio,
const GpioMode mode,
const GpioPull pull,
const GpioSpeed speed,
const GpioAltFn alt_fn) {
hal_gpio_init(gpio, mode, pull, speed);
__disable_irq();
// enable alternate mode
LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ALTERNATE);
// set alternate function
if(hal_gpio_get_pin_num(gpio) < 8) {
LL_GPIO_SetAFPin_0_7(gpio->port, gpio->pin, alt_fn);
} else {
LL_GPIO_SetAFPin_8_15(gpio->port, gpio->pin, alt_fn);
}
__enable_irq();
}
void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) {
furi_assert(gpio);
furi_assert(cb);
__disable_irq();
uint8_t pin_num = hal_gpio_get_pin_num(gpio);
gpio_interrupt[pin_num].callback = cb;
gpio_interrupt[pin_num].context = ctx;
gpio_interrupt[pin_num].ready = true;
__enable_irq();
}
void hal_gpio_enable_int_callback(const GpioPin* gpio) {
furi_assert(gpio);
__disable_irq();
uint8_t pin_num = hal_gpio_get_pin_num(gpio);
if(gpio_interrupt[pin_num].callback) {
gpio_interrupt[pin_num].ready = true;
}
__enable_irq();
}
void hal_gpio_disable_int_callback(const GpioPin* gpio) {
furi_assert(gpio);
__disable_irq();
uint8_t pin_num = hal_gpio_get_pin_num(gpio);
gpio_interrupt[pin_num].ready = false;
__enable_irq();
}
void hal_gpio_remove_int_callback(const GpioPin* gpio) {
furi_assert(gpio);
__disable_irq();
uint8_t pin_num = hal_gpio_get_pin_num(gpio);
gpio_interrupt[pin_num].callback = NULL;
gpio_interrupt[pin_num].context = NULL;
gpio_interrupt[pin_num].ready = false;
__enable_irq();
}
static void hal_gpio_int_call(uint16_t pin_num) {
if(gpio_interrupt[pin_num].callback && gpio_interrupt[pin_num].ready) {
gpio_interrupt[pin_num].callback(gpio_interrupt[pin_num].context);
}
}
/* Interrupt handlers */
void EXTI0_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_0)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_0);
hal_gpio_int_call(0);
}
}
void EXTI1_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_1)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_1);
hal_gpio_int_call(1);
}
}
void EXTI2_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_2)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_2);
hal_gpio_int_call(2);
}
}
void EXTI3_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_3)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_3);
hal_gpio_int_call(3);
}
}
void EXTI4_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_4)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_4);
hal_gpio_int_call(4);
}
}
void EXTI9_5_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_5)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_5);
hal_gpio_int_call(5);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_6)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_6);
hal_gpio_int_call(6);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_7)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_7);
hal_gpio_int_call(7);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_8)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_8);
hal_gpio_int_call(8);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_9)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_9);
hal_gpio_int_call(9);
}
}
void EXTI15_10_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_10)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_10);
hal_gpio_int_call(10);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_11)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_11);
hal_gpio_int_call(11);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_12)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_12);
hal_gpio_int_call(12);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_13)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_13);
hal_gpio_int_call(13);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_14)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_14);
hal_gpio_int_call(14);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_15)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_15);
hal_gpio_int_call(15);
}
}
extern COMP_HandleTypeDef hcomp1;
bool hal_gpio_get_rfid_in_level() {
bool value = false;
if(api_hal_version_get_hw_version() > 7) {
value = (HAL_COMP_GetOutputLevel(&hcomp1) == COMP_OUTPUT_LEVEL_LOW);
} else {
value = (HAL_COMP_GetOutputLevel(&hcomp1) == COMP_OUTPUT_LEVEL_HIGH);
}
#ifdef INVERT_RFID_IN
return !value;
#else
return value;
#endif
}

View File

@ -0,0 +1,255 @@
#pragma once
#include "main.h"
#include "stdbool.h"
#include <stm32wbxx_ll_gpio.h>
#include <stm32wbxx_ll_system.h>
#include <stm32wbxx_ll_exti.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Number of gpio on one port
*/
#define GPIO_NUMBER (16U)
/**
* Interrupt callback prototype
*/
typedef void (*GpioExtiCallback)(void* ctx);
/**
* Gpio interrupt type
*/
typedef struct {
GpioExtiCallback callback;
void* context;
volatile bool ready;
} GpioInterrupt;
/**
* Gpio modes
*/
typedef enum {
GpioModeInput,
GpioModeOutputPushPull,
GpioModeOutputOpenDrain,
GpioModeAltFunctionPushPull,
GpioModeAltFunctionOpenDrain,
GpioModeAnalog,
GpioModeInterruptRise,
GpioModeInterruptFall,
GpioModeInterruptRiseFall,
GpioModeEventRise,
GpioModeEventFall,
GpioModeEventRiseFall,
} GpioMode;
/**
* Gpio pull modes
*/
typedef enum {
GpioPullNo,
GpioPullUp,
GpioPullDown,
} GpioPull;
/**
* Gpio speed modes
*/
typedef enum {
GpioSpeedLow,
GpioSpeedMedium,
GpioSpeedHigh,
GpioSpeedVeryHigh,
} GpioSpeed;
/**
* Gpio alternate functions
*/
typedef enum {
GpioAltFn0MCO = 0, /*!< MCO Alternate Function mapping */
GpioAltFn0LSCO = 0, /*!< LSCO Alternate Function mapping */
GpioAltFn0JTMS_SWDIO = 0, /*!< JTMS-SWDIO Alternate Function mapping */
GpioAltFn0JTCK_SWCLK = 0, /*!< JTCK-SWCLK Alternate Function mapping */
GpioAltFn0JTDI = 0, /*!< JTDI Alternate Function mapping */
GpioAltFn0RTC_OUT = 0, /*!< RCT_OUT Alternate Function mapping */
GpioAltFn0JTD_TRACE = 0, /*!< JTDO-TRACESWO Alternate Function mapping */
GpioAltFn0NJTRST = 0, /*!< NJTRST Alternate Function mapping */
GpioAltFn0RTC_REFIN = 0, /*!< RTC_REFIN Alternate Function mapping */
GpioAltFn0TRACED0 = 0, /*!< TRACED0 Alternate Function mapping */
GpioAltFn0TRACED1 = 0, /*!< TRACED1 Alternate Function mapping */
GpioAltFn0TRACED2 = 0, /*!< TRACED2 Alternate Function mapping */
GpioAltFn0TRACED3 = 0, /*!< TRACED3 Alternate Function mapping */
GpioAltFn0TRIG_INOUT = 0, /*!< TRIG_INOUT Alternate Function mapping */
GpioAltFn0TRACECK = 0, /*!< TRACECK Alternate Function mapping */
GpioAltFn0SYS = 0, /*!< System Function mapping */
GpioAltFn1TIM1 = 1, /*!< TIM1 Alternate Function mapping */
GpioAltFn1TIM2 = 1, /*!< TIM2 Alternate Function mapping */
GpioAltFn1LPTIM1 = 1, /*!< LPTIM1 Alternate Function mapping */
GpioAltFn2TIM2 = 2, /*!< TIM2 Alternate Function mapping */
GpioAltFn2TIM1 = 2, /*!< TIM1 Alternate Function mapping */
GpioAltFn3SAI1 = 3, /*!< SAI1_CK1 Alternate Function mapping */
GpioAltFn3SPI2 = 3, /*!< SPI2 Alternate Function mapping */
GpioAltFn3TIM1 = 3, /*!< TIM1 Alternate Function mapping */
GpioAltFn4I2C1 = 4, /*!< I2C1 Alternate Function mapping */
GpioAltFn4I2C3 = 4, /*!< I2C3 Alternate Function mapping */
GpioAltFn5SPI1 = 5, /*!< SPI1 Alternate Function mapping */
GpioAltFn5SPI2 = 5, /*!< SPI2 Alternate Function mapping */
GpioAltFn6MCO = 6, /*!< MCO Alternate Function mapping */
GpioAltFn6LSCO = 6, /*!< LSCO Alternate Function mapping */
GpioAltFn6RF_DTB0 = 6, /*!< RF_DTB0 Alternate Function mapping */
GpioAltFn6RF_DTB1 = 6, /*!< RF_DTB1 Alternate Function mapping */
GpioAltFn6RF_DTB2 = 6, /*!< RF_DTB2 Alternate Function mapping */
GpioAltFn6RF_DTB3 = 6, /*!< RF_DTB3 Alternate Function mapping */
GpioAltFn6RF_DTB4 = 6, /*!< RF_DTB4 Alternate Function mapping */
GpioAltFn6RF_DTB5 = 6, /*!< RF_DTB5 Alternate Function mapping */
GpioAltFn6RF_DTB6 = 6, /*!< RF_DTB6 Alternate Function mapping */
GpioAltFn6RF_DTB7 = 6, /*!< RF_DTB7 Alternate Function mapping */
GpioAltFn6RF_DTB8 = 6, /*!< RF_DTB8 Alternate Function mapping */
GpioAltFn6RF_DTB9 = 6, /*!< RF_DTB9 Alternate Function mapping */
GpioAltFn6RF_DTB10 = 6, /*!< RF_DTB10 Alternate Function mapping */
GpioAltFn6RF_DTB11 = 6, /*!< RF_DTB11 Alternate Function mapping */
GpioAltFn6RF_DTB12 = 6, /*!< RF_DTB12 Alternate Function mapping */
GpioAltFn6RF_DTB13 = 6, /*!< RF_DTB13 Alternate Function mapping */
GpioAltFn6RF_DTB14 = 6, /*!< RF_DTB14 Alternate Function mapping */
GpioAltFn6RF_DTB15 = 6, /*!< RF_DTB15 Alternate Function mapping */
GpioAltFn6RF_DTB16 = 6, /*!< RF_DTB16 Alternate Function mapping */
GpioAltFn6RF_DTB17 = 6, /*!< RF_DTB17 Alternate Function mapping */
GpioAltFn6RF_DTB18 = 6, /*!< RF_DTB18 Alternate Function mapping */
GpioAltFn6RF_MISO = 6, /*!< RF_MISO Alternate Function mapping */
GpioAltFn6RF_MOSI = 6, /*!< RF_MOSI Alternate Function mapping */
GpioAltFn6RF_SCK = 6, /*!< RF_SCK Alternate Function mapping */
GpioAltFn6RF_NSS = 6, /*!< RF_NSS Alternate Function mapping */
GpioAltFn7USART1 = 7, /*!< USART1 Alternate Function mapping */
GpioAltFn8LPUART1 = 8, /*!< LPUART1 Alternate Function mapping */
GpioAltFn8IR = 8, /*!< IR Alternate Function mapping */
GpioAltFn9TSC = 9, /*!< TSC Alternate Function mapping */
GpioAltFn10QUADSPI = 10, /*!< QUADSPI Alternate Function mapping */
GpioAltFn10USB = 10, /*!< USB Alternate Function mapping */
GpioAltFn11LCD = 11, /*!< LCD Alternate Function mapping */
GpioAltFn12COMP1 = 12, /*!< COMP1 Alternate Function mapping */
GpioAltFn12COMP2 = 12, /*!< COMP2 Alternate Function mapping */
GpioAltFn12TIM1 = 12, /*!< TIM1 Alternate Function mapping */
GpioAltFn13SAI1 = 13, /*!< SAI1 Alternate Function mapping */
GpioAltFn14TIM2 = 14, /*!< TIM2 Alternate Function mapping */
GpioAltFn14TIM16 = 14, /*!< TIM16 Alternate Function mapping */
GpioAltFn14TIM17 = 14, /*!< TIM17 Alternate Function mapping */
GpioAltFn14LPTIM2 = 14, /*!< LPTIM2 Alternate Function mapping */
GpioAltFn15EVENTOUT = 15, /*!< EVENTOUT Alternate Function mapping */
} GpioAltFn;
/**
* Gpio structure
*/
typedef struct {
GPIO_TypeDef* port;
uint16_t pin;
} GpioPin;
/**
* GPIO initialization function
* @param gpio GpioPin
* @param mode GpioMode
* @param pull GpioPull
* @param speed GpioSpeed
*/
void hal_gpio_init(
const GpioPin* gpio,
const GpioMode mode,
const GpioPull pull,
const GpioSpeed speed);
/**
* GPIO initialization with alternative function
* @param gpio GpioPin
* @param mode GpioMode
* @param pull GpioPull
* @param speed GpioSpeed
* @param alt_fn GpioAltFn
*/
void hal_gpio_init_alt(
const GpioPin* gpio,
const GpioMode mode,
const GpioPull pull,
const GpioSpeed speed,
const GpioAltFn alt_fn);
/**
* Add and enable interrupt
* @param gpio GpioPin
* @param cb GpioExtiCallback
* @param ctx context for callback
*/
void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx);
/**
* Enable interrupt
* @param gpio GpioPin
*/
void hal_gpio_enable_int_callback(const GpioPin* gpio);
/**
* Disable interrupt
* @param gpio GpioPin
*/
void hal_gpio_disable_int_callback(const GpioPin* gpio);
/**
* Remove interrupt
* @param gpio GpioPin
*/
void hal_gpio_remove_int_callback(const GpioPin* gpio);
/**
* GPIO write pin
* @param gpio GpioPin
* @param state true / false
*/
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;
}
}
/**
* GPIO read pin
* @param gpio GpioPin
* @return true / false
*/
static inline bool hal_gpio_read(const GpioPin* gpio) {
if((gpio->port->IDR & gpio->pin) != 0x00U) {
return true;
} else {
return false;
}
}
/**
* Get RFID IN level
* @return false = LOW, true = HIGH
*/
bool hal_gpio_get_rfid_in_level();
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,148 @@
#include <api-hal-i2c.h>
#include <stm32wbxx_ll_i2c.h>
#include <stm32wbxx_ll_gpio.h>
#include <stm32wbxx_ll_cortex.h>
#include <furi.h>
osMutexId_t api_hal_i2c_mutex = NULL;
void api_hal_i2c_init() {
api_hal_i2c_mutex = osMutexNew(NULL);
furi_check(api_hal_i2c_mutex);
LL_I2C_InitTypeDef I2C_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
GPIO_InitStruct.Pin = POWER_I2C_SCL_Pin | POWER_I2C_SDA_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
I2C_InitStruct.Timing = POWER_I2C_TIMINGS;
I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
I2C_InitStruct.DigitalFilter = 0;
I2C_InitStruct.OwnAddress1 = 0;
I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
LL_I2C_Init(I2C1, &I2C_InitStruct);
LL_I2C_EnableAutoEndMode(I2C1);
LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);
LL_I2C_DisableOwnAddress2(I2C1);
LL_I2C_DisableGeneralCall(I2C1);
LL_I2C_EnableClockStretching(I2C1);
}
bool api_hal_i2c_tx(
I2C_TypeDef* instance,
uint8_t address,
const uint8_t* data,
uint8_t size,
uint32_t timeout) {
uint32_t time_left = timeout;
bool ret = true;
while(LL_I2C_IsActiveFlag_BUSY(instance))
;
LL_I2C_HandleTransfer(
instance,
address,
LL_I2C_ADDRSLAVE_7BIT,
size,
LL_I2C_MODE_AUTOEND,
LL_I2C_GENERATE_START_WRITE);
while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) {
if(LL_I2C_IsActiveFlag_TXIS(instance)) {
LL_I2C_TransmitData8(instance, (*data));
data++;
size--;
time_left = timeout;
}
if(LL_SYSTICK_IsActiveCounterFlag()) {
if(--time_left == 0) {
ret = false;
break;
}
}
}
LL_I2C_ClearFlag_STOP(instance);
return ret;
}
bool api_hal_i2c_rx(
I2C_TypeDef* instance,
uint8_t address,
uint8_t* data,
uint8_t size,
uint32_t timeout) {
uint32_t time_left = timeout;
bool ret = true;
while(LL_I2C_IsActiveFlag_BUSY(instance))
;
LL_I2C_HandleTransfer(
instance,
address,
LL_I2C_ADDRSLAVE_7BIT,
size,
LL_I2C_MODE_AUTOEND,
LL_I2C_GENERATE_START_READ);
while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) {
if(LL_I2C_IsActiveFlag_RXNE(instance)) {
*data = LL_I2C_ReceiveData8(instance);
data++;
size--;
time_left = timeout;
}
if(LL_SYSTICK_IsActiveCounterFlag()) {
if(--time_left == 0) {
ret = false;
break;
}
}
}
LL_I2C_ClearFlag_STOP(instance);
return ret;
}
bool api_hal_i2c_trx(
I2C_TypeDef* instance,
uint8_t address,
const uint8_t* tx_data,
uint8_t tx_size,
uint8_t* rx_data,
uint8_t rx_size,
uint32_t timeout) {
if(api_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) &&
api_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) {
return true;
} else {
return false;
}
}
void api_hal_i2c_lock() {
furi_check(osMutexAcquire(api_hal_i2c_mutex, osWaitForever) == osOK);
}
void api_hal_i2c_unlock() {
furi_check(osMutexRelease(api_hal_i2c_mutex) == osOK);
}

View File

@ -0,0 +1,24 @@
#include <api-hal-ibutton.h>
#include <api-hal-resources.h>
void api_hal_ibutton_start() {
api_hal_ibutton_pin_high();
hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioSpeedLow, GpioPullNo);
}
void api_hal_ibutton_stop() {
api_hal_ibutton_pin_high();
hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioSpeedLow, GpioPullNo);
}
void api_hal_ibutton_pin_low() {
hal_gpio_write(&ibutton_gpio, false);
}
void api_hal_ibutton_pin_high() {
hal_gpio_write(&ibutton_gpio, true);
}
bool api_hal_ibutton_pin_get_level() {
return hal_gpio_read(&ibutton_gpio);
}

View File

@ -0,0 +1,43 @@
#include <api-hal-light.h>
#include <lp5562.h>
#define LED_CURRENT_RED 50
#define LED_CURRENT_GREEN 50
#define LED_CURRENT_BLUE 50
#define LED_CURRENT_WHITE 150
void api_hal_light_init() {
lp5562_reset();
lp5562_set_channel_current(LP5562ChannelRed, LED_CURRENT_RED);
lp5562_set_channel_current(LP5562ChannelGreen, LED_CURRENT_GREEN);
lp5562_set_channel_current(LP5562ChannelBlue, LED_CURRENT_BLUE);
lp5562_set_channel_current(LP5562ChannelWhite, LED_CURRENT_WHITE);
lp5562_set_channel_value(LP5562ChannelRed, 0x00);
lp5562_set_channel_value(LP5562ChannelGreen, 0x00);
lp5562_set_channel_value(LP5562ChannelBlue, 0x00);
lp5562_set_channel_value(LP5562ChannelWhite, 0x00);
lp5562_enable();
lp5562_configure();
}
void api_hal_light_set(Light light, uint8_t value) {
switch(light) {
case LightRed:
lp5562_set_channel_value(LP5562ChannelRed, value);
break;
case LightGreen:
lp5562_set_channel_value(LP5562ChannelGreen, value);
break;
case LightBlue:
lp5562_set_channel_value(LP5562ChannelBlue, value);
break;
case LightBacklight:
lp5562_set_channel_value(LP5562ChannelWhite, value);
break;
default:
break;
}
}

View File

@ -0,0 +1,85 @@
#include "api-hal-nfc.h"
#include <st25r3916.h>
static bool dev_is_found = false;
ReturnCode api_hal_nfc_init() {
// Check if Nfc worker was started
if(rfalNfcGetState() > RFAL_NFC_STATE_NOTINIT) {
return ERR_NONE;
}
return rfalNfcInitialize();
}
bool api_hal_nfc_is_busy() {
return rfalNfcGetState() > RFAL_NFC_STATE_IDLE;
}
void api_hal_nfc_field_on() {
api_hal_nfc_exit_sleep();
st25r3916TxRxOn();
}
void api_hal_nfc_field_off() {
st25r3916TxRxOff();
api_hal_nfc_start_sleep();
}
void api_hal_nfc_start_sleep() {
rfalLowPowerModeStart();
}
void api_hal_nfc_exit_sleep() {
rfalLowPowerModeStop();
}
static void api_hal_nfc_change_state_cb(rfalNfcState st) {
FURI_LOG_D("HAL NFC", "NFC worker state: %d", st);
if(st >= RFAL_NFC_STATE_POLL_SELECT) {
dev_is_found = true;
}
}
bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t cycles) {
furi_assert(dev_list);
furi_assert(dev_cnt);
rfalLowPowerModeStop();
if(rfalNfcGetState() == RFAL_NFC_STATE_NOTINIT) {
rfalNfcInitialize();
}
rfalNfcDiscoverParam params;
params.compMode = RFAL_COMPLIANCE_MODE_EMV;
params.techs2Find = RFAL_NFC_POLL_TECH_A | RFAL_NFC_POLL_TECH_B | RFAL_NFC_POLL_TECH_F |
RFAL_NFC_POLL_TECH_V | RFAL_NFC_POLL_TECH_AP2P | RFAL_NFC_POLL_TECH_ST25TB;
params.totalDuration = 1000;
params.devLimit = 3;
params.wakeupEnabled = false;
params.wakeupConfigDefault = true;
params.nfcfBR = RFAL_BR_212;
params.ap2pBR = RFAL_BR_424;
params.maxBR = RFAL_BR_KEEP;
params.GBLen = RFAL_NFCDEP_GB_MAX_LEN;
params.notifyCb = api_hal_nfc_change_state_cb;
dev_is_found = false;
rfalNfcDiscover(&params);
while(--cycles) {
rfalNfcWorker();
FURI_LOG_D("HAL NFC", "Current state %d", rfalNfcGetState());
if(dev_is_found) {
rfalNfcGetDevicesFound(dev_list, dev_cnt);
FURI_LOG_D("HAL NFC", "Found %d devices", dev_cnt);
break;
}
osDelay(5);
}
rfalNfcDeactivate(false);
rfalLowPowerModeStart();
if(!cycles) {
FURI_LOG_D("HAL NFC", "Timeout");
return false;
}
return true;
}

View File

@ -0,0 +1,64 @@
#pragma once
#include <stm32wbxx_ll_lptim.h>
#include <stm32wbxx_ll_bus.h>
#include <stdint.h>
// Timer used for system ticks
#define API_HAL_OS_TIMER_MAX 0xFFFF
#define API_HAL_OS_TIMER_REG_LOAD_DLY 0x1
#define API_HAL_OS_TIMER LPTIM2
#define API_HAL_OS_TIMER_IRQ LPTIM2_IRQn
static inline void api_hal_os_timer_init() {
// Configure clock source
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_LSE);
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPTIM2);
// Set interrupt priority and enable them
NVIC_SetPriority(API_HAL_OS_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
NVIC_EnableIRQ(API_HAL_OS_TIMER_IRQ);
}
static inline void api_hal_os_timer_continuous(uint32_t count) {
// Enable timer
LL_LPTIM_Enable(API_HAL_OS_TIMER);
while(!LL_LPTIM_IsEnabled(API_HAL_OS_TIMER));
// Enable rutoreload match interrupt
LL_LPTIM_EnableIT_ARRM(API_HAL_OS_TIMER);
// Set autoreload and start counter
LL_LPTIM_SetAutoReload(API_HAL_OS_TIMER, count);
LL_LPTIM_StartCounter(API_HAL_OS_TIMER, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
}
static inline void api_hal_os_timer_single(uint32_t count) {
// Enable timer
LL_LPTIM_Enable(API_HAL_OS_TIMER);
while(!LL_LPTIM_IsEnabled(API_HAL_OS_TIMER));
// Enable compare match interrupt
LL_LPTIM_EnableIT_CMPM(API_HAL_OS_TIMER);
// Set compare, autoreload and start counter
// Include some marging to workaround ARRM behaviour
LL_LPTIM_SetCompare(API_HAL_OS_TIMER, count-3);
LL_LPTIM_SetAutoReload(API_HAL_OS_TIMER, count);
LL_LPTIM_StartCounter(API_HAL_OS_TIMER, LL_LPTIM_OPERATING_MODE_ONESHOT);
}
static inline void api_hal_os_timer_reset() {
// Hard reset timer
// THE ONLY RELIABLEWAY to stop it according to errata
LL_LPTIM_DeInit(API_HAL_OS_TIMER);
}
static inline uint32_t api_hal_os_timer_get_cnt() {
uint32_t counter = LL_LPTIM_GetCounter(API_HAL_OS_TIMER);
uint32_t counter_shadow = LL_LPTIM_GetCounter(API_HAL_OS_TIMER);
while(counter != counter_shadow) {
counter = counter_shadow;
counter_shadow = LL_LPTIM_GetCounter(API_HAL_OS_TIMER);
}
return counter;
}

View File

@ -0,0 +1,140 @@
#include <api-hal-os.h>
#include <api-hal-os-timer.h>
#include <api-hal-power.h>
#include <stm32wbxx_ll_cortex.h>
#include <FreeRTOS.h>
#include <cmsis_os.h>
#define API_HAL_OS_CLK_FREQUENCY 32768
#define API_HAL_OS_TICK_PER_SECOND 1024
#define API_HAL_OS_CLK_PER_TICK (API_HAL_OS_CLK_FREQUENCY / API_HAL_OS_TICK_PER_SECOND)
#define API_HAL_OS_TICK_PER_EPOCH (API_HAL_OS_TIMER_MAX / API_HAL_OS_CLK_PER_TICK)
#define API_HAL_OS_MAX_SLEEP (API_HAL_OS_TICK_PER_EPOCH - 1)
#ifdef API_HAL_OS_DEBUG
#include <stm32wbxx_ll_gpio.h>
#define LED_SLEEP_PORT GPIOA
#define LED_SLEEP_PIN LL_GPIO_PIN_7
#define LED_TICK_PORT GPIOA
#define LED_TICK_PIN LL_GPIO_PIN_6
#define LED_SECOND_PORT GPIOA
#define LED_SECOND_PIN LL_GPIO_PIN_4
void api_hal_os_timer_callback() {
LL_GPIO_TogglePin(LED_SECOND_PORT, LED_SECOND_PIN);
}
#endif
volatile uint32_t api_hal_os_skew = 0;
void api_hal_os_init() {
LL_DBGMCU_APB1_GRP2_FreezePeriph(LL_DBGMCU_APB1_GRP2_LPTIM2_STOP);
api_hal_os_timer_init();
api_hal_os_timer_continuous(API_HAL_OS_CLK_PER_TICK);
#ifdef API_HAL_OS_DEBUG
LL_GPIO_SetPinMode(LED_SLEEP_PORT, LED_SLEEP_PIN, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinMode(LED_TICK_PORT, LED_TICK_PIN, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinMode(LED_SECOND_PORT, LED_SECOND_PIN, LL_GPIO_MODE_OUTPUT);
osTimerId_t second_timer = osTimerNew(api_hal_os_timer_callback, osTimerPeriodic, NULL, NULL);
osTimerStart(second_timer, 1024);
#endif
}
void LPTIM2_IRQHandler(void) {
// Autoreload
if(LL_LPTIM_IsActiveFlag_ARRM(API_HAL_OS_TIMER)) {
LL_LPTIM_ClearFLAG_ARRM(API_HAL_OS_TIMER);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
#ifdef API_HAL_OS_DEBUG
LL_GPIO_TogglePin(LED_TICK_PORT, LED_TICK_PIN);
#endif
xPortSysTickHandler();
}
}
if(LL_LPTIM_IsActiveFlag_CMPM(API_HAL_OS_TIMER)) {
LL_LPTIM_ClearFLAG_CMPM(API_HAL_OS_TIMER);
}
}
static inline uint32_t api_hal_os_sleep(TickType_t expected_idle_ticks) {
// Stop ticks
api_hal_os_timer_reset();
LL_SYSTICK_DisableIT();
// Start wakeup timer
api_hal_os_timer_single(expected_idle_ticks * API_HAL_OS_CLK_PER_TICK);
#ifdef API_HAL_OS_DEBUG
LL_GPIO_ResetOutputPin(LED_SLEEP_PORT, LED_SLEEP_PIN);
#endif
// Go to sleep mode
api_hal_power_sleep();
#ifdef API_HAL_OS_DEBUG
LL_GPIO_SetOutputPin(LED_SLEEP_PORT, LED_SLEEP_PIN);
#endif
// Calculate how much time we spent in the sleep
uint32_t after_cnt = api_hal_os_timer_get_cnt() + api_hal_os_skew;
uint32_t after_tick = after_cnt / API_HAL_OS_CLK_PER_TICK;
api_hal_os_skew = after_cnt % API_HAL_OS_CLK_PER_TICK;
bool cmpm = LL_LPTIM_IsActiveFlag_CMPM(API_HAL_OS_TIMER);
bool arrm = LL_LPTIM_IsActiveFlag_ARRM(API_HAL_OS_TIMER);
if (cmpm && arrm) after_tick += expected_idle_ticks;
// Prepare tick timer for new round
api_hal_os_timer_reset();
// Resume ticks
LL_SYSTICK_EnableIT();
api_hal_os_timer_continuous(API_HAL_OS_CLK_PER_TICK);
return after_tick;
}
void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) {
if(!api_hal_power_sleep_available()) {
__WFI();
return;
}
// Limit mount of ticks to maximum that timer can count
if (expected_idle_ticks > API_HAL_OS_MAX_SLEEP) {
expected_idle_ticks = API_HAL_OS_MAX_SLEEP;
}
// Stop IRQ handling, no one should disturb us till we finish
__disable_irq();
// Confirm OS that sleep is still possible
if (eTaskConfirmSleepModeStatus() == eAbortSleep) {
__enable_irq();
return;
}
// Sleep and track how much ticks we spent sleeping
uint32_t completed_ticks = api_hal_os_sleep(expected_idle_ticks);
// Reenable IRQ
__enable_irq();
// Notify system about time spent in sleep
if (completed_ticks > 0) {
if (completed_ticks > expected_idle_ticks) {
vTaskStepTick(expected_idle_ticks);
} else {
vTaskStepTick(completed_ticks);
}
}
}
void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) {
asm("bkpt 1");
while(1) {};
}

View File

@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Initialize OS helpers
* Configure and start tick timer
*/
void api_hal_os_init();
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,262 @@
#include <api-hal-power.h>
#include <api-hal-clock.h>
#include <api-hal-bt.h>
#include <stm32wbxx_ll_rcc.h>
#include <stm32wbxx_ll_pwr.h>
#include <stm32wbxx_ll_hsem.h>
#include <stm32wbxx_ll_cortex.h>
#include <stm32wbxx_ll_gpio.h>
#include <main.h>
#include <hw_conf.h>
#include <bq27220.h>
#include <bq25896.h>
typedef struct {
volatile uint32_t insomnia;
volatile uint32_t deep_insomnia;
} ApiHalPower;
static volatile ApiHalPower api_hal_power = {
.insomnia = 0,
.deep_insomnia = 1,
};
const ParamCEDV cedv = {
.full_charge_cap = 2100,
.design_cap = 2100,
.EMF = 3739,
.C0 = 776,
.C1 = 0,
.R1 = 193,
.R0 = 1,
.T0 = 1,
.TC = 11,
.DOD0 = 4044,
.DOD10 = 3899,
.DOD20 = 3796,
.DOD30 = 3704,
.DOD40 = 3627,
.DOD50 = 3573,
.DOD60 = 3535,
.DOD70 = 3501,
.DOD80 = 3453,
.DOD90 = 3366,
.DOD100 = 2419,
};
void HAL_RCC_CSSCallback(void) {
// TODO: notify user about issue with HSE
api_hal_power_reset();
}
void api_hal_power_init() {
LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN);
bq27220_init(&cedv);
bq25896_init();
}
uint16_t api_hal_power_insomnia_level() {
return api_hal_power.insomnia;
}
void api_hal_power_insomnia_enter() {
api_hal_power.insomnia++;
}
void api_hal_power_insomnia_exit() {
api_hal_power.insomnia--;
}
bool api_hal_power_sleep_available() {
return api_hal_power.insomnia == 0;
}
bool api_hal_power_deep_sleep_available() {
return api_hal_bt_is_alive() && api_hal_power.deep_insomnia == 0;
}
void api_hal_power_light_sleep() {
__WFI();
}
void api_hal_power_deep_sleep() {
while( LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));
if (!LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) {
if(LL_PWR_IsActiveFlag_C2DS()) {
// Release ENTRY_STOP_MODE semaphore
LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
// The switch on HSI before entering Stop Mode is required
api_hal_clock_switch_to_hsi();
}
} else {
/**
* The switch on HSI before entering Stop Mode is required
*/
api_hal_clock_switch_to_hsi();
}
/* Release RCC semaphore */
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
// Prepare deep sleep
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1);
LL_LPM_EnableDeepSleep();
#if defined ( __CC_ARM)
// Force store operations
__force_stores();
#endif
__WFI();
/* Release ENTRY_STOP_MODE semaphore */
LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));
if(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
api_hal_clock_switch_to_pll();
}
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
}
void api_hal_power_sleep() {
if(api_hal_power_deep_sleep_available()) {
api_hal_power_deep_sleep();
} else {
api_hal_power_light_sleep();
}
}
uint8_t api_hal_power_get_pct() {
return bq27220_get_state_of_charge();
}
uint8_t api_hal_power_get_bat_health_pct() {
return bq27220_get_state_of_health();
}
bool api_hal_power_is_charging() {
return bq25896_is_charging();
}
void api_hal_power_off() {
bq25896_poweroff();
}
void api_hal_power_reset() {
NVIC_SystemReset();
}
void api_hal_power_enable_otg() {
bq25896_enable_otg();
}
void api_hal_power_disable_otg() {
bq25896_disable_otg();
}
uint32_t api_hal_power_get_battery_remaining_capacity() {
return bq27220_get_remaining_capacity();
}
uint32_t api_hal_power_get_battery_full_capacity() {
return bq27220_get_full_charge_capacity();
}
float api_hal_power_get_battery_voltage(ApiHalPowerIC ic) {
if (ic == ApiHalPowerICCharger) {
return (float)bq25896_get_vbat_voltage() / 1000.0f;
} else if (ic == ApiHalPowerICFuelGauge) {
return (float)bq27220_get_voltage() / 1000.0f;
} else {
return 0.0f;
}
}
float api_hal_power_get_battery_current(ApiHalPowerIC ic) {
if (ic == ApiHalPowerICCharger) {
return (float)bq25896_get_vbat_current() / 1000.0f;
} else if (ic == ApiHalPowerICFuelGauge) {
return (float)bq27220_get_current() / 1000.0f;
} else {
return 0.0f;
}
}
float api_hal_power_get_battery_temperature(ApiHalPowerIC ic) {
if (ic == ApiHalPowerICCharger) {
// Linear approximation, +/- 5 C
return (71.0f - (float)bq25896_get_ntc_mpct()/1000) / 0.6f;
} else if (ic == ApiHalPowerICFuelGauge) {
return ((float)bq27220_get_temperature() - 2731.0f) / 10.0f;
} else {
return 0.0f;
}
}
float api_hal_power_get_usb_voltage(){
return (float)bq25896_get_vbus_voltage() / 1000.0f;
}
void api_hal_power_dump_state() {
BatteryStatus battery_status;
OperationStatus operation_status;
if (bq27220_get_battery_status(&battery_status) == BQ27220_ERROR
|| bq27220_get_operation_status(&operation_status) == BQ27220_ERROR) {
printf("Failed to get bq27220 status. Communication error.\r\n");
} else {
printf(
"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
printf(
"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
printf(
"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
printf(
"bq27220: Full capacity: %dmAh, Design capacity: %dmAh, Remaining capacity: %dmAh, State of Charge: %d%%, State of health: %d%%\r\n",
bq27220_get_full_charge_capacity(), bq27220_get_design_capacity(), bq27220_get_remaining_capacity(),
bq27220_get_state_of_charge(), bq27220_get_state_of_health()
);
printf(
"bq27220: Voltage: %dmV, Current: %dmA, Temperature: %dC\r\n",
bq27220_get_voltage(), bq27220_get_current(), (int)api_hal_power_get_battery_temperature(ApiHalPowerICFuelGauge)
);
}
printf(
"bq25896: VBUS: %d, VSYS: %d, VBAT: %d, Current: %d, NTC: %ldm%%\r\n",
bq25896_get_vbus_voltage(), bq25896_get_vsys_voltage(),
bq25896_get_vbat_voltage(), bq25896_get_vbat_current(),
bq25896_get_ntc_mpct()
);
}
void api_hal_power_enable_external_3_3v(){
LL_GPIO_SetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin);
}
void api_hal_power_disable_external_3_3v(){
LL_GPIO_ResetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin);
}

View 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) - 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_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);
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "main.h"
#include "stdbool.h"
#ifdef __cplusplus
extern "C" {
#endif
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();
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,50 @@
#include <api-hal-resources.h>
#include "main.h"
#include <furi.h>
const InputPin input_pins[] = {
{.port = BUTTON_UP_GPIO_Port, .pin = BUTTON_UP_Pin, .key = InputKeyUp, .inverted = true},
{.port = BUTTON_DOWN_GPIO_Port, .pin = BUTTON_DOWN_Pin, .key = InputKeyDown, .inverted = true},
{.port = BUTTON_RIGHT_GPIO_Port,
.pin = BUTTON_RIGHT_Pin,
.key = InputKeyRight,
.inverted = true},
{.port = BUTTON_LEFT_GPIO_Port, .pin = BUTTON_LEFT_Pin, .key = InputKeyLeft, .inverted = true},
{.port = BUTTON_OK_GPIO_Port, .pin = BUTTON_OK_Pin, .key = InputKeyOk, .inverted = false},
{.port = BUTTON_BACK_GPIO_Port, .pin = BUTTON_BACK_Pin, .key = InputKeyBack, .inverted = true},
};
const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin);
const GpioPin vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin};
const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin};
const GpioPin gpio_cc1101_g0 = {.port = CC1101_G0_GPIO_Port, .pin = CC1101_G0_Pin};
const GpioPin gpio_rf_sw_0 = {.port = RF_SW_0_GPIO_Port, .pin = RF_SW_0_Pin};
const GpioPin gpio_subghz_cs = {.port = CC1101_CS_GPIO_Port, .pin = CC1101_CS_Pin};
const GpioPin gpio_display_cs = {.port = DISPLAY_CS_GPIO_Port, .pin = DISPLAY_CS_Pin};
const GpioPin gpio_display_rst = {.port = DISPLAY_RST_GPIO_Port, .pin = DISPLAY_RST_Pin};
const GpioPin gpio_display_di = {.port = DISPLAY_DI_GPIO_Port, .pin = DISPLAY_DI_Pin};
const GpioPin gpio_sdcard_cs = {.port = SD_CS_GPIO_Port, .pin = SD_CS_Pin};
const GpioPin gpio_nfc_cs = {.port = NFC_CS_GPIO_Port, .pin = NFC_CS_Pin};
const GpioPin gpio_spi_d_miso = {.port = SPI_D_MISO_GPIO_Port, .pin = SPI_D_MISO_Pin};
const GpioPin gpio_spi_d_mosi = {.port = SPI_D_MOSI_GPIO_Port, .pin = SPI_D_MOSI_Pin};
const GpioPin gpio_spi_d_sck = {.port = SPI_D_SCK_GPIO_Port, .pin = SPI_D_SCK_Pin};
const GpioPin gpio_spi_r_miso = {.port = SPI_R_MISO_GPIO_Port, .pin = SPI_R_MISO_Pin};
const GpioPin gpio_spi_r_mosi = {.port = SPI_R_MOSI_GPIO_Port, .pin = SPI_R_MOSI_Pin};
const GpioPin gpio_spi_r_sck = {.port = SPI_R_SCK_GPIO_Port, .pin = SPI_R_SCK_Pin};
const GpioPin gpio_ext_pc0 = {.port = GPIOC, .pin = GPIO_PIN_0};
const GpioPin gpio_ext_pc1 = {.port = GPIOC, .pin = GPIO_PIN_1};
const GpioPin gpio_ext_pc3 = {.port = GPIOC, .pin = GPIO_PIN_3};
const GpioPin gpio_ext_pb2 = {.port = GPIOB, .pin = GPIO_PIN_2};
const GpioPin gpio_ext_pb3 = {.port = GPIOB, .pin = GPIO_PIN_3};
const GpioPin gpio_ext_pa4 = {.port = GPIOA, .pin = GPIO_PIN_4};
const GpioPin gpio_ext_pa6 = {.port = GPIOA, .pin = GPIO_PIN_6};
const GpioPin gpio_ext_pa7 = {.port = GPIOA, .pin = GPIO_PIN_7};
const GpioPin gpio_rfid_pull = {.port = RFID_PULL_GPIO_Port, .pin = RFID_PULL_Pin};
const GpioPin gpio_rfid_carrier_out = {.port = RFID_OUT_GPIO_Port, .pin = RFID_OUT_Pin};
const GpioPin gpio_rfid_data_in = {.port = RFID_RF_IN_GPIO_Port, .pin = RFID_RF_IN_Pin};

View File

@ -0,0 +1,91 @@
#pragma once
#include "main.h"
#include <furi.h>
#include <stm32wbxx.h>
#include <stm32wbxx_ll_gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define POWER_I2C_SCL_Pin LL_GPIO_PIN_9
#define POWER_I2C_SCL_GPIO_Port GPIOA
#define POWER_I2C_SDA_Pin LL_GPIO_PIN_10
#define POWER_I2C_SDA_GPIO_Port GPIOA
#define POWER_I2C I2C1
/** Timing register value is computed with the STM32CubeMX Tool,
* Fast Mode @100kHz with I2CCLK = 64 MHz,
* rise time = 0ns, fall time = 0ns
*/
#define POWER_I2C_TIMINGS 0x10707DBC
/* Input Related Constants */
#define INPUT_DEBOUNCE_TICKS 20
/* Input Keys */
typedef enum {
InputKeyUp,
InputKeyDown,
InputKeyRight,
InputKeyLeft,
InputKeyOk,
InputKeyBack,
} InputKey;
/* Light */
typedef enum {
LightRed,
LightGreen,
LightBlue,
LightBacklight,
} Light;
typedef struct {
const GPIO_TypeDef* port;
const uint16_t pin;
const InputKey key;
const bool inverted;
} InputPin;
extern const InputPin input_pins[];
extern const size_t input_pins_count;
extern const GpioPin vibro_gpio;
extern const GpioPin ibutton_gpio;
extern const GpioPin gpio_cc1101_g0;
extern const GpioPin gpio_rf_sw_0;
extern const GpioPin gpio_subghz_cs;
extern const GpioPin gpio_display_cs;
extern const GpioPin gpio_display_rst;
extern const GpioPin gpio_display_di;
extern const GpioPin gpio_sdcard_cs;
extern const GpioPin gpio_nfc_cs;
extern const GpioPin gpio_spi_d_miso;
extern const GpioPin gpio_spi_d_mosi;
extern const GpioPin gpio_spi_d_sck;
extern const GpioPin gpio_spi_r_miso;
extern const GpioPin gpio_spi_r_mosi;
extern const GpioPin gpio_spi_r_sck;
extern const GpioPin gpio_ext_pc0;
extern const GpioPin gpio_ext_pc1;
extern const GpioPin gpio_ext_pc3;
extern const GpioPin gpio_ext_pb2;
extern const GpioPin gpio_ext_pb3;
extern const GpioPin gpio_ext_pa4;
extern const GpioPin gpio_ext_pa6;
extern const GpioPin gpio_ext_pa7;
extern const GpioPin gpio_rfid_pull;
extern const GpioPin gpio_rfid_carrier_out;
extern const GpioPin gpio_rfid_data_in;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,202 @@
#include <api-hal-rfid.h>
#include <api-hal-ibutton.h>
#include <api-hal-resources.h>
void api_hal_rfid_pins_reset() {
// ibutton bus disable
api_hal_ibutton_stop();
// pulldown rfid antenna
hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo);
hal_gpio_write(&gpio_rfid_carrier_out, true);
// from both sides
hal_gpio_init(&gpio_rfid_pull, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo);
hal_gpio_write(&gpio_rfid_pull, true);
}
void api_hal_rfid_pins_emulate() {
// ibutton low
api_hal_ibutton_start();
api_hal_ibutton_pin_low();
// pull pin to timer out
hal_gpio_init_alt(
&gpio_rfid_pull, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo, GpioAltFn1TIM1);
// pull rfid antenna from carrier side
hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo);
hal_gpio_write(&gpio_rfid_carrier_out, true);
}
void api_hal_rfid_pins_read() {
// ibutton low
api_hal_ibutton_start();
api_hal_ibutton_pin_low();
// dont pull rfid antenna
hal_gpio_init(&gpio_rfid_pull, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo);
hal_gpio_write(&gpio_rfid_pull, false);
// carrier pin to timer out
hal_gpio_init_alt(
&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo, GpioAltFn1TIM1);
// comparator in
hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioSpeedLow, GpioPullNo);
}
void api_hal_rfid_tim_read(float freq, float duty_cycle) {
// TODO LL init
uint32_t period = (uint32_t)((SystemCoreClock) / freq) - 1;
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
// basic PWM setup with needed freq and internal clock
LFRFID_TIM.Instance = TIM1;
LFRFID_TIM.Init.Prescaler = 0;
LFRFID_TIM.Init.CounterMode = TIM_COUNTERMODE_UP;
LFRFID_TIM.Init.Period = period;
LFRFID_TIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
LFRFID_TIM.Init.RepetitionCounter = 0;
LFRFID_TIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if(HAL_TIM_Base_Init(&LFRFID_TIM) != HAL_OK) {
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if(HAL_TIM_ConfigClockSource(&LFRFID_TIM, &sClockSourceConfig) != HAL_OK) {
Error_Handler();
}
if(HAL_TIM_PWM_Init(&LFRFID_TIM) != HAL_OK) {
Error_Handler();
}
// no master-slave mode
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if(HAL_TIMEx_MasterConfigSynchronization(&LFRFID_TIM, &sMasterConfig) != HAL_OK) {
Error_Handler();
}
// pwm config
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = (uint32_t)(LFRFID_TIM.Init.Period * duty_cycle);
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;
if(HAL_TIM_OC_ConfigChannel(&LFRFID_TIM, &sConfigOC, LFRFID_CH) != HAL_OK) {
Error_Handler();
}
// no deadtime
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if(HAL_TIMEx_ConfigBreakDeadTime(&LFRFID_TIM, &sBreakDeadTimeConfig) != HAL_OK) {
Error_Handler();
}
}
void api_hal_rfid_tim_read_start() {
HAL_TIMEx_PWMN_Start(&LFRFID_TIM, LFRFID_CH);
}
void api_hal_rfid_tim_read_stop() {
HAL_TIMEx_PWMN_Stop(&LFRFID_TIM, LFRFID_CH);
}
void api_hal_rfid_tim_emulate(float freq) {
// TODO LL init
uint32_t prescaler = (uint32_t)((SystemCoreClock) / freq) - 1;
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
// basic PWM setup with needed freq and internal clock
LFRFID_TIM.Instance = TIM1;
LFRFID_TIM.Init.Prescaler = prescaler;
LFRFID_TIM.Init.CounterMode = TIM_COUNTERMODE_UP;
LFRFID_TIM.Init.Period = 1;
LFRFID_TIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
LFRFID_TIM.Init.RepetitionCounter = 0;
LFRFID_TIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if(HAL_TIM_Base_Init(&LFRFID_TIM) != HAL_OK) {
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if(HAL_TIM_ConfigClockSource(&LFRFID_TIM, &sClockSourceConfig) != HAL_OK) {
Error_Handler();
}
if(HAL_TIM_PWM_Init(&LFRFID_TIM) != HAL_OK) {
Error_Handler();
}
// no master-slave mode
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if(HAL_TIMEx_MasterConfigSynchronization(&LFRFID_TIM, &sMasterConfig) != HAL_OK) {
Error_Handler();
}
// pwm config
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 1;
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;
if(HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, LFRFID_CH) != HAL_OK) {
Error_Handler();
}
// no deadtime
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if(HAL_TIMEx_ConfigBreakDeadTime(&LFRFID_TIM, &sBreakDeadTimeConfig) != HAL_OK) {
Error_Handler();
}
}
void api_hal_rfid_tim_emulate_start() {
HAL_TIM_PWM_Start_IT(&LFRFID_TIM, LFRFID_CH);
HAL_TIM_Base_Start_IT(&LFRFID_TIM);
}
void api_hal_rfid_tim_emulate_stop() {
HAL_TIM_Base_Stop(&LFRFID_TIM);
HAL_TIM_PWM_Stop(&LFRFID_TIM, LFRFID_CH);
}
void api_hal_rfid_tim_reset() {
}

View File

@ -0,0 +1,22 @@
#include "api-hal-sd.h"
#include <stm32wbxx_ll_gpio.h>
#include <furi.h>
void hal_sd_detect_init(void) {
// low speed input with pullup
LL_GPIO_SetPinMode(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinSpeed(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_SPEED_FREQ_LOW);
LL_GPIO_SetPinPull(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_PULL_UP);
}
void hal_sd_detect_set_low(void) {
// low speed input with pullup
LL_GPIO_SetPinMode(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinOutputType(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_OUTPUT_OPENDRAIN);
LL_GPIO_ResetOutputPin(SD_CD_GPIO_Port, SD_CD_Pin);
}
bool hal_sd_detect(void) {
bool result = !(LL_GPIO_IsInputPinSet(SD_CD_GPIO_Port, SD_CD_Pin));
return result;
}

View File

@ -0,0 +1,122 @@
#include <api-hal-spi-config.h>
#include <api-hal-resources.h>
extern SPI_HandleTypeDef SPI_R;
extern SPI_HandleTypeDef SPI_D;
const SPI_InitTypeDef api_hal_spi_config_nfc = {
.Mode = SPI_MODE_MASTER,
.Direction = SPI_DIRECTION_2LINES,
.DataSize = SPI_DATASIZE_8BIT,
.CLKPolarity = SPI_POLARITY_LOW,
.CLKPhase = SPI_PHASE_2EDGE,
.NSS = SPI_NSS_SOFT,
.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8,
.FirstBit = SPI_FIRSTBIT_MSB,
.TIMode = SPI_TIMODE_DISABLE,
.CRCCalculation = SPI_CRCCALCULATION_DISABLE,
.CRCPolynomial = 7,
.CRCLength = SPI_CRC_LENGTH_DATASIZE,
.NSSPMode = SPI_NSS_PULSE_DISABLE,
};
const SPI_InitTypeDef api_hal_spi_config_subghz = {
.Mode = SPI_MODE_MASTER,
.Direction = SPI_DIRECTION_2LINES,
.DataSize = SPI_DATASIZE_8BIT,
.CLKPolarity = SPI_POLARITY_LOW,
.CLKPhase = SPI_PHASE_1EDGE,
.NSS = SPI_NSS_SOFT,
.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8,
.FirstBit = SPI_FIRSTBIT_MSB,
.TIMode = SPI_TIMODE_DISABLE,
.CRCCalculation = SPI_CRCCALCULATION_DISABLE,
.CRCPolynomial = 7,
.CRCLength = SPI_CRC_LENGTH_DATASIZE,
.NSSPMode = SPI_NSS_PULSE_DISABLE,
};
const SPI_InitTypeDef api_hal_spi_config_display = {
.Mode = SPI_MODE_MASTER,
.Direction = SPI_DIRECTION_2LINES,
.DataSize = SPI_DATASIZE_8BIT,
.CLKPolarity = SPI_POLARITY_LOW,
.CLKPhase = SPI_PHASE_1EDGE,
.NSS = SPI_NSS_SOFT,
.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16,
.FirstBit = SPI_FIRSTBIT_MSB,
.TIMode = SPI_TIMODE_DISABLE,
.CRCCalculation = SPI_CRCCALCULATION_DISABLE,
.CRCPolynomial = 7,
.CRCLength = SPI_CRC_LENGTH_DATASIZE,
.NSSPMode = SPI_NSS_PULSE_ENABLE,
};
osMutexId_t spi_mutex_d = NULL;
osMutexId_t spi_mutex_r = NULL;
const ApiHalSpiBus spi_r = {
.spi=&SPI_R,
.mutex=&spi_mutex_r,
.miso=&gpio_spi_r_miso,
.mosi=&gpio_spi_r_mosi,
.clk=&gpio_spi_r_sck,
};
const ApiHalSpiBus spi_d = {
.spi=&SPI_D,
.mutex=&spi_mutex_d,
.miso=&gpio_spi_d_miso,
.mosi=&gpio_spi_d_mosi,
.clk=&gpio_spi_d_sck,
};
const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax] = {
{ .bus=&spi_r, .config=&api_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, },
{ .bus=&spi_d, .config=&api_hal_spi_config_display, .chip_select=&gpio_display_cs, },
{ .bus=&spi_d, .config=NULL, .chip_select=&gpio_sdcard_cs, },
{ .bus=&spi_r, .config=&api_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs },
};
/**
* SD Card in fast mode (after init)
*/
const SPIDevice sd_fast_spi = {
.bus= &spi_d,
.config = {
.Mode = SPI_MODE_MASTER,
.Direction = SPI_DIRECTION_2LINES,
.DataSize = SPI_DATASIZE_8BIT,
.CLKPolarity = SPI_POLARITY_LOW,
.CLKPhase = SPI_PHASE_1EDGE,
.NSS = SPI_NSS_SOFT,
.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2,
.FirstBit = SPI_FIRSTBIT_MSB,
.TIMode = SPI_TIMODE_DISABLE,
.CRCCalculation = SPI_CRCCALCULATION_DISABLE,
.CRCPolynomial = 7,
.CRCLength = SPI_CRC_LENGTH_DATASIZE,
.NSSPMode = SPI_NSS_PULSE_ENABLE,
}};
/**
* SD Card in slow mode (before init)
*/
const SPIDevice sd_slow_spi = {
.bus= &spi_d,
.config = {
.Mode = SPI_MODE_MASTER,
.Direction = SPI_DIRECTION_2LINES,
.DataSize = SPI_DATASIZE_8BIT,
.CLKPolarity = SPI_POLARITY_LOW,
.CLKPhase = SPI_PHASE_1EDGE,
.NSS = SPI_NSS_SOFT,
.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32,
.FirstBit = SPI_FIRSTBIT_MSB,
.TIMode = SPI_TIMODE_DISABLE,
.CRCCalculation = SPI_CRCCALCULATION_DISABLE,
.CRCPolynomial = 7,
.CRCLength = SPI_CRC_LENGTH_DATASIZE,
.NSSPMode = SPI_NSS_PULSE_ENABLE,
}};

View File

@ -0,0 +1,67 @@
#pragma once
#include <api-hal-gpio.h>
#include <cmsis_os2.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const SPI_InitTypeDef api_hal_spi_config_nfc;
extern const SPI_InitTypeDef api_hal_spi_config_subghz;
extern const SPI_InitTypeDef api_hal_spi_config_display;
/** API HAL SPI BUS handler
* Structure content may change at some point
*/
typedef struct {
const SPI_HandleTypeDef* spi;
const osMutexId_t* mutex;
const GpioPin* miso;
const GpioPin* mosi;
const GpioPin* clk;
} ApiHalSpiBus;
/** API HAL SPI Device handler
* Structure content may change at some point
*/
typedef struct {
const ApiHalSpiBus* bus;
const SPI_InitTypeDef* config;
const GpioPin* chip_select;
} ApiHalSpiDevice;
/** API HAL SPI Standard Device IDs */
typedef enum {
ApiHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */
ApiHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */
ApiHalSpiDeviceIdSdCard, /** SDCARD: no default bus config, bus must explicitly be configured */
ApiHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */
ApiHalSpiDeviceIdMax, /** Service Value, do not use */
} ApiHalSpiDeviceId;
/** Api Hal Spi Bus R
* CC1101, Nfc
*/
extern const ApiHalSpiBus spi_r;
/** Api Hal Spi Bus D
* Display, SdCard
*/
extern const ApiHalSpiBus spi_d;
/** Api Hal Spi devices */
extern const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax];
typedef struct {
const ApiHalSpiBus* bus;
const SPI_InitTypeDef config;
} SPIDevice;
extern const SPIDevice sd_fast_spi;
extern const SPIDevice sd_slow_spi;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,180 @@
#include "api-hal-spi.h"
#include <api-hal-resources.h>
#include <stdbool.h>
#include <string.h>
#include <spi.h>
#include <furi.h>
extern void Enable_SPI(SPI_HandleTypeDef* spi);
void api_hal_spi_init() {
// Spi structure is const, but mutex is not
// Need some hell-ish casting to make it work
*(osMutexId_t*)spi_r.mutex = osMutexNew(NULL);
*(osMutexId_t*)spi_d.mutex = osMutexNew(NULL);
//
for (size_t i=0; i<ApiHalSpiDeviceIdMax; ++i) {
hal_gpio_init(
api_hal_spi_devices[i].chip_select,
GpioModeOutputPushPull,
GpioPullNo,
GpioSpeedVeryHigh
);
}
}
void api_hal_spi_bus_lock(const ApiHalSpiBus* bus) {
furi_assert(bus);
if (bus->mutex) {
osMutexAcquire(*bus->mutex, osWaitForever);
}
}
void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus) {
furi_assert(bus);
if (bus->mutex) {
osMutexRelease(*bus->mutex);
}
}
bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
furi_assert(bus);
furi_assert(buffer);
furi_assert(size > 0);
HAL_StatusTypeDef ret = HAL_SPI_Receive((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY);
return ret == HAL_OK;
}
bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) {
furi_assert(bus);
furi_assert(buffer);
furi_assert(size > 0);
HAL_StatusTypeDef ret = HAL_SPI_Transmit((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY);
return ret == HAL_OK;
}
bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
furi_assert(bus);
furi_assert(tx_buffer);
furi_assert(rx_buffer);
furi_assert(size > 0);
HAL_StatusTypeDef ret = HAL_SPI_TransmitReceive((SPI_HandleTypeDef *)bus->spi, tx_buffer, rx_buffer, size, HAL_MAX_DELAY);
return ret == HAL_OK;
}
const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id) {
furi_assert(device_id < ApiHalSpiDeviceIdMax);
const ApiHalSpiDevice* device = &api_hal_spi_devices[device_id];
assert(device);
api_hal_spi_bus_lock(device->bus);
if (device->config) {
memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, device->config, sizeof(SPI_InitTypeDef));
if(HAL_SPI_Init((SPI_HandleTypeDef *)device->bus->spi) != HAL_OK) {
Error_Handler();
}
Enable_SPI((SPI_HandleTypeDef *)device->bus->spi);
}
return device;
}
void api_hal_spi_device_return(const ApiHalSpiDevice* device) {
api_hal_spi_bus_unlock(device->bus);
}
bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
furi_assert(device);
furi_assert(buffer);
furi_assert(size > 0);
if (device->chip_select) {
hal_gpio_write(device->chip_select, false);
}
bool ret = api_hal_spi_bus_rx(device->bus, buffer, size, HAL_MAX_DELAY);
if (device->chip_select) {
hal_gpio_write(device->chip_select, true);
}
return ret;
}
bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) {
furi_assert(device);
furi_assert(buffer);
furi_assert(size > 0);
if (device->chip_select) {
hal_gpio_write(device->chip_select, false);
}
bool ret = api_hal_spi_bus_tx(device->bus, buffer, size, HAL_MAX_DELAY);
if (device->chip_select) {
hal_gpio_write(device->chip_select, true);
}
return ret;
}
bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) {
furi_assert(device);
furi_assert(tx_buffer);
furi_assert(rx_buffer);
furi_assert(size > 0);
if (device->chip_select) {
hal_gpio_write(device->chip_select, false);
}
bool ret = api_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, HAL_MAX_DELAY);
if (device->chip_select) {
hal_gpio_write(device->chip_select, true);
}
return ret;
}
void api_hal_spi_apply_config(const SPIDevice* device) {
osKernelLock();
memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, &device->config, sizeof(SPI_InitTypeDef));
if(HAL_SPI_Init((SPI_HandleTypeDef*)device->bus->spi) != HAL_OK) {
Error_Handler();
}
Enable_SPI((SPI_HandleTypeDef*)device->bus->spi);
osKernelUnlock();
}
bool api_hal_spi_config_are_actual(const SPIDevice* device) {
return (memcmp(&device->config, &device->bus->spi->Init, sizeof(SPI_InitTypeDef)) == 0);
}
void api_hal_spi_config_device(const SPIDevice* device) {
if(!api_hal_spi_config_are_actual(device)) {
api_hal_spi_apply_config(device);
}
}
void api_hal_spi_lock_device(const SPIDevice* device) {
api_hal_spi_bus_lock(device->bus);
api_hal_spi_config_device(device);
}
void api_hal_spi_unlock_device(const SPIDevice* device) {
api_hal_spi_bus_unlock(device->bus);
}

View File

@ -0,0 +1,106 @@
#pragma once
#include "main.h"
#include "api-hal-spi-config.h"
#include <api-hal-gpio.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Init SPI API
*/
void api_hal_spi_init();
/* Bus Level API */
/** Lock SPI bus
* Takes bus mutex, if used
*/
void api_hal_spi_bus_lock(const ApiHalSpiBus* bus);
/** Unlock SPI bus
* Releases BUS mutex, if used
*/
void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus);
/** SPI Receive
* @param bus - spi bus handler
* @param buffer - receive buffer
* @param size - transaction size
* @param timeout - bus operation timeout in ms
*/
bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout);
/** SPI Transmit
* @param bus - spi bus handler
* @param buffer - transmit buffer
* @param size - transaction size
* @param timeout - bus operation timeout in ms
*/
bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout);
/** SPI Transmit and Receive
* @param bus - spi bus handlere
* @param tx_buffer - device handle
* @param rx_buffer - device handle
* @param size - transaction size
* @param timeout - bus operation timeout in ms
*/
bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout);
/* Device Level API */
/** Get Device handle
* And lock access to the corresponding SPI BUS
* @param device_id - device identifier
* @return device handle
*/
const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id);
/** Return Device handle
* And unlock access to the corresponding SPI BUS
* @param device - device handle
*/
void api_hal_spi_device_return(const ApiHalSpiDevice* device);
/** SPI Recieve
* @param device - device handle
* @param buffer - receive buffer
* @param size - transaction size
* @param timeout - bus operation timeout in ms
*/
bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout);
/** SPI Transmit
* @param device - device handle
* @param buffer - transmit buffer
* @param size - transaction size
* @param timeout - bus operation timeout in ms
*/
bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout);
/** SPI Transmit and Receive
* @param device - device handle
* @param tx_buffer - device handle
* @param rx_buffer - device handle
* @param size - transaction size
* @param timeout - bus operation timeout in ms
*/
bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout);
/**
* Lock SPI device bus and apply config if needed
*/
void api_hal_spi_lock_device(const SPIDevice* device);
/**
* Unlock SPI device bus
*/
void api_hal_spi_unlock_device(const SPIDevice* device);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,191 @@
#include "api-hal-subghz.h"
#include <api-hal-gpio.h>
#include <api-hal-spi.h>
#include <api-hal-resources.h>
#include <furi.h>
#include <cc1101.h>
#include <stdio.h>
static const uint8_t api_hal_subghz_preset_ook_async_regs[][2] = {
/* Base setting */
{ CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input
{ CC1101_FSCTRL1, 0x06 }, // Set IF 26m/2^10*2=2.2MHz
{ CC1101_MCSM0, 0x18 }, // Autocalibrate on idle to TRX, ~150us OSC guard time
/* Async OOK Specific things */
{ CC1101_MDMCFG2, 0x30 }, // ASK/OOK, No preamble/sync
{ CC1101_PKTCTRL0, 0x32 }, // Async, no CRC, Infinite
{ CC1101_FREND0, 0x01 }, // OOK/ASK PATABLE
/* End */
{ 0, 0 },
};
static const uint8_t api_hal_subghz_preset_ook_async_patable[8] = {
0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t api_hal_subghz_preset_2fsk_packet_regs[][2] = {
/* Base setting */
{ CC1101_IOCFG0, 0x06 }, // GD0 as async serial data output/input
{ CC1101_FSCTRL1, 0x06 }, // Set IF 26m/2^10*2=2.2MHz
{ CC1101_MCSM0, 0x18 }, // Autocalibrate on idle to TRX, ~150us OSC guard time
/* End */
{ 0, 0 },
};
static const uint8_t api_hal_subghz_preset_2fsk_packet_patable[8] = {
0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void api_hal_subghz_init() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
// Reset and shutdown
cc1101_reset(device);
// Prepare GD0 for power on self test
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
// GD0 low
cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW);
while(hal_gpio_read(&gpio_cc1101_g0) != false);
// GD0 high
cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV);
while(hal_gpio_read(&gpio_cc1101_g0) != true);
// Reset GD0 to floating state
cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance);
hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
// RF switches
hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW);
// Turn off oscillator
cc1101_shutdown(device);
api_hal_spi_device_return(device);
}
void api_hal_subghz_dump_state() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
printf(
"[api_hal_subghz] cc1101 chip %d, version %d\r\n",
cc1101_get_partnumber(device),
cc1101_get_version(device)
);
api_hal_spi_device_return(device);
}
void api_hal_subghz_load_preset(ApiHalSubGhzPreset preset) {
if(preset == ApiHalSubGhzPresetOokAsync) {
api_hal_subghz_load_registers(api_hal_subghz_preset_ook_async_regs);
api_hal_subghz_load_patable(api_hal_subghz_preset_ook_async_patable);
} else if(preset == ApiHalSubGhzPreset2FskPacket) {
api_hal_subghz_load_registers(api_hal_subghz_preset_2fsk_packet_regs);
api_hal_subghz_load_patable(api_hal_subghz_preset_2fsk_packet_patable);
}
}
void api_hal_subghz_load_registers(const uint8_t data[][2]) {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_reset(device);
uint32_t i = 0;
while (data[i][0]) {
cc1101_write_reg(device, data[i][0], data[i][1]);
i++;
}
api_hal_spi_device_return(device);
}
void api_hal_subghz_load_patable(const uint8_t data[8]) {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_set_pa_table(device, data);
api_hal_spi_device_return(device);
}
void api_hal_subghz_write_packet(const uint8_t* data, uint8_t size) {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_flush_tx(device);
cc1101_write_fifo(device, data, size);
api_hal_spi_device_return(device);
}
void api_hal_subghz_read_packet(uint8_t* data, uint8_t size) {
}
void api_hal_subghz_shutdown() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
// Reset and shutdown
cc1101_shutdown(device);
api_hal_spi_device_return(device);
}
void api_hal_subghz_reset() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_reset(device);
api_hal_spi_device_return(device);
}
void api_hal_subghz_idle() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_switch_to_idle(device);
api_hal_spi_device_return(device);
}
void api_hal_subghz_rx() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_switch_to_rx(device);
api_hal_spi_device_return(device);
}
void api_hal_subghz_tx() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
cc1101_switch_to_tx(device);
api_hal_spi_device_return(device);
}
float api_hal_subghz_get_rssi() {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
int32_t rssi_dec = cc1101_get_rssi(device);
api_hal_spi_device_return(device);
float rssi = rssi_dec;
if(rssi_dec >= 128) {
rssi = ((rssi - 256.0f) / 2.0f) - 74.0f;
} else {
rssi = (rssi / 2.0f) - 74.0f;
}
return rssi;
}
uint32_t api_hal_subghz_set_frequency(uint32_t value) {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
// Compensate rounding
if (value % cc1101_get_frequency_step(device) > (cc1101_get_frequency_step(device) / 2)) {
value += cc1101_get_frequency_step(device);
}
uint32_t real_frequency = cc1101_set_frequency(device, value);
cc1101_calibrate(device);
api_hal_spi_device_return(device);
return real_frequency;
}
void api_hal_subghz_set_path(ApiHalSubGhzPath path) {
const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz);
if (path == ApiHalSubGhzPath1) {
hal_gpio_write(&gpio_rf_sw_0, 0);
cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV);
} else if (path == ApiHalSubGhzPath2) {
hal_gpio_write(&gpio_rf_sw_0, 1);
cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW);
} else if (path == ApiHalSubGhzPath3) {
hal_gpio_write(&gpio_rf_sw_0, 1);
cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV);
} else if (path == ApiHalSubGhzPathIsolate) {
hal_gpio_write(&gpio_rf_sw_0, 0);
cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW);
} else {
furi_check(0);
}
api_hal_spi_device_return(device);
}

View File

@ -0,0 +1,54 @@
#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();
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "main.h"
#include <cmsis_os2.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_is_isr_context(void);

View File

@ -0,0 +1,47 @@
#include "cmsis_os.h"
#include "api-hal-tim.h"
/* setup TIM2 CH1 and CH2 to capture rising and falling events */
void tim_irda_rx_init(void) {
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 64 - 1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 4294967295;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if(HAL_TIM_Base_Init(&htim2) != HAL_OK) {
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if(HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) {
Error_Handler();
}
if(HAL_TIM_IC_Init(&htim2) != HAL_OK) {
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if(HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) {
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if(HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) {
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
if(HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) {
Error_Handler();
}
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);
}

View File

@ -0,0 +1,4 @@
#pragma once
#include "main.h"
void tim_irda_rx_init(void);

View 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;
}

View File

@ -0,0 +1,101 @@
#include <api-hal-vcp.h>
#include <usbd_cdc_if.h>
#include <furi.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;
static ApiHalVcp* api_hal_vcp = NULL;
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 = furi_alloc(sizeof(ApiHalVcp));
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) {
furi_assert(api_hal_vcp);
return xStreamBufferReceive(api_hal_vcp->rx_stream, buffer, size, portMAX_DELAY);
}
size_t api_hal_vcp_rx_with_timeout(uint8_t* buffer, size_t size, uint32_t timeout) {
furi_assert(api_hal_vcp);
return xStreamBufferReceive(api_hal_vcp->rx_stream, buffer, size, timeout);
}
void api_hal_vcp_tx(const uint8_t* buffer, size_t size) {
furi_assert(api_hal_vcp);
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((uint8_t*)buffer, batch_size) == USBD_OK) {
size -= batch_size;
buffer += batch_size;
} else {
// Shouldn't be there
osDelay(100);
}
}
}

View File

@ -0,0 +1,55 @@
#include <api-hal-version.h>
#include <stm32wbxx.h>
#include <stm32wbxx_ll_rtc.h>
typedef struct {
uint8_t version;
uint8_t target;
uint8_t body;
uint8_t connect;
uint32_t timestamp;
char name[8];
} ApiHalVersionOTP;
bool api_hal_version_do_i_belong_here() {
return api_hal_version_get_hw_target() == 5;
}
const uint8_t api_hal_version_get_hw_version() {
return ((ApiHalVersionOTP*)OTP_AREA_BASE)->version;
}
const uint8_t api_hal_version_get_hw_target() {
return ((ApiHalVersionOTP*)OTP_AREA_BASE)->target;
}
const uint8_t api_hal_version_get_hw_body() {
return ((ApiHalVersionOTP*)OTP_AREA_BASE)->body;
}
const uint8_t api_hal_version_get_hw_connect() {
return ((ApiHalVersionOTP*)OTP_AREA_BASE)->connect;
}
const uint32_t api_hal_version_get_hw_timestamp() {
return ((ApiHalVersionOTP*)OTP_AREA_BASE)->timestamp;
}
const char * api_hal_version_get_name_ptr() {
char * name = ((ApiHalVersionOTP*)OTP_AREA_BASE)->name;
return *name == 0xFFU ? NULL : name;
}
const struct Version* api_hal_version_get_fw_version(void) {
return version_get();
}
const struct Version* api_hal_version_get_boot_version(void) {
#ifdef NO_BOOTLOADER
return 0;
#else
/* Backup register which points to structure in flash memory */
return (const struct Version*) LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR1);
#endif
}

View File

@ -0,0 +1,11 @@
#include <api-hal-vibro.h>
#include <api-hal-gpio.h>
void api_hal_vibro_init() {
hal_gpio_init(&vibro_gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
hal_gpio_write(&vibro_gpio, false);
}
void api_hal_vibro_on(bool value) {
hal_gpio_write(&vibro_gpio, value);
}

View File

@ -0,0 +1,22 @@
#include <api-hal.h>
void api_hal_init() {
api_hal_delay_init();
FURI_LOG_I("FURI_HAL", "DELAY OK");
api_hal_os_init();
FURI_LOG_I("FURI_HAL", "OS OK");
api_hal_vcp_init();
FURI_LOG_I("FURI_HAL", "VCP OK");
api_hal_spi_init();
FURI_LOG_I("FURI_HAL", "SPI OK");
api_hal_i2c_init();
FURI_LOG_I("FURI_HAL", "I2C OK");
api_hal_power_init();
FURI_LOG_I("FURI_HAL", "POWER OK");
api_hal_light_init();
FURI_LOG_I("FURI_HAL", "LIGHT OK");
api_hal_vibro_init();
FURI_LOG_I("FURI_HAL", "VIBRO OK");
api_hal_subghz_init();
FURI_LOG_I("FURI_HAL", "SUBGHZ OK");
}

View File

@ -0,0 +1,26 @@
#include "api-hal/api-interrupt-mgr.h"
#include <main.h>
extern void api_interrupt_call(InterruptType type, void* hw);
/* interrupts */
/* Comparator trigger event */
void HAL_COMP_TriggerCallback(COMP_HandleTypeDef* hcomp) {
api_interrupt_call(InterruptTypeComparatorTrigger, hcomp);
}
/* Timer input capture event */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) {
api_interrupt_call(InterruptTypeTimerCapture, htim);
}
/* Output compare event */
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim) {
api_interrupt_call(InterruptTypeTimerOutputCompare, htim);
}
/* Timer update event */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) {
api_interrupt_call(InterruptTypeTimerUpdate, htim);
}

View File

@ -0,0 +1,806 @@
#include "main.h"
#include "app_entry.h"
#include "app_common.h"
#include "dbg_trace.h"
#include "ble.h"
#include "tl.h"
#include "app_ble.h"
#include "cmsis_os.h"
#include "shci.h"
#include "stm32_lpm.h"
#include "otp.h"
#include "dis_app.h"
#include "hrs_app.h"
#include <api-hal.h>
typedef struct _tSecurityParams {
uint8_t ioCapability;
uint8_t mitm_mode;
uint8_t bonding_mode;
uint8_t Use_Fixed_Pin;
uint8_t encryptionKeySizeMin;
uint8_t encryptionKeySizeMax;
uint32_t Fixed_Pin;
uint8_t initiateSecurity;
} tSecurityParams;
typedef struct _tBLEProfileGlobalContext {
tSecurityParams bleSecurityParam;
uint16_t gapServiceHandle;
uint16_t devNameCharHandle;
uint16_t appearanceCharHandle;
uint16_t connectionHandle;
uint8_t advtServUUIDlen;
uint8_t advtServUUID[100];
} BleGlobalContext_t;
typedef struct {
BleGlobalContext_t BleApplicationContext_legacy;
APP_BLE_ConnStatus_t Device_Connection_Status;
uint8_t Advertising_mgr_timer_Id;
} BleApplicationContext_t;
#define APPBLE_GAP_DEVICE_NAME_LENGTH 7
#define FAST_ADV_TIMEOUT (30*1000*1000/CFG_TS_TICK_VAL) /**< 30s */
#define INITIAL_ADV_TIMEOUT (60*1000*1000/CFG_TS_TICK_VAL) /**< 60s */
#define BD_ADDR_SIZE_LOCAL 6
#define LED_ON_TIMEOUT (0.005*1000*1000/CFG_TS_TICK_VAL) /**< 5ms */
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer;
static const uint8_t M_bd_addr[BD_ADDR_SIZE_LOCAL] =
{
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000000000FF)),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x00000000FF00) >> 8),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x000000FF0000) >> 16),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000FF000000) >> 24),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x00FF00000000) >> 32),
(uint8_t)((CFG_ADV_BD_ADDRESS & 0xFF0000000000) >> 40)
};
static uint8_t bd_addr_udn[BD_ADDR_SIZE_LOCAL];
static const uint8_t BLE_CFG_IR_VALUE[16] = CFG_BLE_IRK;
static const uint8_t BLE_CFG_ER_VALUE[16] = CFG_BLE_ERK;
PLACE_IN_SECTION("TAG_OTA_END") const uint32_t MagicKeywordValue = 0x94448A29 ;
PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue;
PLACE_IN_SECTION("BLE_APP_CONTEXT") static BleApplicationContext_t BleApplicationContext;
PLACE_IN_SECTION("BLE_APP_CONTEXT") static uint16_t AdvIntervalMin, AdvIntervalMax;
static const char local_name[] = { AD_TYPE_COMPLETE_LOCAL_NAME ,'F','L','I','P','P', 'E', 'R'};
uint8_t manuf_data[14] = {
sizeof(manuf_data)-1, AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
0x01/*SKD version */,
0x00 /* Generic*/,
0x00 /* GROUP A Feature */,
0x00 /* GROUP A Feature */,
0x00 /* GROUP B Feature */,
0x00 /* GROUP B Feature */,
0x00, /* BLE MAC start -MSB */
0x00,
0x00,
0x00,
0x00,
0x00, /* BLE MAC stop */
};
osMutexId_t MtxHciId;
osSemaphoreId_t SemHciId;
osThreadId_t AdvUpdateProcessId;
osThreadId_t HciUserEvtProcessId;
const osThreadAttr_t AdvUpdateProcess_attr = {
.name = CFG_ADV_UPDATE_PROCESS_NAME,
.attr_bits = CFG_ADV_UPDATE_PROCESS_ATTR_BITS,
.cb_mem = CFG_ADV_UPDATE_PROCESS_CB_MEM,
.cb_size = CFG_ADV_UPDATE_PROCESS_CB_SIZE,
.stack_mem = CFG_ADV_UPDATE_PROCESS_STACK_MEM,
.priority = CFG_ADV_UPDATE_PROCESS_PRIORITY,
.stack_size = CFG_ADV_UPDATE_PROCESS_STACK_SIZE
};
const osThreadAttr_t HciUserEvtProcess_attr = {
.name = CFG_HCI_USER_EVT_PROCESS_NAME,
.attr_bits = CFG_HCI_USER_EVT_PROCESS_ATTR_BITS,
.cb_mem = CFG_HCI_USER_EVT_PROCESS_CB_MEM,
.cb_size = CFG_HCI_USER_EVT_PROCESS_CB_SIZE,
.stack_mem = CFG_HCI_USER_EVT_PROCESS_STACK_MEM,
.priority = CFG_HCI_USER_EVT_PROCESS_PRIORITY,
.stack_size = CFG_HCI_USER_EVT_PROCESS_STACK_SIZE
};
/* Private function prototypes -----------------------------------------------*/
static void HciUserEvtProcess(void *argument);
static void BLE_UserEvtRx( void * pPayload );
static void BLE_StatusNot( HCI_TL_CmdStatus_t status );
static void Ble_Tl_Init( void );
static void Ble_Hci_Gap_Gatt_Init();
static const uint8_t* BleGetBdAddress( void );
static void Adv_Request( APP_BLE_ConnStatus_t New_Status );
static void Add_Advertisment_Service_UUID( uint16_t servUUID );
static void Adv_Mgr( void );
static void AdvUpdateProcess(void *argument);
static void Adv_Update( void );
bool APP_BLE_Init() {
SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = {
{{0,0,0}}, /**< Header unused */
{0, /** pBleBufferAddress not used */
0, /** BleBufferSize not used */
CFG_BLE_NUM_GATT_ATTRIBUTES,
CFG_BLE_NUM_GATT_SERVICES,
CFG_BLE_ATT_VALUE_ARRAY_SIZE,
CFG_BLE_NUM_LINK,
CFG_BLE_DATA_LENGTH_EXTENSION,
CFG_BLE_PREPARE_WRITE_LIST_SIZE,
CFG_BLE_MBLOCK_COUNT,
CFG_BLE_MAX_ATT_MTU,
CFG_BLE_SLAVE_SCA,
CFG_BLE_MASTER_SCA,
CFG_BLE_LSE_SOURCE,
CFG_BLE_MAX_CONN_EVENT_LENGTH,
CFG_BLE_HSE_STARTUP_TIME,
CFG_BLE_VITERBI_MODE,
CFG_BLE_LL_ONLY,
0}
};
// Initialize Ble Transport Layer
Ble_Tl_Init( );
// Register the hci transport layer to handle BLE User Asynchronous Events
HciUserEvtProcessId = osThreadNew(HciUserEvtProcess, NULL, &HciUserEvtProcess_attr);
// Starts the BLE Stack on CPU2
return (SHCI_C2_BLE_Init( &ble_init_cmd_packet ) == SHCI_Success);
}
bool APP_BLE_Start() {
if (APPE_Status() != BleGlueStatusStarted) {
return false;
}
// Initialization of HCI & GATT & GAP layer
Ble_Hci_Gap_Gatt_Init();
// Initialization of the BLE Services
SVCCTL_Init();
// Initialization of the BLE App Context
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0xFFFF;
// From here, all initialization are BLE application specific
AdvUpdateProcessId = osThreadNew(AdvUpdateProcess, NULL, &AdvUpdateProcess_attr);
// Initialization of ADV - Ad Manufacturer Element - Support OTA Bit Masks
#if(BLE_CFG_OTA_REBOOT_CHAR != 0)
manuf_data[sizeof(manuf_data)-8] = CFG_FEATURE_OTA_REBOOT;
#endif
// Initialize DIS Application
DISAPP_Init();
// Initialize HRS Application
HRSAPP_Init();
// Create timer to handle the connection state machine
HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(BleApplicationContext.Advertising_mgr_timer_Id), hw_ts_SingleShot, Adv_Mgr);
// Make device discoverable
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = AD_TYPE_16_BIT_SERV_UUID;
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen = 1;
Add_Advertisment_Service_UUID(HEART_RATE_SERVICE_UUID);
/* Initialize intervals for reconnexion without intervals update */
AdvIntervalMin = CFG_FAST_CONN_ADV_INTERVAL_MIN;
AdvIntervalMax = CFG_FAST_CONN_ADV_INTERVAL_MAX;
Adv_Request(APP_BLE_FAST_ADV);
return true;
}
SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
{
hci_event_pckt *event_pckt;
evt_le_meta_event *meta_evt;
evt_blue_aci *blue_evt;
hci_le_phy_update_complete_event_rp0 *evt_le_phy_update_complete;
uint8_t TX_PHY, RX_PHY;
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) pckt)->data;
switch (event_pckt->evt) {
case EVT_DISCONN_COMPLETE:
{
hci_disconnection_complete_event_rp0 *disconnection_complete_event;
disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data;
if (disconnection_complete_event->Connection_Handle == BleApplicationContext.BleApplicationContext_legacy.connectionHandle) {
BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0;
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
APP_DBG_MSG("\r\n\r** DISCONNECTION EVENT WITH CLIENT \r\n");
}
/* restart advertising */
Adv_Request(APP_BLE_FAST_ADV);
api_hal_power_insomnia_exit();
}
break; /* EVT_DISCONN_COMPLETE */
case EVT_LE_META_EVENT:
{
meta_evt = (evt_le_meta_event*) event_pckt->data;
switch (meta_evt->subevent)
{
case EVT_LE_CONN_UPDATE_COMPLETE:
APP_DBG_MSG("\r\n\r** CONNECTION UPDATE EVENT WITH CLIENT \r\n");
/* USER CODE BEGIN EVT_LE_CONN_UPDATE_COMPLETE */
/* USER CODE END EVT_LE_CONN_UPDATE_COMPLETE */
break;
case EVT_LE_PHY_UPDATE_COMPLETE:
APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE \r\n");
evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data;
if (evt_le_phy_update_complete->Status == 0)
{
APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status ok \r\n");
}
else
{
APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status nok \r\n");
}
ret = hci_le_read_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,&TX_PHY,&RX_PHY);
if (ret == BLE_STATUS_SUCCESS)
{
APP_DBG_MSG("Read_PHY success \r\n");
if ((TX_PHY == TX_2M) && (RX_PHY == RX_2M))
{
APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
}
else
{
APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
}
}
else
{
APP_DBG_MSG("Read conf not succeess \r\n");
}
break;
case EVT_LE_CONN_COMPLETE:
{
api_hal_power_insomnia_enter();
hci_le_connection_complete_event_rp0 *connection_complete_event;
/**
* The connection is done, there is no need anymore to schedule the LP ADV
*/
connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data;
HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id);
APP_DBG_MSG("EVT_LE_CONN_COMPLETE for connection handle 0x%x\r\n", connection_complete_event->Connection_Handle);
if (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_CONNECTING)
{
/* Connection as client */
BleApplicationContext.Device_Connection_Status = APP_BLE_CONNECTED_CLIENT;
}
else
{
/* Connection as server */
BleApplicationContext.Device_Connection_Status = APP_BLE_CONNECTED_SERVER;
}
BleApplicationContext.BleApplicationContext_legacy.connectionHandle = connection_complete_event->Connection_Handle;
}
break; /* HCI_EVT_LE_CONN_COMPLETE */
default:
break;
}
}
break; /* HCI_EVT_LE_META_EVENT */
case EVT_VENDOR:
blue_evt = (evt_blue_aci*) event_pckt->data;
switch (blue_evt->ecode) {
aci_gap_pairing_complete_event_rp0 *pairing_complete;
case EVT_BLUE_GAP_LIMITED_DISCOVERABLE:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_LIMITED_DISCOVERABLE \r\n");
break; /* EVT_BLUE_GAP_LIMITED_DISCOVERABLE */
case EVT_BLUE_GAP_PASS_KEY_REQUEST:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PASS_KEY_REQUEST \r\n");
aci_gap_pass_key_resp(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,123456);
APP_DBG_MSG("\r\n\r** aci_gap_pass_key_resp \r\n");
break; /* EVT_BLUE_GAP_PASS_KEY_REQUEST */
case EVT_BLUE_GAP_AUTHORIZATION_REQUEST:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_AUTHORIZATION_REQUEST \r\n");
break; /* EVT_BLUE_GAP_AUTHORIZATION_REQUEST */
case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED \r\n");
break; /* EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED */
case EVT_BLUE_GAP_BOND_LOST:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_BOND_LOST \r\n");
aci_gap_allow_rebond(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
APP_DBG_MSG("\r\n\r** Send allow rebond \r\n");
break; /* EVT_BLUE_GAP_BOND_LOST */
case EVT_BLUE_GAP_DEVICE_FOUND:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \r\n");
break; /* EVT_BLUE_GAP_DEVICE_FOUND */
case EVT_BLUE_GAP_ADDR_NOT_RESOLVED:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \r\n");
break; /* EVT_BLUE_GAP_DEVICE_FOUND */
case (EVT_BLUE_GAP_KEYPRESS_NOTIFICATION):
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_KEYPRESS_NOTIFICATION \r\n");
break; /* EVT_BLUE_GAP_KEY_PRESS_NOTIFICATION */
case (EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE):
APP_DBG_MSG("numeric_value = %ld\r\n",
((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value);
APP_DBG_MSG("Hex_value = %lx\r\n",
((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value);
aci_gap_numeric_comparison_value_confirm_yesno(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, 1); /* CONFIRM_YES = 1 */
APP_DBG_MSG("\r\n\r** aci_gap_numeric_comparison_value_confirm_yesno-->YES \r\n");
break;
case (EVT_BLUE_GAP_PAIRING_CMPLT):
{
pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data;
APP_DBG_MSG("BLE_CTRL_App_Notification: EVT_BLUE_GAP_PAIRING_CMPLT, pairing_complete->Status = %d\r\n",pairing_complete->Status);
if (pairing_complete->Status == 0) {
APP_DBG_MSG("\r\n\r** Pairing OK \r\n");
} else {
APP_DBG_MSG("\r\n\r** Pairing KO \r\n");
}
}
break;
/* USER CODE END ecode */
case EVT_BLUE_GAP_PROCEDURE_COMPLETE:
APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PROCEDURE_COMPLETE \r\n");
break;
}
break; /* EVT_VENDOR */
default:
break;
}
return (SVCCTL_UserEvtFlowEnable);
}
APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status() {
return BleApplicationContext.Device_Connection_Status;
}
/* USER CODE BEGIN FD*/
void APP_BLE_Key_Button1_Action() {
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
ret = aci_gap_clear_security_db();
if (ret == BLE_STATUS_SUCCESS) {
APP_DBG_MSG("Successfully aci_gap_clear_security_db()\r\n");
} else {
APP_DBG_MSG("aci_gap_clear_security_db() Failed , result: %d \r\n", ret);
}
}
void APP_BLE_Key_Button2_Action() {
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
ret = aci_gap_slave_security_req(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
if (ret == BLE_STATUS_SUCCESS) {
APP_DBG_MSG("Successfully aci_gap_slave_security_req()");
} else {
APP_DBG_MSG("aci_gap_slave_security_req() Failed , result: %d \r\n", ret);
}
}
void APP_BLE_Key_Button3_Action() {
uint8_t TX_PHY, RX_PHY;
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
ret = hci_le_read_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,&TX_PHY,&RX_PHY);
if (ret == BLE_STATUS_SUCCESS) {
APP_DBG_MSG("Read_PHY success \r\n");
APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
if ((TX_PHY == TX_2M) && (RX_PHY == RX_2M)) {
APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_1M, RX_1M);
ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_1M,RX_1M,0);
} else {
APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_2M_PREFERRED, RX_2M_PREFERRED);
ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_2M_PREFERRED,RX_2M_PREFERRED,0);
}
} else {
APP_DBG_MSG("Read conf not succeess \r\n");
}
if (ret == BLE_STATUS_SUCCESS) {
APP_DBG_MSG("set PHY cmd ok\r\n");
} else {
APP_DBG_MSG("set PHY cmd NOK\r\n");
}
}
static void Ble_Tl_Init( void ) {
HCI_TL_HciInitConf_t Hci_Tl_Init_Conf;
MtxHciId = osMutexNew( NULL );
SemHciId = osSemaphoreNew( 1, 0, NULL ); /*< Create the semaphore and make it busy at initialization */
Hci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&BleCmdBuffer;
Hci_Tl_Init_Conf.StatusNotCallBack = BLE_StatusNot;
hci_init(BLE_UserEvtRx, (void*) &Hci_Tl_Init_Conf);
}
static void Ble_Hci_Gap_Gatt_Init() {
uint8_t role;
uint16_t gap_service_handle, gap_dev_name_char_handle, gap_appearance_char_handle;
const uint8_t *bd_addr;
uint32_t srd_bd_addr[2];
uint16_t appearance[1] = { BLE_CFG_GAP_APPEARANCE };
/*HCI Reset to synchronise BLE Stack*/
hci_reset();
/**
* Write the BD Address
*/
bd_addr = BleGetBdAddress();
aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
CONFIG_DATA_PUBADDR_LEN,
(uint8_t*) bd_addr);
/* BLE MAC in ADV Packet */
manuf_data[ sizeof(manuf_data)-6] = bd_addr[5];
manuf_data[ sizeof(manuf_data)-5] = bd_addr[4];
manuf_data[ sizeof(manuf_data)-4] = bd_addr[3];
manuf_data[ sizeof(manuf_data)-3] = bd_addr[2];
manuf_data[ sizeof(manuf_data)-2] = bd_addr[1];
manuf_data[ sizeof(manuf_data)-1] = bd_addr[0];
/**
* Write Identity root key used to derive LTK and CSRK
*/
aci_hal_write_config_data(CONFIG_DATA_IR_OFFSET,
CONFIG_DATA_IR_LEN,
(uint8_t*) BLE_CFG_IR_VALUE);
/**
* Write Encryption root key used to derive LTK and CSRK
*/
aci_hal_write_config_data(CONFIG_DATA_ER_OFFSET,
CONFIG_DATA_ER_LEN,
(uint8_t*) BLE_CFG_ER_VALUE);
/**
* Write random bd_address
*/
/* random_bd_address = R_bd_address;
aci_hal_write_config_data(CONFIG_DATA_RANDOM_ADDRESS_WR,
CONFIG_DATA_RANDOM_ADDRESS_LEN,
(uint8_t*) random_bd_address);
*/
/**
* Static random Address
* The two upper bits shall be set to 1
* The lowest 32bits is read from the UDN to differentiate between devices
* The RNG may be used to provide a random number on each power on
*/
srd_bd_addr[1] = 0x0000ED6E;
srd_bd_addr[0] = LL_FLASH_GetUDN( );
aci_hal_write_config_data( CONFIG_DATA_RANDOM_ADDRESS_OFFSET, CONFIG_DATA_RANDOM_ADDRESS_LEN, (uint8_t*)srd_bd_addr );
/**
* Write Identity root key used to derive LTK and CSRK
*/
aci_hal_write_config_data( CONFIG_DATA_IR_OFFSET, CONFIG_DATA_IR_LEN, (uint8_t*)BLE_CFG_IR_VALUE );
/**
* Write Encryption root key used to derive LTK and CSRK
*/
aci_hal_write_config_data( CONFIG_DATA_ER_OFFSET, CONFIG_DATA_ER_LEN, (uint8_t*)BLE_CFG_ER_VALUE );
/**
* Set TX Power to 0dBm.
*/
aci_hal_set_tx_power_level(1, CFG_TX_POWER);
/**
* Initialize GATT interface
*/
aci_gatt_init();
/**
* Initialize GAP interface
*/
role = 0;
#if (BLE_CFG_PERIPHERAL == 1)
role |= GAP_PERIPHERAL_ROLE;
#endif
#if (BLE_CFG_CENTRAL == 1)
role |= GAP_CENTRAL_ROLE;
#endif
if (role > 0)
{
const char *name = "Flipper";
aci_gap_init(role, 0,
APPBLE_GAP_DEVICE_NAME_LENGTH,
&gap_service_handle, &gap_dev_name_char_handle, &gap_appearance_char_handle);
if (aci_gatt_update_char_value(gap_service_handle, gap_dev_name_char_handle, 0, strlen(name), (uint8_t *) name))
{
BLE_DBG_SVCCTL_MSG("Device Name aci_gatt_update_char_value failed.\r\n");
}
}
if(aci_gatt_update_char_value(gap_service_handle,
gap_appearance_char_handle,
0,
2,
(uint8_t *)&appearance))
{
BLE_DBG_SVCCTL_MSG("Appearance aci_gatt_update_char_value failed.\r\n");
}
/**
* Initialize Default PHY
*/
hci_le_set_default_phy(ALL_PHYS_PREFERENCE,TX_2M_PREFERRED,RX_2M_PREFERRED);
/**
* Initialize IO capability
*/
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability = CFG_IO_CAPABILITY;
aci_gap_set_io_capability(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability);
/**
* Initialize authentication
*/
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode = CFG_MITM_PROTECTION;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin = CFG_ENCRYPTION_KEY_SIZE_MIN;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax = CFG_ENCRYPTION_KEY_SIZE_MAX;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin = CFG_USED_FIXED_PIN;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin = CFG_FIXED_PIN;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode = CFG_BONDING_MODE;
aci_gap_set_authentication_requirement(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode,
CFG_SC_SUPPORT,
CFG_KEYPRESS_NOTIFICATION_SUPPORT,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin,
PUBLIC_ADDR
);
/**
* Initialize whitelist
*/
if (BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode)
{
aci_gap_configure_whitelist();
}
}
static void Adv_Request(APP_BLE_ConnStatus_t New_Status)
{
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
uint16_t Min_Inter, Max_Inter;
if (New_Status == APP_BLE_FAST_ADV)
{
Min_Inter = AdvIntervalMin;
Max_Inter = AdvIntervalMax;
}
else
{
Min_Inter = CFG_LP_CONN_ADV_INTERVAL_MIN;
Max_Inter = CFG_LP_CONN_ADV_INTERVAL_MAX;
}
/**
* Stop the timer, it will be restarted for a new shot
* It does not hurt if the timer was not running
*/
HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id);
APP_DBG_MSG("First index in %d state \r\n", BleApplicationContext.Device_Connection_Status);
if ((New_Status == APP_BLE_LP_ADV)
&& ((BleApplicationContext.Device_Connection_Status == APP_BLE_FAST_ADV)
|| (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_ADV)))
{
/* Connection in ADVERTISE mode have to stop the current advertising */
ret = aci_gap_set_non_discoverable();
if (ret == BLE_STATUS_SUCCESS)
{
APP_DBG_MSG("Successfully Stopped Advertising \r\n");
}
else
{
APP_DBG_MSG("Stop Advertising Failed , result: %d \r\n", ret);
}
}
BleApplicationContext.Device_Connection_Status = New_Status;
/* Start Fast or Low Power Advertising */
ret = aci_gap_set_discoverable(
ADV_IND,
Min_Inter,
Max_Inter,
PUBLIC_ADDR,
NO_WHITE_LIST_USE, /* use white list */
sizeof(local_name),
(uint8_t*) &local_name,
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen,
BleApplicationContext.BleApplicationContext_legacy.advtServUUID,
0,
0);
/* Update Advertising data */
ret = aci_gap_update_adv_data(sizeof(manuf_data), (uint8_t*) manuf_data);
if (ret == BLE_STATUS_SUCCESS) {
if (New_Status == APP_BLE_FAST_ADV) {
APP_DBG_MSG("Successfully Start Fast Advertising \r\n" );
/* Start Timer to STOP ADV - TIMEOUT */
HW_TS_Start(BleApplicationContext.Advertising_mgr_timer_Id, INITIAL_ADV_TIMEOUT);
} else {
APP_DBG_MSG("Successfully Start Low Power Advertising \r\n");
}
} else {
if (New_Status == APP_BLE_FAST_ADV) {
APP_DBG_MSG("Start Fast Advertising Failed , result: %d \r\n", ret);
} else {
APP_DBG_MSG("Start Low Power Advertising Failed , result: %d \r\n", ret);
}
}
}
const uint8_t* BleGetBdAddress( void ) {
uint8_t *otp_addr;
const uint8_t *bd_addr;
uint32_t udn;
uint32_t company_id;
uint32_t device_id;
udn = LL_FLASH_GetUDN();
if(udn != 0xFFFFFFFF) {
company_id = LL_FLASH_GetSTCompanyID();
device_id = LL_FLASH_GetDeviceID();
bd_addr_udn[0] = (uint8_t)(udn & 0x000000FF);
bd_addr_udn[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 );
bd_addr_udn[2] = (uint8_t)( (udn & 0x00FF0000) >> 16 );
bd_addr_udn[3] = (uint8_t)device_id;
bd_addr_udn[4] = (uint8_t)(company_id & 0x000000FF);;
bd_addr_udn[5] = (uint8_t)( (company_id & 0x0000FF00) >> 8 );
bd_addr = (const uint8_t *)bd_addr_udn;
} else {
otp_addr = OTP_Read(0);
if(otp_addr) {
bd_addr = ((OTP_ID0_t*)otp_addr)->bd_address;
} else {
bd_addr = M_bd_addr;
}
}
return bd_addr;
}
/*************************************************************
*
*SPECIFIC FUNCTIONS
*
*************************************************************/
static void Add_Advertisment_Service_UUID( uint16_t servUUID ) {
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen] =
(uint8_t) (servUUID & 0xFF);
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen++;
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen] =
(uint8_t) (servUUID >> 8) & 0xFF;
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen++;
}
static void Adv_Mgr( void ) {
/**
* The code shall be executed in the background as an aci command may be sent
* The background is the only place where the application can make sure a new aci command
* is not sent if there is a pending one
*/
osThreadFlagsSet( AdvUpdateProcessId, 1 );
}
static void AdvUpdateProcess(void *argument) {
UNUSED(argument);
for(;;) {
osThreadFlagsWait( 1, osFlagsWaitAny, osWaitForever);
Adv_Update( );
}
}
static void Adv_Update( void ) {
Adv_Request(APP_BLE_LP_ADV);
}
static void HciUserEvtProcess(void *argument) {
UNUSED(argument);
for(;;)
{
osThreadFlagsWait( 1, osFlagsWaitAny, osWaitForever);
hci_user_evt_proc( );
}
}
/*************************************************************
*
* WRAP FUNCTIONS
*
*************************************************************/
void hci_notify_asynch_evt(void* pdata) {
UNUSED(pdata);
osThreadFlagsSet( HciUserEvtProcessId, 1 );
}
void hci_cmd_resp_release(uint32_t flag) {
UNUSED(flag);
osSemaphoreRelease( SemHciId );
}
void hci_cmd_resp_wait(uint32_t timeout) {
UNUSED(timeout);
osSemaphoreAcquire( SemHciId, osWaitForever );
}
static void BLE_UserEvtRx( void * pPayload ) {
SVCCTL_UserEvtFlowStatus_t svctl_return_status;
tHCI_UserEvtRxParam *pParam;
pParam = (tHCI_UserEvtRxParam *)pPayload;
svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial));
if (svctl_return_status != SVCCTL_UserEvtFlowDisable) {
pParam->status = HCI_TL_UserEventFlow_Enable;
} else {
pParam->status = HCI_TL_UserEventFlow_Disable;
}
}
static void BLE_StatusNot( HCI_TL_CmdStatus_t status ) {
switch (status) {
case HCI_TL_CmdBusy:
osMutexAcquire( MtxHciId, osWaitForever );
break;
case HCI_TL_CmdAvailable:
osMutexRelease( MtxHciId );
break;
default:
break;
}
}
void SVCCTL_ResumeUserEventFlow( void ) {
hci_resume_flow();
}

Some files were not shown because too many files have changed in this diff Show More