From 80739929255ff1861eef82600f216c76c1064a08 Mon Sep 17 00:00:00 2001 From: SG Date: Fri, 10 Sep 2021 12:19:02 +1000 Subject: [PATCH] [FL-1587] RFID: Clock for emulation timer from antenna (#622) * RFID: pull antenna down when emulating * Rfid: fixed HID emulation by adding zero pulse every 4 bits * Rfid: HID emulation fixed with DSP based FSK oscillator. * Rfid: receive 125KHz clock for emulation timer from antenna and comparator * Rfid: commented unused variable * Firmware: rollback changes in f6. * Add F7 target based on F6. * F7/F6: update cube projects, apply changes to the targets, update linker scripts with correct RAM start values. * FuriHal: RFID init routine. * Scripts: update OTP tool for v11 board Co-authored-by: Aleksandr Kutuzov --- .github/workflows/build.yml | 2 +- .github/workflows/lint_c.yml | 2 +- .../targets/f7/furi-hal/furi-hal-gpio.c | 189 +++ .../targets/f7/furi-hal/furi-hal-gpio.h | 264 ++++ bootloader/targets/f7/furi-hal/furi-hal-i2c.c | 137 +++ bootloader/targets/f7/furi-hal/furi-hal-i2c.h | 43 + .../targets/f7/furi-hal/furi-hal-light.c | 43 + .../targets/f7/furi-hal/furi-hal-light.h | 17 + .../targets/f7/furi-hal/furi-hal-resources.c | 41 + .../targets/f7/furi-hal/furi-hal-resources.h | 82 ++ .../targets/f7/furi-hal/furi-hal-spi-config.c | 114 ++ .../targets/f7/furi-hal/furi-hal-spi-config.h | 61 + bootloader/targets/f7/furi-hal/furi-hal-spi.c | 240 ++++ bootloader/targets/f7/furi-hal/furi-hal-spi.h | 129 ++ bootloader/targets/f7/furi-hal/furi-hal.c | 7 + bootloader/targets/f7/furi-hal/furi-hal.h | 8 + bootloader/targets/f7/furi-hal/main.h | 108 ++ .../targets/f7/furi-hal/u8g2_periphery.c | 69 ++ .../targets/f7/stm32wb55xx_flash_cm4.ld | 187 +++ bootloader/targets/f7/target.c | 264 ++++ bootloader/targets/f7/target.mk | 48 + firmware/targets/f6/Inc/FreeRTOSConfig.h | 8 + firmware/targets/f6/cube/Inc/FreeRTOSConfig.h | 20 +- firmware/targets/f6/cube/Inc/main.h | 38 +- firmware/targets/f6/cube/Inc/usbd_cdc_if.h | 3 +- firmware/targets/f6/cube/Makefile | 126 +- firmware/targets/f6/cube/Src/adc.c | 11 + firmware/targets/f6/cube/Src/aes.c | 20 + firmware/targets/f6/cube/Src/comp.c | 10 + firmware/targets/f6/cube/Src/crc.c | 10 + firmware/targets/f6/cube/Src/i2c.c | 11 + firmware/targets/f6/cube/Src/main.c | 8 +- firmware/targets/f6/cube/Src/pka.c | 10 + firmware/targets/f6/cube/Src/rf.c | 11 + firmware/targets/f6/cube/Src/rng.c | 11 + firmware/targets/f6/cube/Src/rtc.c | 11 + firmware/targets/f6/cube/Src/spi.c | 20 + .../targets/f6/cube/Src/system_stm32wbxx.c | 725 +++++------ firmware/targets/f6/cube/Src/tim.c | 33 + firmware/targets/f6/cube/Src/usart.c | 13 +- firmware/targets/f6/cube/Src/usbd_cdc_if.c | 2 +- firmware/targets/f6/cube/Src/usbd_conf.c | 6 +- firmware/targets/f6/cube/Src/usbd_desc.c | 2 +- firmware/targets/f6/cube/f6.ioc | 23 +- .../targets/f6/cube/startup_stm32wb55xx_cm4.s | 889 +++++++------- .../targets/f6/cube/stm32wb55xx_flash_cm4.ld | 2 +- firmware/targets/f6/furi-hal/furi-hal-clock.c | 1 + firmware/targets/f6/furi-hal/furi-hal-rfid.c | 4 + firmware/targets/f6/furi-hal/furi-hal.c | 1 + .../targets/f6/stm32wb55xx_flash_cm4_boot.ld | 2 +- .../f6/stm32wb55xx_flash_cm4_no_boot.ld | 2 +- firmware/targets/f7/Inc/FreeRTOSConfig.h | 180 +++ firmware/targets/f7/Inc/aes.h | 54 + firmware/targets/f7/Inc/comp.h | 52 + firmware/targets/f7/Inc/gpio.h | 49 + firmware/targets/f7/Inc/main.h | 149 +++ firmware/targets/f7/Inc/pka.h | 52 + firmware/targets/f7/Inc/rf.h | 50 + firmware/targets/f7/Inc/rng.h | 52 + firmware/targets/f7/Inc/rtc.h | 52 + firmware/targets/f7/Inc/stm32wbxx_hal_conf.h | 353 ++++++ firmware/targets/f7/Inc/stm32wbxx_it.h | 69 ++ firmware/targets/f7/Inc/tim.h | 58 + firmware/targets/f7/Src/aes.c | 127 ++ firmware/targets/f7/Src/comp.c | 103 ++ firmware/targets/f7/Src/fatfs/fatfs.c | 56 + firmware/targets/f7/Src/fatfs/fatfs.h | 49 + firmware/targets/f7/Src/fatfs/ffconf.h | 270 +++++ firmware/targets/f7/Src/fatfs/spi_sd_hal.c | 100 ++ .../targets/f7/Src/fatfs/stm32_adafruit_sd.c | 1073 +++++++++++++++++ .../targets/f7/Src/fatfs/stm32_adafruit_sd.h | 252 ++++ firmware/targets/f7/Src/fatfs/syscall.c | 138 +++ firmware/targets/f7/Src/fatfs/user_diskio.c | 223 ++++ firmware/targets/f7/Src/fatfs/user_diskio.h | 48 + firmware/targets/f7/Src/freertos-openocd.c | 21 + firmware/targets/f7/Src/gpio.c | 139 +++ firmware/targets/f7/Src/main.c | 55 + firmware/targets/f7/Src/pka.c | 77 ++ firmware/targets/f7/Src/rf.c | 37 + firmware/targets/f7/Src/rng.c | 77 ++ firmware/targets/f7/Src/rtc.c | 123 ++ firmware/targets/f7/Src/stm32wbxx_hal_msp.c | 93 ++ firmware/targets/f7/Src/stm32wbxx_it.c | 52 + firmware/targets/f7/Src/system_stm32wbxx.c | 357 ++++++ firmware/targets/f7/Src/tim.c | 361 ++++++ firmware/targets/f7/ble-glue/app_ble.c | 776 ++++++++++++ firmware/targets/f7/ble-glue/app_ble.h | 27 + firmware/targets/f7/ble-glue/app_common.h | 43 + firmware/targets/f7/ble-glue/app_conf.h | 474 ++++++++ firmware/targets/f7/ble-glue/app_entry.c | 192 +++ firmware/targets/f7/ble-glue/app_entry.h | 20 + .../targets/f7/ble-glue/battery_service.c | 55 + .../targets/f7/ble-glue/battery_service.h | 16 + firmware/targets/f7/ble-glue/ble_conf.h | 69 ++ firmware/targets/f7/ble-glue/ble_dbg_conf.h | 199 +++ .../targets/f7/ble-glue/dev_info_service.c | 121 ++ .../targets/f7/ble-glue/dev_info_service.h | 20 + firmware/targets/f7/ble-glue/hw_conf.h | 199 +++ firmware/targets/f7/ble-glue/hw_if.h | 250 ++++ firmware/targets/f7/ble-glue/hw_ipcc.c | 675 +++++++++++ firmware/targets/f7/ble-glue/hw_timerserver.c | 893 ++++++++++++++ firmware/targets/f7/ble-glue/serial_service.c | 102 ++ firmware/targets/f7/ble-glue/serial_service.h | 22 + firmware/targets/f7/ble-glue/tl_dbg_conf.h | 136 +++ firmware/targets/f7/ble-glue/utilities_conf.h | 68 ++ firmware/targets/f7/cube/Inc/FreeRTOSConfig.h | 186 +++ firmware/targets/f7/cube/Inc/adc.h | 52 + firmware/targets/f7/cube/Inc/aes.h | 54 + firmware/targets/f7/cube/Inc/comp.h | 52 + firmware/targets/f7/cube/Inc/crc.h | 52 + firmware/targets/f7/cube/Inc/gpio.h | 49 + firmware/targets/f7/cube/Inc/i2c.h | 50 + firmware/targets/f7/cube/Inc/main.h | 175 +++ firmware/targets/f7/cube/Inc/pka.h | 52 + firmware/targets/f7/cube/Inc/rf.h | 50 + firmware/targets/f7/cube/Inc/rng.h | 52 + firmware/targets/f7/cube/Inc/rtc.h | 52 + firmware/targets/f7/cube/Inc/spi.h | 54 + firmware/targets/f7/cube/Inc/stm32_assert.h | 53 + .../targets/f7/cube/Inc/stm32wbxx_hal_conf.h | 353 ++++++ firmware/targets/f7/cube/Inc/stm32wbxx_it.h | 77 ++ firmware/targets/f7/cube/Inc/tim.h | 58 + firmware/targets/f7/cube/Inc/usart.h | 50 + firmware/targets/f7/cube/Inc/usb_device.h | 105 ++ firmware/targets/f7/cube/Inc/usbd_cdc_if.h | 133 ++ firmware/targets/f7/cube/Inc/usbd_conf.h | 176 +++ firmware/targets/f7/cube/Inc/usbd_desc.h | 145 +++ firmware/targets/f7/cube/Makefile | 253 ++++ firmware/targets/f7/cube/Src/adc.c | 139 +++ firmware/targets/f7/cube/Src/aes.c | 147 +++ firmware/targets/f7/cube/Src/app_freertos.c | 183 +++ firmware/targets/f7/cube/Src/comp.c | 113 ++ firmware/targets/f7/cube/Src/crc.c | 92 ++ firmware/targets/f7/cube/Src/gpio.c | 181 +++ firmware/targets/f7/cube/Src/i2c.c | 83 ++ firmware/targets/f7/cube/Src/main.c | 290 +++++ firmware/targets/f7/cube/Src/pka.c | 87 ++ firmware/targets/f7/cube/Src/rf.c | 48 + firmware/targets/f7/cube/Src/rng.c | 88 ++ firmware/targets/f7/cube/Src/rtc.c | 134 ++ firmware/targets/f7/cube/Src/spi.c | 232 ++++ .../targets/f7/cube/Src/stm32wbxx_hal_msp.c | 93 ++ firmware/targets/f7/cube/Src/stm32wbxx_it.c | 326 +++++ .../targets/f7/cube/Src/system_stm32wbxx.c | 368 ++++++ firmware/targets/f7/cube/Src/tim.c | 394 ++++++ firmware/targets/f7/cube/Src/usart.c | 95 ++ firmware/targets/f7/cube/Src/usb_device.c | 99 ++ firmware/targets/f7/cube/Src/usbd_cdc_if.c | 331 +++++ firmware/targets/f7/cube/Src/usbd_conf.c | 810 +++++++++++++ firmware/targets/f7/cube/Src/usbd_desc.c | 396 ++++++ firmware/targets/f7/cube/f7.ioc | 598 +++++++++ .../targets/f7/cube/startup_stm32wb55xx_cm4.s | 444 +++++++ .../targets/f7/cube/stm32wb55xx_flash_cm4.ld | 187 +++ firmware/targets/f7/furi-hal/furi-hal-boot.c | 31 + firmware/targets/f7/furi-hal/furi-hal-bt.c | 144 +++ firmware/targets/f7/furi-hal/furi-hal-clock.c | 141 +++ firmware/targets/f7/furi-hal/furi-hal-clock.h | 10 + .../targets/f7/furi-hal/furi-hal-console.c | 73 ++ .../targets/f7/furi-hal/furi-hal-console.h | 26 + firmware/targets/f7/furi-hal/furi-hal-delay.c | 34 + firmware/targets/f7/furi-hal/furi-hal-flash.c | 89 ++ firmware/targets/f7/furi-hal/furi-hal-flash.h | 74 ++ firmware/targets/f7/furi-hal/furi-hal-gpio.c | 299 +++++ firmware/targets/f7/furi-hal/furi-hal-gpio.h | 264 ++++ firmware/targets/f7/furi-hal/furi-hal-i2c.c | 152 +++ .../targets/f7/furi-hal/furi-hal-ibutton.c | 24 + .../targets/f7/furi-hal/furi-hal-interrupt.c | 208 ++++ .../targets/f7/furi-hal/furi-hal-interrupt.h | 34 + firmware/targets/f7/furi-hal/furi-hal-irda.c | 639 ++++++++++ firmware/targets/f7/furi-hal/furi-hal-light.c | 44 + firmware/targets/f7/furi-hal/furi-hal-nfc.c | 174 +++ .../targets/f7/furi-hal/furi-hal-os-timer.h | 64 + firmware/targets/f7/furi-hal/furi-hal-os.c | 143 +++ firmware/targets/f7/furi-hal/furi-hal-os.h | 17 + firmware/targets/f7/furi-hal/furi-hal-power.c | 280 +++++ firmware/targets/f7/furi-hal/furi-hal-pwm.c | 50 + firmware/targets/f7/furi-hal/furi-hal-pwm.h | 16 + .../targets/f7/furi-hal/furi-hal-resources.c | 57 + .../targets/f7/furi-hal/furi-hal-resources.h | 105 ++ firmware/targets/f7/furi-hal/furi-hal-rfid.c | 297 +++++ firmware/targets/f7/furi-hal/furi-hal-sd.c | 22 + .../targets/f7/furi-hal/furi-hal-spi-config.c | 103 ++ .../targets/f7/furi-hal/furi-hal-spi-config.h | 63 + firmware/targets/f7/furi-hal/furi-hal-spi.c | 200 +++ firmware/targets/f7/furi-hal/furi-hal-spi.h | 108 ++ .../targets/f7/furi-hal/furi-hal-subghz.c | 714 +++++++++++ firmware/targets/f7/furi-hal/furi-hal-task.c | 54 + firmware/targets/f7/furi-hal/furi-hal-task.h | 12 + firmware/targets/f7/furi-hal/furi-hal-vcp.c | 128 ++ firmware/targets/f7/furi-hal/furi-hal-vcp_i.h | 13 + .../targets/f7/furi-hal/furi-hal-version.c | 242 ++++ firmware/targets/f7/furi-hal/furi-hal-vibro.c | 13 + firmware/targets/f7/furi-hal/furi-hal.c | 65 + firmware/targets/f7/startup_stm32wb55xx_cm4.s | 444 +++++++ .../targets/f7/stm32wb55xx_flash_cm4_boot.ld | 192 +++ .../f7/stm32wb55xx_flash_cm4_no_boot.ld | 192 +++ firmware/targets/f7/target.mk | 169 +++ firmware/targets/f7/usb-glue/usb_device.c | 34 + firmware/targets/f7/usb-glue/usb_device.h | 11 + firmware/targets/f7/usb-glue/usbd_cdc_if.c | 142 +++ firmware/targets/f7/usb-glue/usbd_cdc_if.h | 22 + firmware/targets/f7/usb-glue/usbd_conf.c | 506 ++++++++ firmware/targets/f7/usb-glue/usbd_conf.h | 73 ++ firmware/targets/f7/usb-glue/usbd_desc.c | 206 ++++ firmware/targets/f7/usb-glue/usbd_desc.h | 19 + .../targets/furi-hal-include/furi-hal-rfid.h | 3 + scripts/otp.py | 8 +- 207 files changed, 28052 insertions(+), 932 deletions(-) create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-gpio.c create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-gpio.h create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-i2c.c create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-i2c.h create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-light.c create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-light.h create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-resources.c create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-resources.h create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-spi-config.c create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-spi-config.h create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-spi.c create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-spi.h create mode 100644 bootloader/targets/f7/furi-hal/furi-hal.c create mode 100644 bootloader/targets/f7/furi-hal/furi-hal.h create mode 100644 bootloader/targets/f7/furi-hal/main.h create mode 100644 bootloader/targets/f7/furi-hal/u8g2_periphery.c create mode 100644 bootloader/targets/f7/stm32wb55xx_flash_cm4.ld create mode 100644 bootloader/targets/f7/target.c create mode 100644 bootloader/targets/f7/target.mk create mode 100644 firmware/targets/f7/Inc/FreeRTOSConfig.h create mode 100644 firmware/targets/f7/Inc/aes.h create mode 100644 firmware/targets/f7/Inc/comp.h create mode 100644 firmware/targets/f7/Inc/gpio.h create mode 100644 firmware/targets/f7/Inc/main.h create mode 100644 firmware/targets/f7/Inc/pka.h create mode 100644 firmware/targets/f7/Inc/rf.h create mode 100644 firmware/targets/f7/Inc/rng.h create mode 100644 firmware/targets/f7/Inc/rtc.h create mode 100644 firmware/targets/f7/Inc/stm32wbxx_hal_conf.h create mode 100644 firmware/targets/f7/Inc/stm32wbxx_it.h create mode 100644 firmware/targets/f7/Inc/tim.h create mode 100644 firmware/targets/f7/Src/aes.c create mode 100644 firmware/targets/f7/Src/comp.c create mode 100644 firmware/targets/f7/Src/fatfs/fatfs.c create mode 100644 firmware/targets/f7/Src/fatfs/fatfs.h create mode 100644 firmware/targets/f7/Src/fatfs/ffconf.h create mode 100644 firmware/targets/f7/Src/fatfs/spi_sd_hal.c create mode 100644 firmware/targets/f7/Src/fatfs/stm32_adafruit_sd.c create mode 100644 firmware/targets/f7/Src/fatfs/stm32_adafruit_sd.h create mode 100644 firmware/targets/f7/Src/fatfs/syscall.c create mode 100644 firmware/targets/f7/Src/fatfs/user_diskio.c create mode 100644 firmware/targets/f7/Src/fatfs/user_diskio.h create mode 100644 firmware/targets/f7/Src/freertos-openocd.c create mode 100644 firmware/targets/f7/Src/gpio.c create mode 100644 firmware/targets/f7/Src/main.c create mode 100644 firmware/targets/f7/Src/pka.c create mode 100644 firmware/targets/f7/Src/rf.c create mode 100644 firmware/targets/f7/Src/rng.c create mode 100644 firmware/targets/f7/Src/rtc.c create mode 100644 firmware/targets/f7/Src/stm32wbxx_hal_msp.c create mode 100644 firmware/targets/f7/Src/stm32wbxx_it.c create mode 100644 firmware/targets/f7/Src/system_stm32wbxx.c create mode 100644 firmware/targets/f7/Src/tim.c create mode 100644 firmware/targets/f7/ble-glue/app_ble.c create mode 100644 firmware/targets/f7/ble-glue/app_ble.h create mode 100644 firmware/targets/f7/ble-glue/app_common.h create mode 100644 firmware/targets/f7/ble-glue/app_conf.h create mode 100644 firmware/targets/f7/ble-glue/app_entry.c create mode 100644 firmware/targets/f7/ble-glue/app_entry.h create mode 100644 firmware/targets/f7/ble-glue/battery_service.c create mode 100644 firmware/targets/f7/ble-glue/battery_service.h create mode 100644 firmware/targets/f7/ble-glue/ble_conf.h create mode 100644 firmware/targets/f7/ble-glue/ble_dbg_conf.h create mode 100644 firmware/targets/f7/ble-glue/dev_info_service.c create mode 100644 firmware/targets/f7/ble-glue/dev_info_service.h create mode 100644 firmware/targets/f7/ble-glue/hw_conf.h create mode 100644 firmware/targets/f7/ble-glue/hw_if.h create mode 100644 firmware/targets/f7/ble-glue/hw_ipcc.c create mode 100644 firmware/targets/f7/ble-glue/hw_timerserver.c create mode 100644 firmware/targets/f7/ble-glue/serial_service.c create mode 100644 firmware/targets/f7/ble-glue/serial_service.h create mode 100644 firmware/targets/f7/ble-glue/tl_dbg_conf.h create mode 100644 firmware/targets/f7/ble-glue/utilities_conf.h create mode 100644 firmware/targets/f7/cube/Inc/FreeRTOSConfig.h create mode 100644 firmware/targets/f7/cube/Inc/adc.h create mode 100644 firmware/targets/f7/cube/Inc/aes.h create mode 100644 firmware/targets/f7/cube/Inc/comp.h create mode 100644 firmware/targets/f7/cube/Inc/crc.h create mode 100644 firmware/targets/f7/cube/Inc/gpio.h create mode 100644 firmware/targets/f7/cube/Inc/i2c.h create mode 100644 firmware/targets/f7/cube/Inc/main.h create mode 100644 firmware/targets/f7/cube/Inc/pka.h create mode 100644 firmware/targets/f7/cube/Inc/rf.h create mode 100644 firmware/targets/f7/cube/Inc/rng.h create mode 100644 firmware/targets/f7/cube/Inc/rtc.h create mode 100644 firmware/targets/f7/cube/Inc/spi.h create mode 100644 firmware/targets/f7/cube/Inc/stm32_assert.h create mode 100644 firmware/targets/f7/cube/Inc/stm32wbxx_hal_conf.h create mode 100644 firmware/targets/f7/cube/Inc/stm32wbxx_it.h create mode 100644 firmware/targets/f7/cube/Inc/tim.h create mode 100644 firmware/targets/f7/cube/Inc/usart.h create mode 100644 firmware/targets/f7/cube/Inc/usb_device.h create mode 100644 firmware/targets/f7/cube/Inc/usbd_cdc_if.h create mode 100644 firmware/targets/f7/cube/Inc/usbd_conf.h create mode 100644 firmware/targets/f7/cube/Inc/usbd_desc.h create mode 100644 firmware/targets/f7/cube/Makefile create mode 100644 firmware/targets/f7/cube/Src/adc.c create mode 100644 firmware/targets/f7/cube/Src/aes.c create mode 100644 firmware/targets/f7/cube/Src/app_freertos.c create mode 100644 firmware/targets/f7/cube/Src/comp.c create mode 100644 firmware/targets/f7/cube/Src/crc.c create mode 100644 firmware/targets/f7/cube/Src/gpio.c create mode 100644 firmware/targets/f7/cube/Src/i2c.c create mode 100644 firmware/targets/f7/cube/Src/main.c create mode 100644 firmware/targets/f7/cube/Src/pka.c create mode 100644 firmware/targets/f7/cube/Src/rf.c create mode 100644 firmware/targets/f7/cube/Src/rng.c create mode 100644 firmware/targets/f7/cube/Src/rtc.c create mode 100644 firmware/targets/f7/cube/Src/spi.c create mode 100644 firmware/targets/f7/cube/Src/stm32wbxx_hal_msp.c create mode 100644 firmware/targets/f7/cube/Src/stm32wbxx_it.c create mode 100644 firmware/targets/f7/cube/Src/system_stm32wbxx.c create mode 100644 firmware/targets/f7/cube/Src/tim.c create mode 100644 firmware/targets/f7/cube/Src/usart.c create mode 100644 firmware/targets/f7/cube/Src/usb_device.c create mode 100644 firmware/targets/f7/cube/Src/usbd_cdc_if.c create mode 100644 firmware/targets/f7/cube/Src/usbd_conf.c create mode 100644 firmware/targets/f7/cube/Src/usbd_desc.c create mode 100644 firmware/targets/f7/cube/f7.ioc create mode 100644 firmware/targets/f7/cube/startup_stm32wb55xx_cm4.s create mode 100644 firmware/targets/f7/cube/stm32wb55xx_flash_cm4.ld create mode 100644 firmware/targets/f7/furi-hal/furi-hal-boot.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-bt.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-clock.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-clock.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-console.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-console.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-delay.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-flash.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-flash.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-gpio.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-gpio.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-i2c.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-ibutton.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-interrupt.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-interrupt.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-irda.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-light.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-nfc.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-os-timer.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-os.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-os.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-power.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-pwm.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-pwm.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-resources.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-resources.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-rfid.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-sd.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-spi-config.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-spi-config.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-spi.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-spi.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-subghz.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-task.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-task.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-vcp.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-vcp_i.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-version.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-vibro.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal.c create mode 100644 firmware/targets/f7/startup_stm32wb55xx_cm4.s create mode 100644 firmware/targets/f7/stm32wb55xx_flash_cm4_boot.ld create mode 100644 firmware/targets/f7/stm32wb55xx_flash_cm4_no_boot.ld create mode 100644 firmware/targets/f7/target.mk create mode 100644 firmware/targets/f7/usb-glue/usb_device.c create mode 100644 firmware/targets/f7/usb-glue/usb_device.h create mode 100644 firmware/targets/f7/usb-glue/usbd_cdc_if.c create mode 100644 firmware/targets/f7/usb-glue/usbd_cdc_if.h create mode 100644 firmware/targets/f7/usb-glue/usbd_conf.c create mode 100644 firmware/targets/f7/usb-glue/usbd_conf.h create mode 100644 firmware/targets/f7/usb-glue/usbd_desc.c create mode 100644 firmware/targets/f7/usb-glue/usbd_desc.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 765da29a..722c7711 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ on: pull_request: env: - TARGETS: f6 + TARGETS: f6 f7 jobs: build: diff --git a/.github/workflows/lint_c.yml b/.github/workflows/lint_c.yml index 7d4942a2..1fa47e5a 100644 --- a/.github/workflows/lint_c.yml +++ b/.github/workflows/lint_c.yml @@ -10,7 +10,7 @@ on: pull_request: env: - TARGETS: f6 + TARGETS: f6 f7 jobs: lint_c_cpp: diff --git a/bootloader/targets/f7/furi-hal/furi-hal-gpio.c b/bootloader/targets/f7/furi-hal/furi-hal-gpio.c new file mode 100644 index 00000000..ec926d77 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-gpio.c @@ -0,0 +1,189 @@ +#include +#include +#include + +#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_simple(const GpioPin* gpio, const GpioMode mode) { + hal_gpio_init(gpio, mode, GpioPullNo, GpioSpeedLow); +} + +void hal_gpio_init( + const GpioPin* gpio, + const GpioMode mode, + const GpioPull pull, + const GpioSpeed speed) { + // we cannot set alternate mode in this function + assert(mode != GpioModeAltFunctionPushPull); + assert(mode != GpioModeAltFunctionOpenDrain); + + hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused); +} + +void hal_gpio_init_ex( + const GpioPin* gpio, + const GpioMode mode, + const GpioPull pull, + const GpioSpeed speed, + const GpioAltFn alt_fn) { + 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); + } + } + + if(mode == GpioModeAltFunctionPushPull || mode == GpioModeAltFunctionOpenDrain) { + // 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) { + assert(gpio); + 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) { + 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) { + 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) { + 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(); +} diff --git a/bootloader/targets/f7/furi-hal/furi-hal-gpio.h b/bootloader/targets/f7/furi-hal/furi-hal-gpio.h new file mode 100644 index 00000000..a81afb39 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-gpio.h @@ -0,0 +1,264 @@ +#pragma once +#include "main.h" +#include "stdbool.h" +#include +#include +#include + +#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 */ + + GpioAltFnUnused = 16, /*!< just dummy value */ +} GpioAltFn; + +/** + * Gpio structure + */ +typedef struct { + GPIO_TypeDef* port; + uint16_t pin; +} GpioPin; + +/** + * GPIO initialization function, simple version + * @param gpio GpioPin + * @param mode GpioMode + */ +void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); + +/** + * GPIO initialization function, normal version + * @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 function, extended version + * @param gpio GpioPin + * @param mode GpioMode + * @param pull GpioPull + * @param speed GpioSpeed + * @param alt_fn GpioAltFn + */ +void hal_gpio_init_ex( + 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 diff --git a/bootloader/targets/f7/furi-hal/furi-hal-i2c.c b/bootloader/targets/f7/furi-hal/furi-hal-i2c.c new file mode 100644 index 00000000..c40a70af --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-i2c.c @@ -0,0 +1,137 @@ +#include + +#include +#include +#include +#include +#include + +void furi_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 furi_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 furi_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 furi_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(furi_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && + furi_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { + return true; + } else { + return false; + } +} diff --git a/bootloader/targets/f7/furi-hal/furi-hal-i2c.h b/bootloader/targets/f7/furi-hal/furi-hal-i2c.h new file mode 100644 index 00000000..5db562e0 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-i2c.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void furi_hal_i2c_init(); + +bool furi_hal_i2c_tx( + I2C_TypeDef* instance, + const uint8_t address, + const uint8_t* data, + const uint8_t size, + uint32_t timeout); + +bool furi_hal_i2c_rx( + I2C_TypeDef* instance, + const uint8_t address, + uint8_t* data, + const uint8_t size, + uint32_t timeout); + +bool furi_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_furi_hal_i2c(type, pointer, function_body) \ + { \ + *pointer = ({ type __fn__ function_body __fn__; })(); \ + } + +#ifdef __cplusplus +} +#endif diff --git a/bootloader/targets/f7/furi-hal/furi-hal-light.c b/bootloader/targets/f7/furi-hal/furi-hal-light.c new file mode 100644 index 00000000..d5f54f6d --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-light.c @@ -0,0 +1,43 @@ +#include +#include + +#define LED_CURRENT_RED 50 +#define LED_CURRENT_GREEN 50 +#define LED_CURRENT_BLUE 50 +#define LED_CURRENT_WHITE 150 + +void furi_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 furi_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; + } +} \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal-light.h b/bootloader/targets/f7/furi-hal/furi-hal-light.h new file mode 100644 index 00000000..de976103 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-light.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void furi_hal_light_init(); + +void furi_hal_light_set(Light light, uint8_t value); + +#ifdef __cplusplus +} +#endif diff --git a/bootloader/targets/f7/furi-hal/furi-hal-resources.c b/bootloader/targets/f7/furi-hal/furi-hal-resources.c new file mode 100644 index 00000000..1260a485 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-resources.c @@ -0,0 +1,41 @@ +#include "furi-hal-resources.h" +#include "main.h" + +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 = LL_GPIO_PIN_0}; +const GpioPin gpio_ext_pc1 = {.port = GPIOC, .pin = LL_GPIO_PIN_1}; +const GpioPin gpio_ext_pc3 = {.port = GPIOC, .pin = LL_GPIO_PIN_3}; +const GpioPin gpio_ext_pb2 = {.port = GPIOB, .pin = LL_GPIO_PIN_2}; +const GpioPin gpio_ext_pb3 = {.port = GPIOB, .pin = LL_GPIO_PIN_3}; +const GpioPin gpio_ext_pa4 = {.port = GPIOA, .pin = LL_GPIO_PIN_4}; +const GpioPin gpio_ext_pa6 = {.port = GPIOA, .pin = LL_GPIO_PIN_6}; +const GpioPin gpio_ext_pa7 = {.port = GPIOA, .pin = LL_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}; + +const GpioPin gpio_irda_rx = {.port = IR_RX_GPIO_Port, .pin = IR_RX_Pin}; +const GpioPin gpio_irda_tx = {.port = IR_TX_GPIO_Port, .pin = IR_TX_Pin}; + +const GpioPin gpio_usart_tx = {.port = USART1_TX_Port, .pin = USART1_TX_Pin}; +const GpioPin gpio_usart_rx = {.port = USART1_RX_Port, .pin = USART1_RX_Pin}; diff --git a/bootloader/targets/f7/furi-hal/furi-hal-resources.h b/bootloader/targets/f7/furi-hal/furi-hal-resources.h new file mode 100644 index 00000000..95bb4d0d --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-resources.h @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include + +#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; + +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; + +extern const GpioPin gpio_irda_rx; +extern const GpioPin gpio_irda_tx; + +extern const GpioPin gpio_usart_tx; +extern const GpioPin gpio_usart_rx; + +#ifdef __cplusplus +} +#endif diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c new file mode 100644 index 00000000..00b06a4f --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c @@ -0,0 +1,114 @@ +#include +#include + +#define SPI_R SPI1 +#define SPI_D SPI2 + +const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_2EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const LL_SPI_InitTypeDef furi_hal_spi_config_display = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV16, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +/** + * SD Card in fast mode (after init) + */ +const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +/** + * SD Card in slow mode (before init) + */ +const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const FuriHalSpiBus spi_r = { + .spi = SPI_R, + .miso = &gpio_spi_r_miso, + .mosi = &gpio_spi_r_mosi, + .clk = &gpio_spi_r_sck, +}; + +const FuriHalSpiBus spi_d = { + .spi = SPI_D, + .miso = &gpio_spi_d_miso, + .mosi = &gpio_spi_d_mosi, + .clk = &gpio_spi_d_sck, +}; + +const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { + { + .bus = &spi_r, + .config = &furi_hal_spi_config_subghz, + .chip_select = &gpio_subghz_cs, + }, + { + .bus = &spi_d, + .config = &furi_hal_spi_config_display, + .chip_select = &gpio_display_cs, + }, + { + .bus = &spi_d, + .config = &furi_hal_spi_config_sd_fast, + .chip_select = &gpio_sdcard_cs, + }, + { + .bus = &spi_d, + .config = &furi_hal_spi_config_sd_slow, + .chip_select = &gpio_sdcard_cs, + }, + {.bus = &spi_r, .config = &furi_hal_spi_config_nfc, .chip_select = &gpio_nfc_cs}, +}; diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h new file mode 100644 index 00000000..dea1cd65 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; + +/** FURI HAL SPI BUS handler + * Structure content may change at some point + */ +typedef struct { + const SPI_TypeDef* spi; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* clk; +} FuriHalSpiBus; + +/** FURI HAL SPI Device handler + * Structure content may change at some point + */ +typedef struct { + const FuriHalSpiBus* bus; + const LL_SPI_InitTypeDef* config; + const GpioPin* chip_select; +} FuriHalSpiDevice; + +/** FURI HAL SPI Standard Device IDs */ +typedef enum { + FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ + FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ + FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ + FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ + FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ + + FuriHalSpiDeviceIdMax, /** Service Value, do not use */ +} FuriHalSpiDeviceId; + +/** Furi Hal Spi Bus R + * CC1101, Nfc + */ +extern const FuriHalSpiBus spi_r; + +/** Furi Hal Spi Bus D + * Display, SdCard + */ +extern const FuriHalSpiBus spi_d; + +/** Furi Hal Spi devices */ +extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi.c b/bootloader/targets/f7/furi-hal/furi-hal-spi.c new file mode 100644 index 00000000..e36e9230 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi.c @@ -0,0 +1,240 @@ +#include "furi-hal-spi.h" +#include "furi-hal-resources.h" + +#include +#include + +#include +#include +#include + +extern void Enable_SPI(SPI_TypeDef* spi); + +void furi_hal_spi_init() { + for(size_t i = 0; i < FuriHalSpiDeviceIdMax; ++i) { + hal_gpio_write(furi_hal_spi_devices[i].chip_select, true); + hal_gpio_init( + furi_hal_spi_devices[i].chip_select, + GpioModeOutputPushPull, + GpioPullNo, + GpioSpeedVeryHigh); + } + + hal_gpio_init_ex( + &gpio_spi_r_miso, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + hal_gpio_init_ex( + &gpio_spi_r_mosi, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + hal_gpio_init_ex( + &gpio_spi_r_sck, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + + hal_gpio_init_ex( + &gpio_spi_d_miso, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + hal_gpio_init_ex( + &gpio_spi_d_mosi, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + hal_gpio_init_ex( + &gpio_spi_d_sck, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); +} + +void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) { + assert(bus); +} + +void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { + assert(bus); +} + +void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { + assert(bus); + LL_SPI_DeInit((SPI_TypeDef*)bus->spi); + LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config); + LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable((SPI_TypeDef*)bus->spi); +} + +void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_TX_FIFO_EMPTY) + ; + while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef*)bus->spi)) + ; + while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { + LL_SPI_ReceiveData8((SPI_TypeDef*)bus->spi); + } +} + +bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + assert(bus); + assert(buffer); + assert(size > 0); + + return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout); +} + +bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + assert(bus); + assert(buffer); + assert(size > 0); + bool ret = true; + + while(size > 0) { + if(LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi)) { + LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *buffer); + buffer++; + size--; + } + } + + furi_hal_spi_bus_end_txrx(bus, timeout); + LL_SPI_ClearFlag_OVR((SPI_TypeDef*)bus->spi); + + return ret; +} + +bool furi_hal_spi_bus_trx( + const FuriHalSpiBus* bus, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout) { + assert(bus); + assert(tx_buffer); + assert(rx_buffer); + assert(size > 0); + bool ret = true; + size_t tx_size = size; + bool tx_allowed = true; + + while(size > 0) { + if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi) && tx_allowed) { + LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *tx_buffer); + tx_buffer++; + tx_size--; + tx_allowed = false; + } + + if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef*)bus->spi)) { + *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef*)bus->spi); + rx_buffer++; + size--; + tx_allowed = true; + } + } + + furi_hal_spi_bus_end_txrx(bus, timeout); + + return ret; +} + +void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) { + assert(device); + assert(device->config); + + furi_hal_spi_bus_configure(device->bus, device->config); +} + +const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { + assert(device_id < FuriHalSpiDeviceIdMax); + + const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; + assert(device); + + furi_hal_spi_bus_lock(device->bus); + furi_hal_spi_device_configure(device); + + return device; +} + +void furi_hal_spi_device_return(const FuriHalSpiDevice* device) { + furi_hal_spi_bus_unlock(device->bus); +} + +bool furi_hal_spi_device_rx( + const FuriHalSpiDevice* device, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(device); + assert(buffer); + assert(size > 0); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool furi_hal_spi_device_tx( + const FuriHalSpiDevice* device, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(device); + assert(buffer); + assert(size > 0); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool furi_hal_spi_device_trx( + const FuriHalSpiDevice* device, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout) { + assert(device); + assert(tx_buffer); + assert(rx_buffer); + assert(size > 0); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi.h b/bootloader/targets/f7/furi-hal/furi-hal-spi.h new file mode 100644 index 00000000..8027eb5d --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi.h @@ -0,0 +1,129 @@ +#pragma once + +#include "main.h" + +#include "furi-hal-spi-config.h" +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Init SPI API + */ +void furi_hal_spi_init(); + +/* Bus Level API */ + +/** Lock SPI bus + * Takes bus mutex, if used + */ +void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); + +/** Unlock SPI bus + * Releases BUS mutex, if used + */ +void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); + +/** + * Configure SPI bus + * @param bus - spi bus handler + * @param config - spi configuration structure + */ +void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); + +/** SPI Receive + * @param bus - spi bus handler + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_bus_rx(const FuriHalSpiBus* 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 furi_hal_spi_bus_tx(const FuriHalSpiBus* 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 furi_hal_spi_bus_trx( + const FuriHalSpiBus* bus, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout); + +/* Device Level API */ + +/** Reconfigure SPI bus for device + * @param device - device description + */ +void furi_hal_spi_device_configure(const FuriHalSpiDevice* device); + +/** Get Device handle + * And lock access to the corresponding SPI BUS + * @param device_id - device identifier + * @return device handle + */ +const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id); + +/** Return Device handle + * And unlock access to the corresponding SPI BUS + * @param device - device handle + */ +void furi_hal_spi_device_return(const FuriHalSpiDevice* device); + +/** SPI Recieve + * @param device - device handle + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_device_rx( + const FuriHalSpiDevice* 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 furi_hal_spi_device_tx( + const FuriHalSpiDevice* 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 furi_hal_spi_device_trx( + const FuriHalSpiDevice* device, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal.c b/bootloader/targets/f7/furi-hal/furi-hal.c new file mode 100644 index 00000000..e0521cc9 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal.c @@ -0,0 +1,7 @@ +#include + +void furi_hal_init() { + furi_hal_i2c_init(); + furi_hal_light_init(); + furi_hal_spi_init(); +} \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal.h b/bootloader/targets/f7/furi-hal/furi-hal.h new file mode 100644 index 00000000..9e60092f --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include +#include +#include + +void furi_hal_init(); \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/main.h b/bootloader/targets/f7/furi-hal/main.h new file mode 100644 index 00000000..1c453c57 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/main.h @@ -0,0 +1,108 @@ +#pragma once + +#include +#include +#include + +#define BUTTON_BACK_GPIO_Port GPIOC +#define BUTTON_BACK_Pin LL_GPIO_PIN_13 +#define BUTTON_DOWN_GPIO_Port GPIOC +#define BUTTON_DOWN_Pin LL_GPIO_PIN_6 +#define BUTTON_LEFT_GPIO_Port GPIOB +#define BUTTON_LEFT_Pin LL_GPIO_PIN_11 +#define BUTTON_OK_GPIO_Port GPIOH +#define BUTTON_OK_Pin LL_GPIO_PIN_3 +#define BUTTON_RIGHT_GPIO_Port GPIOB +#define BUTTON_RIGHT_Pin LL_GPIO_PIN_12 +#define BUTTON_UP_GPIO_Port GPIOB +#define BUTTON_UP_Pin LL_GPIO_PIN_10 + +#define CC1101_CS_GPIO_Port GPIOD +#define CC1101_CS_Pin LL_GPIO_PIN_0 +#define CC1101_G0_GPIO_Port GPIOA +#define CC1101_G0_Pin LL_GPIO_PIN_1 + +#define DISPLAY_CS_GPIO_Port GPIOC +#define DISPLAY_CS_Pin LL_GPIO_PIN_11 +#define DISPLAY_DI_GPIO_Port GPIOB +#define DISPLAY_DI_Pin LL_GPIO_PIN_1 +#define DISPLAY_RST_GPIO_Port GPIOB +#define DISPLAY_RST_Pin LL_GPIO_PIN_0 + +#define IR_RX_GPIO_Port GPIOA +#define IR_RX_Pin LL_GPIO_PIN_0 +#define IR_TX_GPIO_Port GPIOB +#define IR_TX_Pin LL_GPIO_PIN_9 + +#define NFC_CS_GPIO_Port GPIOE +#define NFC_CS_Pin LL_GPIO_PIN_4 + +#define PA4_GPIO_Port GPIOA +#define PA4_Pin LL_GPIO_PIN_4 +#define PA6_GPIO_Port GPIOA +#define PA6_Pin LL_GPIO_PIN_6 +#define PA7_GPIO_Port GPIOA +#define PA7_Pin LL_GPIO_PIN_7 +#define PB2_GPIO_Port GPIOB +#define PB2_Pin LL_GPIO_PIN_2 +#define PB3_GPIO_Port GPIOB +#define PB3_Pin LL_GPIO_PIN_3 +#define PC0_GPIO_Port GPIOC +#define PC0_Pin LL_GPIO_PIN_0 +#define PC1_GPIO_Port GPIOC +#define PC1_Pin LL_GPIO_PIN_1 +#define PC3_GPIO_Port GPIOC +#define PC3_Pin LL_GPIO_PIN_3 + +#define PERIPH_POWER_GPIO_Port GPIOA +#define PERIPH_POWER_Pin LL_GPIO_PIN_3 + +#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC +#define QUARTZ_32MHZ_IN_Pin LL_GPIO_PIN_14 +#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC +#define QUARTZ_32MHZ_OUT_Pin LL_GPIO_PIN_15 + +#define RFID_OUT_GPIO_Port GPIOB +#define RFID_OUT_Pin LL_GPIO_PIN_13 +#define RFID_PULL_GPIO_Port GPIOA +#define RFID_PULL_Pin LL_GPIO_PIN_2 +#define RFID_RF_IN_GPIO_Port GPIOC +#define RFID_RF_IN_Pin LL_GPIO_PIN_5 +#define RFID_TUNE_GPIO_Port GPIOA +#define RFID_TUNE_Pin LL_GPIO_PIN_8 + +#define RF_SW_0_GPIO_Port GPIOC +#define RF_SW_0_Pin LL_GPIO_PIN_4 + +#define SD_CD_GPIO_Port GPIOC +#define SD_CD_Pin LL_GPIO_PIN_10 +#define SD_CS_GPIO_Port GPIOC +#define SD_CS_Pin LL_GPIO_PIN_12 + +#define SPEAKER_GPIO_Port GPIOB +#define SPEAKER_Pin LL_GPIO_PIN_8 + +#define VIBRO_GPIO_Port GPIOA +#define VIBRO_Pin LL_GPIO_PIN_15 + +#define iBTN_GPIO_Port GPIOB +#define iBTN_Pin LL_GPIO_PIN_14 + +#define USART1_TX_Pin LL_GPIO_PIN_6 +#define USART1_TX_Port GPIOB +#define USART1_RX_Pin LL_GPIO_PIN_7 +#define USART1_RX_Port GPIOB + +#define SPI_D_MISO_GPIO_Port GPIOC +#define SPI_D_MISO_Pin LL_GPIO_PIN_2 +#define SPI_D_MOSI_GPIO_Port GPIOB +#define SPI_D_MOSI_Pin LL_GPIO_PIN_15 +#define SPI_D_SCK_GPIO_Port GPIOD +#define SPI_D_SCK_Pin LL_GPIO_PIN_1 + +#define SPI_R_MISO_GPIO_Port GPIOB +#define SPI_R_MISO_Pin LL_GPIO_PIN_4 +#define SPI_R_MOSI_GPIO_Port GPIOB +#define SPI_R_MOSI_Pin LL_GPIO_PIN_5 +#define SPI_R_SCK_GPIO_Port GPIOA +#define SPI_R_SCK_Pin LL_GPIO_PIN_5 diff --git a/bootloader/targets/f7/furi-hal/u8g2_periphery.c b/bootloader/targets/f7/furi-hal/u8g2_periphery.c new file mode 100644 index 00000000..a1c153f7 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/u8g2_periphery.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +static FuriHalSpiDevice* u8g2_periphery_display = NULL; + +uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { + switch(msg) { + case U8X8_MSG_GPIO_AND_DELAY_INIT: + /* HAL initialization contains all what we need so we can skip this part. */ + break; + + case U8X8_MSG_DELAY_MILLI: + LL_mDelay(arg_int); + break; + + case U8X8_MSG_DELAY_10MICRO: + LL_mDelay(1); + break; + + case U8X8_MSG_DELAY_100NANO: + asm("nop"); + break; + + case U8X8_MSG_GPIO_RESET: + hal_gpio_write(&gpio_display_rst, arg_int); + break; + + default: + return 0; + } + + return 1; +} + +uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { + switch(msg) { + case U8X8_MSG_BYTE_SEND: + furi_hal_spi_bus_tx(u8g2_periphery_display->bus, (uint8_t*)arg_ptr, arg_int, 10000); + break; + + case U8X8_MSG_BYTE_SET_DC: + hal_gpio_write(&gpio_display_di, arg_int); + break; + + case U8X8_MSG_BYTE_INIT: + break; + + case U8X8_MSG_BYTE_START_TRANSFER: + assert(u8g2_periphery_display == NULL); + u8g2_periphery_display = + (FuriHalSpiDevice*)furi_hal_spi_device_get(FuriHalSpiDeviceIdDisplay); + hal_gpio_write(u8g2_periphery_display->chip_select, false); + break; + + case U8X8_MSG_BYTE_END_TRANSFER: + assert(u8g2_periphery_display); + hal_gpio_write(u8g2_periphery_display->chip_select, true); + furi_hal_spi_device_return(u8g2_periphery_display); + u8g2_periphery_display = NULL; + break; + + default: + return 0; + } + + return 1; +} diff --git a/bootloader/targets/f7/stm32wb55xx_flash_cm4.ld b/bootloader/targets/f7/stm32wb55xx_flash_cm4.ld new file mode 100644 index 00000000..41d36b11 --- /dev/null +++ b/bootloader/targets/f7/stm32wb55xx_flash_cm4.ld @@ -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. +** +***************************************************************************** +** +**

© COPYRIGHT(c) 2019 Ac6

+** +** 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 +} + + diff --git a/bootloader/targets/f7/target.c b/bootloader/targets/f7/target.c new file mode 100644 index 00000000..da1d6397 --- /dev/null +++ b/bootloader/targets/f7/target.c @@ -0,0 +1,264 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +const uint8_t I_DFU_128x50[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x75, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x0A, 0x00, 0x00, 0x0F, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE0, 0x0F, 0x00, 0xC0, 0xE0, 0x4F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x30, 0x1E, 0x90, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x18, 0x00, 0x8C, 0x01, 0xA0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0xFF, 0x19, 0x00, 0x63, 0x00, 0xC0, 0xF0, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x5E, 0x1F, 0x80, 0x18, 0x00, 0xE0, 0x0E, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x18, 0xAF, 0x0F, 0x40, 0x06, 0x00, 0xF8, 0x01, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x57, 0x01, 0x20, 0x01, 0x00, 0x78, 0x00, 0x3E, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x81, 0xAF, 0x02, 0x90, 0x00, 0x00, 0x38, 0x80, 0x41, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x80, 0x57, 0x01, 0x48, 0x00, 0x00, 0x10, 0x60, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x10, 0x80, 0xAB, 0x00, 0x24, 0x00, 0x00, 0x08, 0x10, 0x40, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0C, 0xC0, 0x57, 0x01, 0x12, 0x00, 0x00, 0x04, 0x08, 0x40, + 0xC0, 0x0F, 0x00, 0x00, 0xC0, 0x07, 0x03, 0xF0, 0xAB, 0x00, 0x0A, 0x00, 0x00, 0x02, 0x04, 0x40, + 0x00, 0xF0, 0x1F, 0x80, 0x3F, 0xC0, 0x00, 0xFC, 0x55, 0x01, 0x05, 0xE0, 0x00, 0x01, 0x04, 0x40, + 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x30, 0x00, 0xFF, 0xAB, 0x00, 0x05, 0xE0, 0x80, 0x00, 0x02, 0x40, + 0x0F, 0x00, 0x00, 0x00, 0x80, 0x0F, 0xE0, 0xCF, 0x55, 0x81, 0x02, 0xF0, 0x40, 0x00, 0x02, 0x40, + 0xF0, 0x0F, 0x00, 0x00, 0x7F, 0x00, 0xFE, 0xC3, 0xAB, 0x80, 0x02, 0x78, 0x20, 0x00, 0x01, 0x40, + 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0xF0, 0xFF, 0xC0, 0xD5, 0x81, 0x01, 0x7E, 0x10, 0x80, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x0F, 0xE0, 0xFA, 0x83, 0xC1, 0x3F, 0x08, 0x80, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0xD8, 0x07, 0x83, 0xF1, 0x1F, 0x04, 0x40, 0x00, 0x20, + 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x0F, 0x80, 0xC7, 0x01, 0x83, 0xF1, 0x0F, 0x00, 0x20, 0x00, 0x10, + 0xE0, 0xFF, 0xFF, 0xFF, 0x3F, 0xC0, 0x7F, 0x40, 0x80, 0x83, 0xE1, 0x01, 0x00, 0x20, 0x00, 0x18, + 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x3F, 0x00, 0x20, 0xFC, 0x83, 0x01, 0x00, 0x00, 0x10, 0x00, 0x18, + 0xFF, 0xFF, 0xFF, 0x3F, 0xF0, 0x00, 0x00, 0x10, 0xD7, 0x01, 0x03, 0x00, 0x00, 0x08, 0x00, 0x1C, + 0xFF, 0xFF, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x88, 0xAB, 0x02, 0xE3, 0x01, 0x00, 0x08, 0x00, 0x0C, + 0xFF, 0x07, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC4, 0x55, 0x05, 0x1E, 0x00, 0x00, 0x04, 0x00, 0x0E, + 0x7F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xA3, 0xAB, 0x02, 0x06, 0x00, 0x00, 0x02, 0x00, 0x0F, + 0x0F, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x10, 0x57, 0x05, 0x02, 0x00, 0x00, 0x01, 0x80, 0x07, + 0x03, 0x00, 0x70, 0x00, 0x00, 0x00, 0x30, 0x08, 0xAB, 0x0A, 0x02, 0x00, 0xC0, 0x00, 0xC0, 0x07, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x84, 0x57, 0x15, 0x01, 0x00, 0x30, 0x00, 0xE0, 0x07, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0xC3, 0xFF, 0x2A, 0x01, 0x00, 0x0C, 0x00, 0xF0, 0x0F, + 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0xE0, 0xFE, 0x55, 0x01, 0x82, 0x03, 0x00, 0xF8, 0x15, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x1C, 0x30, 0x78, 0xFE, 0xAA, 0x01, 0x7C, 0x00, 0x00, 0xFC, 0x23, + 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x0C, 0x3C, 0x7F, 0x5D, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x45, + 0xC0, 0x01, 0x00, 0x00, 0x3E, 0x00, 0x02, 0x8F, 0xBF, 0xAE, 0x03, 0x00, 0x00, 0xC0, 0xFF, 0x82, + 0x30, 0x00, 0x00, 0xC0, 0x01, 0x80, 0xC1, 0x43, 0xFE, 0x5D, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x05, + 0x0F, 0x00, 0x80, 0x3F, 0x00, 0x60, 0xF0, 0x31, 0xF6, 0xAE, 0x03, 0x00, 0x00, 0xFA, 0xAF, 0x02, + 0xFC, 0xFF, 0x7F, 0x00, 0x00, 0x18, 0x7C, 0x08, 0x23, 0xFF, 0x05, 0x00, 0x00, 0xFD, 0x55, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x1F, 0x84, 0x30, 0xFE, 0x0A, 0x00, 0x00, 0xAA, 0xAA, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xF1, 0x07, 0x43, 0x18, 0xFF, 0x15, 0x00, 0x00, 0x54, 0x15, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x80, 0x20, 0x8C, 0xFF, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +// Boot request enum +#define BOOT_REQUEST_TAINTED 0x00000000 +#define BOOT_REQUEST_CLEAN 0xDADEDADE +#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()) + +uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); +uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); + +void target_led_control(char* c) { + furi_hal_light_set(LightRed, 0x00); + furi_hal_light_set(LightGreen, 0x00); + furi_hal_light_set(LightBlue, 0x00); + do { + if(*c == 'R') { + furi_hal_light_set(LightRed, 0xFF); + } else if(*c == 'G') { + furi_hal_light_set(LightGreen, 0xFF); + } else if(*c == 'B') { + furi_hal_light_set(LightBlue, 0xFF); + } else if(*c == '.') { + LL_mDelay(125); + furi_hal_light_set(LightRed, 0x00); + furi_hal_light_set(LightGreen, 0x00); + furi_hal_light_set(LightBlue, 0x00); + LL_mDelay(125); + } else if(*c == '-') { + LL_mDelay(250); + furi_hal_light_set(LightRed, 0x00); + furi_hal_light_set(LightGreen, 0x00); + furi_hal_light_set(LightBlue, 0x00); + LL_mDelay(250); + } else if(*c == '|') { + furi_hal_light_set(LightRed, 0x00); + furi_hal_light_set(LightGreen, 0x00); + furi_hal_light_set(LightBlue, 0x00); + } + c++; + } while(*c != 0); +} + +void target_clock_init() { + LL_Init1msTick(4000000); + LL_SetSystemCoreClock(4000000); + + 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); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); + + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); +} + +void target_gpio_init() { + // 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 target_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_HIGH); + 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 target_version_save(void) { + LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR1, (uint32_t)version_get()); +} + +void target_usb_wire_reset() { + LL_GPIO_ResetOutputPin(BOOT_USB_PORT, BOOT_USB_PIN); +} + +void target_display_init() { + // Prepare gpio + hal_gpio_init_simple(&gpio_display_rst, GpioModeOutputPushPull); + hal_gpio_init_simple(&gpio_display_di, GpioModeOutputPushPull); + // Initialize + u8g2_t fb; + u8g2_Setup_st7565_erc12864_alt_f(&fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32); + u8g2_InitDisplay(&fb); + u8g2_SetContrast(&fb, 36); + // Create payload + u8g2_ClearBuffer(&fb); + u8g2_SetDrawColor(&fb, 0x01); + u8g2_SetFont(&fb, u8g2_font_helvB08_tf); + u8g2_DrawXBM(&fb, 0, 64 - 50, 128, 50, I_DFU_128x50); + u8g2_DrawStr(&fb, 2, 8, "Update & Recovery Mode"); + u8g2_DrawStr(&fb, 2, 21, "DFU started"); + // Send buffer + u8g2_SetPowerSave(&fb, 0); + u8g2_SendBuffer(&fb); +} + +void target_init() { + target_clock_init(); + target_gpio_init(); + furi_hal_init(); + target_led_control("RGB"); + target_rtc_init(); + target_version_save(); + target_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_TAINTED) { + // Default system state is tainted + // We must ensure that MCU is cleanly booted + LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_CLEAN); + NVIC_SystemReset(); + } else if(LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR0) == BOOT_REQUEST_DFU) { + 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"); + furi_hal_light_set(LightBacklight, 0xFF); + target_display_init(); + // Mark system as tainted, it will be soon + LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_TAINTED); + // Remap memory to system bootloader + LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SYSTEMFLASH); + // Jump + target_switch(0x0); +} + +void target_switch2os() { + target_led_control("G"); + SCB->VTOR = OS_OFFSET; + target_switch((void*)(BOOT_ADDRESS + OS_OFFSET)); +} diff --git a/bootloader/targets/f7/target.mk b/bootloader/targets/f7/target.mk new file mode 100644 index 00000000..e6430585 --- /dev/null +++ b/bootloader/targets/f7/target.mk @@ -0,0 +1,48 @@ +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 "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 = $(PROJECT_ROOT)/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 +C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_spi.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 = $(PROJECT_ROOT)//lib/drivers +CFLAGS += -I$(DRIVERS_DIR) +C_SOURCES += $(DRIVERS_DIR)/lp5562.c + +# API-HAL +CFLAGS += -I$(TARGET_DIR)/furi-hal +C_SOURCES += $(wildcard $(TARGET_DIR)/furi-hal/*.c) + +# Version generation +C_SOURCES += $(PROJECT_ROOT)/lib/toolbox/version.c + +ASM_SOURCES += $(wildcard $(TARGET_DIR)/*.s) +C_SOURCES += $(wildcard $(TARGET_DIR)/*.c) +CPP_SOURCES += $(wildcard $(TARGET_DIR)/*.cpp) + +SVD_FILE = $(PROJECT_ROOT)/debug/STM32WB55_CM4.svd diff --git a/firmware/targets/f6/Inc/FreeRTOSConfig.h b/firmware/targets/f6/Inc/FreeRTOSConfig.h index 5d2befde..1e32e894 100644 --- a/firmware/targets/f6/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f6/Inc/FreeRTOSConfig.h @@ -118,6 +118,14 @@ to exclude the API function. */ #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTimerPendFunctionCall 1 +/* CMSIS-RTOS V2 flags */ +#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 +#define configUSE_OS2_THREAD_ENUMERATE 1 +#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 +#define configUSE_OS2_THREAD_FLAGS 1 +#define configUSE_OS2_TIMER 1 +#define configUSE_OS2_MUTEX 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 diff --git a/firmware/targets/f6/cube/Inc/FreeRTOSConfig.h b/firmware/targets/f6/cube/Inc/FreeRTOSConfig.h index a5b9c959..258ab421 100644 --- a/firmware/targets/f6/cube/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f6/cube/Inc/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* USER CODE BEGIN Header */ /* - * FreeRTOS Kernel V10.2.1 + * FreeRTOS Kernel V10.3.1 * Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Portion Copyright (C) 2019 StMicroelectronics, Inc. All Rights Reserved. * @@ -57,6 +57,10 @@ extern unsigned long getRunTimeCounterValue(void); /* USER CODE END 0 */ #endif +#ifndef CMSIS_device_header +#define CMSIS_device_header "stm32wbxx.h" +#endif /* CMSIS_device_header */ + #define configENABLE_FPU 1 #define configENABLE_MPU 0 @@ -99,6 +103,14 @@ #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH 256 +/* CMSIS-RTOS V2 flags */ +#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 +#define configUSE_OS2_THREAD_ENUMERATE 1 +#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 +#define configUSE_OS2_THREAD_FLAGS 1 +#define configUSE_OS2_TIMER 1 +#define configUSE_OS2_MUTEX 1 + /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 @@ -112,6 +124,7 @@ to exclude the API function. */ #define INCLUDE_xTimerPendFunctionCall 1 #define INCLUDE_xQueueGetMutexHolder 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_eTaskGetState 1 /* @@ -156,10 +169,9 @@ 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 */ +/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */ -/* #define xPortSysTickHandler SysTick_Handler */ +#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1 /* USER CODE BEGIN 2 */ /* Definitions needed when configGENERATE_RUN_TIME_STATS is on */ diff --git a/firmware/targets/f6/cube/Inc/main.h b/firmware/targets/f6/cube/Inc/main.h index 4e159c5d..77c128f0 100644 --- a/firmware/targets/f6/cube/Inc/main.h +++ b/firmware/targets/f6/cube/Inc/main.h @@ -29,7 +29,7 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ #include "stm32wbxx_hal.h" -#include "stm32wbxx.h" + #include "stm32wbxx_ll_i2c.h" #include "stm32wbxx_ll_crs.h" #include "stm32wbxx_ll_rcc.h" @@ -164,42 +164,6 @@ void Error_Handler(void); #define SPI_R_MOSI_GPIO_Port GPIOB /* USER CODE BEGIN Private defines */ -#define MISO_PIN GpioPin{.port = SPI_R_MISO_GPIO_Port, .pin = SPI_R_MISO_Pin} - -#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 - -#define VIBRO_Pin GPIO_PIN_10 -#define VIBRO_GPIO_Port GPIOC - /* USER CODE END Private defines */ #ifdef __cplusplus diff --git a/firmware/targets/f6/cube/Inc/usbd_cdc_if.h b/firmware/targets/f6/cube/Inc/usbd_cdc_if.h index e9a32911..bbd5af07 100644 --- a/firmware/targets/f6/cube/Inc/usbd_cdc_if.h +++ b/firmware/targets/f6/cube/Inc/usbd_cdc_if.h @@ -48,11 +48,10 @@ * @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 512 #define APP_TX_DATA_SIZE 512 +/* USER CODE BEGIN EXPORTED_DEFINES */ /* USER CODE END EXPORTED_DEFINES */ diff --git a/firmware/targets/f6/cube/Makefile b/firmware/targets/f6/cube/Makefile index 21254942..e86835f7 100644 --- a/firmware/targets/f6/cube/Makefile +++ b/firmware/targets/f6/cube/Makefile @@ -1,5 +1,5 @@ ########################################################################################################################## -# File automatically-generated by tool: [projectgenerator] version: [3.13.0-B3] date: [Tue Jul 20 02:23:07 MSK 2021] +# File automatically-generated by tool: [projectgenerator] version: [3.14.1] date: [Fri Sep 10 04:51:15 MSK 2021] ########################################################################################################################## # ------------------------------------------------ @@ -57,60 +57,60 @@ Src/usbd_desc.c \ Src/usbd_cdc_if.c \ Src/stm32wbxx_it.c \ Src/stm32wbxx_hal_msp.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_exti.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_gpio.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_hsem.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cortex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_adc.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_comp.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_dma.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pka.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rng.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim_ex.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rcc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_exti.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_gpio.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_hsem.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cortex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_adc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_comp.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_dma.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pka.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rng.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rcc.c \ Src/system_stm32wbxx.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/list.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/queue.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/timers.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ -/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/list.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/queue.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/timers.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c # ASM sources ASM_SOURCES = \ @@ -170,15 +170,15 @@ AS_INCLUDES = \ # C includes C_INCLUDES = \ -IInc \ --I/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Inc \ --I/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/STM32WBxx_HAL_Driver/Inc/Legacy \ --I/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/include \ --I/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ --I/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \ --I/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/ST/STM32_USB_Device_Library/Core/Inc \ --I/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \ --I/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/CMSIS/Device/ST/STM32WBxx/Include \ --I/Users/aku/STM32Cube/Repository/STM32Cube_FW_WB_V1.10.1/Drivers/CMSIS/Include +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/Legacy \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/include \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Inc \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/CMSIS/Device/ST/STM32WBxx/Include \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/CMSIS/Include # compile gcc flags diff --git a/firmware/targets/f6/cube/Src/adc.c b/firmware/targets/f6/cube/Src/adc.c index 1ad43f2f..e1294c43 100644 --- a/firmware/targets/f6/cube/Src/adc.c +++ b/firmware/targets/f6/cube/Src/adc.c @@ -29,8 +29,16 @@ ADC_HandleTypeDef hadc1; /* ADC1 init function */ void MX_ADC1_Init(void) { + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + ADC_ChannelConfTypeDef sConfig = {0}; + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ /** Common config */ hadc1.Instance = ADC1; @@ -64,6 +72,9 @@ void MX_ADC1_Init(void) { Error_Handler(); } + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/aes.c b/firmware/targets/f6/cube/Src/aes.c index 1a042e9b..06d5aacb 100644 --- a/firmware/targets/f6/cube/Src/aes.c +++ b/firmware/targets/f6/cube/Src/aes.c @@ -35,6 +35,13 @@ __ALIGN_BEGIN static const uint32_t pKeyAES2[4] __ALIGN_END = { void MX_AES1_Init(void) { + /* USER CODE BEGIN AES1_Init 0 */ + + /* USER CODE END AES1_Init 0 */ + + /* USER CODE BEGIN AES1_Init 1 */ + + /* USER CODE END AES1_Init 1 */ hcryp1.Instance = AES1; hcryp1.Init.DataType = CRYP_DATATYPE_32B; hcryp1.Init.KeySize = CRYP_KEYSIZE_128B; @@ -46,12 +53,22 @@ void MX_AES1_Init(void) { Error_Handler(); } + /* USER CODE BEGIN AES1_Init 2 */ + + /* USER CODE END AES1_Init 2 */ } /* AES2 init function */ void MX_AES2_Init(void) { + /* USER CODE BEGIN AES2_Init 0 */ + + /* USER CODE END AES2_Init 0 */ + + /* USER CODE BEGIN AES2_Init 1 */ + + /* USER CODE END AES2_Init 1 */ hcryp2.Instance = AES2; hcryp2.Init.DataType = CRYP_DATATYPE_32B; hcryp2.Init.KeySize = CRYP_KEYSIZE_128B; @@ -63,6 +80,9 @@ void MX_AES2_Init(void) { Error_Handler(); } + /* USER CODE BEGIN AES2_Init 2 */ + + /* USER CODE END AES2_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/comp.c b/firmware/targets/f6/cube/Src/comp.c index 9401ed34..00f9fa66 100644 --- a/firmware/targets/f6/cube/Src/comp.c +++ b/firmware/targets/f6/cube/Src/comp.c @@ -30,6 +30,13 @@ COMP_HandleTypeDef hcomp1; void MX_COMP1_Init(void) { + /* USER CODE BEGIN COMP1_Init 0 */ + + /* USER CODE END COMP1_Init 0 */ + + /* USER CODE BEGIN COMP1_Init 1 */ + + /* USER CODE END COMP1_Init 1 */ hcomp1.Instance = COMP1; hcomp1.Init.InputMinus = COMP_INPUT_MINUS_1_4VREFINT; hcomp1.Init.InputPlus = COMP_INPUT_PLUS_IO1; @@ -43,6 +50,9 @@ void MX_COMP1_Init(void) { Error_Handler(); } + /* USER CODE BEGIN COMP1_Init 2 */ + + /* USER CODE END COMP1_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/crc.c b/firmware/targets/f6/cube/Src/crc.c index 42b98724..be2138ec 100644 --- a/firmware/targets/f6/cube/Src/crc.c +++ b/firmware/targets/f6/cube/Src/crc.c @@ -30,6 +30,13 @@ CRC_HandleTypeDef hcrc; void MX_CRC_Init(void) { + /* USER CODE BEGIN CRC_Init 0 */ + + /* USER CODE END CRC_Init 0 */ + + /* USER CODE BEGIN CRC_Init 1 */ + + /* USER CODE END CRC_Init 1 */ hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; @@ -40,6 +47,9 @@ void MX_CRC_Init(void) { Error_Handler(); } + /* USER CODE BEGIN CRC_Init 2 */ + + /* USER CODE END CRC_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/i2c.c b/firmware/targets/f6/cube/Src/i2c.c index c41b35d5..507de62c 100644 --- a/firmware/targets/f6/cube/Src/i2c.c +++ b/firmware/targets/f6/cube/Src/i2c.c @@ -27,6 +27,11 @@ /* I2C1 init function */ void MX_I2C1_Init(void) { + + /* USER CODE BEGIN I2C1_Init 0 */ + + /* USER CODE END I2C1_Init 0 */ + LL_I2C_InitTypeDef I2C_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; @@ -47,6 +52,9 @@ void MX_I2C1_Init(void) /* Peripheral clock enable */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + /* USER CODE BEGIN I2C1_Init 1 */ + + /* USER CODE END I2C1_Init 1 */ /** I2C Initialization */ I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; @@ -62,6 +70,9 @@ void MX_I2C1_Init(void) LL_I2C_DisableOwnAddress2(I2C1); LL_I2C_DisableGeneralCall(I2C1); LL_I2C_EnableClockStretching(I2C1); + /* USER CODE BEGIN I2C1_Init 2 */ + + /* USER CODE END I2C1_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/main.c b/firmware/targets/f6/cube/Src/main.c index d4bfe02f..c8cada7b 100644 --- a/firmware/targets/f6/cube/Src/main.c +++ b/firmware/targets/f6/cube/Src/main.c @@ -163,6 +163,11 @@ void SystemClock_Config(void) } LL_PWR_EnableBkUpAccess(); + if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) + { + LL_RCC_ForceBackupDomainReset(); + LL_RCC_ReleaseBackupDomainReset(); + } LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_MEDIUMLOW); LL_RCC_LSE_Enable(); @@ -229,8 +234,6 @@ void SystemClock_Config(void) } if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) { - LL_RCC_ForceBackupDomainReset(); - LL_RCC_ReleaseBackupDomainReset(); LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); } LL_RCC_EnableRTC(); @@ -239,6 +242,7 @@ void SystemClock_Config(void) LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1); + LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_PLLSAI1); LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1); LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); diff --git a/firmware/targets/f6/cube/Src/pka.c b/firmware/targets/f6/cube/Src/pka.c index 8377ce57..9728cf5e 100644 --- a/firmware/targets/f6/cube/Src/pka.c +++ b/firmware/targets/f6/cube/Src/pka.c @@ -30,11 +30,21 @@ PKA_HandleTypeDef hpka; void MX_PKA_Init(void) { + /* USER CODE BEGIN PKA_Init 0 */ + + /* USER CODE END PKA_Init 0 */ + + /* USER CODE BEGIN PKA_Init 1 */ + + /* USER CODE END PKA_Init 1 */ hpka.Instance = PKA; if (HAL_PKA_Init(&hpka) != HAL_OK) { Error_Handler(); } + /* USER CODE BEGIN PKA_Init 2 */ + + /* USER CODE END PKA_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/rf.c b/firmware/targets/f6/cube/Src/rf.c index 62daf9b2..5682dd9d 100644 --- a/firmware/targets/f6/cube/Src/rf.c +++ b/firmware/targets/f6/cube/Src/rf.c @@ -28,6 +28,17 @@ void MX_RF_Init(void) { + /* USER CODE BEGIN RF_Init 0 */ + + /* USER CODE END RF_Init 0 */ + + /* USER CODE BEGIN RF_Init 1 */ + + /* USER CODE END RF_Init 1 */ + /* USER CODE BEGIN RF_Init 2 */ + + /* USER CODE END RF_Init 2 */ + } /* USER CODE BEGIN 1 */ diff --git a/firmware/targets/f6/cube/Src/rng.c b/firmware/targets/f6/cube/Src/rng.c index c2fb144e..ba70ae7b 100644 --- a/firmware/targets/f6/cube/Src/rng.c +++ b/firmware/targets/f6/cube/Src/rng.c @@ -30,11 +30,22 @@ RNG_HandleTypeDef hrng; void MX_RNG_Init(void) { + /* USER CODE BEGIN RNG_Init 0 */ + + /* USER CODE END RNG_Init 0 */ + + /* USER CODE BEGIN RNG_Init 1 */ + + /* USER CODE END RNG_Init 1 */ hrng.Instance = RNG; + hrng.Init.ClockErrorDetection = RNG_CED_ENABLE; if (HAL_RNG_Init(&hrng) != HAL_OK) { Error_Handler(); } + /* USER CODE BEGIN RNG_Init 2 */ + + /* USER CODE END RNG_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/rtc.c b/firmware/targets/f6/cube/Src/rtc.c index a460c52d..2aaa7897 100644 --- a/firmware/targets/f6/cube/Src/rtc.c +++ b/firmware/targets/f6/cube/Src/rtc.c @@ -29,9 +29,17 @@ RTC_HandleTypeDef hrtc; /* RTC init function */ void MX_RTC_Init(void) { + + /* USER CODE BEGIN RTC_Init 0 */ + + /* USER CODE END RTC_Init 0 */ + RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; + /* USER CODE BEGIN RTC_Init 1 */ + + /* USER CODE END RTC_Init 1 */ /** Initialize RTC Only */ hrtc.Instance = RTC; @@ -72,6 +80,9 @@ void MX_RTC_Init(void) { Error_Handler(); } + /* USER CODE BEGIN RTC_Init 2 */ + + /* USER CODE END RTC_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/spi.c b/firmware/targets/f6/cube/Src/spi.c index 637a9807..81864c8b 100644 --- a/firmware/targets/f6/cube/Src/spi.c +++ b/firmware/targets/f6/cube/Src/spi.c @@ -31,6 +31,13 @@ SPI_HandleTypeDef hspi2; void MX_SPI1_Init(void) { + /* USER CODE BEGIN SPI1_Init 0 */ + + /* USER CODE END SPI1_Init 0 */ + + /* USER CODE BEGIN SPI1_Init 1 */ + + /* USER CODE END SPI1_Init 1 */ hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; @@ -49,12 +56,22 @@ void MX_SPI1_Init(void) { Error_Handler(); } + /* USER CODE BEGIN SPI1_Init 2 */ + + /* USER CODE END SPI1_Init 2 */ } /* SPI2 init function */ void MX_SPI2_Init(void) { + /* USER CODE BEGIN SPI2_Init 0 */ + + /* USER CODE END SPI2_Init 0 */ + + /* USER CODE BEGIN SPI2_Init 1 */ + + /* USER CODE END SPI2_Init 1 */ hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES; @@ -73,6 +90,9 @@ void MX_SPI2_Init(void) { Error_Handler(); } + /* USER CODE BEGIN SPI2_Init 2 */ + + /* USER CODE END SPI2_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/system_stm32wbxx.c b/firmware/targets/f6/cube/Src/system_stm32wbxx.c index 9d136693..d0ff7d2d 100644 --- a/firmware/targets/f6/cube/Src/system_stm32wbxx.c +++ b/firmware/targets/f6/cube/Src/system_stm32wbxx.c @@ -1,357 +1,368 @@ -/** - ****************************************************************************** - * @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 - * - *

© Copyright (c) 2019 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 - * - ****************************************************************************** - */ - -/** @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 0x0U /*!< 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****/ +/** + ****************************************************************************** + * @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 + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @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 + * @{ + */ + +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line if you need to relocate CPU1 CM4 and/or CPU2 + CM0+ vector table anywhere in Sram or Flash. Else vector table will be kept + at address 0x00 which correspond to automatic remap of boot address selected */ +/* #define USER_VECT_TAB_ADDRESS */ +#if defined(USER_VECT_TAB_ADDRESS) + /*!< Uncomment this line for user vector table remap in Sram else user remap + will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS SRAM1_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +#else +#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +#endif +#endif + +/** + * @} + */ + +/** @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) || defined (STM32WB15xx) || defined (STM32WB10xx) + 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) +{ +#if defined(USER_VECT_TAB_ADDRESS) + /* Configure the Vector Table location add offset address ------------------*/ + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; +#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****/ diff --git a/firmware/targets/f6/cube/Src/tim.c b/firmware/targets/f6/cube/Src/tim.c index 37685b9d..1c38c1d7 100644 --- a/firmware/targets/f6/cube/Src/tim.c +++ b/firmware/targets/f6/cube/Src/tim.c @@ -31,11 +31,19 @@ TIM_HandleTypeDef htim16; /* TIM1 init function */ void MX_TIM1_Init(void) { + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ htim1.Instance = TIM1; htim1.Init.Prescaler = 0; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; @@ -100,16 +108,27 @@ void MX_TIM1_Init(void) { Error_Handler(); } + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ HAL_TIM_MspPostInit(&htim1); } /* TIM2 init function */ void MX_TIM2_Init(void) { + + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_IC_InitTypeDef sConfigIC = {0}; + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; htim2.Init.Prescaler = 64-1; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; @@ -149,14 +168,25 @@ void MX_TIM2_Init(void) { Error_Handler(); } + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ } /* TIM16 init function */ void MX_TIM16_Init(void) { + + /* USER CODE BEGIN TIM16_Init 0 */ + + /* USER CODE END TIM16_Init 0 */ + TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; + /* USER CODE BEGIN TIM16_Init 1 */ + + /* USER CODE END TIM16_Init 1 */ htim16.Instance = TIM16; htim16.Init.Prescaler = 500 - 1; htim16.Init.CounterMode = TIM_COUNTERMODE_UP; @@ -195,6 +225,9 @@ void MX_TIM16_Init(void) { Error_Handler(); } + /* USER CODE BEGIN TIM16_Init 2 */ + + /* USER CODE END TIM16_Init 2 */ HAL_TIM_MspPostInit(&htim16); } diff --git a/firmware/targets/f6/cube/Src/usart.c b/firmware/targets/f6/cube/Src/usart.c index 51a8298c..0a0466dc 100644 --- a/firmware/targets/f6/cube/Src/usart.c +++ b/firmware/targets/f6/cube/Src/usart.c @@ -28,6 +28,11 @@ void MX_USART1_UART_Init(void) { + + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + LL_USART_InitTypeDef USART_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; @@ -48,6 +53,9 @@ void MX_USART1_UART_Init(void) GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + /* USER CODE BEGIN USART1_Init 1 */ + + /* USER CODE END USART1_Init 1 */ USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; USART_InitStruct.BaudRate = 115200; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; @@ -71,9 +79,12 @@ void MX_USART1_UART_Init(void) LL_USART_Enable(USART1); /* Polling USART1 initialisation */ - while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))) + while(!(LL_USART_IsActiveFlag_TEACK(USART1))) { } + /* USER CODE BEGIN USART1_Init 2 */ + + /* USER CODE END USART1_Init 2 */ } diff --git a/firmware/targets/f6/cube/Src/usbd_cdc_if.c b/firmware/targets/f6/cube/Src/usbd_cdc_if.c index e3301aae..d52d1e3e 100644 --- a/firmware/targets/f6/cube/Src/usbd_cdc_if.c +++ b/firmware/targets/f6/cube/Src/usbd_cdc_if.c @@ -295,7 +295,7 @@ uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) /** * @brief CDC_TransmitCplt_FS - * Data transmited callback + * Data transmitted callback * * @note * This function is IN transfer complete callback used to inform user that diff --git a/firmware/targets/f6/cube/Src/usbd_conf.c b/firmware/targets/f6/cube/Src/usbd_conf.c index 2ebde906..033e619a 100644 --- a/firmware/targets/f6/cube/Src/usbd_conf.c +++ b/firmware/targets/f6/cube/Src/usbd_conf.c @@ -685,10 +685,10 @@ USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_a } /** - * @brief Returns the last transfered packet size. + * @brief Returns the last transferred packet size. * @param pdev: Device handle * @param ep_addr: Endpoint number - * @retval Recived Data Size + * @retval Received Data Size */ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { @@ -779,7 +779,7 @@ static void SystemClockConfig_Resume(void) /* USER CODE END 5 */ /** - * @brief Retuns the USB status depending on the HAL status: + * @brief Returns the USB status depending on the HAL status: * @param hal_status: HAL status * @retval USB status */ diff --git a/firmware/targets/f6/cube/Src/usbd_desc.c b/firmware/targets/f6/cube/Src/usbd_desc.c index 9fbb3f5c..26f4b7c5 100644 --- a/firmware/targets/f6/cube/Src/usbd_desc.c +++ b/firmware/targets/f6/cube/Src/usbd_desc.c @@ -182,7 +182,7 @@ __ALIGN_BEGIN uint8_t USBD_CDC_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = #pragma data_alignment=4 #endif /* defined ( __ICCARM__ ) */ -/** USB lang indentifier descriptor. */ +/** USB lang identifier descriptor. */ __ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = { USB_LEN_LANGID_STR_DESC, diff --git a/firmware/targets/f6/cube/f6.ioc b/firmware/targets/f6/cube/f6.ioc index fcf156c7..03c9c140 100644 --- a/firmware/targets/f6/cube/f6.ioc +++ b/firmware/targets/f6/cube/f6.ioc @@ -135,8 +135,8 @@ Mcu.PinsNb=69 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32WB55RGVx -MxCube.Version=6.1.2 -MxDb.Version=DB.6.0.10 +MxCube.Version=6.3.0 +MxDb.Version=DB.6.0.30 NVIC.ADC1_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.COMP_IRQn=true\:5\:0\:true\:false\:true\:false\:false\:true @@ -178,8 +178,9 @@ PA1.GPIOParameters=GPIO_Label PA1.GPIO_Label=CC1101_G0 PA1.Locked=true PA1.Signal=GPIO_Analog -PA10.GPIOParameters=GPIO_Speed,GPIO_Label +PA10.GPIOParameters=GPIO_Speed,GPIO_Label,GPIO_Pu PA10.GPIO_Label=I2C_SDA +PA10.GPIO_Pu=GPIO_PULLUP PA10.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PA10.Locked=true PA10.Mode=I2C @@ -233,8 +234,9 @@ PA8.GPIOParameters=GPIO_Label PA8.GPIO_Label=RFID_TUNE PA8.Locked=true PA8.Signal=GPIO_Output -PA9.GPIOParameters=GPIO_Speed,GPIO_Label +PA9.GPIOParameters=GPIO_Speed,GPIO_Label,GPIO_Pu PA9.GPIO_Label=I2C_SCL +PA9.GPIO_Pu=GPIO_PULLUP PA9.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PA9.Locked=true PA9.Mode=I2C @@ -371,8 +373,15 @@ PC6.Locked=true PC6.Signal=GPIO_Input PCC.Ble.ConnectionInterval=1000.0 PCC.Ble.DataLength=6 +PCC.Ble.IsUsed=false PCC.Ble.Mode=NOT_SELECTED PCC.Ble.PowerLevel=Min +PCC.Zigbee.IsUsed=false +PCC.Zigbee.Mode=Sleepy End Device +PCC.Zigbee.Payload=15 +PCC.Zigbee.PoolPeriodicity=480.0 +PCC.Zigbee.PowerLevel=Min +PCC.Zigbee.RequestPeriodicity=1500.0 PD0.GPIOParameters=GPIO_Speed,PinState,GPIO_Label PD0.GPIO_Label=CC1101_CS PD0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH @@ -401,11 +410,11 @@ ProjectManager.BackupPrevious=false ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false ProjectManager.CoupleFile=true -ProjectManager.CustomerFirmwarePackage= -ProjectManager.DefaultFWLocation=true +ProjectManager.CustomerFirmwarePackage=../../../../lib/STM32CubeWB +ProjectManager.DefaultFWLocation=false ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32WB55RGVx -ProjectManager.FirmwarePackage=STM32Cube FW_WB V1.10.1 +ProjectManager.FirmwarePackage=STM32Cube FW_WB V1.12.1 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x400 diff --git a/firmware/targets/f6/cube/startup_stm32wb55xx_cm4.s b/firmware/targets/f6/cube/startup_stm32wb55xx_cm4.s index fc26cb42..c5c2b3fc 100644 --- a/firmware/targets/f6/cube/startup_stm32wb55xx_cm4.s +++ b/firmware/targets/f6/cube/startup_stm32wb55xx_cm4.s @@ -1,445 +1,444 @@ -/** - ****************************************************************************** - * @file startup_stm32wb55xx_cm4.s - * @author MCD Application Team - * @brief STM32WB55xx devices vector table GCC toolchain. - * This module performs: - * - Set the initial SP - * - Set the initial PC == Reset_Handler, - * - Set the vector table entries with the exceptions ISR address - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M4 processor is in Thread mode, - * priority is Privileged, and the Stack is set to Main. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 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 - * - ****************************************************************************** - */ - - .syntax unified - .cpu cortex-m4 - .fpu softvfp - .thumb - -.global g_pfnVectors -.global Default_Handler - -/* start address for the initialization values of the .data section. -defined in linker script */ -.word _sidata -/* start address for the .data section. defined in linker script */ -.word _sdata -/* end address for the .data section. defined in linker script */ -.word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss -/* start address for the .MB_MEM2 section. defined in linker script */ -.word _sMB_MEM2 -/* end address for the .MB_MEM2 section. defined in linker script */ -.word _eMB_MEM2 - -/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */ -.macro INIT_BSS start, end - ldr r0, =\start - ldr r1, =\end - movs r3, #0 - bl LoopFillZerobss -.endm - -/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */ -.macro INIT_DATA start, end, src - ldr r0, =\start - ldr r1, =\end - ldr r2, =\src - movs r3, #0 - bl LoopCopyDataInit -.endm - -.section .text.data_initializers -CopyDataInit: - ldr r4, [r2, r3] - str r4, [r0, r3] - adds r3, r3, #4 - -LoopCopyDataInit: - adds r4, r0, r3 - cmp r4, r1 - bcc CopyDataInit - bx lr - -FillZerobss: - str r3, [r0] - adds r0, r0, #4 - -LoopFillZerobss: - cmp r0, r1 - bcc FillZerobss - bx lr - - .section .text.Reset_Handler - .weak Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - ldr r0, =_estack - mov sp, r0 /* set stack pointer */ -/* Call the clock system intitialization function.*/ - bl SystemInit - -/* Copy the data segment initializers from flash to SRAM */ - INIT_DATA _sdata, _edata, _sidata - -/* Zero fill the bss segments. */ - INIT_BSS _sbss, _ebss - INIT_BSS _sMB_MEM2, _eMB_MEM2 - -/* Call static constructors */ - bl __libc_init_array -/* Call the application s entry point.*/ - bl main - -LoopForever: - b LoopForever - -.size Reset_Handler, .-Reset_Handler - -/** - * @brief This is the code that gets called when the processor receives an - * unexpected interrupt. This simply enters an infinite loop, preserving - * the system state for examination by a debugger. - * - * @param None - * @retval None -*/ - .section .text.Default_Handler,"ax",%progbits -Default_Handler: -Infinite_Loop: - b Infinite_Loop - .size Default_Handler, .-Default_Handler -/****************************************************************************** -* -* The minimal vector table for a Cortex-M4. Note that the proper constructs -* must be placed on this to ensure that it ends up at physical address -* 0x0000.0000. -* -******************************************************************************/ - .section .isr_vector,"a",%progbits - .type g_pfnVectors, %object - .size g_pfnVectors, .-g_pfnVectors - - -g_pfnVectors: - .word _estack - .word Reset_Handler - .word NMI_Handler - .word HardFault_Handler - .word MemManage_Handler - .word BusFault_Handler - .word UsageFault_Handler - .word 0 - .word 0 - .word 0 - .word 0 - .word SVC_Handler - .word DebugMon_Handler - .word 0 - .word PendSV_Handler - .word SysTick_Handler - .word WWDG_IRQHandler - .word PVD_PVM_IRQHandler - .word TAMP_STAMP_LSECSS_IRQHandler - .word RTC_WKUP_IRQHandler - .word FLASH_IRQHandler - .word RCC_IRQHandler - .word EXTI0_IRQHandler - .word EXTI1_IRQHandler - .word EXTI2_IRQHandler - .word EXTI3_IRQHandler - .word EXTI4_IRQHandler - .word DMA1_Channel1_IRQHandler - .word DMA1_Channel2_IRQHandler - .word DMA1_Channel3_IRQHandler - .word DMA1_Channel4_IRQHandler - .word DMA1_Channel5_IRQHandler - .word DMA1_Channel6_IRQHandler - .word DMA1_Channel7_IRQHandler - .word ADC1_IRQHandler - .word USB_HP_IRQHandler - .word USB_LP_IRQHandler - .word C2SEV_PWR_C2H_IRQHandler - .word COMP_IRQHandler - .word EXTI9_5_IRQHandler - .word TIM1_BRK_IRQHandler - .word TIM1_UP_TIM16_IRQHandler - .word TIM1_TRG_COM_TIM17_IRQHandler - .word TIM1_CC_IRQHandler - .word TIM2_IRQHandler - .word PKA_IRQHandler - .word I2C1_EV_IRQHandler - .word I2C1_ER_IRQHandler - .word I2C3_EV_IRQHandler - .word I2C3_ER_IRQHandler - .word SPI1_IRQHandler - .word SPI2_IRQHandler - .word USART1_IRQHandler - .word LPUART1_IRQHandler - .word SAI1_IRQHandler - .word TSC_IRQHandler - .word EXTI15_10_IRQHandler - .word RTC_Alarm_IRQHandler - .word CRS_IRQHandler - .word PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler - .word IPCC_C1_RX_IRQHandler - .word IPCC_C1_TX_IRQHandler - .word HSEM_IRQHandler - .word LPTIM1_IRQHandler - .word LPTIM2_IRQHandler - .word LCD_IRQHandler - .word QUADSPI_IRQHandler - .word AES1_IRQHandler - .word AES2_IRQHandler - .word RNG_IRQHandler - .word FPU_IRQHandler - .word DMA2_Channel1_IRQHandler - .word DMA2_Channel2_IRQHandler - .word DMA2_Channel3_IRQHandler - .word DMA2_Channel4_IRQHandler - .word DMA2_Channel5_IRQHandler - .word DMA2_Channel6_IRQHandler - .word DMA2_Channel7_IRQHandler - .word DMAMUX1_OVR_IRQHandler - -/******************************************************************************* -* -* Provide weak aliases for each Exception handler to the Default_Handler. -* As they are weak aliases, any function with the same name will override -* this definition. -* -*******************************************************************************/ - .weak NMI_Handler - .thumb_set NMI_Handler,Default_Handler - - .weak HardFault_Handler - .thumb_set HardFault_Handler,Default_Handler - - .weak MemManage_Handler - .thumb_set MemManage_Handler,Default_Handler - - .weak BusFault_Handler - .thumb_set BusFault_Handler,Default_Handler - - .weak UsageFault_Handler - .thumb_set UsageFault_Handler,Default_Handler - - .weak SVC_Handler - .thumb_set SVC_Handler,Default_Handler - - .weak DebugMon_Handler - .thumb_set DebugMon_Handler,Default_Handler - - .weak PendSV_Handler - .thumb_set PendSV_Handler,Default_Handler - - .weak SysTick_Handler - .thumb_set SysTick_Handler,Default_Handler - - .weak WWDG_IRQHandler - .thumb_set WWDG_IRQHandler,Default_Handler - - .weak PVD_PVM_IRQHandler - .thumb_set PVD_PVM_IRQHandler,Default_Handler - - .weak TAMP_STAMP_LSECSS_IRQHandler - .thumb_set TAMP_STAMP_LSECSS_IRQHandler,Default_Handler - - .weak RTC_WKUP_IRQHandler - .thumb_set RTC_WKUP_IRQHandler,Default_Handler - - .weak FLASH_IRQHandler - .thumb_set FLASH_IRQHandler,Default_Handler - - .weak RCC_IRQHandler - .thumb_set RCC_IRQHandler,Default_Handler - - .weak EXTI0_IRQHandler - .thumb_set EXTI0_IRQHandler,Default_Handler - - .weak EXTI1_IRQHandler - .thumb_set EXTI1_IRQHandler,Default_Handler - - .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler - - .weak EXTI3_IRQHandler - .thumb_set EXTI3_IRQHandler,Default_Handler - - .weak EXTI4_IRQHandler - .thumb_set EXTI4_IRQHandler,Default_Handler - - .weak DMA1_Channel1_IRQHandler - .thumb_set DMA1_Channel1_IRQHandler,Default_Handler - - .weak DMA1_Channel2_IRQHandler - .thumb_set DMA1_Channel2_IRQHandler,Default_Handler - - .weak DMA1_Channel3_IRQHandler - .thumb_set DMA1_Channel3_IRQHandler,Default_Handler - - .weak DMA1_Channel4_IRQHandler - .thumb_set DMA1_Channel4_IRQHandler,Default_Handler - - .weak DMA1_Channel5_IRQHandler - .thumb_set DMA1_Channel5_IRQHandler,Default_Handler - - .weak DMA1_Channel6_IRQHandler - .thumb_set DMA1_Channel6_IRQHandler,Default_Handler - - .weak DMA1_Channel7_IRQHandler - .thumb_set DMA1_Channel7_IRQHandler,Default_Handler - - .weak ADC1_IRQHandler - .thumb_set ADC1_IRQHandler,Default_Handler - - .weak USB_HP_IRQHandler - .thumb_set USB_HP_IRQHandler,Default_Handler - - .weak USB_LP_IRQHandler - .thumb_set USB_LP_IRQHandler,Default_Handler - - .weak C2SEV_PWR_C2H_IRQHandler - .thumb_set C2SEV_PWR_C2H_IRQHandler,Default_Handler - - .weak COMP_IRQHandler - .thumb_set COMP_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_IRQHandler - .thumb_set TIM1_BRK_IRQHandler,Default_Handler - - .weak TIM1_UP_TIM16_IRQHandler - .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_TIM17_IRQHandler - .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_IRQHandler,Default_Handler - - .weak TIM2_IRQHandler - .thumb_set TIM2_IRQHandler,Default_Handler - - .weak PKA_IRQHandler - .thumb_set PKA_IRQHandler,Default_Handler - - .weak I2C1_EV_IRQHandler - .thumb_set I2C1_EV_IRQHandler,Default_Handler - - .weak I2C1_ER_IRQHandler - .thumb_set I2C1_ER_IRQHandler,Default_Handler - - .weak I2C3_EV_IRQHandler - .thumb_set I2C3_EV_IRQHandler,Default_Handler - - .weak I2C3_ER_IRQHandler - .thumb_set I2C3_ER_IRQHandler,Default_Handler - - .weak SPI1_IRQHandler - .thumb_set SPI1_IRQHandler,Default_Handler - - .weak SPI2_IRQHandler - .thumb_set SPI2_IRQHandler,Default_Handler - - .weak USART1_IRQHandler - .thumb_set USART1_IRQHandler,Default_Handler - - .weak LPUART1_IRQHandler - .thumb_set LPUART1_IRQHandler,Default_Handler - - .weak SAI1_IRQHandler - .thumb_set SAI1_IRQHandler,Default_Handler - - .weak TSC_IRQHandler - .thumb_set TSC_IRQHandler,Default_Handler - - .weak EXTI15_10_IRQHandler - .thumb_set EXTI15_10_IRQHandler,Default_Handler - - .weak RTC_Alarm_IRQHandler - .thumb_set RTC_Alarm_IRQHandler,Default_Handler - - .weak CRS_IRQHandler - .thumb_set CRS_IRQHandler,Default_Handler - - .weak PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler - .thumb_set PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,Default_Handler - - .weak IPCC_C1_RX_IRQHandler - .thumb_set IPCC_C1_RX_IRQHandler,Default_Handler - - .weak IPCC_C1_TX_IRQHandler - .thumb_set IPCC_C1_TX_IRQHandler,Default_Handler - - .weak HSEM_IRQHandler - .thumb_set HSEM_IRQHandler,Default_Handler - - .weak LPTIM1_IRQHandler - .thumb_set LPTIM1_IRQHandler,Default_Handler - - .weak LPTIM2_IRQHandler - .thumb_set LPTIM2_IRQHandler,Default_Handler - - .weak LCD_IRQHandler - .thumb_set LCD_IRQHandler,Default_Handler - - .weak QUADSPI_IRQHandler - .thumb_set QUADSPI_IRQHandler,Default_Handler - - .weak AES1_IRQHandler - .thumb_set AES1_IRQHandler,Default_Handler - - .weak AES2_IRQHandler - .thumb_set AES2_IRQHandler,Default_Handler - - .weak RNG_IRQHandler - .thumb_set RNG_IRQHandler,Default_Handler - - .weak FPU_IRQHandler - .thumb_set FPU_IRQHandler,Default_Handler - - .weak DMA2_Channel1_IRQHandler - .thumb_set DMA2_Channel1_IRQHandler,Default_Handler - - .weak DMA2_Channel2_IRQHandler - .thumb_set DMA2_Channel2_IRQHandler,Default_Handler - - .weak DMA2_Channel3_IRQHandler - .thumb_set DMA2_Channel3_IRQHandler,Default_Handler - - .weak DMA2_Channel4_IRQHandler - .thumb_set DMA2_Channel4_IRQHandler,Default_Handler - - .weak DMA2_Channel5_IRQHandler - .thumb_set DMA2_Channel5_IRQHandler,Default_Handler - - .weak DMA2_Channel6_IRQHandler - .thumb_set DMA2_Channel6_IRQHandler,Default_Handler - - .weak DMA2_Channel7_IRQHandler - .thumb_set DMA2_Channel7_IRQHandler,Default_Handler - - .weak DMAMUX1_OVR_IRQHandler - .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file startup_stm32wb55xx_cm4.s + * @author MCD Application Team + * @brief STM32WB55xx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* start address for the .MB_MEM2 section. defined in linker script */ +.word _sMB_MEM2 +/* end address for the .MB_MEM2 section. defined in linker script */ +.word _eMB_MEM2 + +/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */ +.macro INIT_BSS start, end + ldr r0, =\start + ldr r1, =\end + movs r3, #0 + bl LoopFillZerobss +.endm + +/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */ +.macro INIT_DATA start, end, src + ldr r0, =\start + ldr r1, =\end + ldr r2, =\src + movs r3, #0 + bl LoopCopyDataInit +.endm + +.section .text.data_initializers +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + bx lr + +FillZerobss: + str r3, [r0] + adds r0, r0, #4 + +LoopFillZerobss: + cmp r0, r1 + bcc FillZerobss + bx lr + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + mov sp, r0 /* set stack pointer */ +/* Call the clock system intitialization function.*/ + bl SystemInit + +/* Copy the data segment initializers from flash to SRAM */ + INIT_DATA _sdata, _edata, _sidata + +/* Zero fill the bss segments. */ + INIT_BSS _sbss, _ebss + INIT_BSS _sMB_MEM2, _eMB_MEM2 + +/* Call static constructors */ + bl __libc_init_array +/* Call the application s entry point.*/ + bl main + +LoopForever: + b LoopForever + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex-M4. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_PVM_IRQHandler + .word TAMP_STAMP_LSECSS_IRQHandler + .word RTC_WKUP_IRQHandler + .word FLASH_IRQHandler + .word RCC_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word DMA1_Channel5_IRQHandler + .word DMA1_Channel6_IRQHandler + .word DMA1_Channel7_IRQHandler + .word ADC1_IRQHandler + .word USB_HP_IRQHandler + .word USB_LP_IRQHandler + .word C2SEV_PWR_C2H_IRQHandler + .word COMP_IRQHandler + .word EXTI9_5_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_TIM16_IRQHandler + .word TIM1_TRG_COM_TIM17_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word PKA_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word USART1_IRQHandler + .word LPUART1_IRQHandler + .word SAI1_IRQHandler + .word TSC_IRQHandler + .word EXTI15_10_IRQHandler + .word RTC_Alarm_IRQHandler + .word CRS_IRQHandler + .word PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .word IPCC_C1_RX_IRQHandler + .word IPCC_C1_TX_IRQHandler + .word HSEM_IRQHandler + .word LPTIM1_IRQHandler + .word LPTIM2_IRQHandler + .word LCD_IRQHandler + .word QUADSPI_IRQHandler + .word AES1_IRQHandler + .word AES2_IRQHandler + .word RNG_IRQHandler + .word FPU_IRQHandler + .word DMA2_Channel1_IRQHandler + .word DMA2_Channel2_IRQHandler + .word DMA2_Channel3_IRQHandler + .word DMA2_Channel4_IRQHandler + .word DMA2_Channel5_IRQHandler + .word DMA2_Channel6_IRQHandler + .word DMA2_Channel7_IRQHandler + .word DMAMUX1_OVR_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak TAMP_STAMP_LSECSS_IRQHandler + .thumb_set TAMP_STAMP_LSECSS_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_IRQHandler + .thumb_set DMA1_Channel2_IRQHandler,Default_Handler + + .weak DMA1_Channel3_IRQHandler + .thumb_set DMA1_Channel3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_IRQHandler + .thumb_set DMA1_Channel4_IRQHandler,Default_Handler + + .weak DMA1_Channel5_IRQHandler + .thumb_set DMA1_Channel5_IRQHandler,Default_Handler + + .weak DMA1_Channel6_IRQHandler + .thumb_set DMA1_Channel6_IRQHandler,Default_Handler + + .weak DMA1_Channel7_IRQHandler + .thumb_set DMA1_Channel7_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak USB_HP_IRQHandler + .thumb_set USB_HP_IRQHandler,Default_Handler + + .weak USB_LP_IRQHandler + .thumb_set USB_LP_IRQHandler,Default_Handler + + .weak C2SEV_PWR_C2H_IRQHandler + .thumb_set C2SEV_PWR_C2H_IRQHandler,Default_Handler + + .weak COMP_IRQHandler + .thumb_set COMP_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM16_IRQHandler + .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_TIM17_IRQHandler + .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak TSC_IRQHandler + .thumb_set TSC_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .thumb_set PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,Default_Handler + + .weak IPCC_C1_RX_IRQHandler + .thumb_set IPCC_C1_RX_IRQHandler,Default_Handler + + .weak IPCC_C1_TX_IRQHandler + .thumb_set IPCC_C1_TX_IRQHandler,Default_Handler + + .weak HSEM_IRQHandler + .thumb_set HSEM_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak LCD_IRQHandler + .thumb_set LCD_IRQHandler,Default_Handler + + .weak QUADSPI_IRQHandler + .thumb_set QUADSPI_IRQHandler,Default_Handler + + .weak AES1_IRQHandler + .thumb_set AES1_IRQHandler,Default_Handler + + .weak AES2_IRQHandler + .thumb_set AES2_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak DMA2_Channel1_IRQHandler + .thumb_set DMA2_Channel1_IRQHandler,Default_Handler + + .weak DMA2_Channel2_IRQHandler + .thumb_set DMA2_Channel2_IRQHandler,Default_Handler + + .weak DMA2_Channel3_IRQHandler + .thumb_set DMA2_Channel3_IRQHandler,Default_Handler + + .weak DMA2_Channel4_IRQHandler + .thumb_set DMA2_Channel4_IRQHandler,Default_Handler + + .weak DMA2_Channel5_IRQHandler + .thumb_set DMA2_Channel5_IRQHandler,Default_Handler + + .weak DMA2_Channel6_IRQHandler + .thumb_set DMA2_Channel6_IRQHandler,Default_Handler + + .weak DMA2_Channel7_IRQHandler + .thumb_set DMA2_Channel7_IRQHandler,Default_Handler + + .weak DMAMUX1_OVR_IRQHandler + .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/cube/stm32wb55xx_flash_cm4.ld b/firmware/targets/f6/cube/stm32wb55xx_flash_cm4.ld index 226505bf..fc975f4a 100644 --- a/firmware/targets/f6/cube/stm32wb55xx_flash_cm4.ld +++ b/firmware/targets/f6/cube/stm32wb55xx_flash_cm4.ld @@ -56,7 +56,7 @@ _Min_Stack_Size = 0x1000; /* required amount of stack */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K -RAM1 (xrw) : ORIGIN = 0x20000004, LENGTH = 0x2FFFC +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K } diff --git a/firmware/targets/f6/furi-hal/furi-hal-clock.c b/firmware/targets/f6/furi-hal/furi-hal-clock.c index 59637ddb..0ed918e3 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-clock.c +++ b/firmware/targets/f6/furi-hal/furi-hal-clock.c @@ -88,6 +88,7 @@ void furi_hal_clock_init() { LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1); + LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_PLLSAI1); LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1); LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); diff --git a/firmware/targets/f6/furi-hal/furi-hal-rfid.c b/firmware/targets/f6/furi-hal/furi-hal-rfid.c index 4990c5a9..f4d8ff6b 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-rfid.c +++ b/firmware/targets/f6/furi-hal/furi-hal-rfid.c @@ -9,6 +9,10 @@ #define LFRFID_EMULATE_TIM htim2 #define LFRFID_EMULATE_CHANNEL TIM_CHANNEL_3 +void furi_hal_rfid_init() { + furi_hal_rfid_pins_reset(); +} + void furi_hal_rfid_pins_reset() { // ibutton bus disable furi_hal_ibutton_stop(); diff --git a/firmware/targets/f6/furi-hal/furi-hal.c b/firmware/targets/f6/furi-hal/furi-hal.c index 3dc94a50..eebe1423 100644 --- a/firmware/targets/f6/furi-hal/furi-hal.c +++ b/firmware/targets/f6/furi-hal/furi-hal.c @@ -58,6 +58,7 @@ void furi_hal_init() { furi_hal_vibro_init(); furi_hal_subghz_init(); furi_hal_nfc_init(); + furi_hal_rfid_init(); // FreeRTOS glue furi_hal_os_init(); diff --git a/firmware/targets/f6/stm32wb55xx_flash_cm4_boot.ld b/firmware/targets/f6/stm32wb55xx_flash_cm4_boot.ld index f87127cc..6d55107e 100644 --- a/firmware/targets/f6/stm32wb55xx_flash_cm4_boot.ld +++ b/firmware/targets/f6/stm32wb55xx_flash_cm4_boot.ld @@ -56,7 +56,7 @@ _Min_Stack_Size = 0x1000; /* required amount of stack */ MEMORY { FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 992K -RAM1 (xrw) : ORIGIN = 0x20000004, LENGTH = 0x2FFFC +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K } diff --git a/firmware/targets/f6/stm32wb55xx_flash_cm4_no_boot.ld b/firmware/targets/f6/stm32wb55xx_flash_cm4_no_boot.ld index ac7a1015..c03809f3 100644 --- a/firmware/targets/f6/stm32wb55xx_flash_cm4_no_boot.ld +++ b/firmware/targets/f6/stm32wb55xx_flash_cm4_no_boot.ld @@ -56,7 +56,7 @@ _Min_Stack_Size = 0x1000; /* required amount of stack */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K -RAM1 (xrw) : ORIGIN = 0x20000004, LENGTH = 0x2FFFC +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K } diff --git a/firmware/targets/f7/Inc/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h new file mode 100644 index 00000000..1e32e894 --- /dev/null +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -0,0 +1,180 @@ +/* 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 + extern uint32_t SystemCoreClock; +#endif +#ifndef CMSIS_device_header +#define CMSIS_device_header "stm32wbxx.h" +#endif /* CMSIS_device_header */ + +#define configENABLE_FPU 1 +#define configENABLE_MPU 1 + +#define configUSE_PREEMPTION 1 +#define configSUPPORT_STATIC_ALLOCATION 0 +#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) +/* Heap size determined automatically by linker */ +// #define configTOTAL_HEAP_SIZE ((size_t)0) +#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 32 +#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_eTaskGetState 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerPendFunctionCall 1 + +/* CMSIS-RTOS V2 flags */ +#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 +#define configUSE_OS2_THREAD_ENUMERATE 1 +#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 +#define configUSE_OS2_THREAD_FLAGS 1 +#define configUSE_OS2_TIMER 1 +#define configUSE_OS2_MUTEX 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: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */ + +#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1 + +/* USER CODE BEGIN Defines */ +/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ +#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 1 /* required only for Keil but does not hurt otherwise */ +/* USER CODE END Defines */ + +#endif /* FREERTOS_CONFIG_H */ diff --git a/firmware/targets/f7/Inc/aes.h b/firmware/targets/f7/Inc/aes.h new file mode 100644 index 00000000..bde8ad5a --- /dev/null +++ b/firmware/targets/f7/Inc/aes.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * @file aes.h + * @brief This file contains all the function prototypes for + * the aes.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Inc/comp.h b/firmware/targets/f7/Inc/comp.h new file mode 100644 index 00000000..5cc7f16e --- /dev/null +++ b/firmware/targets/f7/Inc/comp.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file comp.h + * @brief This file contains all the function prototypes for + * the comp.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Inc/gpio.h b/firmware/targets/f7/Inc/gpio.h new file mode 100644 index 00000000..6b6fe6fb --- /dev/null +++ b/firmware/targets/f7/Inc/gpio.h @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * @file gpio.h + * @brief This file contains all the function prototypes for + * the gpio.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Inc/main.h b/firmware/targets/f7/Inc/main.h new file mode 100644 index 00000000..7462a3ba --- /dev/null +++ b/firmware/targets/f7/Inc/main.h @@ -0,0 +1,149 @@ +#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_CARRIER_GPIO_Port GPIOA +#define RFID_CARRIER_Pin GPIO_PIN_15 + +#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_8 + +#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 + +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 diff --git a/firmware/targets/f7/Inc/pka.h b/firmware/targets/f7/Inc/pka.h new file mode 100644 index 00000000..377ed010 --- /dev/null +++ b/firmware/targets/f7/Inc/pka.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file pka.h + * @brief This file contains all the function prototypes for + * the pka.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Inc/rf.h b/firmware/targets/f7/Inc/rf.h new file mode 100644 index 00000000..1796e939 --- /dev/null +++ b/firmware/targets/f7/Inc/rf.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * @file rf.h + * @brief This file contains all the function prototypes for + * the rf.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Inc/rng.h b/firmware/targets/f7/Inc/rng.h new file mode 100644 index 00000000..fa121ad1 --- /dev/null +++ b/firmware/targets/f7/Inc/rng.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file rng.h + * @brief This file contains all the function prototypes for + * the rng.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Inc/rtc.h b/firmware/targets/f7/Inc/rtc.h new file mode 100644 index 00000000..3e961b71 --- /dev/null +++ b/firmware/targets/f7/Inc/rtc.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file rtc.h + * @brief This file contains all the function prototypes for + * the rtc.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h b/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h new file mode 100644 index 00000000..1c96d8cd --- /dev/null +++ b/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h @@ -0,0 +1,353 @@ +/** + ****************************************************************************** + * @file stm32wbxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 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 + * + ****************************************************************************** + */ + +/* 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****/ diff --git a/firmware/targets/f7/Inc/stm32wbxx_it.h b/firmware/targets/f7/Inc/stm32wbxx_it.h new file mode 100644 index 00000000..1804c941 --- /dev/null +++ b/firmware/targets/f7/Inc/stm32wbxx_it.h @@ -0,0 +1,69 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbxx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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 SysTick_Handler(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****/ diff --git a/firmware/targets/f7/Inc/tim.h b/firmware/targets/f7/Inc/tim.h new file mode 100644 index 00000000..9d530bce --- /dev/null +++ b/firmware/targets/f7/Inc/tim.h @@ -0,0 +1,58 @@ +/** + ****************************************************************************** + * @file tim.h + * @brief This file contains all the function prototypes for + * the tim.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/aes.c b/firmware/targets/f7/Src/aes.c new file mode 100644 index 00000000..1a042e9b --- /dev/null +++ b/firmware/targets/f7/Src/aes.c @@ -0,0 +1,127 @@ +/** + ****************************************************************************** + * @file aes.c + * @brief This file provides code for the configuration + * of the AES instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/comp.c b/firmware/targets/f7/Src/comp.c new file mode 100644 index 00000000..9401ed34 --- /dev/null +++ b/firmware/targets/f7/Src/comp.c @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * @file comp.c + * @brief This file provides code for the configuration + * of the COMP instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/fatfs/fatfs.c b/firmware/targets/f7/Src/fatfs/fatfs.c new file mode 100644 index 00000000..d52b3d4e --- /dev/null +++ b/firmware/targets/f7/Src/fatfs/fatfs.c @@ -0,0 +1,56 @@ +/** + ****************************************************************************** + * @file fatfs.c + * @brief Code for fatfs applications + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/fatfs/fatfs.h b/firmware/targets/f7/Src/fatfs/fatfs.h new file mode 100644 index 00000000..a0775d88 --- /dev/null +++ b/firmware/targets/f7/Src/fatfs/fatfs.h @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * @file fatfs.h + * @brief Header for fatfs applications + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/fatfs/ffconf.h b/firmware/targets/f7/Src/fatfs/ffconf.h new file mode 100644 index 00000000..d32d49a4 --- /dev/null +++ b/firmware/targets/f7/Src/fatfs/ffconf.h @@ -0,0 +1,270 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * FatFs - Generic FAT file system module R0.12c (C)ChaN, 2017 + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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 0 +/* 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 0 +/* 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 0 /* 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 1 +#define _NORTC_MON 7 +#define _NORTC_MDAY 20 +#define _NORTC_YEAR 2021 +/* 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 0 /* 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 0 /* 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 +#define ff_malloc malloc +#define ff_free free +#endif + +#endif /* _FFCONF */ diff --git a/firmware/targets/f7/Src/fatfs/spi_sd_hal.c b/firmware/targets/f7/Src/fatfs/spi_sd_hal.c new file mode 100644 index 00000000..70e9bbf1 --- /dev/null +++ b/firmware/targets/f7/Src/fatfs/spi_sd_hal.c @@ -0,0 +1,100 @@ +#include "main.h" +#include +#include + +#define SD_DUMMY_BYTE 0xFF + +const uint32_t SpiTimeout = 1000; +uint8_t SD_IO_WriteByte(uint8_t Data); + +static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDeviceIdSdCardFast]; + +/****************************************************************************** + BUS OPERATIONS + *******************************************************************************/ + +/** + * @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) { + furi_check(furi_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); +} + +/** + * @brief SPI Write a byte to device + * @param Value: value to be written + * @retval None + */ +__attribute__((unused)) static void SPIx_Write(uint8_t Value) { + furi_check(furi_hal_spi_bus_tx(sd_spi_dev->bus, (uint8_t*)&Value, 1, SpiTimeout)); +} + +/****************************************************************************** + 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 */ + hal_gpio_write(sd_spi_dev->chip_select, true); + delay_us(10); + + /* 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) { + /* Some SD Cards are prone to fail if CLK-ed too soon after CS transition. Worst case found: 8us */ + if(val == 1) { + delay_us(10); // Exit guard time for some SD cards + hal_gpio_write(sd_spi_dev->chip_select, true); + } else { + hal_gpio_write(sd_spi_dev->chip_select, false); + delay_us(10); // Entry guard time for some SD cards + } +} + +/** + * @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; +} diff --git a/firmware/targets/f7/Src/fatfs/stm32_adafruit_sd.c b/firmware/targets/f7/Src/fatfs/stm32_adafruit_sd.c new file mode 100644 index 00000000..e90ebd62 --- /dev/null +++ b/firmware/targets/f7/Src/fatfs/stm32_adafruit_sd.c @@ -0,0 +1,1073 @@ +/** + ****************************************************************************** + * @file stm32_adafruit_sd.c + * @author MCD Application Team + * @version V3.0.0 + * @date 23-December-2016 + * @brief This file provides a set of functions needed to manage the SD card + * mounted on the Adafruit 1.8" TFT LCD shield (reference ID 802), + * that is used with the STM32 Nucleo board through SPI interface. + * It implements a high level communication layer for read and write + * from/to this memory. The needed STM32XXxx hardware resources (SPI and + * GPIO) are defined in stm32XXxx_nucleo.h file, and the initialization is + * performed in SD_IO_Init() function declared in stm32XXxx_nucleo.c + * file. + * You can easily tailor this driver to any other development board, + * by just adapting the defines for hardware resources and + * SD_IO_Init() function. + * + * +-------------------------------------------------------+ + * | Pin assignment | + * +-------------------------+---------------+-------------+ + * | STM32XXxx SPI Pins | SD | Pin | + * +-------------------------+---------------+-------------+ + * | SD_SPI_CS_PIN | ChipSelect | 1 | + * | SD_SPI_MOSI_PIN / MOSI | DataIn | 2 | + * | | GND | 3 (0 V) | + * | | VDD | 4 (3.3 V)| + * | SD_SPI_SCK_PIN / SCLK | Clock | 5 | + * | | GND | 6 (0 V) | + * | SD_SPI_MISO_PIN / MISO | DataOut | 7 | + * +-------------------------+---------------+-------------+ + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2016 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + */ + +/* File Info : ----------------------------------------------------------------- + User NOTES +1. How to use this driver: +-------------------------- + - This driver does not need a specific component driver for the micro SD device + to be included with. + +2. Driver description: +--------------------- + + Initialization steps: + o Initialize the micro SD card using the BSP_SD_Init() function. + o Checking the SD card presence is not managed because SD detection pin is + not physically mapped on the Adafruit shield. + o The function BSP_SD_GetCardInfo() is used to get the micro SD card information + which is stored in the structure "SD_CardInfo". + + + Micro SD card operations + o The micro SD card can be accessed with read/write block(s) operations once + it is ready for access. The access can be performed in polling + mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks() + + o The SD erase block(s) is performed using the function BSP_SD_Erase() with + specifying the number of blocks to erase. + o The SD runtime status is returned when calling the function BSP_SD_GetStatus(). + +------------------------------------------------------------------------------*/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_adafruit_sd.h" +#include "stdlib.h" +#include "string.h" +#include "stdio.h" +#include +#include +#include +#include +#include +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32_ADAFRUIT + * @{ + */ + +/** @defgroup STM32_ADAFRUIT_SD + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ + +/** @defgroup STM32_ADAFRUIT_SD_Private_Types_Definitions + * @{ + */ +typedef struct { + uint8_t r1; + uint8_t r2; + uint8_t r3; + uint8_t r4; + uint8_t r5; +} SD_CmdAnswer_typedef; + +/** + * @} + */ + +/* Private define ------------------------------------------------------------*/ + +/** @defgroup STM32_ADAFRUIT_SD_Private_Defines + * @{ + */ +#define SD_DUMMY_BYTE 0xFF + +#define SD_MAX_FRAME_LENGTH 17 /* Lenght = 16 + 1 */ +#define SD_CMD_LENGTH 6 + +#define SD_MAX_TRY 100 /* Number of try */ + +#define SD_CSD_STRUCT_V1 0x2 /* CSD struct version V1 */ +#define SD_CSD_STRUCT_V2 0x1 /* CSD struct version V2 */ + +/** + * @brief SD ansewer format + */ +typedef enum { + SD_ANSWER_R1_EXPECTED, + SD_ANSWER_R1B_EXPECTED, + SD_ANSWER_R2_EXPECTED, + SD_ANSWER_R3_EXPECTED, + SD_ANSWER_R4R5_EXPECTED, + SD_ANSWER_R7_EXPECTED, +} SD_Answer_type; + +/** + * @brief Start Data tokens: + * Tokens (necessary because at nop/idle (and CS active) only 0xff is + * on the data/command line) + */ +#define SD_TOKEN_START_DATA_SINGLE_BLOCK_READ \ + 0xFE /* Data token start byte, Start Single Block Read */ +#define SD_TOKEN_START_DATA_MULTIPLE_BLOCK_READ \ + 0xFE /* Data token start byte, Start Multiple Block Read */ +#define SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE \ + 0xFE /* Data token start byte, Start Single Block Write */ +#define SD_TOKEN_START_DATA_MULTIPLE_BLOCK_WRITE \ + 0xFD /* Data token start byte, Start Multiple Block Write */ +#define SD_TOKEN_STOP_DATA_MULTIPLE_BLOCK_WRITE \ + 0xFD /* Data toke stop byte, Stop Multiple Block Write */ + +/** + * @brief Commands: CMDxx = CMD-number | 0x40 + */ +#define SD_CMD_GO_IDLE_STATE 0 /* CMD0 = 0x40 */ +#define SD_CMD_SEND_OP_COND 1 /* CMD1 = 0x41 */ +#define SD_CMD_SEND_IF_COND 8 /* CMD8 = 0x48 */ +#define SD_CMD_SEND_CSD 9 /* CMD9 = 0x49 */ +#define SD_CMD_SEND_CID 10 /* CMD10 = 0x4A */ +#define SD_CMD_STOP_TRANSMISSION 12 /* CMD12 = 0x4C */ +#define SD_CMD_SEND_STATUS 13 /* CMD13 = 0x4D */ +#define SD_CMD_SET_BLOCKLEN 16 /* CMD16 = 0x50 */ +#define SD_CMD_READ_SINGLE_BLOCK 17 /* CMD17 = 0x51 */ +#define SD_CMD_READ_MULT_BLOCK 18 /* CMD18 = 0x52 */ +#define SD_CMD_SET_BLOCK_COUNT 23 /* CMD23 = 0x57 */ +#define SD_CMD_WRITE_SINGLE_BLOCK 24 /* CMD24 = 0x58 */ +#define SD_CMD_WRITE_MULT_BLOCK 25 /* CMD25 = 0x59 */ +#define SD_CMD_PROG_CSD 27 /* CMD27 = 0x5B */ +#define SD_CMD_SET_WRITE_PROT 28 /* CMD28 = 0x5C */ +#define SD_CMD_CLR_WRITE_PROT 29 /* CMD29 = 0x5D */ +#define SD_CMD_SEND_WRITE_PROT 30 /* CMD30 = 0x5E */ +#define SD_CMD_SD_ERASE_GRP_START 32 /* CMD32 = 0x60 */ +#define SD_CMD_SD_ERASE_GRP_END 33 /* CMD33 = 0x61 */ +#define SD_CMD_UNTAG_SECTOR 34 /* CMD34 = 0x62 */ +#define SD_CMD_ERASE_GRP_START 35 /* CMD35 = 0x63 */ +#define SD_CMD_ERASE_GRP_END 36 /* CMD36 = 0x64 */ +#define SD_CMD_UNTAG_ERASE_GROUP 37 /* CMD37 = 0x65 */ +#define SD_CMD_ERASE 38 /* CMD38 = 0x66 */ +#define SD_CMD_SD_APP_OP_COND 41 /* CMD41 = 0x69 */ +#define SD_CMD_APP_CMD 55 /* CMD55 = 0x77 */ +#define SD_CMD_READ_OCR 58 /* CMD55 = 0x79 */ + +/** + * @brief SD reponses and error flags + */ +typedef enum { + /* R1 answer value */ + SD_R1_NO_ERROR = (0x00), + SD_R1_IN_IDLE_STATE = (0x01), + SD_R1_ERASE_RESET = (0x02), + SD_R1_ILLEGAL_COMMAND = (0x04), + SD_R1_COM_CRC_ERROR = (0x08), + SD_R1_ERASE_SEQUENCE_ERROR = (0x10), + SD_R1_ADDRESS_ERROR = (0x20), + SD_R1_PARAMETER_ERROR = (0x40), + + /* R2 answer value */ + SD_R2_NO_ERROR = 0x00, + SD_R2_CARD_LOCKED = 0x01, + SD_R2_LOCKUNLOCK_ERROR = 0x02, + SD_R2_ERROR = 0x04, + SD_R2_CC_ERROR = 0x08, + SD_R2_CARD_ECC_FAILED = 0x10, + SD_R2_WP_VIOLATION = 0x20, + SD_R2_ERASE_PARAM = 0x40, + SD_R2_OUTOFRANGE = 0x80, + + /** + * @brief Data response error + */ + SD_DATA_OK = (0x05), + SD_DATA_CRC_ERROR = (0x0B), + SD_DATA_WRITE_ERROR = (0x0D), + SD_DATA_OTHER_ERROR = (0xFF) +} SD_Error; + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ + +/** @defgroup STM32_ADAFRUIT_SD_Private_Macros + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ + +/** @defgroup STM32_ADAFRUIT_SD_Private_Variables + * @{ + */ +__IO uint8_t SdStatus = SD_NOT_PRESENT; + +/* flag_SDHC : + 0 : Standard capacity + 1 : High capacity +*/ +uint16_t flag_SDHC = 0; + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +static uint8_t SD_GetCIDRegister(SD_CID* Cid); +static uint8_t SD_GetCSDRegister(SD_CSD* Csd); +static uint8_t SD_GetDataResponse(void); +static uint8_t SD_GoIdleState(void); +static SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Answer); +static uint8_t SD_WaitData(uint8_t data); +static uint8_t SD_ReadData(void); +/** @defgroup STM32_ADAFRUIT_SD_Private_Function_Prototypes + * @{ + */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +void SD_SPI_Bus_To_Down_State(){ + hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + + hal_gpio_write(&gpio_sdcard_cs, false); + hal_gpio_write(&gpio_spi_d_miso, false); + hal_gpio_write(&gpio_spi_d_mosi, false); + hal_gpio_write(&gpio_spi_d_sck, false); +} + +void SD_SPI_Bus_To_Normal_State(){ + hal_gpio_write(&gpio_sdcard_cs, true); + + hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); +} + +/** @defgroup STM32_ADAFRUIT_SD_Private_Functions + * @{ + */ + +/** + * @brief Initializes the SD/SD communication. + * @param None + * @retval The SD Response: + * - MSD_ERROR: Sequence failed + * - MSD_OK: Sequence succeed + */ +uint8_t BSP_SD_Init(bool reset_card) { + /* Slow speed init */ + const FuriHalSpiDevice* sd_spi_slow_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardSlow); + + /* We must reset card in spi_lock context */ + if(reset_card) { + /* disable power and set low on all bus pins */ + furi_hal_power_disable_external_3_3v(); + SD_SPI_Bus_To_Down_State(); + hal_sd_detect_set_low(); + delay(250); + + /* reinit bus and enable power */ + SD_SPI_Bus_To_Normal_State(); + hal_sd_detect_init(); + furi_hal_power_enable_external_3_3v(); + delay(100); + } + + /* Configure IO functionalities for SD pin */ + SD_IO_Init(); + + /* SD detection pin is not physically mapped on the Adafruit shield */ + SdStatus = SD_PRESENT; + uint8_t res = BSP_SD_ERROR; + + for(uint8_t i = 0; i < 128; i++) { + res = SD_GoIdleState(); + if(res == BSP_SD_OK) break; + } + + furi_hal_spi_device_return(sd_spi_slow_dev); + + /* SD initialized and set to SPI mode properly */ + return res; +} + +/** + * @brief Returns information about specific card. + * @param pCardInfo: Pointer to a SD_CardInfo structure that contains all SD + * card information. + * @retval The SD Response: + * - MSD_ERROR: Sequence failed + * - MSD_OK: Sequence succeed + */ +uint8_t BSP_SD_GetCardInfo(SD_CardInfo* pCardInfo) { + uint8_t status; + + status = SD_GetCSDRegister(&(pCardInfo->Csd)); + status |= SD_GetCIDRegister(&(pCardInfo->Cid)); + if(flag_SDHC == 1) { + pCardInfo->LogBlockSize = 512; + pCardInfo->CardBlockSize = 512; + pCardInfo->CardCapacity = ((uint64_t)pCardInfo->Csd.version.v2.DeviceSize + 1UL) * 1024UL * + (uint64_t)pCardInfo->LogBlockSize; + pCardInfo->LogBlockNbr = (pCardInfo->CardCapacity) / (pCardInfo->LogBlockSize); + } else { + pCardInfo->CardCapacity = (pCardInfo->Csd.version.v1.DeviceSize + 1); + pCardInfo->CardCapacity *= (1 << (pCardInfo->Csd.version.v1.DeviceSizeMul + 2)); + pCardInfo->LogBlockSize = 512; + pCardInfo->CardBlockSize = 1 << (pCardInfo->Csd.RdBlockLen); + pCardInfo->CardCapacity *= pCardInfo->CardBlockSize; + pCardInfo->LogBlockNbr = (pCardInfo->CardCapacity) / (pCardInfo->LogBlockSize); + } + + return status; +} + +/** + * @brief Reads block(s) from a specified address in the SD card, in polling mode. + * @param pData: Pointer to the buffer that will contain the data to transmit + * @param ReadAddr: Address from where data is to be read. The address is counted + * in blocks of 512bytes + * @param NumOfBlocks: Number of SD blocks to read + * @param Timeout: This parameter is used for compatibility with BSP implementation + * @retval SD status + */ +uint8_t +BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout) { + uint32_t offset = 0; + uint32_t addr; + uint8_t retr = BSP_SD_ERROR; + uint8_t* ptr = NULL; + SD_CmdAnswer_typedef response; + uint16_t BlockSize = 512; + + /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and + Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(response.r1 != SD_R1_NO_ERROR) { + goto error; + } + + ptr = malloc(sizeof(uint8_t) * BlockSize); + if(ptr == NULL) { + goto error; + } + memset(ptr, SD_DUMMY_BYTE, sizeof(uint8_t) * BlockSize); + + /* Initialize the address */ + addr = (ReadAddr * ((flag_SDHC == 1) ? 1 : BlockSize)); + + /* Data transfer */ + while(NumOfBlocks--) { + /* Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */ + /* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_READ_SINGLE_BLOCK, addr, 0xFF, SD_ANSWER_R1_EXPECTED); + if(response.r1 != SD_R1_NO_ERROR) { + goto error; + } + + /* Now look for the data token to signify the start of the data */ + if(SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK) { + /* Read the SD block data : read NumByteToRead data */ + SD_IO_WriteReadData(ptr, (uint8_t*)pData + offset, BlockSize); + + /* Set next read address*/ + offset += BlockSize; + addr = ((flag_SDHC == 1) ? (addr + 1) : (addr + BlockSize)); + + /* get CRC bytes (not really needed by us, but required by SD) */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } else { + goto error; + } + + /* End the command data read cycle */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + + retr = BSP_SD_OK; + +error: + /* Send dummy byte: 8 Clock pulses of delay */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(ptr != NULL) free(ptr); + + /* Return the reponse */ + return retr; +} + +/** + * @brief Writes block(s) to a specified address in the SD card, in polling mode. + * @param pData: Pointer to the buffer that will contain the data to transmit + * @param WriteAddr: Address from where data is to be written. The address is counted + * in blocks of 512bytes + * @param NumOfBlocks: Number of SD blocks to write + * @param Timeout: This parameter is used for compatibility with BSP implementation + * @retval SD status + */ +uint8_t +BSP_SD_WriteBlocks(uint32_t* pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout) { + uint32_t offset = 0; + uint32_t addr; + uint8_t retr = BSP_SD_ERROR; + uint8_t* ptr = NULL; + SD_CmdAnswer_typedef response; + uint16_t BlockSize = 512; + + /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and + Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(response.r1 != SD_R1_NO_ERROR) { + goto error; + } + + ptr = malloc(sizeof(uint8_t) * BlockSize); + if(ptr == NULL) { + goto error; + } + + /* Initialize the address */ + addr = (WriteAddr * ((flag_SDHC == 1) ? 1 : BlockSize)); + + /* Data transfer */ + while(NumOfBlocks--) { + /* Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks and + Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, addr, 0xFF, SD_ANSWER_R1_EXPECTED); + if(response.r1 != SD_R1_NO_ERROR) { + goto error; + } + + /* Send dummy byte for NWR timing : one byte between CMDWRITE and TOKEN */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Send the data token to signify the start of the data */ + SD_IO_WriteByte(SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE); + + /* Write the block data to SD */ + SD_IO_WriteReadData((uint8_t*)pData + offset, ptr, BlockSize); + + /* Set next write address */ + offset += BlockSize; + addr = ((flag_SDHC == 1) ? (addr + 1) : (addr + BlockSize)); + + /* Put CRC bytes (not really needed by us, but required by SD) */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Read data response */ + if(SD_GetDataResponse() != SD_DATA_OK) { + /* Set response value to failure */ + goto error; + } + + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + retr = BSP_SD_OK; + +error: + if(ptr != NULL) free(ptr); + /* Send dummy byte: 8 Clock pulses of delay */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Return the reponse */ + return retr; +} + +/** + * @brief Erases the specified memory area of the given SD card. + * @param StartAddr: Start address in Blocks (Size of a block is 512bytes) + * @param EndAddr: End address in Blocks (Size of a block is 512bytes) + * @retval SD status + */ +uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr) { + uint8_t retr = BSP_SD_ERROR; + SD_CmdAnswer_typedef response; + uint16_t BlockSize = 512; + + /* Send CMD32 (Erase group start) and check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ + response = SD_SendCmd( + SD_CMD_SD_ERASE_GRP_START, + (StartAddr) * (flag_SDHC == 1 ? 1 : BlockSize), + 0xFF, + SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(response.r1 == SD_R1_NO_ERROR) { + /* Send CMD33 (Erase group end) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ + response = SD_SendCmd( + SD_CMD_SD_ERASE_GRP_END, + (EndAddr * 512) * (flag_SDHC == 1 ? 1 : BlockSize), + 0xFF, + SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(response.r1 == SD_R1_NO_ERROR) { + /* Send CMD38 (Erase) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_ERASE, 0, 0xFF, SD_ANSWER_R1B_EXPECTED); + if(response.r1 == SD_R1_NO_ERROR) { + retr = BSP_SD_OK; + } + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + } + } + + /* Return the reponse */ + return retr; +} + +/** + * @brief Returns the SD status. + * @param None + * @retval The SD status. + */ +uint8_t BSP_SD_GetCardState(void) { + SD_CmdAnswer_typedef retr; + + /* Send CMD13 (SD_SEND_STATUS) to get SD status */ + retr = SD_SendCmd(SD_CMD_SEND_STATUS, 0, 0xFF, SD_ANSWER_R2_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Find SD status according to card state */ + if((retr.r1 == SD_R1_NO_ERROR) && (retr.r2 == SD_R2_NO_ERROR)) { + return BSP_SD_OK; + } + + return BSP_SD_ERROR; +} + +/** + * @brief Reads the SD card SCD register. + * Reading the contents of the CSD register in SPI mode is a simple + * read-block transaction. + * @param Csd: pointer on an SCD register structure + * @retval SD status + */ +uint8_t SD_GetCSDRegister(SD_CSD* Csd) { + uint16_t counter = 0; + uint8_t CSD_Tab[16]; + uint8_t retr = BSP_SD_ERROR; + SD_CmdAnswer_typedef response; + + /* Send CMD9 (CSD register) or CMD10(CSD register) and Wait for response in the R1 format (0x00 is no errors) */ + response = SD_SendCmd(SD_CMD_SEND_CSD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); + if(response.r1 == SD_R1_NO_ERROR) { + if(SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK) { + for(counter = 0; counter < 16; counter++) { + /* Store CSD register value on CSD_Tab */ + CSD_Tab[counter] = SD_IO_WriteByte(SD_DUMMY_BYTE); + } + + /* Get CRC bytes (not really needed by us, but required by SD) */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /************************************************************************* + CSD header decoding + *************************************************************************/ + + /* Byte 0 */ + Csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6; + Csd->Reserved1 = CSD_Tab[0] & 0x3F; + + /* Byte 1 */ + Csd->TAAC = CSD_Tab[1]; + + /* Byte 2 */ + Csd->NSAC = CSD_Tab[2]; + + /* Byte 3 */ + Csd->MaxBusClkFrec = CSD_Tab[3]; + + /* Byte 4/5 */ + Csd->CardComdClasses = (CSD_Tab[4] << 4) | ((CSD_Tab[5] & 0xF0) >> 4); + Csd->RdBlockLen = CSD_Tab[5] & 0x0F; + + /* Byte 6 */ + Csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7; + Csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6; + Csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5; + Csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4; + + /************************************************************************* + CSD v1/v2 decoding + *************************************************************************/ + + if(flag_SDHC == 0) { + Csd->version.v1.Reserved1 = ((CSD_Tab[6] & 0x0C) >> 2); + + Csd->version.v1.DeviceSize = ((CSD_Tab[6] & 0x03) << 10) | (CSD_Tab[7] << 2) | + ((CSD_Tab[8] & 0xC0) >> 6); + Csd->version.v1.MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3; + Csd->version.v1.MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07); + Csd->version.v1.MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5; + Csd->version.v1.MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2; + Csd->version.v1.DeviceSizeMul = ((CSD_Tab[9] & 0x03) << 1) | + ((CSD_Tab[10] & 0x80) >> 7); + } else { + Csd->version.v2.Reserved1 = ((CSD_Tab[6] & 0x0F) << 2) | + ((CSD_Tab[7] & 0xC0) >> 6); + Csd->version.v2.DeviceSize = ((CSD_Tab[7] & 0x3F) << 16) | (CSD_Tab[8] << 8) | + CSD_Tab[9]; + Csd->version.v2.Reserved2 = ((CSD_Tab[10] & 0x80) >> 8); + } + + Csd->EraseSingleBlockEnable = (CSD_Tab[10] & 0x40) >> 6; + Csd->EraseSectorSize = ((CSD_Tab[10] & 0x3F) << 1) | ((CSD_Tab[11] & 0x80) >> 7); + Csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F); + Csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7; + Csd->Reserved2 = (CSD_Tab[12] & 0x60) >> 5; + Csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2; + Csd->MaxWrBlockLen = ((CSD_Tab[12] & 0x03) << 2) | ((CSD_Tab[13] & 0xC0) >> 6); + Csd->WriteBlockPartial = (CSD_Tab[13] & 0x20) >> 5; + Csd->Reserved3 = (CSD_Tab[13] & 0x1F); + Csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7; + Csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6; + Csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5; + Csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4; + Csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2; + Csd->Reserved4 = (CSD_Tab[14] & 0x03); + Csd->crc = (CSD_Tab[15] & 0xFE) >> 1; + Csd->Reserved5 = (CSD_Tab[15] & 0x01); + + retr = BSP_SD_OK; + } + } + + /* Send dummy byte: 8 Clock pulses of delay */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Return the reponse */ + return retr; +} + +/** + * @brief Reads the SD card CID register. + * Reading the contents of the CID register in SPI mode is a simple + * read-block transaction. + * @param Cid: pointer on an CID register structure + * @retval SD status + */ +uint8_t SD_GetCIDRegister(SD_CID* Cid) { + uint32_t counter = 0; + uint8_t retr = BSP_SD_ERROR; + uint8_t CID_Tab[16]; + SD_CmdAnswer_typedef response; + + /* Send CMD10 (CID register) and Wait for response in the R1 format (0x00 is no errors) */ + response = SD_SendCmd(SD_CMD_SEND_CID, 0, 0xFF, SD_ANSWER_R1_EXPECTED); + if(response.r1 == SD_R1_NO_ERROR) { + if(SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK) { + /* Store CID register value on CID_Tab */ + for(counter = 0; counter < 16; counter++) { + CID_Tab[counter] = SD_IO_WriteByte(SD_DUMMY_BYTE); + } + + /* Get CRC bytes (not really needed by us, but required by SD) */ + SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Byte 0 */ + Cid->ManufacturerID = CID_Tab[0]; + + /* Byte 1 */ + Cid->OEM_AppliID = CID_Tab[1] << 8; + + /* Byte 2 */ + Cid->OEM_AppliID |= CID_Tab[2]; + + /* Byte 3 */ + Cid->ProdName1 = CID_Tab[3] << 24; + + /* Byte 4 */ + Cid->ProdName1 |= CID_Tab[4] << 16; + + /* Byte 5 */ + Cid->ProdName1 |= CID_Tab[5] << 8; + + /* Byte 6 */ + Cid->ProdName1 |= CID_Tab[6]; + + /* Byte 7 */ + Cid->ProdName2 = CID_Tab[7]; + + /* Byte 8 */ + Cid->ProdRev = CID_Tab[8]; + + /* Byte 9 */ + Cid->ProdSN = CID_Tab[9] << 24; + + /* Byte 10 */ + Cid->ProdSN |= CID_Tab[10] << 16; + + /* Byte 11 */ + Cid->ProdSN |= CID_Tab[11] << 8; + + /* Byte 12 */ + Cid->ProdSN |= CID_Tab[12]; + + /* Byte 13 */ + Cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4; + Cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8; + + /* Byte 14 */ + Cid->ManufactDate |= CID_Tab[14]; + + /* Byte 15 */ + Cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1; + Cid->Reserved2 = 1; + + retr = BSP_SD_OK; + } + } + + /* Send dummy byte: 8 Clock pulses of delay */ + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Return the reponse */ + return retr; +} + +/** + * @brief Sends 5 bytes command to the SD card and get response + * @param Cmd: The user expected command to send to SD card. + * @param Arg: The command argument. + * @param Crc: The CRC. + * @param Answer: SD_ANSWER_NOT_EXPECTED or SD_ANSWER_EXPECTED + * @retval SD status + */ +SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Answer) { + uint8_t frame[SD_CMD_LENGTH], frameout[SD_CMD_LENGTH]; + SD_CmdAnswer_typedef retr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + /* R1 Lenght = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 1 Bytes answer + NEC(0) = 15bytes */ + /* R1b identical to R1 + Busy information */ + /* R2 Lenght = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 2 Bytes answer + NEC(0) = 16bytes */ + + /* Prepare Frame to send */ + frame[0] = (Cmd | 0x40); /* Construct byte 1 */ + frame[1] = (uint8_t)(Arg >> 24); /* Construct byte 2 */ + frame[2] = (uint8_t)(Arg >> 16); /* Construct byte 3 */ + frame[3] = (uint8_t)(Arg >> 8); /* Construct byte 4 */ + frame[4] = (uint8_t)(Arg); /* Construct byte 5 */ + frame[5] = (Crc | 0x01); /* Construct byte 6 */ + + /* Send the command */ + SD_IO_CSState(0); + SD_IO_WriteReadData(frame, frameout, SD_CMD_LENGTH); /* Send the Cmd bytes */ + + switch(Answer) { + case SD_ANSWER_R1_EXPECTED: + retr.r1 = SD_ReadData(); + break; + case SD_ANSWER_R1B_EXPECTED: + retr.r1 = SD_ReadData(); + retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); + /* Set CS High */ + SD_IO_CSState(1); + HAL_Delay(1); + /* Set CS Low */ + SD_IO_CSState(0); + + /* Wait IO line return 0xFF */ + while(SD_IO_WriteByte(SD_DUMMY_BYTE) != 0xFF) + ; + break; + case SD_ANSWER_R2_EXPECTED: + retr.r1 = SD_ReadData(); + retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); + break; + case SD_ANSWER_R3_EXPECTED: + case SD_ANSWER_R7_EXPECTED: + retr.r1 = SD_ReadData(); + retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); + retr.r3 = SD_IO_WriteByte(SD_DUMMY_BYTE); + retr.r4 = SD_IO_WriteByte(SD_DUMMY_BYTE); + retr.r5 = SD_IO_WriteByte(SD_DUMMY_BYTE); + break; + default: + break; + } + return retr; +} + +/** + * @brief Gets the SD card data response and check the busy flag. + * @param None + * @retval The SD status: Read data response xxx01 + * - status 010: Data accecpted + * - status 101: Data rejected due to a crc error + * - status 110: Data rejected due to a Write error. + * - status 111: Data rejected due to other error. + */ +uint8_t SD_GetDataResponse(void) { + uint8_t dataresponse; + uint8_t rvalue = SD_DATA_OTHER_ERROR; + + dataresponse = SD_IO_WriteByte(SD_DUMMY_BYTE); + SD_IO_WriteByte(SD_DUMMY_BYTE); /* read the busy response byte*/ + + /* Mask unused bits */ + switch(dataresponse & 0x1F) { + case SD_DATA_OK: + rvalue = SD_DATA_OK; + + /* Set CS High */ + SD_IO_CSState(1); + /* Set CS Low */ + SD_IO_CSState(0); + + /* Wait IO line return 0xFF */ + while(SD_IO_WriteByte(SD_DUMMY_BYTE) != 0xFF) + ; + break; + case SD_DATA_CRC_ERROR: + rvalue = SD_DATA_CRC_ERROR; + break; + case SD_DATA_WRITE_ERROR: + rvalue = SD_DATA_WRITE_ERROR; + break; + default: + break; + } + + /* Return response */ + return rvalue; +} + +/** + * @brief Put the SD in Idle state. + * @param None + * @retval SD status + */ +uint8_t SD_GoIdleState(void) { + SD_CmdAnswer_typedef response; + __IO uint8_t counter; + /* Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode and + wait for In Idle State Response (R1 Format) equal to 0x01 */ + counter = 0; + do { + counter++; + response = SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(counter >= SD_MAX_TRY) { + return BSP_SD_ERROR; + } + } while(response.r1 != SD_R1_IN_IDLE_STATE); + + /* Send CMD8 (SD_CMD_SEND_IF_COND) to check the power supply status + and wait until response (R7 Format) equal to 0xAA and */ + response = SD_SendCmd(SD_CMD_SEND_IF_COND, 0x1AA, 0x87, SD_ANSWER_R7_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) { + /* initialise card V1 */ + counter = 0; + do { + counter++; + /* initialise card V1 */ + /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_APP_CMD, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(counter >= SD_MAX_TRY) { + return BSP_SD_ERROR; + } + } while(response.r1 == SD_R1_IN_IDLE_STATE); + flag_SDHC = 0; + } else if(response.r1 == SD_R1_IN_IDLE_STATE) { + /* initialise card V2 */ + counter = 0; + do { + counter++; + /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + + /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x40000000, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(counter >= SD_MAX_TRY) { + return BSP_SD_ERROR; + } + } while(response.r1 == SD_R1_IN_IDLE_STATE); + + if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) { + counter = 0; + do { + counter++; + /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(response.r1 != SD_R1_IN_IDLE_STATE) { + return BSP_SD_ERROR; + } + /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */ + response = + SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(counter >= SD_MAX_TRY) { + return BSP_SD_ERROR; + } + } while(response.r1 == SD_R1_IN_IDLE_STATE); + } + + /* Send CMD58 (SD_CMD_READ_OCR) to initialize SDHC or SDXC cards: R3 response (0x00: no errors) */ + response = SD_SendCmd(SD_CMD_READ_OCR, 0x00000000, 0xFF, SD_ANSWER_R3_EXPECTED); + SD_IO_CSState(1); + SD_IO_WriteByte(SD_DUMMY_BYTE); + if(response.r1 != SD_R1_NO_ERROR) { + return BSP_SD_ERROR; + } + flag_SDHC = (response.r2 & 0x40) >> 6; + } else { + return BSP_SD_ERROR; + } + + return BSP_SD_OK; +} + +/** + * @brief Waits a data until a value different from SD_DUMMY_BITE + * @param None + * @retval the value read + */ +uint8_t SD_ReadData(void) { + uint8_t timeout = 0x08; + uint8_t readvalue; + + /* Check if response is got or a timeout is happen */ + do { + readvalue = SD_IO_WriteByte(SD_DUMMY_BYTE); + timeout--; + + } while((readvalue == SD_DUMMY_BYTE) && timeout); + + /* Right response got */ + return readvalue; +} + +/** + * @brief Waits a data from the SD card + * @param data : Expected data from the SD card + * @retval BSP_SD_OK or BSP_SD_TIMEOUT + */ +uint8_t SD_WaitData(uint8_t data) { + uint16_t timeout = 0xFFFF; + uint8_t readvalue; + + /* Check if response is got or a timeout is happen */ + + do { + readvalue = SD_IO_WriteByte(SD_DUMMY_BYTE); + timeout--; + } while((readvalue != data) && timeout); + + if(timeout == 0) { + /* After time out */ + return BSP_SD_TIMEOUT; + } + + /* Right response got */ + return BSP_SD_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Src/fatfs/stm32_adafruit_sd.h b/firmware/targets/f7/Src/fatfs/stm32_adafruit_sd.h new file mode 100644 index 00000000..38f9da49 --- /dev/null +++ b/firmware/targets/f7/Src/fatfs/stm32_adafruit_sd.h @@ -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 + * + *

© COPYRIGHT(c) 2016 STMicroelectronics

+ * + * 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 +#include + +/** @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****/ diff --git a/firmware/targets/f7/Src/fatfs/syscall.c b/firmware/targets/f7/Src/fatfs/syscall.c new file mode 100644 index 00000000..8d488dc7 --- /dev/null +++ b/firmware/targets/f7/Src/fatfs/syscall.c @@ -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 diff --git a/firmware/targets/f7/Src/fatfs/user_diskio.c b/firmware/targets/f7/Src/fatfs/user_diskio.c new file mode 100644 index 00000000..ca3d60a5 --- /dev/null +++ b/firmware/targets/f7/Src/fatfs/user_diskio.c @@ -0,0 +1,223 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file user_diskio.c + * @brief This file includes a diskio driver skeleton to be completed by the user. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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 "furi-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 */ + + const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + + DSTATUS status = User_CheckStatus(pdrv); + + furi_hal_spi_device_return(sd_spi_fast_dev); + + 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; + + const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + + 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; + } + + furi_hal_spi_device_return(sd_spi_fast_dev); + + 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; + + const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + + 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; + } + + furi_hal_spi_device_return(sd_spi_fast_dev); + + 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; + + const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + + 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; + } + + furi_hal_spi_device_return(sd_spi_fast_dev); + + return res; + /* USER CODE END IOCTL */ +} +#endif /* _USE_IOCTL == 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ \ No newline at end of file diff --git a/firmware/targets/f7/Src/fatfs/user_diskio.h b/firmware/targets/f7/Src/fatfs/user_diskio.h new file mode 100644 index 00000000..177723be --- /dev/null +++ b/firmware/targets/f7/Src/fatfs/user_diskio.h @@ -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 + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/freertos-openocd.c b/firmware/targets/f7/Src/freertos-openocd.c new file mode 100644 index 00000000..abde4411 --- /dev/null +++ b/firmware/targets/f7/Src/freertos-openocd.c @@ -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; \ No newline at end of file diff --git a/firmware/targets/f7/Src/gpio.c b/firmware/targets/f7/Src/gpio.c new file mode 100644 index 00000000..8363bc91 --- /dev/null +++ b/firmware/targets/f7/Src/gpio.c @@ -0,0 +1,139 @@ +#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 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); + + /* 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); + + /* Enable all NVIC lines related to gpio */ + 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); +} diff --git a/firmware/targets/f7/Src/main.c b/firmware/targets/f7/Src/main.c new file mode 100644 index 00000000..b9deedf2 --- /dev/null +++ b/firmware/targets/f7/Src/main.c @@ -0,0 +1,55 @@ +#include "main.h" + +#include "fatfs/fatfs.h" + +#include +#include +#include + +int main(void) { + // Initialize FURI layer + furi_init(); + + // Initialize ST HAL + HAL_Init(); + + // Flipper FURI HAL + furi_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 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 */ diff --git a/firmware/targets/f7/Src/pka.c b/firmware/targets/f7/Src/pka.c new file mode 100644 index 00000000..8377ce57 --- /dev/null +++ b/firmware/targets/f7/Src/pka.c @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file pka.c + * @brief This file provides code for the configuration + * of the PKA instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/rf.c b/firmware/targets/f7/Src/rf.c new file mode 100644 index 00000000..62daf9b2 --- /dev/null +++ b/firmware/targets/f7/Src/rf.c @@ -0,0 +1,37 @@ +/** + ****************************************************************************** + * @file rf.c + * @brief This file provides code for the configuration + * of the RF instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/rng.c b/firmware/targets/f7/Src/rng.c new file mode 100644 index 00000000..c2fb144e --- /dev/null +++ b/firmware/targets/f7/Src/rng.c @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file rng.c + * @brief This file provides code for the configuration + * of the RNG instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/rtc.c b/firmware/targets/f7/Src/rtc.c new file mode 100644 index 00000000..8a6f4c92 --- /dev/null +++ b/firmware/targets/f7/Src/rtc.c @@ -0,0 +1,123 @@ +/** + ****************************************************************************** + * @file rtc.c + * @brief This file provides code for the configuration + * of the RTC instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/stm32wbxx_hal_msp.c b/firmware/targets/f7/Src/stm32wbxx_hal_msp.c new file mode 100644 index 00000000..c96a5dfa --- /dev/null +++ b/firmware/targets/f7/Src/stm32wbxx_hal_msp.c @@ -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 + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/Src/stm32wbxx_it.c b/firmware/targets/f7/Src/stm32wbxx_it.c new file mode 100644 index 00000000..01fbdc1d --- /dev/null +++ b/firmware/targets/f7/Src/stm32wbxx_it.c @@ -0,0 +1,52 @@ +#include "main.h" +#include "stm32wbxx_it.h" +#include "FreeRTOS.h" +#include "task.h" + +extern PCD_HandleTypeDef hpcd_USB_FS; +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 SysTick_Handler(void) { + HAL_IncTick(); +} + +void USB_LP_IRQHandler(void) { + HAL_PCD_IRQHandler(&hpcd_USB_FS); +} + +void COMP_IRQHandler(void) { + HAL_COMP_IRQHandler(&hcomp1); +} + +void TIM1_TRG_COM_TIM17_IRQHandler(void) { + HAL_TIM_IRQHandler(&htim1); +} + +void TIM1_CC_IRQHandler(void) { + HAL_TIM_IRQHandler(&htim1); +} + +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(); +} diff --git a/firmware/targets/f7/Src/system_stm32wbxx.c b/firmware/targets/f7/Src/system_stm32wbxx.c new file mode 100644 index 00000000..38db6ece --- /dev/null +++ b/firmware/targets/f7/Src/system_stm32wbxx.c @@ -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 + * + *

© Copyright (c) 2019 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 + * + ****************************************************************************** + */ + +/** @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****/ diff --git a/firmware/targets/f7/Src/tim.c b/firmware/targets/f7/Src/tim.c new file mode 100644 index 00000000..1d558dd5 --- /dev/null +++ b/firmware/targets/f7/Src/tim.c @@ -0,0 +1,361 @@ +/** + ****************************************************************************** + * @file tim.c + * @brief This file provides code for the configuration + * of the TIM instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/ble-glue/app_ble.c b/firmware/targets/f7/ble-glue/app_ble.c new file mode 100644 index 00000000..bb80fcea --- /dev/null +++ b/firmware/targets/f7/ble-glue/app_ble.c @@ -0,0 +1,776 @@ +#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 "otp.h" +#include "dev_info_service.h" +#include "battery_service.h" +#include "serial_service.h" + +#include + +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 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; + +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 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); +} + +static void set_advertisment_service_uid(uint8_t* uid, uint8_t uin_len); + +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 + dev_info_service_init(); + // Initialize BAS Application + battery_svc_init(); + // Initialize Serial application + serial_svc_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); + uint8_t adv_service_uid[2]; + adv_service_uid[0] = 0x80 | furi_hal_version_get_hw_color(); + adv_service_uid[1] = 0x30; + + set_advertisment_service_uid(adv_service_uid, sizeof(adv_service_uid)); + /* 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; +} + +void SVCCTL_SvcInit() { + // Dummy function to prevent unused services initialization + // TODO refactore +} + +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); + furi_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: + { + furi_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); +} + +static void set_advertisment_service_uid(uint8_t* uid, uint8_t uid_len) { + BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen = 1; + if(uid_len == 2) { + BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = AD_TYPE_16_BIT_SERV_UUID; + } else if (uid_len == 4) { + BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = AD_TYPE_32_BIT_SERV_UUID; + } else if(uid_len == 16) { + BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST; + } + memcpy(&BleApplicationContext.BleApplicationContext_legacy.advtServUUID[1], uid, uid_len); + BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen += uid_len; +} + +APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status() { + return BleApplicationContext.Device_Connection_Status; +} + +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 = furi_hal_version_get_device_name_ptr(); + aci_gap_init(role, 0, + strlen(name), + &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; + + const char* name = furi_hal_version_get_ble_local_device_name_ptr(); + + /* 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 */ + strlen(name), + (uint8_t*)name, + BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen, + BleApplicationContext.BleApplicationContext_legacy.advtServUUID, + 0, + 0); + if(ret) { + FURI_LOG_E("APP ble", "Set discoverable err: %d", ret); + } + + /* 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 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(); +} diff --git a/firmware/targets/f7/ble-glue/app_ble.h b/firmware/targets/f7/ble-glue/app_ble.h new file mode 100644 index 00000000..2bbd5165 --- /dev/null +++ b/firmware/targets/f7/ble-glue/app_ble.h @@ -0,0 +1,27 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "hci_tl.h" + +typedef enum { + APP_BLE_IDLE, + APP_BLE_FAST_ADV, + APP_BLE_LP_ADV, + APP_BLE_SCAN, + APP_BLE_LP_CONNECTING, + APP_BLE_CONNECTED_SERVER, + APP_BLE_CONNECTED_CLIENT +} APP_BLE_ConnStatus_t; + +bool APP_BLE_Init(); +bool APP_BLE_Start(); + +APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/ble-glue/app_common.h b/firmware/targets/f7/ble-glue/app_common.h new file mode 100644 index 00000000..d21860f6 --- /dev/null +++ b/firmware/targets/f7/ble-glue/app_common.h @@ -0,0 +1,43 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : app_common.h + * Description : App Common application configuration file for STM32WPAN Middleware. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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 APP_COMMON_H +#define APP_COMMON_H + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include +#include +#include +#include + +#include + +#include "app_conf.h" + +#define DIVC( x, y ) (((x)+(y)-1)/(y)) + +#define DIVR( x, y ) (((x)+((y)/2))/(y)) + +#endif \ No newline at end of file diff --git a/firmware/targets/f7/ble-glue/app_conf.h b/firmware/targets/f7/ble-glue/app_conf.h new file mode 100644 index 00000000..dc22b4ba --- /dev/null +++ b/firmware/targets/f7/ble-glue/app_conf.h @@ -0,0 +1,474 @@ +#pragma once + +#include "hw.h" +#include "hw_conf.h" +#include "hw_if.h" +#include "ble_bufsize.h" + +#define CFG_TX_POWER (0x19) /* +0dBm */ + +/** + * Define Advertising parameters + */ +#define CFG_ADV_BD_ADDRESS (0x7257acd87a6c) +#define CFG_FAST_CONN_ADV_INTERVAL_MIN (0x80) /**< 80ms */ +#define CFG_FAST_CONN_ADV_INTERVAL_MAX (0xa0) /**< 100ms */ +#define CFG_LP_CONN_ADV_INTERVAL_MIN (0x640) /**< 1s */ +#define CFG_LP_CONN_ADV_INTERVAL_MAX (0xfa0) /**< 2.5s */ + +/** + * Define IO Authentication + */ +#define CFG_BONDING_MODE (1) +#define CFG_FIXED_PIN (111111) +#define CFG_USED_FIXED_PIN (1) +#define CFG_ENCRYPTION_KEY_SIZE_MAX (16) +#define CFG_ENCRYPTION_KEY_SIZE_MIN (8) + +/** + * Define IO capabilities + */ +#define CFG_IO_CAPABILITY_DISPLAY_ONLY (0x00) +#define CFG_IO_CAPABILITY_DISPLAY_YES_NO (0x01) +#define CFG_IO_CAPABILITY_KEYBOARD_ONLY (0x02) +#define CFG_IO_CAPABILITY_NO_INPUT_NO_OUTPUT (0x03) +#define CFG_IO_CAPABILITY_KEYBOARD_DISPLAY (0x04) + +#define CFG_IO_CAPABILITY CFG_IO_CAPABILITY_DISPLAY_YES_NO + +/** + * Define MITM modes + */ +#define CFG_MITM_PROTECTION_NOT_REQUIRED (0x00) +#define CFG_MITM_PROTECTION_REQUIRED (0x01) + +#define CFG_MITM_PROTECTION CFG_MITM_PROTECTION_REQUIRED + +/** + * Define Secure Connections Support + */ +#define CFG_SECURE_NOT_SUPPORTED (0x00) +#define CFG_SECURE_OPTIONAL (0x01) +#define CFG_SECURE_MANDATORY (0x02) + +#define CFG_SC_SUPPORT CFG_SECURE_OPTIONAL + +/** + * Define Keypress Notification Support + */ +#define CFG_KEYPRESS_NOT_SUPPORTED (0x00) +#define CFG_KEYPRESS_SUPPORTED (0x01) + +#define CFG_KEYPRESS_NOTIFICATION_SUPPORT CFG_KEYPRESS_NOT_SUPPORTED + +/** + * Numeric Comparison Answers + */ +#define YES (0x01) +#define NO (0x00) + +/** + * Device name configuration for Generic Access Service + */ +#define CFG_GAP_DEVICE_NAME "TEMPLATE" +#define CFG_GAP_DEVICE_NAME_LENGTH (8) + +/** + * Define PHY + */ +#define ALL_PHYS_PREFERENCE 0x00 +#define RX_2M_PREFERRED 0x02 +#define TX_2M_PREFERRED 0x02 +#define TX_1M 0x01 +#define TX_2M 0x02 +#define RX_1M 0x01 +#define RX_2M 0x02 + +/** +* Identity root key used to derive LTK and CSRK +*/ +#define CFG_BLE_IRK {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0} + +/** +* Encryption root key used to derive LTK and CSRK +*/ +#define CFG_BLE_ERK {0xfe,0xdc,0xba,0x09,0x87,0x65,0x43,0x21,0xfe,0xdc,0xba,0x09,0x87,0x65,0x43,0x21} + +/* USER CODE BEGIN Generic_Parameters */ +/** + * SMPS supply + * SMPS not used when Set to 0 + * SMPS used when Set to 1 + */ +#define CFG_USE_SMPS 1 +/* USER CODE END Generic_Parameters */ + +/**< specific parameters */ +/*****************************************************/ + +/** +* AD Element - Group B Feature +*/ +/* LSB - Second Byte */ +#define CFG_FEATURE_OTA_REBOOT (0x20) + +/****************************************************************************** + * BLE Stack + ******************************************************************************/ +/** + * Maximum number of simultaneous connections that the device will support. + * Valid values are from 1 to 8 + */ +#define CFG_BLE_NUM_LINK 2 + +/** + * Maximum number of Services that can be stored in the GATT database. + * Note that the GAP and GATT services are automatically added so this parameter should be 2 plus the number of user services + */ +#define CFG_BLE_NUM_GATT_SERVICES 8 + +/** + * Maximum number of Attributes + * (i.e. the number of characteristic + the number of characteristic values + the number of descriptors, excluding the services) + * that can be stored in the GATT database. + * Note that certain characteristics and relative descriptors are added automatically during device initialization + * so this parameters should be 9 plus the number of user Attributes + */ +#define CFG_BLE_NUM_GATT_ATTRIBUTES 68 + +/** + * Maximum supported ATT_MTU size + */ +#define CFG_BLE_MAX_ATT_MTU (156) + +/** + * Size of the storage area for Attribute values + * This value depends on the number of attributes used by application. In particular the sum of the following quantities (in octets) should be made for each attribute: + * - attribute value length + * - 5, if UUID is 16 bit; 19, if UUID is 128 bit + * - 2, if server configuration descriptor is used + * - 2*DTM_NUM_LINK, if client configuration descriptor is used + * - 2, if extended properties is used + * The total amount of memory needed is the sum of the above quantities for each attribute. + */ +#define CFG_BLE_ATT_VALUE_ARRAY_SIZE (1344) + +/** + * Prepare Write List size in terms of number of packet + */ +#define CFG_BLE_PREPARE_WRITE_LIST_SIZE BLE_PREP_WRITE_X_ATT(CFG_BLE_MAX_ATT_MTU) + +/** + * Number of allocated memory blocks + */ +#define CFG_BLE_MBLOCK_COUNT (BLE_MBLOCKS_CALC(CFG_BLE_PREPARE_WRITE_LIST_SIZE, CFG_BLE_MAX_ATT_MTU, CFG_BLE_NUM_LINK)) + +/** + * Enable or disable the Extended Packet length feature. Valid values are 0 or 1. + */ +#define CFG_BLE_DATA_LENGTH_EXTENSION 1 + +/** + * Sleep clock accuracy in Slave mode (ppm value) + */ +#define CFG_BLE_SLAVE_SCA 500 + +/** + * Sleep clock accuracy in Master mode + * 0 : 251 ppm to 500 ppm + * 1 : 151 ppm to 250 ppm + * 2 : 101 ppm to 150 ppm + * 3 : 76 ppm to 100 ppm + * 4 : 51 ppm to 75 ppm + * 5 : 31 ppm to 50 ppm + * 6 : 21 ppm to 30 ppm + * 7 : 0 ppm to 20 ppm + */ +#define CFG_BLE_MASTER_SCA 0 + +/** + * Source for the low speed clock for RF wake-up + * 1 : external high speed crystal HSE/32/32 + * 0 : external low speed crystal ( no calibration ) + */ +#define CFG_BLE_LSE_SOURCE 0 + +/** + * Start up time of the high speed (16 or 32 MHz) crystal oscillator in units of 625/256 us (~2.44 us) + */ +#define CFG_BLE_HSE_STARTUP_TIME 0x148 + +/** + * Maximum duration of the connection event when the device is in Slave mode in units of 625/256 us (~2.44 us) + */ +#define CFG_BLE_MAX_CONN_EVENT_LENGTH ( 0xFFFFFFFF ) + +/** + * Viterbi Mode + * 1 : enabled + * 0 : disabled + */ +#define CFG_BLE_VITERBI_MODE 1 + +/** + * LL Only Mode + * 1 : LL Only + * 0 : LL + Host + */ +#define CFG_BLE_LL_ONLY 0 +/****************************************************************************** + * Transport Layer + ******************************************************************************/ +/** + * Queue length of BLE Event + * This parameter defines the number of asynchronous events that can be stored in the HCI layer before + * being reported to the application. When a command is sent to the BLE core coprocessor, the HCI layer + * is waiting for the event with the Num_HCI_Command_Packets set to 1. The receive queue shall be large + * enough to store all asynchronous events received in between. + * When CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE is set to 27, this allow to store three 255 bytes long asynchronous events + * between the HCI command and its event. + * This parameter depends on the value given to CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE. When the queue size is to small, + * the system may hang if the queue is full with asynchronous events and the HCI layer is still waiting + * for a CC/CS event, In that case, the notification TL_BLE_HCI_ToNot() is called to indicate + * to the application a HCI command did not receive its command event within 30s (Default HCI Timeout). + */ +#define CFG_TLBLE_EVT_QUEUE_LENGTH 5 +/** + * This parameter should be set to fit most events received by the HCI layer. It defines the buffer size of each element + * allocated in the queue of received events and can be used to optimize the amount of RAM allocated by the Memory Manager. + * It should not exceed 255 which is the maximum HCI packet payload size (a greater value is a lost of memory as it will + * never be used) + * With the current wireless firmware implementation, this parameter shall be kept to 255 + * + */ +#define CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE 255 /**< Set to 255 with the memory manager and the mailbox */ + +#define TL_BLE_EVENT_FRAME_SIZE ( TL_EVT_HDR_SIZE + CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE ) +/****************************************************************************** + * UART interfaces + ******************************************************************************/ + +/** + * Select UART interfaces + */ +#define CFG_DEBUG_TRACE_UART hw_uart1 +#define CFG_CONSOLE_MENU 0 + +/****************************************************************************** + * Low Power + ******************************************************************************/ +/** + * When set to 1, the low power mode is enable + * When set to 0, the device stays in RUN mode + */ +#define CFG_LPM_SUPPORTED 1 + +/****************************************************************************** + * Timer Server + ******************************************************************************/ +/** + * CFG_RTC_WUCKSEL_DIVIDER: This sets the RTCCLK divider to the wakeup timer. + * The lower is the value, the better is the power consumption and the accuracy of the timerserver + * The higher is the value, the finest is the granularity + * + * CFG_RTC_ASYNCH_PRESCALER: This sets the asynchronous prescaler of the RTC. It should as high as possible ( to ouput + * clock as low as possible) but the output clock should be equal or higher frequency compare to the clock feeding + * the wakeup timer. A lower clock speed would impact the accuracy of the timer server. + * + * CFG_RTC_SYNCH_PRESCALER: This sets the synchronous prescaler of the RTC. + * When the 1Hz calendar clock is required, it shall be sets according to other settings + * When the 1Hz calendar clock is not needed, CFG_RTC_SYNCH_PRESCALER should be set to 0x7FFF (MAX VALUE) + * + * CFG_RTCCLK_DIVIDER_CONF: + * Shall be set to either 0,2,4,8,16 + * When set to either 2,4,8,16, the 1Hhz calendar is supported + * When set to 0, the user sets its own configuration + * + * The following settings are computed with LSI as input to the RTC + */ +#define CFG_RTCCLK_DIVIDER_CONF 0 + +#if (CFG_RTCCLK_DIVIDER_CONF == 0) +/** + * Custom configuration + * It does not support 1Hz calendar + * It divides the RTC CLK by 16 + */ +#define CFG_RTCCLK_DIV (16) +#define CFG_RTC_WUCKSEL_DIVIDER (0) +#define CFG_RTC_ASYNCH_PRESCALER (CFG_RTCCLK_DIV - 1) +#define CFG_RTC_SYNCH_PRESCALER (0x7FFF) + +#else + +#if (CFG_RTCCLK_DIVIDER_CONF == 2) +/** + * It divides the RTC CLK by 2 + */ +#define CFG_RTC_WUCKSEL_DIVIDER (3) +#endif + +#if (CFG_RTCCLK_DIVIDER_CONF == 4) +/** + * It divides the RTC CLK by 4 + */ +#define CFG_RTC_WUCKSEL_DIVIDER (2) +#endif + +#if (CFG_RTCCLK_DIVIDER_CONF == 8) +/** + * It divides the RTC CLK by 8 + */ +#define CFG_RTC_WUCKSEL_DIVIDER (1) +#endif + +#if (CFG_RTCCLK_DIVIDER_CONF == 16) +/** + * It divides the RTC CLK by 16 + */ +#define CFG_RTC_WUCKSEL_DIVIDER (0) +#endif + +#define CFG_RTCCLK_DIV CFG_RTCCLK_DIVIDER_CONF +#define CFG_RTC_ASYNCH_PRESCALER (CFG_RTCCLK_DIV - 1) +#define CFG_RTC_SYNCH_PRESCALER (DIVR( LSE_VALUE, (CFG_RTC_ASYNCH_PRESCALER+1) ) - 1 ) + +#endif + +/** tick timer value in us */ +#define CFG_TS_TICK_VAL DIVR( (CFG_RTCCLK_DIV * 1000000), LSE_VALUE ) + +typedef enum +{ + CFG_TIM_PROC_ID_ISR, + /* USER CODE BEGIN CFG_TimProcID_t */ + + /* USER CODE END CFG_TimProcID_t */ +} CFG_TimProcID_t; + +/****************************************************************************** + * Debug + ******************************************************************************/ +/** + * When set, this resets some hw resources to set the device in the same state than the power up + * The FW resets only register that may prevent the FW to run properly + * + * This shall be set to 0 in a final product + * + */ +#define CFG_HW_RESET_BY_FW 0 + +/** + * keep debugger enabled while in any low power mode when set to 1 + * should be set to 0 in production + */ +#define CFG_DEBUGGER_SUPPORTED 0 + +/** + * When set to 1, the traces are enabled in the BLE services + */ +#define CFG_DEBUG_BLE_TRACE 1 + +/** + * Enable or Disable traces in application + */ +#define CFG_DEBUG_APP_TRACE 1 + +#if (CFG_DEBUG_APP_TRACE != 0) +#define APP_DBG_MSG PRINT_MESG_DBG +#else +#define APP_DBG_MSG PRINT_NO_MESG +#endif + +#if ( (CFG_DEBUG_BLE_TRACE != 0) || (CFG_DEBUG_APP_TRACE != 0) ) +#define CFG_DEBUG_TRACE 1 +#endif + +#if (CFG_DEBUG_TRACE != 0) +#undef CFG_LPM_SUPPORTED +#undef CFG_DEBUGGER_SUPPORTED +#define CFG_LPM_SUPPORTED 0 +#define CFG_DEBUGGER_SUPPORTED 1 +#endif + +/** + * When CFG_DEBUG_TRACE_FULL is set to 1, the trace are output with the API name, the file name and the line number + * When CFG_DEBUG_TRACE_LIGHT is set to 1, only the debug message is output + * + * When both are set to 0, no trace are output + * When both are set to 1, CFG_DEBUG_TRACE_FULL is selected + */ +#define CFG_DEBUG_TRACE_LIGHT 0 +#define CFG_DEBUG_TRACE_FULL 0 + +#if (( CFG_DEBUG_TRACE != 0 ) && ( CFG_DEBUG_TRACE_LIGHT == 0 ) && (CFG_DEBUG_TRACE_FULL == 0)) +#undef CFG_DEBUG_TRACE_FULL +#undef CFG_DEBUG_TRACE_LIGHT +#define CFG_DEBUG_TRACE_FULL 0 +#define CFG_DEBUG_TRACE_LIGHT 1 +#endif + +#if ( CFG_DEBUG_TRACE == 0 ) +#undef CFG_DEBUG_TRACE_FULL +#undef CFG_DEBUG_TRACE_LIGHT +#define CFG_DEBUG_TRACE_FULL 0 +#define CFG_DEBUG_TRACE_LIGHT 0 +#endif + +/** + * When not set, the traces is looping on sending the trace over UART + */ +#define DBG_TRACE_USE_CIRCULAR_QUEUE 0 + +/** + * max buffer Size to queue data traces and max data trace allowed. + * Only Used if DBG_TRACE_USE_CIRCULAR_QUEUE is defined + */ +#define DBG_TRACE_MSG_QUEUE_SIZE 4096 +#define MAX_DBG_TRACE_MSG_SIZE 1024 + +#define CFG_LED_SUPPORTED 0 +#define CFG_BUTTON_SUPPORTED 0 + +/****************************************************************************** + * FreeRTOS + ******************************************************************************/ +#define CFG_SHCI_USER_EVT_PROCESS_NAME "ble_shci_evt" +#define CFG_SHCI_USER_EVT_PROCESS_ATTR_BITS (0) +#define CFG_SHCI_USER_EVT_PROCESS_CB_MEM (0) +#define CFG_SHCI_USER_EVT_PROCESS_CB_SIZE (0) +#define CFG_SHCI_USER_EVT_PROCESS_STACK_MEM (0) +#define CFG_SHCI_USER_EVT_PROCESS_PRIORITY osPriorityNone +#define CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE (128 * 7) + +#define CFG_HCI_USER_EVT_PROCESS_NAME "ble_hci_evt" +#define CFG_HCI_USER_EVT_PROCESS_ATTR_BITS (0) +#define CFG_HCI_USER_EVT_PROCESS_CB_MEM (0) +#define CFG_HCI_USER_EVT_PROCESS_CB_SIZE (0) +#define CFG_HCI_USER_EVT_PROCESS_STACK_MEM (0) +#define CFG_HCI_USER_EVT_PROCESS_PRIORITY osPriorityNone +#define CFG_HCI_USER_EVT_PROCESS_STACK_SIZE (128 * 8) + +#define CFG_ADV_UPDATE_PROCESS_NAME "ble_adv_upd" +#define CFG_ADV_UPDATE_PROCESS_ATTR_BITS (0) +#define CFG_ADV_UPDATE_PROCESS_CB_MEM (0) +#define CFG_ADV_UPDATE_PROCESS_CB_SIZE (0) +#define CFG_ADV_UPDATE_PROCESS_STACK_MEM (0) +#define CFG_ADV_UPDATE_PROCESS_PRIORITY osPriorityNone +#define CFG_ADV_UPDATE_PROCESS_STACK_SIZE (128 * 6) + +#define CFG_HRS_PROCESS_NAME "hrs" +#define CFG_HRS_PROCESS_ATTR_BITS (0) +#define CFG_HRS_PROCESS_CB_MEM (0) +#define CFG_HRS_PROCESS_CB_SIZE (0) +#define CFG_HRS_PROCESS_STACK_MEM (0) +#define CFG_HRS_PROCESS_PRIORITY osPriorityNone +#define CFG_HRS_PROCESS_STACK_SIZE (128 * 8) + +typedef enum { + CFG_LPM_APP, + CFG_LPM_APP_BLE, +} CFG_LPM_Id_t; + +#define CFG_OTP_BASE_ADDRESS OTP_AREA_BASE +#define CFG_OTP_END_ADRESS OTP_AREA_END_ADDR diff --git a/firmware/targets/f7/ble-glue/app_entry.c b/firmware/targets/f7/ble-glue/app_entry.c new file mode 100644 index 00000000..f2367263 --- /dev/null +++ b/firmware/targets/f7/ble-glue/app_entry.c @@ -0,0 +1,192 @@ +#include "app_common.h" +#include "main.h" +#include "app_entry.h" +#include "app_ble.h" +#include "ble.h" +#include "tl.h" +#include "cmsis_os.h" +#include "shci_tl.h" +#include + +extern RTC_HandleTypeDef hrtc; + +#define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH*4U*DIVC(( sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE ), 4U)) + +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t EvtPool[POOL_SIZE]; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t SystemCmdBuffer; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t SystemSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U]; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t BleSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255]; + +osMutexId_t MtxShciId; +osSemaphoreId_t SemShciId; +osThreadId_t ShciUserEvtProcessId; + +volatile static BleGlueStatus ble_glue_status = BleGlueStatusUninitialized; + +const osThreadAttr_t ShciUserEvtProcess_attr = { + .name = CFG_SHCI_USER_EVT_PROCESS_NAME, + .attr_bits = CFG_SHCI_USER_EVT_PROCESS_ATTR_BITS, + .cb_mem = CFG_SHCI_USER_EVT_PROCESS_CB_MEM, + .cb_size = CFG_SHCI_USER_EVT_PROCESS_CB_SIZE, + .stack_mem = CFG_SHCI_USER_EVT_PROCESS_STACK_MEM, + .priority = CFG_SHCI_USER_EVT_PROCESS_PRIORITY, + .stack_size = CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE +}; + +static void ShciUserEvtProcess(void *argument); +static void SystemPower_Config( void ); +static void appe_Tl_Init( void ); +static void APPE_SysStatusNot( SHCI_TL_CmdStatus_t status ); +static void APPE_SysUserEvtRx( void * pPayload ); + +BleGlueStatus APPE_Status() { + return ble_glue_status; +} + +void APPE_Init() { + ble_glue_status = BleGlueStatusStartup; + SystemPower_Config(); /**< Configure the system Power Mode */ + + HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */ + + // APPD_Init(); + furi_hal_power_insomnia_enter(); + + appe_Tl_Init(); /* Initialize all transport layers */ + + /** + * From now, the application is waiting for the ready event ( VS_HCI_C2_Ready ) + * received on the system channel before starting the Stack + * This system event is received with APPE_SysUserEvtRx() + */ +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ + +/** + * @brief Configure the system for power optimization + * + * @note This API configures the system to be ready for low power mode + * + * @param None + * @retval None + */ +static void SystemPower_Config(void) { + // Select HSI as system clock source after Wake Up from Stop mode + LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI); + + /* Initialize the CPU2 reset value before starting CPU2 with C2BOOT */ + LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); +} + +static void appe_Tl_Init( void ) { + TL_MM_Config_t tl_mm_config; + SHCI_TL_HciInitConf_t SHci_Tl_Init_Conf; + /**< Reference table initialization */ + TL_Init(); + + MtxShciId = osMutexNew( NULL ); + SemShciId = osSemaphoreNew( 1, 0, NULL ); /*< Create the semaphore and make it busy at initialization */ + + /** FreeRTOS system task creation */ + ShciUserEvtProcessId = osThreadNew(ShciUserEvtProcess, NULL, &ShciUserEvtProcess_attr); + + /**< System channel initialization */ + SHci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&SystemCmdBuffer; + SHci_Tl_Init_Conf.StatusNotCallBack = APPE_SysStatusNot; + shci_init(APPE_SysUserEvtRx, (void*) &SHci_Tl_Init_Conf); + + /**< Memory Manager channel initialization */ + tl_mm_config.p_BleSpareEvtBuffer = BleSpareEvtBuffer; + tl_mm_config.p_SystemSpareEvtBuffer = SystemSpareEvtBuffer; + tl_mm_config.p_AsynchEvtPool = EvtPool; + tl_mm_config.AsynchEvtPoolSize = POOL_SIZE; + TL_MM_Init( &tl_mm_config ); + + TL_Enable(); +} + +static void APPE_SysStatusNot( SHCI_TL_CmdStatus_t status ) { + switch (status) { + case SHCI_TL_CmdBusy: + osMutexAcquire( MtxShciId, osWaitForever ); + break; + case SHCI_TL_CmdAvailable: + osMutexRelease( MtxShciId ); + break; + default: + break; + } +} + +/** + * The type of the payload for a system user event is tSHCI_UserEvtRxParam + * When the system event is both : + * - a ready event (subevtcode = SHCI_SUB_EVT_CODE_READY) + * - reported by the FUS (sysevt_ready_rsp == FUS_FW_RUNNING) + * The buffer shall not be released + * ( eg ((tSHCI_UserEvtRxParam*)pPayload)->status shall be set to SHCI_TL_UserEventFlow_Disable ) + * When the status is not filled, the buffer is released by default + */ +static void APPE_SysUserEvtRx( void * pPayload ) { + UNUSED(pPayload); + /* Traces channel initialization */ + // APPD_EnableCPU2( ); + + if (APP_BLE_Init()) { + ble_glue_status = BleGlueStatusStarted; + } else { + ble_glue_status = BleGlueStatusBroken; + } + furi_hal_power_insomnia_exit(); +} + +/************************************************************* + * + * FREERTOS WRAPPER FUNCTIONS + * +*************************************************************/ +static void ShciUserEvtProcess(void *argument) { + UNUSED(argument); + for(;;) { + osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + shci_user_evt_proc(); + } +} + +/************************************************************* + * + * WRAP FUNCTIONS + * + *************************************************************/ +void shci_notify_asynch_evt(void* pdata) { + UNUSED(pdata); + osThreadFlagsSet( ShciUserEvtProcessId, 1 ); +} + +void shci_cmd_resp_release(uint32_t flag) { + UNUSED(flag); + osSemaphoreRelease( SemShciId ); +} + +void shci_cmd_resp_wait(uint32_t timeout) { + UNUSED(timeout); + osSemaphoreAcquire( SemShciId, osWaitForever ); +} + +#if(CFG_DEBUG_TRACE != 0) +void DbgOutputInit( void ) +{ +} + +void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) ) +{ + furi_hal_console_tx(p_data, size); + cb(); +} +#endif + diff --git a/firmware/targets/f7/ble-glue/app_entry.h b/firmware/targets/f7/ble-glue/app_entry.h new file mode 100644 index 00000000..f1ce6038 --- /dev/null +++ b/firmware/targets/f7/ble-glue/app_entry.h @@ -0,0 +1,20 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + BleGlueStatusUninitialized, + BleGlueStatusStartup, + BleGlueStatusBroken, + BleGlueStatusStarted +} BleGlueStatus; + +void APPE_Init(); + +BleGlueStatus APPE_Status(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/firmware/targets/f7/ble-glue/battery_service.c b/firmware/targets/f7/ble-glue/battery_service.c new file mode 100644 index 00000000..bcf54049 --- /dev/null +++ b/firmware/targets/f7/ble-glue/battery_service.c @@ -0,0 +1,55 @@ +#include "battery_service.h" +#include "app_common.h" +#include "ble.h" + +#include + +#define BATTERY_SERVICE_TAG "battery service" + +typedef struct { + uint16_t svc_handle; + uint16_t char_level_handle; +} BatterySvc; + +static BatterySvc battery_svc; + +bool battery_svc_init() { + tBleStatus status; + const uint16_t service_uuid = BATTERY_SERVICE_UUID; + const uint16_t char_battery_level_uuid = BATTERY_LEVEL_CHAR_UUID; + + // Add Battery service + status = aci_gatt_add_service(UUID_TYPE_16, (Service_UUID_t*)&service_uuid, PRIMARY_SERVICE, 4, &battery_svc.svc_handle); + if(status) { + FURI_LOG_E(BATTERY_SERVICE_TAG, "Failed to add Battery service: %d", status); + } + + // Add Battery level characteristic + status = aci_gatt_add_char(battery_svc.svc_handle, + UUID_TYPE_16, + (Char_UUID_t *) &char_battery_level_uuid, + 1, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &battery_svc.char_level_handle); + if(status) { + FURI_LOG_E(BATTERY_SERVICE_TAG, "Failed to add Battery level characteristic: %d", status); + } + return status != BLE_STATUS_SUCCESS; +} + +bool battery_svc_update_level(uint8_t battery_charge) { + FURI_LOG_I(BATTERY_SERVICE_TAG, "Updating battery level characteristic"); + tBleStatus result = aci_gatt_update_char_value(battery_svc.svc_handle, + battery_svc.char_level_handle, + 0, + 1, + &battery_charge); + if(result) { + FURI_LOG_E(BATTERY_SERVICE_TAG, "Failed updating RX characteristic: %d", result); + } + return result != BLE_STATUS_SUCCESS; +} diff --git a/firmware/targets/f7/ble-glue/battery_service.h b/firmware/targets/f7/ble-glue/battery_service.h new file mode 100644 index 00000000..82445d2c --- /dev/null +++ b/firmware/targets/f7/ble-glue/battery_service.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +bool battery_svc_init(); + +bool battery_svc_update_level(uint8_t battery_level); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/ble-glue/ble_conf.h b/firmware/targets/f7/ble-glue/ble_conf.h new file mode 100644 index 00000000..0acd8860 --- /dev/null +++ b/firmware/targets/f7/ble-glue/ble_conf.h @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * File Name : App/ble_conf.h + * Description : Configuration file for BLE Middleware. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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 BLE_CONF_H +#define BLE_CONF_H + +#include "app_conf.h" + +/****************************************************************************** + * + * BLE SERVICES CONFIGURATION + * blesvc + * + ******************************************************************************/ + + /** + * This setting shall be set to '1' if the device needs to support the Peripheral Role + * In the MS configuration, both BLE_CFG_PERIPHERAL and BLE_CFG_CENTRAL shall be set to '1' + */ +#define BLE_CFG_PERIPHERAL 1 + +/** + * This setting shall be set to '1' if the device needs to support the Central Role + * In the MS configuration, both BLE_CFG_PERIPHERAL and BLE_CFG_CENTRAL shall be set to '1' + */ +#define BLE_CFG_CENTRAL 0 + +/** + * There is one handler per service enabled + * Note: There is no handler for the Device Information Service + * + * This shall take into account all registered handlers + * (from either the provided services or the custom services) + */ +#define BLE_CFG_SVC_MAX_NBR_CB 7 + +#define BLE_CFG_CLT_MAX_NBR_CB 0 + +/****************************************************************************** + * GAP Service - Apprearance + ******************************************************************************/ + +#define BLE_CFG_UNKNOWN_APPEARANCE (0) +#define BLE_CFG_GAP_APPEARANCE (0x0086) + +/****************************************************************************** + * Over The Air Feature (OTA) - STM Proprietary + ******************************************************************************/ +#define BLE_CFG_OTA_REBOOT_CHAR 0/**< REBOOT OTA MODE CHARACTERISTIC */ + +#endif /*BLE_CONF_H */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble-glue/ble_dbg_conf.h b/firmware/targets/f7/ble-glue/ble_dbg_conf.h new file mode 100644 index 00000000..4eb0239b --- /dev/null +++ b/firmware/targets/f7/ble-glue/ble_dbg_conf.h @@ -0,0 +1,199 @@ +/** + ****************************************************************************** + * File Name : App/ble_dbg_conf.h + * Description : Debug configuration file for BLE Middleware. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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 __BLE_DBG_CONF_H +#define __BLE_DBG_CONF_H + +/** + * Enable or Disable traces from BLE + */ + +#define BLE_DBG_APP_EN 0 +#define BLE_DBG_DIS_EN 0 +#define BLE_DBG_HRS_EN 0 +#define BLE_DBG_SVCCTL_EN 0 +#define BLE_DBG_BLS_EN 0 +#define BLE_DBG_HTS_EN 0 +#define BLE_DBG_P2P_STM_EN 0 + +/** + * Macro definition + */ +#if ( BLE_DBG_APP_EN != 0 ) +#define BLE_DBG_APP_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_APP_MSG PRINT_NO_MESG +#endif + +#if ( BLE_DBG_DIS_EN != 0 ) +#define BLE_DBG_DIS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_DIS_MSG PRINT_NO_MESG +#endif + +#if ( BLE_DBG_HRS_EN != 0 ) +#define BLE_DBG_HRS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_HRS_MSG PRINT_NO_MESG +#endif + +#if ( BLE_DBG_P2P_STM_EN != 0 ) +#define BLE_DBG_P2P_STM_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_P2P_STM_MSG PRINT_NO_MESG +#endif + +#if ( BLE_DBG_TEMPLATE_STM_EN != 0 ) +#define BLE_DBG_TEMPLATE_STM_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_TEMPLATE_STM_MSG PRINT_NO_MESG +#endif + +#if ( BLE_DBG_EDS_STM_EN != 0 ) +#define BLE_DBG_EDS_STM_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_EDS_STM_MSG PRINT_NO_MESG +#endif + +#if ( BLE_DBG_LBS_STM_EN != 0 ) +#define BLE_DBG_LBS_STM_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_LBS_STM_MSG PRINT_NO_MESG +#endif + +#if ( BLE_DBG_SVCCTL_EN != 0 ) +#define BLE_DBG_SVCCTL_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_SVCCTL_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_CTS_EN != 0) +#define BLE_DBG_CTS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_CTS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_HIDS_EN != 0) +#define BLE_DBG_HIDS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_HIDS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_PASS_EN != 0) +#define BLE_DBG_PASS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_PASS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_BLS_EN != 0) +#define BLE_DBG_BLS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_BLS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_HTS_EN != 0) +#define BLE_DBG_HTS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_HTS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_ANS_EN != 0) +#define BLE_DBG_ANS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_ANS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_ESS_EN != 0) +#define BLE_DBG_ESS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_ESS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_GLS_EN != 0) +#define BLE_DBG_GLS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_GLS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_BAS_EN != 0) +#define BLE_DBG_BAS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_BAS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_RTUS_EN != 0) +#define BLE_DBG_RTUS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_RTUS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_HPS_EN != 0) +#define BLE_DBG_HPS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_HPS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_TPS_EN != 0) +#define BLE_DBG_TPS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_TPS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_LLS_EN != 0) +#define BLE_DBG_LLS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_LLS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_IAS_EN != 0) +#define BLE_DBG_IAS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_IAS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_WSS_EN != 0) +#define BLE_DBG_WSS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_WSS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_LNS_EN != 0) +#define BLE_DBG_LNS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_LNS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_SCPS_EN != 0) +#define BLE_DBG_SCPS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_SCPS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_DTS_EN != 0) +#define BLE_DBG_DTS_MSG PRINT_MESG_DBG +#define BLE_DBG_DTS_BUF PRINT_LOG_BUFF_DBG +#else +#define BLE_DBG_DTS_MSG PRINT_NO_MESG +#define BLE_DBG_DTS_BUF PRINT_NO_MESG +#endif + +#endif /*__BLE_DBG_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble-glue/dev_info_service.c b/firmware/targets/f7/ble-glue/dev_info_service.c new file mode 100644 index 00000000..d2b60cfd --- /dev/null +++ b/firmware/targets/f7/ble-glue/dev_info_service.c @@ -0,0 +1,121 @@ +#include "dev_info_service.h" +#include "app_common.h" +#include "ble.h" + +#include + +#define DEV_INFO_SERVICE_TAG "dev info service" + +typedef struct { + uint16_t service_handle; + uint16_t man_name_char_handle; + uint16_t serial_num_char_handle; + uint16_t firmware_rev_char_handle; + uint16_t software_rev_char_handle; +} DevInfoSvc; + +bool dev_info_service_init() { + tBleStatus status; + DevInfoSvc dev_info_svc; + + // Add Device Information Service + uint16_t uuid = DEVICE_INFORMATION_SERVICE_UUID; + status = aci_gatt_add_service(UUID_TYPE_16, (Service_UUID_t*)&uuid, PRIMARY_SERVICE, 9, &dev_info_svc.service_handle); + if(status) { + FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add Device Information Service: %d", status); + } + + // Add characteristics + uuid = MANUFACTURER_NAME_UUID; + status = aci_gatt_add_char(dev_info_svc.service_handle, + UUID_TYPE_16, + (Char_UUID_t*)&uuid, + strlen(DEV_INFO_MANUFACTURER_NAME), + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &dev_info_svc.man_name_char_handle); + if(status) { + FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add manufacturer name char: %d", status); + + } + uuid = SERIAL_NUMBER_UUID; + status = aci_gatt_add_char(dev_info_svc.service_handle, + UUID_TYPE_16, + (Char_UUID_t*)&uuid, + strlen(DEV_INFO_SERIAL_NUMBER), + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &dev_info_svc.serial_num_char_handle); + if(status) { + FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add serial number char: %d", status); + } + uuid = FIRMWARE_REVISION_UUID; + status = aci_gatt_add_char(dev_info_svc.service_handle, + UUID_TYPE_16, + (Char_UUID_t*)&uuid, + strlen(DEV_INFO_FIRMWARE_REVISION_NUMBER), + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &dev_info_svc.firmware_rev_char_handle); + if(status) { + FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add firmware revision char: %d", status); + } + uuid = SOFTWARE_REVISION_UUID; + status = aci_gatt_add_char(dev_info_svc.service_handle, + UUID_TYPE_16, + (Char_UUID_t*)&uuid, + strlen(DEV_INFO_SOFTWARE_REVISION_NUMBER), + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &dev_info_svc.software_rev_char_handle); + if(status) { + FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to add software revision char: %d", status); + } + + // Update characteristics + status = aci_gatt_update_char_value(dev_info_svc.service_handle, + dev_info_svc.man_name_char_handle, + 0, + strlen(DEV_INFO_MANUFACTURER_NAME), + (uint8_t*)DEV_INFO_MANUFACTURER_NAME); + if(status) { + FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to update manufacturer name char: %d", status); + } + status = aci_gatt_update_char_value(dev_info_svc.service_handle, + dev_info_svc.serial_num_char_handle, + 0, + strlen(DEV_INFO_SERIAL_NUMBER), + (uint8_t*)DEV_INFO_SERIAL_NUMBER); + if(status) { + FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to update serial number char: %d", status); + } + status = aci_gatt_update_char_value(dev_info_svc.service_handle, + dev_info_svc.firmware_rev_char_handle, + 0, + strlen(DEV_INFO_FIRMWARE_REVISION_NUMBER), + (uint8_t*)DEV_INFO_FIRMWARE_REVISION_NUMBER); + if(status) { + FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to update firmware revision char: %d", status); + } + status = aci_gatt_update_char_value(dev_info_svc.service_handle, + dev_info_svc.software_rev_char_handle, + 0, + strlen(DEV_INFO_SOFTWARE_REVISION_NUMBER), + (uint8_t*)DEV_INFO_SOFTWARE_REVISION_NUMBER); + if(status) { + FURI_LOG_E(DEV_INFO_SERVICE_TAG, "Failed to update software revision char: %d", status); + } + return status != BLE_STATUS_SUCCESS; +} diff --git a/firmware/targets/f7/ble-glue/dev_info_service.h b/firmware/targets/f7/ble-glue/dev_info_service.h new file mode 100644 index 00000000..b0e08d3f --- /dev/null +++ b/firmware/targets/f7/ble-glue/dev_info_service.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEV_INFO_MANUFACTURER_NAME "Flipper Devices Inc." +#define DEV_INFO_SERIAL_NUMBER "1.0" +#define DEV_INFO_FIRMWARE_REVISION_NUMBER TARGET +#define DEV_INFO_SOFTWARE_REVISION_NUMBER GIT_COMMIT " " GIT_BRANCH " " GIT_BRANCH_NUM " " BUILD_DATE + + +bool dev_info_service_init(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/ble-glue/hw_conf.h b/firmware/targets/f7/ble-glue/hw_conf.h new file mode 100644 index 00000000..dcda0176 --- /dev/null +++ b/firmware/targets/f7/ble-glue/hw_conf.h @@ -0,0 +1,199 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file hw_conf.h + * @author MCD Application Team + * @brief Configuration of hardware interface + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * 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 HW_CONF_H +#define HW_CONF_H + +#include "FreeRTOSConfig.h" + +/****************************************************************************** + * Semaphores + * THIS SHALL NO BE CHANGED AS THESE SEMAPHORES ARE USED AS WELL ON THE CM0+ + *****************************************************************************/ +/** +* Index of the semaphore used by CPU2 to prevent the CPU1 to either write or erase data in flash +* The CPU1 shall not either write or erase in flash when this semaphore is taken by the CPU2 +* When the CPU1 needs to either write or erase in flash, it shall first get the semaphore and release it just +* after writing a raw (64bits data) or erasing one sector. +* Once the Semaphore has been released, there shall be at least 1us before it can be taken again. This is required +* to give the opportunity to CPU2 to take it. +* On v1.4.0 and older CPU2 wireless firmware, this semaphore is unused and CPU2 is using PES bit. +* By default, CPU2 is using the PES bit to protect its timing. The CPU1 may request the CPU2 to use the semaphore +* instead of the PES bit by sending the system command SHCI_C2_SetFlashActivityControl() +*/ +#define CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID 7 + +/** +* Index of the semaphore used by CPU1 to prevent the CPU2 to either write or erase data in flash +* In order to protect its timing, the CPU1 may get this semaphore to prevent the CPU2 to either +* write or erase in flash (as this will stall both CPUs) +* The PES bit shall not be used as this may stall the CPU2 in some cases. +*/ +#define CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID 6 + +/** +* Index of the semaphore used to manage the CLK48 clock configuration +* When the USB is required, this semaphore shall be taken before configuring te CLK48 for USB +* and should be released after the application switch OFF the clock when the USB is not used anymore +* When using the RNG, it is good enough to use CFG_HW_RNG_SEMID to control CLK48. +* More details in AN5289 +*/ +#define CFG_HW_CLK48_CONFIG_SEMID 5 + +/* Index of the semaphore used to manage the entry Stop Mode procedure */ +#define CFG_HW_ENTRY_STOP_MODE_SEMID 4 + +/* Index of the semaphore used to access the RCC */ +#define CFG_HW_RCC_SEMID 3 + +/* Index of the semaphore used to access the FLASH */ +#define CFG_HW_FLASH_SEMID 2 + +/* Index of the semaphore used to access the PKA */ +#define CFG_HW_PKA_SEMID 1 + +/* Index of the semaphore used to access the RNG */ +#define CFG_HW_RNG_SEMID 0 + +/****************************************************************************** + * HW TIMER SERVER + *****************************************************************************/ +/** + * The user may define the maximum number of virtual timers supported. + * It shall not exceed 255 + */ +#define CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER 6 + +/** + * The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the + * wakeup timer. + * This setting is the preemptpriority part of the NVIC. + */ +#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1) /* FreeRTOS requirement */ + +/** + * The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the + * wakeup timer. + * This setting is the subpriority part of the NVIC. It does not exist on all processors. When it is not supported + * on the CPU, the setting is ignored + */ +#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO 0 + +/** + * Define a critical section in the Timer server + * The Timer server does not support the API to be nested + * The Application shall either: + * a) Ensure this will never happen + * b) Define the critical section + * The default implementations is masking all interrupts using the PRIMASK bit + * The TimerServer driver uses critical sections to avoid context corruption. This is achieved with the macro + * TIMER_ENTER_CRITICAL_SECTION and TIMER_EXIT_CRITICAL_SECTION. When CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION is set + * to 1, all STM32 interrupts are masked with the PRIMASK bit of the CortexM CPU. It is possible to use the BASEPRI + * register of the CortexM CPU to keep allowed some interrupts with high priority. In that case, the user shall + * re-implement TIMER_ENTER_CRITICAL_SECTION and TIMER_EXIT_CRITICAL_SECTION and shall make sure that no TimerServer + * API are called when the TIMER critical section is entered + */ +#define CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION 1 + +/** + * This value shall reflect the maximum delay there could be in the application between the time the RTC interrupt + * is generated by the Hardware and the time when the RTC interrupt handler is called. This time is measured in + * number of RTCCLK ticks. + * A relaxed timing would be 10ms + * When the value is too short, the timerserver will not be able to count properly and all timeout may be random. + * When the value is too long, the device may wake up more often than the most optimal configuration. However, the + * impact on power consumption would be marginal (unless the value selected is extremely too long). It is strongly + * recommended to select a value large enough to make sure it is not too short to ensure reliability of the system + * as this will have marginal impact on low power mode + */ +#define CFG_HW_TS_RTC_HANDLER_MAX_DELAY ( 10 * (LSI_VALUE/1000) ) + + /** + * Interrupt ID in the NVIC of the RTC Wakeup interrupt handler + * It shall be type of IRQn_Type + */ +#define CFG_HW_TS_RTC_WAKEUP_HANDLER_ID RTC_WKUP_IRQn + +/****************************************************************************** + * HW UART + *****************************************************************************/ +#define CFG_HW_LPUART1_ENABLED 0 +#define CFG_HW_LPUART1_DMA_TX_SUPPORTED 0 + +#define CFG_HW_USART1_ENABLED 1 +#define CFG_HW_USART1_DMA_TX_SUPPORTED 1 + +/** + * UART1 + */ +#define CFG_HW_USART1_PREEMPTPRIORITY 0x0F +#define CFG_HW_USART1_SUBPRIORITY 0 + +/** < The application shall check the selected source clock is enable */ +#define CFG_HW_USART1_SOURCE_CLOCK RCC_USART1CLKSOURCE_SYSCLK + +#define CFG_HW_USART1_BAUDRATE 115200 +#define CFG_HW_USART1_WORDLENGTH UART_WORDLENGTH_8B +#define CFG_HW_USART1_STOPBITS UART_STOPBITS_1 +#define CFG_HW_USART1_PARITY UART_PARITY_NONE +#define CFG_HW_USART1_HWFLOWCTL UART_HWCONTROL_NONE +#define CFG_HW_USART1_MODE UART_MODE_TX_RX +#define CFG_HW_USART1_ADVFEATUREINIT UART_ADVFEATURE_NO_INIT +#define CFG_HW_USART1_OVERSAMPLING UART_OVERSAMPLING_8 + +#define CFG_HW_USART1_TX_PORT_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE +#define CFG_HW_USART1_TX_PORT GPIOB +#define CFG_HW_USART1_TX_PIN GPIO_PIN_6 +#define CFG_HW_USART1_TX_MODE GPIO_MODE_AF_PP +#define CFG_HW_USART1_TX_PULL GPIO_NOPULL +#define CFG_HW_USART1_TX_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define CFG_HW_USART1_TX_ALTERNATE GPIO_AF7_USART1 + +#define CFG_HW_USART1_RX_PORT_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE +#define CFG_HW_USART1_RX_PORT GPIOB +#define CFG_HW_USART1_RX_PIN GPIO_PIN_7 +#define CFG_HW_USART1_RX_MODE GPIO_MODE_AF_PP +#define CFG_HW_USART1_RX_PULL GPIO_NOPULL +#define CFG_HW_USART1_RX_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define CFG_HW_USART1_RX_ALTERNATE GPIO_AF7_USART1 + +#define CFG_HW_USART1_CTS_PORT_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE +#define CFG_HW_USART1_CTS_PORT GPIOA +#define CFG_HW_USART1_CTS_PIN GPIO_PIN_11 +#define CFG_HW_USART1_CTS_MODE GPIO_MODE_AF_PP +#define CFG_HW_USART1_CTS_PULL GPIO_PULLDOWN +#define CFG_HW_USART1_CTS_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define CFG_HW_USART1_CTS_ALTERNATE GPIO_AF7_USART1 + +#define CFG_HW_USART1_DMA_TX_PREEMPTPRIORITY 0x0F +#define CFG_HW_USART1_DMA_TX_SUBPRIORITY 0 + +#define CFG_HW_USART1_DMAMUX_CLK_ENABLE __HAL_RCC_DMAMUX1_CLK_ENABLE +#define CFG_HW_USART1_DMA_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE +#define CFG_HW_USART1_TX_DMA_REQ DMA_REQUEST_USART1_TX +#define CFG_HW_USART1_TX_DMA_CHANNEL DMA2_Channel4 +#define CFG_HW_USART1_TX_DMA_IRQn DMA2_Channel4_IRQn +#define CFG_HW_USART1_DMA_TX_IRQHandler DMA2_Channel4_IRQHandler + +#endif /*HW_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble-glue/hw_if.h b/firmware/targets/f7/ble-glue/hw_if.h new file mode 100644 index 00000000..271a222a --- /dev/null +++ b/firmware/targets/f7/ble-glue/hw_if.h @@ -0,0 +1,250 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file hw_if.h + * @author MCD Application Team + * @brief Hardware Interface + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * 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 HW_IF_H +#define HW_IF_H + +#ifdef __cplusplus +extern "C" { +#endif + + /* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx.h" +#include "stm32wbxx_ll_exti.h" +#include "stm32wbxx_ll_system.h" +#include "stm32wbxx_ll_rcc.h" +#include "stm32wbxx_ll_ipcc.h" +#include "stm32wbxx_ll_bus.h" +#include "stm32wbxx_ll_pwr.h" +#include "stm32wbxx_ll_cortex.h" +#include "stm32wbxx_ll_utils.h" +#include "stm32wbxx_ll_hsem.h" +#include "stm32wbxx_ll_gpio.h" +#include "stm32wbxx_ll_rtc.h" + +#ifdef USE_STM32WBXX_USB_DONGLE +#include "stm32wbxx_usb_dongle.h" +#endif +#ifdef USE_STM32WBXX_NUCLEO +#include "stm32wbxx_nucleo.h" +#endif +#ifdef USE_X_NUCLEO_EPD +#include "x_nucleo_epd.h" +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + + /****************************************************************************** + * HW UART + ******************************************************************************/ + typedef enum + { + hw_uart1, + hw_uart2, + hw_lpuart1, + } hw_uart_id_t; + + typedef enum + { + hw_uart_ok, + hw_uart_error, + hw_uart_busy, + hw_uart_to, + } hw_status_t; + + void HW_UART_Init(hw_uart_id_t hw_uart_id); + void HW_UART_Receive_IT(hw_uart_id_t hw_uart_id, uint8_t *pData, uint16_t Size, void (*Callback)(void)); + void HW_UART_Transmit_IT(hw_uart_id_t hw_uart_id, uint8_t *pData, uint16_t Size, void (*Callback)(void)); + hw_status_t HW_UART_Transmit(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, uint32_t timeout); + hw_status_t HW_UART_Transmit_DMA(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*Callback)(void)); + void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id); + void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id); + + /****************************************************************************** + * HW TimerServer + ******************************************************************************/ + /* Exported types ------------------------------------------------------------*/ + /** + * This setting is used when standby mode is supported. + * hw_ts_InitMode_Limited should be used when the device restarts from Standby Mode. In that case, the Timer Server does + * not re-initialized its context. Only the Hardware register which content has been lost is reconfigured + * Otherwise, hw_ts_InitMode_Full should be requested (Start from Power ON) and everything is re-initialized. + */ + typedef enum + { + hw_ts_InitMode_Full, + hw_ts_InitMode_Limited, + } HW_TS_InitMode_t; + + /** + * When a Timer is created as a SingleShot timer, it is not automatically restarted when the timeout occurs. However, + * the timer is kept reserved in the list and could be restarted at anytime with HW_TS_Start() + * + * When a Timer is created as a Repeated timer, it is automatically restarted when the timeout occurs. + */ + typedef enum + { + hw_ts_SingleShot, + hw_ts_Repeated + } HW_TS_Mode_t; + + /** + * hw_ts_Successful is returned when a Timer has been successfully created with HW_TS_Create(). Otherwise, hw_ts_Failed + * is returned. When hw_ts_Failed is returned, that means there are not enough free slots in the list to create a + * Timer. In that case, CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER should be increased + */ + typedef enum + { + hw_ts_Successful, + hw_ts_Failed, + }HW_TS_ReturnStatus_t; + + typedef void (*HW_TS_pTimerCb_t)(void); + + /** + * @brief Initialize the timer server + * This API shall be called by the application before any timer is requested to the timer server. It + * configures the RTC module to be connected to the LSI input clock. + * + * @param TimerInitMode: When the device restarts from Standby, it should request hw_ts_InitMode_Limited so that the + * Timer context is not re-initialized. Otherwise, hw_ts_InitMode_Full should be requested + * @param hrtc: RTC Handle + * @retval None + */ + void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *hrtc); + + /** + * @brief Interface to create a virtual timer + * The user shall call this API to create a timer. Once created, the timer is reserved to the module until it + * has been deleted. When creating a timer, the user shall specify the mode (single shot or repeated), the + * callback to be notified when the timer expires and a module ID to identify in the timer interrupt handler + * which module is concerned. In return, the user gets a timer ID to handle it. + * + * @param TimerProcessID: This is an identifier provided by the user and returned in the callback to allow + * identification of the requester + * @param pTimerId: Timer Id returned to the user to request operation (start, stop, delete) + * @param TimerMode: Mode of the virtual timer (Single shot or repeated) + * @param pTimerCallBack: Callback when the virtual timer expires + * @retval HW_TS_ReturnStatus_t: Return whether the creation is sucessfull or not + */ + HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pTimerCallBack); + + /** + * @brief Stop a virtual timer + * This API may be used to stop a running timer. A timer which is stopped is move to the pending state. + * A pending timer may be restarted at any time with a different timeout value but the mode cannot be changed. + * Nothing is done when it is called to stop a timer which has been already stopped + * + * @param TimerID: Id of the timer to stop + * @retval None + */ + void HW_TS_Stop(uint8_t TimerID); + + /** + * @brief Start a virtual timer + * This API shall be used to start a timer. The timeout value is specified and may be different each time. + * When the timer is in the single shot mode, it will move to the pending state when it expires. The user may + * restart it at any time with a different timeout value. When the timer is in the repeated mode, it always + * stay in the running state. When the timer expires, it will be restarted with the same timeout value. + * This API shall not be called on a running timer. + * + * @param TimerID: The ID Id of the timer to start + * @param timeout_ticks: Number of ticks of the virtual timer (Maximum value is (0xFFFFFFFF-0xFFFF = 0xFFFF0000) + * @retval None + */ + void HW_TS_Start(uint8_t TimerID, uint32_t timeout_ticks); + + /** + * @brief Delete a virtual timer from the list + * This API should be used when a timer is not needed anymore by the user. A deleted timer is removed from + * the timer list managed by the timer server. It cannot be restarted again. The user has to go with the + * creation of a new timer if required and may get a different timer id + * + * @param TimerID: The ID of the timer to remove from the list + * @retval None + */ + void HW_TS_Delete(uint8_t TimerID); + + /** + * @brief Schedule the timer list on the timer interrupt handler + * This interrupt handler shall be called by the application in the RTC interrupt handler. This handler takes + * care of clearing all status flag required in the RTC and EXTI peripherals + * + * @param None + * @retval None + */ + void HW_TS_RTC_Wakeup_Handler(void); + + /** + * @brief Return the number of ticks to count before the interrupt + * This API returns the number of ticks left to be counted before an interrupt is generated by the + * Timer Server. This API may be used by the application for power management optimization. When the system + * enters low power mode, the mode selection is a tradeoff between the wakeup time where the CPU is running + * and the time while the CPU will be kept in low power mode before next wakeup. The deeper is the + * low power mode used, the longer is the wakeup time. The low power mode management considering wakeup time + * versus time in low power mode is implementation specific + * When the timer is disabled (No timer in the list), it returns 0xFFFF + * + * @param None + * @retval The number of ticks left to count + */ + uint16_t HW_TS_RTC_ReadLeftTicksToCount(void); + + /** + * @brief Notify the application that a registered timer has expired + * This API shall be implemented by the user application. + * This API notifies the application that a timer expires. This API is running in the RTC Wakeup interrupt + * context. The application may implement an Operating System to change the context priority where the timer + * callback may be handled. This API provides the module ID to identify which module is concerned and to allow + * sending the information to the correct task + * + * @param TimerProcessID: The TimerProcessId associated with the timer when it has been created + * @param TimerID: The TimerID of the expired timer + * @param pTimerCallBack: The Callback associated with the timer when it has been created + * @retval None + */ + void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack); + + /** + * @brief Notify the application that the wakeupcounter has been updated + * This API should be implemented by the user application + * This API notifies the application that the counter has been updated. This is expected to be used along + * with the HW_TS_RTC_ReadLeftTicksToCount () API. It could be that the counter has been updated since the + * last call of HW_TS_RTC_ReadLeftTicksToCount () and before entering low power mode. This notification + * provides a way to the application to solve that race condition to reevaluate the counter value before + * entering low power mode + * + * @param None + * @retval None + */ + void HW_TS_RTC_CountUpdated_AppNot(void); + +#ifdef __cplusplus +} +#endif + +#endif /*HW_IF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble-glue/hw_ipcc.c b/firmware/targets/f7/ble-glue/hw_ipcc.c new file mode 100644 index 00000000..17b5a4d8 --- /dev/null +++ b/firmware/targets/f7/ble-glue/hw_ipcc.c @@ -0,0 +1,675 @@ +/** + ****************************************************************************** + * File Name : Target/hw_ipcc.c + * Description : Hardware IPCC source file for STM32WPAN Middleware. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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 "app_common.h" +#include "mbox_def.h" + +/* Global variables ---------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +#define HW_IPCC_TX_PENDING( channel ) ( !(LL_C1_IPCC_IsActiveFlag_CHx( IPCC, channel )) ) && (((~(IPCC->C1MR)) & (channel << 16U))) +#define HW_IPCC_RX_PENDING( channel ) (LL_C2_IPCC_IsActiveFlag_CHx( IPCC, channel )) && (((~(IPCC->C1MR)) & (channel << 0U))) + +/* Private macros ------------------------------------------------------------*/ +/* Private typedef -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static void (*FreeBufCb)( void ); + +/* Private function prototypes -----------------------------------------------*/ +static void HW_IPCC_BLE_EvtHandler( void ); +static void HW_IPCC_BLE_AclDataEvtHandler( void ); +static void HW_IPCC_MM_FreeBufHandler( void ); +static void HW_IPCC_SYS_CmdEvtHandler( void ); +static void HW_IPCC_SYS_EvtHandler( void ); +static void HW_IPCC_TRACES_EvtHandler( void ); + +#ifdef THREAD_WB +static void HW_IPCC_OT_CmdEvtHandler( void ); +static void HW_IPCC_THREAD_NotEvtHandler( void ); +static void HW_IPCC_THREAD_CliNotEvtHandler( void ); +#endif + +#ifdef LLD_TESTS_WB +static void HW_IPCC_LLDTESTS_ReceiveCliRspHandler( void ); +static void HW_IPCC_LLDTESTS_ReceiveM0CmdHandler( void ); +#endif +#ifdef LLD_BLE_WB +/*static void HW_IPCC_LLD_BLE_ReceiveCliRspHandler( void );*/ +static void HW_IPCC_LLD_BLE_ReceiveRspHandler( void ); +static void HW_IPCC_LLD_BLE_ReceiveM0CmdHandler( void ); +#endif + +#ifdef MAC_802_15_4_WB +static void HW_IPCC_MAC_802_15_4_CmdEvtHandler( void ); +static void HW_IPCC_MAC_802_15_4_NotEvtHandler( void ); +#endif + +#ifdef ZIGBEE_WB +static void HW_IPCC_ZIGBEE_CmdEvtHandler( void ); +static void HW_IPCC_ZIGBEE_StackNotifEvtHandler( void ); +static void HW_IPCC_ZIGBEE_StackM0RequestHandler( void ); +#endif + +/* Public function definition -----------------------------------------------*/ + +/****************************************************************************** + * INTERRUPT HANDLER + ******************************************************************************/ +void HW_IPCC_Rx_Handler( void ) +{ + if (HW_IPCC_RX_PENDING( HW_IPCC_SYSTEM_EVENT_CHANNEL )) + { + HW_IPCC_SYS_EvtHandler(); + } +#ifdef MAC_802_15_4_WB + else if (HW_IPCC_RX_PENDING( HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL )) + { + HW_IPCC_MAC_802_15_4_NotEvtHandler(); + } +#endif /* MAC_802_15_4_WB */ +#ifdef THREAD_WB + else if (HW_IPCC_RX_PENDING( HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL )) + { + HW_IPCC_THREAD_NotEvtHandler(); + } + else if (HW_IPCC_RX_PENDING( HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL )) + { + HW_IPCC_THREAD_CliNotEvtHandler(); + } +#endif /* THREAD_WB */ +#ifdef LLD_TESTS_WB + else if (HW_IPCC_RX_PENDING( HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL )) + { + HW_IPCC_LLDTESTS_ReceiveCliRspHandler(); + } + else if (HW_IPCC_RX_PENDING( HW_IPCC_LLDTESTS_M0_CMD_CHANNEL )) + { + HW_IPCC_LLDTESTS_ReceiveM0CmdHandler(); + } +#endif /* LLD_TESTS_WB */ +#ifdef LLD_BLE_WB + else if (HW_IPCC_RX_PENDING( HW_IPCC_LLD_BLE_RSP_CHANNEL )) + { + HW_IPCC_LLD_BLE_ReceiveRspHandler(); + } + else if (HW_IPCC_RX_PENDING( HW_IPCC_LLD_BLE_M0_CMD_CHANNEL )) + { + HW_IPCC_LLD_BLE_ReceiveM0CmdHandler(); + } +#endif /* LLD_TESTS_WB */ +#ifdef ZIGBEE_WB + else if (HW_IPCC_RX_PENDING( HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL )) + { + HW_IPCC_ZIGBEE_StackNotifEvtHandler(); + } + else if (HW_IPCC_RX_PENDING( HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL )) + { + HW_IPCC_ZIGBEE_StackM0RequestHandler(); + } +#endif /* ZIGBEE_WB */ + else if (HW_IPCC_RX_PENDING( HW_IPCC_BLE_EVENT_CHANNEL )) + { + HW_IPCC_BLE_EvtHandler(); + } + else if (HW_IPCC_RX_PENDING( HW_IPCC_TRACES_CHANNEL )) + { + HW_IPCC_TRACES_EvtHandler(); + } + + return; +} + +void HW_IPCC_Tx_Handler( void ) +{ + if (HW_IPCC_TX_PENDING( HW_IPCC_SYSTEM_CMD_RSP_CHANNEL )) + { + HW_IPCC_SYS_CmdEvtHandler(); + } +#ifdef MAC_802_15_4_WB + else if (HW_IPCC_TX_PENDING( HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL )) + { + HW_IPCC_MAC_802_15_4_CmdEvtHandler(); + } +#endif /* MAC_802_15_4_WB */ +#ifdef THREAD_WB + else if (HW_IPCC_TX_PENDING( HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL )) + { + HW_IPCC_OT_CmdEvtHandler(); + } +#endif /* THREAD_WB */ +#ifdef LLD_TESTS_WB +// No TX handler for LLD tests +#endif /* LLD_TESTS_WB */ +#ifdef ZIGBEE_WB + if (HW_IPCC_TX_PENDING( HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL )) + { + HW_IPCC_ZIGBEE_CmdEvtHandler(); + } +#endif /* ZIGBEE_WB */ + else if (HW_IPCC_TX_PENDING( HW_IPCC_SYSTEM_CMD_RSP_CHANNEL )) + { + HW_IPCC_SYS_CmdEvtHandler(); + } + else if (HW_IPCC_TX_PENDING( HW_IPCC_MM_RELEASE_BUFFER_CHANNEL )) + { + HW_IPCC_MM_FreeBufHandler(); + } + else if (HW_IPCC_TX_PENDING( HW_IPCC_HCI_ACL_DATA_CHANNEL )) + { + HW_IPCC_BLE_AclDataEvtHandler(); + } + + return; +} +/****************************************************************************** + * GENERAL + ******************************************************************************/ +void HW_IPCC_Enable( void ) +{ + /** + * Such as IPCC IP available to the CPU2, it is required to keep the IPCC clock running + when FUS is running on CPU2 and CPU1 enters deep sleep mode + */ + LL_C2_AHB3_GRP1_EnableClock(LL_C2_AHB3_GRP1_PERIPH_IPCC); + + /** + * When the device is out of standby, it is required to use the EXTI mechanism to wakeup CPU2 + */ + LL_C2_EXTI_EnableEvent_32_63( LL_EXTI_LINE_41 ); + LL_EXTI_EnableRisingTrig_32_63( LL_EXTI_LINE_41 ); + + /** + * In case the SBSFU is implemented, it may have already set the C2BOOT bit to startup the CPU2. + * In that case, to keep the mechanism transparent to the user application, it shall call the system command + * SHCI_C2_Reinit( ) before jumping to the application. + * When the CPU2 receives that command, it waits for its event input to be set to restart the CPU2 firmware. + * This is required because once C2BOOT has been set once, a clear/set on C2BOOT has no effect. + * When SHCI_C2_Reinit( ) is not called, generating an event to the CPU2 does not have any effect + * So, by default, the application shall both set the event flag and set the C2BOOT bit. + */ + __SEV( ); /* Set the internal event flag and send an event to the CPU2 */ + __WFE( ); /* Clear the internal event flag */ + LL_PWR_EnableBootC2( ); + + return; +} + +void HW_IPCC_Init( void ) +{ + LL_AHB3_GRP1_EnableClock( LL_AHB3_GRP1_PERIPH_IPCC ); + + LL_C1_IPCC_EnableIT_RXO( IPCC ); + LL_C1_IPCC_EnableIT_TXF( IPCC ); + + HAL_NVIC_SetPriority(IPCC_C1_RX_IRQn, 6, 0); + HAL_NVIC_EnableIRQ(IPCC_C1_RX_IRQn); + HAL_NVIC_SetPriority(IPCC_C1_TX_IRQn, 6, 0); + HAL_NVIC_EnableIRQ(IPCC_C1_TX_IRQn); + + return; +} + +/****************************************************************************** + * BLE + ******************************************************************************/ +void HW_IPCC_BLE_Init( void ) +{ + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_BLE_EVENT_CHANNEL ); + + return; +} + +void HW_IPCC_BLE_SendCmd( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_BLE_CMD_CHANNEL ); + + return; +} + +static void HW_IPCC_BLE_EvtHandler( void ) +{ + HW_IPCC_BLE_RxEvtNot(); + + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_BLE_EVENT_CHANNEL ); + + return; +} + +void HW_IPCC_BLE_SendAclData( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_HCI_ACL_DATA_CHANNEL ); + LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_HCI_ACL_DATA_CHANNEL ); + + return; +} + +static void HW_IPCC_BLE_AclDataEvtHandler( void ) +{ + LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_HCI_ACL_DATA_CHANNEL ); + + HW_IPCC_BLE_AclDataAckNot(); + + return; +} + +__weak void HW_IPCC_BLE_AclDataAckNot( void ){}; +__weak void HW_IPCC_BLE_RxEvtNot( void ){}; + +/****************************************************************************** + * SYSTEM + ******************************************************************************/ +void HW_IPCC_SYS_Init( void ) +{ + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_SYSTEM_EVENT_CHANNEL ); + + return; +} + +void HW_IPCC_SYS_SendCmd( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_SYSTEM_CMD_RSP_CHANNEL ); + LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_SYSTEM_CMD_RSP_CHANNEL ); + + return; +} + +static void HW_IPCC_SYS_CmdEvtHandler( void ) +{ + LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_SYSTEM_CMD_RSP_CHANNEL ); + + HW_IPCC_SYS_CmdEvtNot(); + + return; +} + +static void HW_IPCC_SYS_EvtHandler( void ) +{ + HW_IPCC_SYS_EvtNot(); + + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_SYSTEM_EVENT_CHANNEL ); + + return; +} + +__weak void HW_IPCC_SYS_CmdEvtNot( void ){}; +__weak void HW_IPCC_SYS_EvtNot( void ){}; + +/****************************************************************************** + * MAC 802.15.4 + ******************************************************************************/ +#ifdef MAC_802_15_4_WB +void HW_IPCC_MAC_802_15_4_Init( void ) +{ + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL ); + + return; +} + +void HW_IPCC_MAC_802_15_4_SendCmd( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL ); + LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL ); + + return; +} + +void HW_IPCC_MAC_802_15_4_SendAck( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL ); + + return; +} + +static void HW_IPCC_MAC_802_15_4_CmdEvtHandler( void ) +{ + LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL ); + + HW_IPCC_MAC_802_15_4_CmdEvtNot(); + + return; +} + +static void HW_IPCC_MAC_802_15_4_NotEvtHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL ); + + HW_IPCC_MAC_802_15_4_EvtNot(); + + return; +} +__weak void HW_IPCC_MAC_802_15_4_CmdEvtNot( void ){}; +__weak void HW_IPCC_MAC_802_15_4_EvtNot( void ){}; +#endif + +/****************************************************************************** + * THREAD + ******************************************************************************/ +#ifdef THREAD_WB +void HW_IPCC_THREAD_Init( void ) +{ + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL ); + + return; +} + +void HW_IPCC_OT_SendCmd( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL ); + LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL ); + + return; +} + +void HW_IPCC_CLI_SendCmd( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_THREAD_CLI_CMD_CHANNEL ); + + return; +} + +void HW_IPCC_THREAD_SendAck( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL ); + + return; +} + +void HW_IPCC_THREAD_CliSendAck( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL ); + + return; +} + +static void HW_IPCC_OT_CmdEvtHandler( void ) +{ + LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL ); + + HW_IPCC_OT_CmdEvtNot(); + + return; +} + +static void HW_IPCC_THREAD_NotEvtHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL ); + + HW_IPCC_THREAD_EvtNot(); + + return; +} + +static void HW_IPCC_THREAD_CliNotEvtHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL ); + + HW_IPCC_THREAD_CliEvtNot(); + + return; +} + +__weak void HW_IPCC_OT_CmdEvtNot( void ){}; +__weak void HW_IPCC_CLI_CmdEvtNot( void ){}; +__weak void HW_IPCC_THREAD_EvtNot( void ){}; + +#endif /* THREAD_WB */ + +/****************************************************************************** + * LLD TESTS + ******************************************************************************/ +#ifdef LLD_TESTS_WB +void HW_IPCC_LLDTESTS_Init( void ) +{ + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLDTESTS_M0_CMD_CHANNEL ); + return; +} + +void HW_IPCC_LLDTESTS_SendCliCmd( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_LLDTESTS_CLI_CMD_CHANNEL ); + return; +} + +static void HW_IPCC_LLDTESTS_ReceiveCliRspHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL ); + HW_IPCC_LLDTESTS_ReceiveCliRsp(); + return; +} + +void HW_IPCC_LLDTESTS_SendCliRspAck( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL ); + return; +} + +static void HW_IPCC_LLDTESTS_ReceiveM0CmdHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_LLDTESTS_M0_CMD_CHANNEL ); + HW_IPCC_LLDTESTS_ReceiveM0Cmd(); + return; +} + +void HW_IPCC_LLDTESTS_SendM0CmdAck( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_LLDTESTS_M0_CMD_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLDTESTS_M0_CMD_CHANNEL ); + return; +} +__weak void HW_IPCC_LLDTESTS_ReceiveCliRsp( void ){}; +__weak void HW_IPCC_LLDTESTS_ReceiveM0Cmd( void ){}; +#endif /* LLD_TESTS_WB */ + +/****************************************************************************** + * LLD BLE + ******************************************************************************/ +#ifdef LLD_BLE_WB +void HW_IPCC_LLD_BLE_Init( void ) +{ + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_RSP_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_M0_CMD_CHANNEL ); + return; +} + +void HW_IPCC_LLD_BLE_SendCliCmd( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_LLD_BLE_CLI_CMD_CHANNEL ); + return; +} + +/*static void HW_IPCC_LLD_BLE_ReceiveCliRspHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_CLI_RSP_CHANNEL ); + HW_IPCC_LLD_BLE_ReceiveCliRsp(); + return; +}*/ + +void HW_IPCC_LLD_BLE_SendCliRspAck( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_LLD_BLE_CLI_RSP_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_CLI_RSP_CHANNEL ); + return; +} + +static void HW_IPCC_LLD_BLE_ReceiveM0CmdHandler( void ) +{ + //LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_M0_CMD_CHANNEL ); + HW_IPCC_LLD_BLE_ReceiveM0Cmd(); + return; +} + +void HW_IPCC_LLD_BLE_SendM0CmdAck( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_LLD_BLE_M0_CMD_CHANNEL ); + //LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_M0_CMD_CHANNEL ); + return; +} +__weak void HW_IPCC_LLD_BLE_ReceiveCliRsp( void ){}; +__weak void HW_IPCC_LLD_BLE_ReceiveM0Cmd( void ){}; + +/* Transparent Mode */ +void HW_IPCC_LLD_BLE_SendCmd( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_LLD_BLE_CMD_CHANNEL ); + return; +} + +static void HW_IPCC_LLD_BLE_ReceiveRspHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_RSP_CHANNEL ); + HW_IPCC_LLD_BLE_ReceiveRsp(); + return; +} + +void HW_IPCC_LLD_BLE_SendRspAck( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_LLD_BLE_RSP_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_RSP_CHANNEL ); + return; +} + +#endif /* LLD_BLE_WB */ + +/****************************************************************************** + * ZIGBEE + ******************************************************************************/ +#ifdef ZIGBEE_WB +void HW_IPCC_ZIGBEE_Init( void ) +{ + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL ); + + return; +} + +void HW_IPCC_ZIGBEE_SendM4RequestToM0( void ) +{ + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL ); + LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL ); + + return; +} + +void HW_IPCC_ZIGBEE_SendM4AckToM0Notify( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL ); + + return; +} + +static void HW_IPCC_ZIGBEE_CmdEvtHandler( void ) +{ + LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL ); + + HW_IPCC_ZIGBEE_RecvAppliAckFromM0(); + + return; +} + +static void HW_IPCC_ZIGBEE_StackNotifEvtHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL ); + + HW_IPCC_ZIGBEE_RecvM0NotifyToM4(); + + return; +} + +static void HW_IPCC_ZIGBEE_StackM0RequestHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL ); + + HW_IPCC_ZIGBEE_RecvM0RequestToM4(); + + return; +} + +void HW_IPCC_ZIGBEE_SendM4AckToM0Request( void ) +{ + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL ); + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL ); + + return; +} + +__weak void HW_IPCC_ZIGBEE_RecvAppliAckFromM0( void ){}; +__weak void HW_IPCC_ZIGBEE_RecvM0NotifyToM4( void ){}; +__weak void HW_IPCC_ZIGBEE_RecvM0RequestToM4( void ){}; +#endif /* ZIGBEE_WB */ + +/****************************************************************************** + * MEMORY MANAGER + ******************************************************************************/ +void HW_IPCC_MM_SendFreeBuf( void (*cb)( void ) ) +{ + if ( LL_C1_IPCC_IsActiveFlag_CHx( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL ) ) + { + FreeBufCb = cb; + LL_C1_IPCC_EnableTransmitChannel( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL ); + } + else + { + cb(); + + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL ); + } + + return; +} + +static void HW_IPCC_MM_FreeBufHandler( void ) +{ + LL_C1_IPCC_DisableTransmitChannel( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL ); + + FreeBufCb(); + + LL_C1_IPCC_SetFlag_CHx( IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL ); + + return; +} + +/****************************************************************************** + * TRACES + ******************************************************************************/ +void HW_IPCC_TRACES_Init( void ) +{ + LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_TRACES_CHANNEL ); + + return; +} + +static void HW_IPCC_TRACES_EvtHandler( void ) +{ + HW_IPCC_TRACES_EvtNot(); + + LL_C1_IPCC_ClearFlag_CHx( IPCC, HW_IPCC_TRACES_CHANNEL ); + + return; +} + +__weak void HW_IPCC_TRACES_EvtNot( void ){}; + +/******************* (C) COPYRIGHT 2019 STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble-glue/hw_timerserver.c b/firmware/targets/f7/ble-glue/hw_timerserver.c new file mode 100644 index 00000000..e0e4fcb5 --- /dev/null +++ b/firmware/targets/f7/ble-glue/hw_timerserver.c @@ -0,0 +1,893 @@ +/** + ****************************************************************************** + * File Name : hw_timerserver.c + * Description : Hardware timerserver source file for STM32WPAN Middleware. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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 "app_common.h" +#include "hw_conf.h" + +/* Private typedef -----------------------------------------------------------*/ +typedef enum +{ + TimerID_Free, + TimerID_Created, + TimerID_Running +}TimerIDStatus_t; + +typedef enum +{ + SSR_Read_Requested, + SSR_Read_Not_Requested +}RequestReadSSR_t; + +typedef enum +{ + WakeupTimerValue_Overpassed, + WakeupTimerValue_LargeEnough +}WakeupTimerLimitation_Status_t; + +typedef struct +{ + HW_TS_pTimerCb_t pTimerCallBack; + uint32_t CounterInit; + uint32_t CountLeft; + TimerIDStatus_t TimerIDStatus; + HW_TS_Mode_t TimerMode; + uint32_t TimerProcessID; + uint8_t PreviousID; + uint8_t NextID; +}TimerContext_t; + +/* Private defines -----------------------------------------------------------*/ +#define SSR_FORBIDDEN_VALUE 0xFFFFFFFF +#define TIMER_LIST_EMPTY 0xFFFF + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/** + * START of Section TIMERSERVER_CONTEXT + */ + +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile TimerContext_t aTimerContext[CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER]; +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t CurrentRunningTimerID; +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t PreviousRunningTimerID; +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint32_t SSRValueOnLastSetup; +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile WakeupTimerLimitation_Status_t WakeupTimerLimitation; + +/** + * END of Section TIMERSERVER_CONTEXT + */ + +static RTC_HandleTypeDef *phrtc; /**< RTC handle */ +static uint8_t WakeupTimerDivider; +static uint8_t AsynchPrescalerUserConfig; +static uint16_t SynchPrescalerUserConfig; +static volatile uint16_t MaxWakeupTimerSetup; + +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void RestartWakeupCounter(uint16_t Value); +static uint16_t ReturnTimeElapsed(void); +static void RescheduleTimerList(void); +static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR); +static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID); +static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID); +static uint16_t linkTimer(uint8_t TimerID); +static uint32_t ReadRtcSsrValue(void); + +__weak void HW_TS_RTC_CountUpdated_AppNot(void); + +/* Functions Definition ------------------------------------------------------*/ + +/** + * @brief Read the RTC_SSR value + * As described in the reference manual, the RTC_SSR shall be read twice to ensure + * reliability of the value + * @param None + * @retval SSR value read + */ +static uint32_t ReadRtcSsrValue(void) +{ + uint32_t first_read; + uint32_t second_read; + + first_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS)); + + second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS)); + + while(first_read != second_read) + { + first_read = second_read; + + second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS)); + } + + return second_read; +} + +/** + * @brief Insert a Timer in the list after the Timer ID specified + * @param TimerID: The ID of the Timer + * @param RefTimerID: The ID of the Timer to be linked after + * @retval None + */ +static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID) +{ + uint8_t next_id; + + next_id = aTimerContext[RefTimerID].NextID; + + if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + aTimerContext[next_id].PreviousID = TimerID; + } + aTimerContext[TimerID].NextID = next_id; + aTimerContext[TimerID].PreviousID = RefTimerID ; + aTimerContext[RefTimerID].NextID = TimerID; + + return; +} + +/** + * @brief Insert a Timer in the list before the ID specified + * @param TimerID: The ID of the Timer + * @param RefTimerID: The ID of the Timer to be linked before + * @retval None + */ +static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID) +{ + uint8_t previous_id; + + if(RefTimerID != CurrentRunningTimerID) + { + previous_id = aTimerContext[RefTimerID].PreviousID; + + aTimerContext[previous_id].NextID = TimerID; + aTimerContext[TimerID].NextID = RefTimerID; + aTimerContext[TimerID].PreviousID = previous_id ; + aTimerContext[RefTimerID].PreviousID = TimerID; + } + else + { + aTimerContext[TimerID].NextID = RefTimerID; + aTimerContext[RefTimerID].PreviousID = TimerID; + } + + return; +} + +/** + * @brief Insert a Timer in the list + * @param TimerID: The ID of the Timer + * @retval None + */ +static uint16_t linkTimer(uint8_t TimerID) +{ + uint32_t time_left; + uint16_t time_elapsed; + uint8_t timer_id_lookup; + uint8_t next_id; + + if(CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + /** + * No timer in the list + */ + PreviousRunningTimerID = CurrentRunningTimerID; + CurrentRunningTimerID = TimerID; + aTimerContext[TimerID].NextID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; + + SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE; + time_elapsed = 0; + } + else + { + time_elapsed = ReturnTimeElapsed(); + + /** + * update count of the timer to be linked + */ + aTimerContext[TimerID].CountLeft += time_elapsed; + time_left = aTimerContext[TimerID].CountLeft; + + /** + * Search for index where the new timer shall be linked + */ + if(aTimerContext[CurrentRunningTimerID].CountLeft <= time_left) + { + /** + * Search for the ID after the first one + */ + timer_id_lookup = CurrentRunningTimerID; + next_id = aTimerContext[timer_id_lookup].NextID; + while((next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[next_id].CountLeft <= time_left)) + { + timer_id_lookup = aTimerContext[timer_id_lookup].NextID; + next_id = aTimerContext[timer_id_lookup].NextID; + } + + /** + * Link after the ID + */ + LinkTimerAfter(TimerID, timer_id_lookup); + } + else + { + /** + * Link before the first ID + */ + LinkTimerBefore(TimerID, CurrentRunningTimerID); + PreviousRunningTimerID = CurrentRunningTimerID; + CurrentRunningTimerID = TimerID; + } + } + + return time_elapsed; +} + +/** + * @brief Remove a Timer from the list + * @param TimerID: The ID of the Timer + * @param RequestReadSSR: Request to read the SSR register or not + * @retval None + */ +static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR) +{ + uint8_t previous_id; + uint8_t next_id; + + if(TimerID == CurrentRunningTimerID) + { + PreviousRunningTimerID = CurrentRunningTimerID; + CurrentRunningTimerID = aTimerContext[TimerID].NextID; + } + else + { + previous_id = aTimerContext[TimerID].PreviousID; + next_id = aTimerContext[TimerID].NextID; + + aTimerContext[previous_id].NextID = aTimerContext[TimerID].NextID; + if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + aTimerContext[next_id].PreviousID = aTimerContext[TimerID].PreviousID; + } + } + + /** + * Timer is out of the list + */ + aTimerContext[TimerID].TimerIDStatus = TimerID_Created; + + if((CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (RequestReadSSR == SSR_Read_Requested)) + { + SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE; + } + + return; +} + +/** + * @brief Return the number of ticks counted by the wakeuptimer since it has been started + * @note The API is reading the SSR register to get how many ticks have been counted + * since the time the timer has been started + * @param None + * @retval Time expired in Ticks + */ +static uint16_t ReturnTimeElapsed(void) +{ + uint32_t return_value; + uint32_t wrap_counter; + + if(SSRValueOnLastSetup != SSR_FORBIDDEN_VALUE) + { + return_value = ReadRtcSsrValue(); /**< Read SSR register first */ + + if (SSRValueOnLastSetup >= return_value) + { + return_value = SSRValueOnLastSetup - return_value; + } + else + { + wrap_counter = SynchPrescalerUserConfig - return_value; + return_value = SSRValueOnLastSetup + wrap_counter; + } + + /** + * At this stage, ReturnValue holds the number of ticks counted by SSR + * Need to translate in number of ticks counted by the Wakeuptimer + */ + return_value = return_value*AsynchPrescalerUserConfig; + return_value = return_value >> WakeupTimerDivider; + } + else + { + return_value = 0; + } + + return (uint16_t)return_value; +} + +/** + * @brief Set the wakeup counter + * @note The API is writing the counter value so that the value is decreased by one to cope with the fact + * the interrupt is generated with 1 extra clock cycle (See RefManuel) + * It assumes all condition are met to be allowed to write the wakeup counter + * @param Value: Value to be written in the counter + * @retval None + */ +static void RestartWakeupCounter(uint16_t Value) +{ + /** + * The wakeuptimer has been disabled in the calling function to reduce the time to poll the WUTWF + * FLAG when the new value will have to be written + * __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); + */ + + if(Value == 0) + { + SSRValueOnLastSetup = ReadRtcSsrValue(); + + /** + * Simulate that the Timer expired + */ + HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); + } + else + { + if((Value > 1) ||(WakeupTimerDivider != 1)) + { + Value -= 1; + } + + while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET); + + /** + * make sure to clear the flags after checking the WUTWF. + * It takes 2 RTCCLK between the time the WUTE bit is disabled and the + * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable + * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between + * due to the autoreload feature + */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */ + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */ + HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */ + + MODIFY_REG(RTC->WUTR, RTC_WUTR_WUT, Value); + + /** + * Update the value here after the WUTWF polling that may take some time + */ + SSRValueOnLastSetup = ReadRtcSsrValue(); + + __HAL_RTC_WAKEUPTIMER_ENABLE(phrtc); /**< Enable the Wakeup Timer */ + + HW_TS_RTC_CountUpdated_AppNot(); + } + + return ; +} + +/** + * @brief Reschedule the list of timer + * @note 1) Update the count left for each timer in the list + * 2) Setup the wakeuptimer + * @param None + * @retval None + */ +static void RescheduleTimerList(void) +{ + uint8_t localTimerID; + uint32_t timecountleft; + uint16_t wakeup_timer_value; + uint16_t time_elapsed; + + /** + * The wakeuptimer is disabled now to reduce the time to poll the WUTWF + * FLAG when the new value will have to be written + */ + if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET) + { + /** + * Wait for the flag to be back to 0 when the wakeup timer is enabled + */ + while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET); + } + __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */ + + localTimerID = CurrentRunningTimerID; + + /** + * Calculate what will be the value to write in the wakeuptimer + */ + timecountleft = aTimerContext[localTimerID].CountLeft; + + /** + * Read how much has been counted + */ + time_elapsed = ReturnTimeElapsed(); + + if(timecountleft < time_elapsed ) + { + /** + * There is no tick left to count + */ + wakeup_timer_value = 0; + WakeupTimerLimitation = WakeupTimerValue_LargeEnough; + } + else + { + if(timecountleft > (time_elapsed + MaxWakeupTimerSetup)) + { + /** + * The number of tick left is greater than the Wakeuptimer maximum value + */ + wakeup_timer_value = MaxWakeupTimerSetup; + + WakeupTimerLimitation = WakeupTimerValue_Overpassed; + } + else + { + wakeup_timer_value = timecountleft - time_elapsed; + WakeupTimerLimitation = WakeupTimerValue_LargeEnough; + } + + } + + /** + * update ticks left to be counted for each timer + */ + while(localTimerID != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + if (aTimerContext[localTimerID].CountLeft < time_elapsed) + { + aTimerContext[localTimerID].CountLeft = 0; + } + else + { + aTimerContext[localTimerID].CountLeft -= time_elapsed; + } + localTimerID = aTimerContext[localTimerID].NextID; + } + + /** + * Write next count + */ + RestartWakeupCounter(wakeup_timer_value); + + return ; +} + +/* Public functions ----------------------------------------------------------*/ + +/** + * For all public interface except that may need write access to the RTC, the RTC + * shall be unlock at the beginning and locked at the output + * In order to ease maintainability, the unlock is done at the top and the lock at then end + * in case some new implementation is coming in the future + */ + +void HW_TS_RTC_Wakeup_Handler(void) +{ + HW_TS_pTimerCb_t ptimer_callback; + uint32_t timer_process_id; + uint8_t local_current_running_timer_id; +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + uint32_t primask_bit; +#endif + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ +#endif + +/* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc ); + + /** + * Disable the Wakeup Timer + * This may speed up a bit the processing to wait the timer to be disabled + * The timer is still counting 2 RTCCLK + */ + __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); + + local_current_running_timer_id = CurrentRunningTimerID; + + if(aTimerContext[local_current_running_timer_id].TimerIDStatus == TimerID_Running) + { + ptimer_callback = aTimerContext[local_current_running_timer_id].pTimerCallBack; + timer_process_id = aTimerContext[local_current_running_timer_id].TimerProcessID; + + /** + * It should be good to check whether the TimeElapsed is greater or not than the tick left to be counted + * However, due to the inaccuracy of the reading of the time elapsed, it may return there is 1 tick + * to be left whereas the count is over + * A more secure implementation has been done with a flag to state whereas the full count has been written + * in the wakeuptimer or not + */ + if(WakeupTimerLimitation != WakeupTimerValue_Overpassed) + { + if(aTimerContext[local_current_running_timer_id].TimerMode == hw_ts_Repeated) + { + UnlinkTimer(local_current_running_timer_id, SSR_Read_Not_Requested); +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + HW_TS_Start(local_current_running_timer_id, aTimerContext[local_current_running_timer_id].CounterInit); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc ); + } + else + { +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + HW_TS_Stop(local_current_running_timer_id); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc ); + } + + HW_TS_RTC_Int_AppNot(timer_process_id, local_current_running_timer_id, ptimer_callback); + } + else + { + RescheduleTimerList(); +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + } + } + else + { + /** + * We should never end up in this case + * However, if due to any bug in the timer server this is the case, the mistake may not impact the user. + * We could just clean the interrupt flag and get out from this unexpected interrupt + */ + while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET); + + /** + * make sure to clear the flags after checking the WUTWF. + * It takes 2 RTCCLK between the time the WUTE bit is disabled and the + * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable + * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between + * due to the autoreload feature + */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */ + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */ + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc ); + + return; +} + +void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *hrtc) +{ + uint8_t loop; + uint32_t localmaxwakeuptimersetup; + + /** + * Get RTC handler + */ + phrtc = hrtc; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc ); + + SET_BIT(RTC->CR, RTC_CR_BYPSHAD); + + /** + * Readout the user config + */ + WakeupTimerDivider = (4 - ((uint32_t)(READ_BIT(RTC->CR, RTC_CR_WUCKSEL)))); + + AsynchPrescalerUserConfig = (uint8_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_A) >> (uint32_t)POSITION_VAL(RTC_PRER_PREDIV_A)) + 1; + + SynchPrescalerUserConfig = (uint16_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_S)) + 1; + + /** + * Margin is taken to avoid wrong calculation when the wrap around is there and some + * application interrupts may have delayed the reading + */ + localmaxwakeuptimersetup = ((((SynchPrescalerUserConfig - 1)*AsynchPrescalerUserConfig) - CFG_HW_TS_RTC_HANDLER_MAX_DELAY) >> WakeupTimerDivider); + + if(localmaxwakeuptimersetup >= 0xFFFF) + { + MaxWakeupTimerSetup = 0xFFFF; + } + else + { + MaxWakeupTimerSetup = (uint16_t)localmaxwakeuptimersetup; + } + + /** + * Configure EXTI module + */ + LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT); + LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT); + + if(TimerInitMode == hw_ts_InitMode_Full) + { + WakeupTimerLimitation = WakeupTimerValue_LargeEnough; + SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE; + + /** + * Initialize the timer server + */ + for(loop = 0; loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; loop++) + { + aTimerContext[loop].TimerIDStatus = TimerID_Free; + } + + CurrentRunningTimerID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; /**< Set ID to non valid value */ + + __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */ + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */ + HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */ + __HAL_RTC_WAKEUPTIMER_ENABLE_IT(phrtc, RTC_IT_WUT); /**< Enable interrupt in RTC module */ + } + else + { + if(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTF) != RESET) + { + /** + * Simulate that the Timer expired + */ + HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc ); + + HAL_NVIC_SetPriority(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO); /**< Set NVIC priority */ + HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */ + + return; +} + +HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pftimeout_handler) +{ + HW_TS_ReturnStatus_t localreturnstatus; + uint8_t loop = 0; +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + uint32_t primask_bit; +#endif + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ +#endif + + while((loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[loop].TimerIDStatus != TimerID_Free)) + { + loop++; + } + + if(loop != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + aTimerContext[loop].TimerIDStatus = TimerID_Created; + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + + aTimerContext[loop].TimerProcessID = TimerProcessID; + aTimerContext[loop].TimerMode = TimerMode; + aTimerContext[loop].pTimerCallBack = pftimeout_handler; + *pTimerId = loop; + + localreturnstatus = hw_ts_Successful; + } + else + { +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + + localreturnstatus = hw_ts_Failed; + } + + return(localreturnstatus); +} + +void HW_TS_Delete(uint8_t timer_id) +{ + HW_TS_Stop(timer_id); + + aTimerContext[timer_id].TimerIDStatus = TimerID_Free; /**< release ID */ + + return; +} + +void HW_TS_Stop(uint8_t timer_id) +{ + uint8_t localcurrentrunningtimerid; + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + uint32_t primask_bit; +#endif + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ +#endif + + HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */ + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc ); + + if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running) + { + UnlinkTimer(timer_id, SSR_Read_Requested); + localcurrentrunningtimerid = CurrentRunningTimerID; + + if(localcurrentrunningtimerid == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + /** + * List is empty + */ + + /** + * Disable the timer + */ + if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET) + { + /** + * Wait for the flag to be back to 0 when the wakeup timer is enabled + */ + while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET); + } + __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */ + + while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET); + + /** + * make sure to clear the flags after checking the WUTWF. + * It takes 2 RTCCLK between the time the WUTE bit is disabled and the + * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable + * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between + * due to the autoreload feature + */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */ + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */ + HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */ + } + else if(PreviousRunningTimerID != localcurrentrunningtimerid) + { + RescheduleTimerList(); + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc ); + + HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */ + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + + return; +} + +void HW_TS_Start(uint8_t timer_id, uint32_t timeout_ticks) +{ + uint16_t time_elapsed; + uint8_t localcurrentrunningtimerid; + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + uint32_t primask_bit; +#endif + + if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running) + { + HW_TS_Stop( timer_id ); + } + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ +#endif + + HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */ + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc ); + + aTimerContext[timer_id].TimerIDStatus = TimerID_Running; + + aTimerContext[timer_id].CountLeft = timeout_ticks; + aTimerContext[timer_id].CounterInit = timeout_ticks; + + time_elapsed = linkTimer(timer_id); + + localcurrentrunningtimerid = CurrentRunningTimerID; + + if(PreviousRunningTimerID != localcurrentrunningtimerid) + { + RescheduleTimerList(); + } + else + { + aTimerContext[timer_id].CountLeft -= time_elapsed; + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc ); + + HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */ + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + + return; +} + +uint16_t HW_TS_RTC_ReadLeftTicksToCount(void) +{ + uint32_t primask_bit; + uint16_t return_value, auro_reload_value, elapsed_time_value; + + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ + + if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET) + { + auro_reload_value = (uint32_t)(READ_BIT(RTC->WUTR, RTC_WUTR_WUT)); + + elapsed_time_value = ReturnTimeElapsed(); + + if(auro_reload_value > elapsed_time_value) + { + return_value = auro_reload_value - elapsed_time_value; + } + else + { + return_value = 0; + } + } + else + { + return_value = TIMER_LIST_EMPTY; + } + + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ + + return (return_value); +} + +__weak void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack) +{ + pTimerCallBack(); + + return; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble-glue/serial_service.c b/firmware/targets/f7/ble-glue/serial_service.c new file mode 100644 index 00000000..4b0ad402 --- /dev/null +++ b/firmware/targets/f7/ble-glue/serial_service.c @@ -0,0 +1,102 @@ +#include "serial_service.h" +#include "app_common.h" +#include "ble.h" + +#include + +#define SERIAL_SERVICE_TAG "serial service" + +typedef struct { + uint16_t svc_handle; + uint16_t rx_char_handle; + uint16_t tx_char_handle; +} SerialSvc; + +static SerialSvc serial_svc; + +static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void *event) { + SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck; + hci_event_pckt* event_pckt = (hci_event_pckt *)(((hci_uart_pckt*)event)->data); + evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data; + aci_gatt_attribute_modified_event_rp0* attribute_modified; + if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) { + if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) { + attribute_modified = (aci_gatt_attribute_modified_event_rp0*)blecore_evt->data; + if(attribute_modified->Attr_Handle == serial_svc.tx_char_handle + 2) { + // Descriptor handle + ret = SVCCTL_EvtAckFlowEnable; + FURI_LOG_D(SERIAL_SERVICE_TAG, "TX descriptor event"); + } else if(attribute_modified->Attr_Handle == serial_svc.tx_char_handle + 1) { + FURI_LOG_I(SERIAL_SERVICE_TAG, "Data len: %d", attribute_modified->Attr_Data_Length); + for(uint8_t i = 0; i < attribute_modified->Attr_Data_Length; i++) { + printf("%02X ", attribute_modified->Attr_Data[i]); + } + printf("\r\n"); + serial_svc_update_rx(attribute_modified->Attr_Data, attribute_modified->Attr_Data_Length); + ret = SVCCTL_EvtAckFlowEnable; + } + } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { + FURI_LOG_I(SERIAL_SERVICE_TAG, "Ack received", blecore_evt->ecode); + ret = SVCCTL_EvtAckFlowEnable; + } + } + return ret; +} + +bool serial_svc_init() { + tBleStatus status; + const uint8_t service_uuid[] = {SERIAL_SVC_UUID_128}; + const uint8_t char_rx_uuid[] = {SERIAL_CHAR_RX_UUID_128}; + const uint8_t char_tx_uuid[] = {SERIAL_CHAR_TX_UUID_128}; + + // Register event handler + SVCCTL_RegisterSvcHandler(serial_svc_event_handler); + + // Add service + status = aci_gatt_add_service(UUID_TYPE_128, (Service_UUID_t *)service_uuid, PRIMARY_SERVICE, 6, &serial_svc.svc_handle); + if(status) { + FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed to add Serial service: %d", status); + } + + // Add TX characteristics + status = aci_gatt_add_char(serial_svc.svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_tx_uuid , + SERIAL_SVC_DATA_LEN_MAX, + CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE | CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_VARIABLE, + &serial_svc.tx_char_handle); + if(status) { + FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed to add TX characteristic: %d", status); + } + + // Add RX characteristic + status = aci_gatt_add_char(serial_svc.svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_rx_uuid , + SERIAL_SVC_DATA_LEN_MAX, + CHAR_PROP_READ | CHAR_PROP_INDICATE, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &serial_svc.rx_char_handle); + if(status) { + FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed to add RX characteristic: %d", status); + } + + return status != BLE_STATUS_SUCCESS; +} + +bool serial_svc_update_rx(uint8_t* data, uint8_t data_len) { + furi_assert(data_len < SERIAL_SVC_DATA_LEN_MAX); + + tBleStatus result = aci_gatt_update_char_value(serial_svc.svc_handle, + serial_svc.rx_char_handle, + 0, + data_len, + data); + if(result) { + FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed updating RX characteristic: %d", result); + } + return result != BLE_STATUS_SUCCESS; +} diff --git a/firmware/targets/f7/ble-glue/serial_service.h b/firmware/targets/f7/ble-glue/serial_service.h new file mode 100644 index 00000000..92b943a0 --- /dev/null +++ b/firmware/targets/f7/ble-glue/serial_service.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SERIAL_SVC_DATA_LEN_MAX 255 + +#define SERIAL_SVC_UUID_128 0x00, 0x00, 0xfe, 0x60, 0xcc, 0x7a, 0x48, 0x2a, 0x98, 0x4a, 0x7f, 0x2e, 0xd5, 0xb3, 0xe5, 0x8f +#define SERIAL_CHAR_RX_UUID_128 0x00, 0x00, 0xfe, 0x61, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 +#define SERIAL_CHAR_TX_UUID_128 0x00, 0x00, 0xfe, 0x62, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 + +bool serial_svc_init(); + +bool serial_svc_update_rx(uint8_t* data, uint8_t data_len); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/ble-glue/tl_dbg_conf.h b/firmware/targets/f7/ble-glue/tl_dbg_conf.h new file mode 100644 index 00000000..4c38cfb5 --- /dev/null +++ b/firmware/targets/f7/ble-glue/tl_dbg_conf.h @@ -0,0 +1,136 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : App/tl_dbg_conf.h + * Description : Debug configuration file for stm32wpan transport layer interface. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * 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 __TL_DBG_CONF_H +#define __TL_DBG_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* USER CODE BEGIN Tl_Conf */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_conf.h" /* required as some configuration used in dbg_trace.h are set there */ +#include "dbg_trace.h" +#include "hw_if.h" + +/** + * Enable or Disable traces + * The raw data output is the hci binary packet format as specified by the BT specification * + */ +#define TL_SHCI_CMD_DBG_EN 0 /* Reports System commands sent to CPU2 and the command response */ +#define TL_SHCI_CMD_DBG_RAW_EN 0 /* Reports raw data System commands sent to CPU2 and the command response */ +#define TL_SHCI_EVT_DBG_EN 0 /* Reports System Asynchronous Events received from CPU2 */ +#define TL_SHCI_EVT_DBG_RAW_EN 0 /* Reports raw data System Asynchronous Events received from CPU2 */ + +#define TL_HCI_CMD_DBG_EN 0 /* Reports BLE command sent to CPU2 and the command response */ +#define TL_HCI_CMD_DBG_RAW_EN 0 /* Reports raw data BLE command sent to CPU2 and the command response */ +#define TL_HCI_EVT_DBG_EN 0 /* Reports BLE Asynchronous Events received from CPU2 */ +#define TL_HCI_EVT_DBG_RAW_EN 0 /* Reports raw data BLE Asynchronous Events received from CPU2 */ + +#define TL_MM_DBG_EN 0 /* Reports the informations of the buffer released to CPU2 */ + +/** + * Macro definition + */ + +/** + * System Transport Layer + */ +#if (TL_SHCI_CMD_DBG_EN != 0) +#define TL_SHCI_CMD_DBG_MSG PRINT_MESG_DBG +#define TL_SHCI_CMD_DBG_BUF PRINT_LOG_BUFF_DBG +#else +#define TL_SHCI_CMD_DBG_MSG(...) +#define TL_SHCI_CMD_DBG_BUF(...) +#endif + +#if (TL_SHCI_CMD_DBG_RAW_EN != 0) +#define TL_SHCI_CMD_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx(_PDATA_, _SIZE_) +#else +#define TL_SHCI_CMD_DBG_RAW(...) +#endif + +#if (TL_SHCI_EVT_DBG_EN != 0) +#define TL_SHCI_EVT_DBG_MSG PRINT_MESG_DBG +#define TL_SHCI_EVT_DBG_BUF PRINT_LOG_BUFF_DBG +#else +#define TL_SHCI_EVT_DBG_MSG(...) +#define TL_SHCI_EVT_DBG_BUF(...) +#endif + +#if (TL_SHCI_EVT_DBG_RAW_EN != 0) +#define TL_SHCI_EVT_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx(_PDATA_, _SIZE_) +#else +#define TL_SHCI_EVT_DBG_RAW(...) +#endif + +/** + * BLE Transport Layer + */ +#if (TL_HCI_CMD_DBG_EN != 0) +#define TL_HCI_CMD_DBG_MSG PRINT_MESG_DBG +#define TL_HCI_CMD_DBG_BUF PRINT_LOG_BUFF_DBG +#else +#define TL_HCI_CMD_DBG_MSG(...) +#define TL_HCI_CMD_DBG_BUF(...) +#endif + +#if (TL_HCI_CMD_DBG_RAW_EN != 0) +#define TL_HCI_CMD_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx(_PDATA_, _SIZE_) +#else +#define TL_HCI_CMD_DBG_RAW(...) +#endif + +#if (TL_HCI_EVT_DBG_EN != 0) +#define TL_HCI_EVT_DBG_MSG PRINT_MESG_DBG +#define TL_HCI_EVT_DBG_BUF PRINT_LOG_BUFF_DBG +#else +#define TL_HCI_EVT_DBG_MSG(...) +#define TL_HCI_EVT_DBG_BUF(...) +#endif + +#if (TL_HCI_EVT_DBG_RAW_EN != 0) +#define TL_HCI_EVT_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx(_PDATA_, _SIZE_) +#else +#define TL_HCI_EVT_DBG_RAW(...) +#endif + +/** + * Memory Manager - Released buffer tracing + */ +#if (TL_MM_DBG_EN != 0) +#define TL_MM_DBG_MSG PRINT_MESG_DBG +#else +#define TL_MM_DBG_MSG(...) +#endif + +/* USER CODE END Tl_Conf */ + +#ifdef __cplusplus +} +#endif + +#endif /*__TL_DBG_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble-glue/utilities_conf.h b/firmware/targets/f7/ble-glue/utilities_conf.h new file mode 100644 index 00000000..92a5d07a --- /dev/null +++ b/firmware/targets/f7/ble-glue/utilities_conf.h @@ -0,0 +1,68 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : utilities_conf.h + * Description : Configuration file for STM32 Utilities. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 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 + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef UTILITIES_CONF_H +#define UTILITIES_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "cmsis_compiler.h" +#include "string.h" + +/****************************************************************************** + * common + ******************************************************************************/ +#define UTILS_ENTER_CRITICAL_SECTION( ) uint32_t primask_bit = __get_PRIMASK( );\ + __disable_irq( ) + +#define UTILS_EXIT_CRITICAL_SECTION( ) __set_PRIMASK( primask_bit ) + +#define UTILS_MEMSET8( dest, value, size ) memset( dest, value, size); + +/****************************************************************************** + * tiny low power manager + * (any macro that does not need to be modified can be removed) + ******************************************************************************/ +#define UTIL_LPM_INIT_CRITICAL_SECTION( ) +#define UTIL_LPM_ENTER_CRITICAL_SECTION( ) UTILS_ENTER_CRITICAL_SECTION( ) +#define UTIL_LPM_EXIT_CRITICAL_SECTION( ) UTILS_EXIT_CRITICAL_SECTION( ) + +/****************************************************************************** + * sequencer + * (any macro that does not need to be modified can be removed) + ******************************************************************************/ +#define UTIL_SEQ_INIT_CRITICAL_SECTION( ) +#define UTIL_SEQ_ENTER_CRITICAL_SECTION( ) UTILS_ENTER_CRITICAL_SECTION( ) +#define UTIL_SEQ_EXIT_CRITICAL_SECTION( ) UTILS_EXIT_CRITICAL_SECTION( ) +#define UTIL_SEQ_CONF_TASK_NBR (32) +#define UTIL_SEQ_CONF_PRIO_NBR (2) +#define UTIL_SEQ_MEMSET8( dest, value, size ) UTILS_MEMSET8( dest, value, size ) + +#ifdef __cplusplus +} +#endif + +#endif /*UTILITIES_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/FreeRTOSConfig.h b/firmware/targets/f7/cube/Inc/FreeRTOSConfig.h new file mode 100644 index 00000000..258ab421 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/FreeRTOSConfig.h @@ -0,0 +1,186 @@ +/* USER CODE BEGIN Header */ +/* + * FreeRTOS Kernel V10.3.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 + 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 +#ifndef CMSIS_device_header +#define CMSIS_device_header "stm32wbxx.h" +#endif /* CMSIS_device_header */ + +#define configENABLE_FPU 1 +#define configENABLE_MPU 0 + +#define configUSE_PREEMPTION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES ( 56 ) +#define configMINIMAL_STACK_SIZE ((uint16_t)128) +#define configTOTAL_HEAP_SIZE ((size_t)40960) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configGENERATE_RUN_TIME_STATS 1 +#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 +/* 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 +/* 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 + +/* CMSIS-RTOS V2 flags */ +#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 +#define configUSE_OS2_THREAD_ENUMERATE 1 +#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 +#define configUSE_OS2_THREAD_FLAGS 1 +#define configUSE_OS2_TIMER 1 +#define configUSE_OS2_MUTEX 1 + +/* 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_vTaskCleanUpResources 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_xTaskGetCurrentTaskHandle 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(); 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: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */ + +#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1 + +/* USER CODE BEGIN 2 */ +/* Definitions needed when configGENERATE_RUN_TIME_STATS is on */ +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS configureTimerForRunTimeStats +#define portGET_RUN_TIME_COUNTER_VALUE getRunTimeCounterValue +/* USER CODE END 2 */ + +/* USER CODE BEGIN Defines */ +/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ +/* USER CODE END Defines */ + +#endif /* FREERTOS_CONFIG_H */ diff --git a/firmware/targets/f7/cube/Inc/adc.h b/firmware/targets/f7/cube/Inc/adc.h new file mode 100644 index 00000000..5f945644 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/adc.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file adc.h + * @brief This file contains all the function prototypes for + * the adc.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/aes.h b/firmware/targets/f7/cube/Inc/aes.h new file mode 100644 index 00000000..bde8ad5a --- /dev/null +++ b/firmware/targets/f7/cube/Inc/aes.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * @file aes.h + * @brief This file contains all the function prototypes for + * the aes.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/comp.h b/firmware/targets/f7/cube/Inc/comp.h new file mode 100644 index 00000000..5cc7f16e --- /dev/null +++ b/firmware/targets/f7/cube/Inc/comp.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file comp.h + * @brief This file contains all the function prototypes for + * the comp.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/crc.h b/firmware/targets/f7/cube/Inc/crc.h new file mode 100644 index 00000000..d1b47518 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/crc.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file crc.h + * @brief This file contains all the function prototypes for + * the crc.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/gpio.h b/firmware/targets/f7/cube/Inc/gpio.h new file mode 100644 index 00000000..6b6fe6fb --- /dev/null +++ b/firmware/targets/f7/cube/Inc/gpio.h @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * @file gpio.h + * @brief This file contains all the function prototypes for + * the gpio.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/i2c.h b/firmware/targets/f7/cube/Inc/i2c.h new file mode 100644 index 00000000..d5a09031 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/i2c.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * @file i2c.h + * @brief This file contains all the function prototypes for + * the i2c.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 __I2C_H__ +#define __I2C_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_I2C1_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __I2C_H__ */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/main.h b/firmware/targets/f7/cube/Inc/main.h new file mode 100644 index 00000000..bd7b4129 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/main.h @@ -0,0 +1,175 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx_hal.h" + +#include "stm32wbxx_ll_i2c.h" +#include "stm32wbxx_ll_crs.h" +#include "stm32wbxx_ll_rcc.h" +#include "stm32wbxx_ll_bus.h" +#include "stm32wbxx_ll_system.h" +#include "stm32wbxx_ll_exti.h" +#include "stm32wbxx_ll_cortex.h" +#include "stm32wbxx_ll_utils.h" +#include "stm32wbxx_ll_pwr.h" +#include "stm32wbxx_ll_dma.h" +#include "stm32wbxx_ll_usart.h" +#include "stm32wbxx_ll_gpio.h" + +/* 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 Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +#define BUTTON_BACK_Pin GPIO_PIN_13 +#define BUTTON_BACK_GPIO_Port GPIOC +#define BUTTON_BACK_EXTI_IRQn EXTI15_10_IRQn +#define QUARTZ_32MHZ_IN_Pin GPIO_PIN_14 +#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC +#define QUARTZ_32MHZ_OUT_Pin GPIO_PIN_15 +#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC +#define BUTTON_OK_Pin GPIO_PIN_3 +#define BUTTON_OK_GPIO_Port GPIOH +#define BUTTON_OK_EXTI_IRQn EXTI3_IRQn +#define SPEAKER_Pin GPIO_PIN_8 +#define SPEAKER_GPIO_Port GPIOB +#define IR_TX_Pin GPIO_PIN_9 +#define IR_TX_GPIO_Port GPIOB +#define PC0_Pin GPIO_PIN_0 +#define PC0_GPIO_Port GPIOC +#define PC1_Pin GPIO_PIN_1 +#define PC1_GPIO_Port GPIOC +#define SPI_D_MISO_Pin GPIO_PIN_2 +#define SPI_D_MISO_GPIO_Port GPIOC +#define PC3_Pin GPIO_PIN_3 +#define PC3_GPIO_Port GPIOC +#define IR_RX_Pin GPIO_PIN_0 +#define IR_RX_GPIO_Port GPIOA +#define CC1101_G0_Pin GPIO_PIN_1 +#define CC1101_G0_GPIO_Port GPIOA +#define RFID_PULL_Pin GPIO_PIN_2 +#define RFID_PULL_GPIO_Port GPIOA +#define PERIPH_POWER_Pin GPIO_PIN_3 +#define PERIPH_POWER_GPIO_Port GPIOA +#define PA4_Pin GPIO_PIN_4 +#define PA4_GPIO_Port GPIOA +#define SPI_R_SCK_Pin GPIO_PIN_5 +#define SPI_R_SCK_GPIO_Port GPIOA +#define PA6_Pin GPIO_PIN_6 +#define PA6_GPIO_Port GPIOA +#define PA7_Pin GPIO_PIN_7 +#define PA7_GPIO_Port GPIOA +#define VIBRO_Pin GPIO_PIN_8 +#define VIBRO_GPIO_Port GPIOA +#define I2C_SCL_Pin GPIO_PIN_9 +#define I2C_SCL_GPIO_Port GPIOA +#define RF_SW_0_Pin GPIO_PIN_4 +#define RF_SW_0_GPIO_Port GPIOC +#define RFID_RF_IN_Pin GPIO_PIN_5 +#define RFID_RF_IN_GPIO_Port GPIOC +#define PB2_Pin GPIO_PIN_2 +#define PB2_GPIO_Port GPIOB +#define BUTTON_UP_Pin GPIO_PIN_10 +#define BUTTON_UP_GPIO_Port GPIOB +#define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn +#define BUTTON_LEFT_Pin GPIO_PIN_11 +#define BUTTON_LEFT_GPIO_Port GPIOB +#define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn +#define DISPLAY_RST_Pin GPIO_PIN_0 +#define DISPLAY_RST_GPIO_Port GPIOB +#define DISPLAY_DI_Pin GPIO_PIN_1 +#define DISPLAY_DI_GPIO_Port GPIOB +#define NFC_CS_Pin GPIO_PIN_4 +#define NFC_CS_GPIO_Port GPIOE +#define BUTTON_RIGHT_Pin GPIO_PIN_12 +#define BUTTON_RIGHT_GPIO_Port GPIOB +#define BUTTON_RIGHT_EXTI_IRQn EXTI15_10_IRQn +#define RFID_OUT_Pin GPIO_PIN_13 +#define RFID_OUT_GPIO_Port GPIOB +#define iBTN_Pin GPIO_PIN_14 +#define iBTN_GPIO_Port GPIOB +#define SPI_D_MOSI_Pin GPIO_PIN_15 +#define SPI_D_MOSI_GPIO_Port GPIOB +#define BUTTON_DOWN_Pin GPIO_PIN_6 +#define BUTTON_DOWN_GPIO_Port GPIOC +#define I2C_SDA_Pin GPIO_PIN_10 +#define I2C_SDA_GPIO_Port GPIOA +#define RFID_CARRIER_Pin GPIO_PIN_15 +#define RFID_CARRIER_GPIO_Port GPIOA +#define SD_CD_Pin GPIO_PIN_10 +#define SD_CD_GPIO_Port GPIOC +#define DISPLAY_CS_Pin GPIO_PIN_11 +#define DISPLAY_CS_GPIO_Port GPIOC +#define SD_CS_Pin GPIO_PIN_12 +#define SD_CS_GPIO_Port GPIOC +#define CC1101_CS_Pin GPIO_PIN_0 +#define CC1101_CS_GPIO_Port GPIOD +#define SPI_D_SCK_Pin GPIO_PIN_1 +#define SPI_D_SCK_GPIO_Port GPIOD +#define PB3_Pin GPIO_PIN_3 +#define PB3_GPIO_Port GPIOB +#define SPI_R_MISO_Pin GPIO_PIN_4 +#define SPI_R_MISO_GPIO_Port GPIOB +#define SPI_R_MOSI_Pin GPIO_PIN_5 +#define SPI_R_MOSI_GPIO_Port GPIOB +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/pka.h b/firmware/targets/f7/cube/Inc/pka.h new file mode 100644 index 00000000..377ed010 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/pka.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file pka.h + * @brief This file contains all the function prototypes for + * the pka.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/rf.h b/firmware/targets/f7/cube/Inc/rf.h new file mode 100644 index 00000000..1796e939 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/rf.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * @file rf.h + * @brief This file contains all the function prototypes for + * the rf.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/rng.h b/firmware/targets/f7/cube/Inc/rng.h new file mode 100644 index 00000000..fa121ad1 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/rng.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file rng.h + * @brief This file contains all the function prototypes for + * the rng.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/rtc.h b/firmware/targets/f7/cube/Inc/rtc.h new file mode 100644 index 00000000..3e961b71 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/rtc.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file rtc.h + * @brief This file contains all the function prototypes for + * the rtc.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/spi.h b/firmware/targets/f7/cube/Inc/spi.h new file mode 100644 index 00000000..01a2233f --- /dev/null +++ b/firmware/targets/f7/cube/Inc/spi.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * @file spi.h + * @brief This file contains all the function prototypes for + * the spi.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SPI_H__ */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/stm32_assert.h b/firmware/targets/f7/cube/Inc/stm32_assert.h new file mode 100644 index 00000000..734c6558 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/stm32_assert.h @@ -0,0 +1,53 @@ +/** + ****************************************************************************** + * @file stm32_assert.h + * @brief STM32 assert file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 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 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_ASSERT_H +#define __STM32_ASSERT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Includes ------------------------------------------------------------------*/ +/* 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 /* __STM32_ASSERT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/stm32wbxx_hal_conf.h b/firmware/targets/f7/cube/Inc/stm32wbxx_hal_conf.h new file mode 100644 index 00000000..cab30f03 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/stm32wbxx_hal_conf.h @@ -0,0 +1,353 @@ +/** + ****************************************************************************** + * @file stm32wbxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 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 + * + ****************************************************************************** + */ + +/* 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 15U /*!< 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****/ diff --git a/firmware/targets/f7/cube/Inc/stm32wbxx_it.h b/firmware/targets/f7/cube/Inc/stm32wbxx_it.h new file mode 100644 index 00000000..953d5a88 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/stm32wbxx_it.h @@ -0,0 +1,77 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbxx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 EXTI3_IRQHandler(void); +void ADC1_IRQHandler(void); +void USB_LP_IRQHandler(void); +void COMP_IRQHandler(void); +void TIM1_TRG_COM_TIM17_IRQHandler(void); +void TIM2_IRQHandler(void); +void EXTI15_10_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****/ diff --git a/firmware/targets/f7/cube/Inc/tim.h b/firmware/targets/f7/cube/Inc/tim.h new file mode 100644 index 00000000..9d530bce --- /dev/null +++ b/firmware/targets/f7/cube/Inc/tim.h @@ -0,0 +1,58 @@ +/** + ****************************************************************************** + * @file tim.h + * @brief This file contains all the function prototypes for + * the tim.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/usart.h b/firmware/targets/f7/cube/Inc/usart.h new file mode 100644 index 00000000..506e8972 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/usart.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * @file usart.h + * @brief This file contains all the function prototypes for + * the usart.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 */ + +/* 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****/ diff --git a/firmware/targets/f7/cube/Inc/usb_device.h b/firmware/targets/f7/cube/Inc/usb_device.h new file mode 100644 index 00000000..dc9bbdc6 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/usb_device.h @@ -0,0 +1,105 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usb_device.h + * @version : v3.0_Cube + * @brief : Header for usb_device.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Inc/usbd_cdc_if.h b/firmware/targets/f7/cube/Inc/usbd_cdc_if.h new file mode 100644 index 00000000..bbd5af07 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/usbd_cdc_if.h @@ -0,0 +1,133 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_cdc_if.h + * @version : v3.0_Cube + * @brief : Header for usbd_cdc_if.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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. + * @{ + */ +/* Define size for the receive and transmit buffer over CDC */ +#define APP_RX_DATA_SIZE 512 +#define APP_TX_DATA_SIZE 512 +/* USER CODE BEGIN EXPORTED_DEFINES */ + +/* 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****/ diff --git a/firmware/targets/f7/cube/Inc/usbd_conf.h b/firmware/targets/f7/cube/Inc/usbd_conf.h new file mode 100644 index 00000000..e4aa2fd5 --- /dev/null +++ b/firmware/targets/f7/cube/Inc/usbd_conf.h @@ -0,0 +1,176 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_conf.h + * @version : v3.0_Cube + * @brief : Header for usbd_conf.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 +#include +#include +#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****/ diff --git a/firmware/targets/f7/cube/Inc/usbd_desc.h b/firmware/targets/f7/cube/Inc/usbd_desc.h new file mode 100644 index 00000000..772b538f --- /dev/null +++ b/firmware/targets/f7/cube/Inc/usbd_desc.h @@ -0,0 +1,145 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_desc.c + * @version : v3.0_Cube + * @brief : Header for usbd_conf.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 0x1A + +/* 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****/ diff --git a/firmware/targets/f7/cube/Makefile b/firmware/targets/f7/cube/Makefile new file mode 100644 index 00000000..f5e7c874 --- /dev/null +++ b/firmware/targets/f7/cube/Makefile @@ -0,0 +1,253 @@ +########################################################################################################################## +# File automatically-generated by tool: [projectgenerator] version: [3.14.1] date: [Fri Sep 10 04:36:47 MSK 2021] +########################################################################################################################## + +# ------------------------------------------------ +# Generic Makefile (based on gcc) +# +# ChangeLog : +# 2017-02-10 - Several enhancements + project update mode +# 2015-07-22 - first version +# ------------------------------------------------ + +###################################### +# target +###################################### +TARGET = f7 + + +###################################### +# building variables +###################################### +# debug build? +DEBUG = 1 +# optimization +OPT = -Og + + +####################################### +# paths +####################################### +# Build path +BUILD_DIR = build + +###################################### +# source +###################################### +# C sources +C_SOURCES = \ +Src/main.c \ +Src/gpio.c \ +Src/app_freertos.c \ +Src/adc.c \ +Src/aes.c \ +Src/comp.c \ +Src/crc.c \ +Src/i2c.c \ +Src/pka.c \ +Src/rf.c \ +Src/rng.c \ +Src/rtc.c \ +Src/spi.c \ +Src/tim.c \ +Src/usart.c \ +Src/usb_device.c \ +Src/usbd_conf.c \ +Src/usbd_desc.c \ +Src/usbd_cdc_if.c \ +Src/stm32wbxx_it.c \ +Src/stm32wbxx_hal_msp.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_exti.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_gpio.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_hsem.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cortex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_adc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_comp.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_dma.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pka.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rng.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim_ex.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rcc.c \ +Src/system_stm32wbxx.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/list.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/queue.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/timers.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ +/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c + +# ASM sources +ASM_SOURCES = \ +startup_stm32wb55xx_cm4.s + + +####################################### +# binaries +####################################### +PREFIX = arm-none-eabi- +# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) +# either it can be added to the PATH environment variable. +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc +AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp +CP = $(GCC_PATH)/$(PREFIX)objcopy +SZ = $(GCC_PATH)/$(PREFIX)size +else +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc -x assembler-with-cpp +CP = $(PREFIX)objcopy +SZ = $(PREFIX)size +endif +HEX = $(CP) -O ihex +BIN = $(CP) -O binary -S + +####################################### +# CFLAGS +####################################### +# cpu +CPU = -mcpu=cortex-m4 + +# fpu +FPU = -mfpu=fpv4-sp-d16 + +# float-abi +FLOAT-ABI = -mfloat-abi=hard + +# mcu +MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) + +# macros for gcc +# AS defines +AS_DEFS = + +# C defines +C_DEFS = \ +-DUSE_FULL_LL_DRIVER \ +-DUSE_HAL_DRIVER \ +-DSTM32WB55xx + + +# AS includes +AS_INCLUDES = \ +-IInc + +# C includes +C_INCLUDES = \ +-IInc \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/Legacy \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/include \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Inc \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/CMSIS/Device/ST/STM32WBxx/Include \ +-I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/CMSIS/Include + + +# compile gcc flags +ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +ifeq ($(DEBUG), 1) +CFLAGS += -g -gdwarf-2 +endif + + +# Generate dependency information +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + + +####################################### +# LDFLAGS +####################################### +# link script +LDSCRIPT = stm32wb55xx_flash_cm4.ld + +# libraries +LIBS = -lc -lm -lnosys +LIBDIR = +LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections + +# default action: build all +all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin + + +####################################### +# build the application +####################################### +# list of objects +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) +vpath %.s $(sort $(dir $(ASM_SOURCES))) + +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) + $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ + +$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) + $(AS) -c $(CFLAGS) $< -o $@ + +$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile + $(CC) $(OBJECTS) $(LDFLAGS) -o $@ + $(SZ) $@ + +$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + $(HEX) $< $@ + +$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + $(BIN) $< $@ + +$(BUILD_DIR): + mkdir $@ + +####################################### +# clean up +####################################### +clean: + -rm -fR $(BUILD_DIR) + +####################################### +# dependencies +####################################### +-include $(wildcard $(BUILD_DIR)/*.d) + +# *** EOF *** \ No newline at end of file diff --git a/firmware/targets/f7/cube/Src/adc.c b/firmware/targets/f7/cube/Src/adc.c new file mode 100644 index 00000000..e1294c43 --- /dev/null +++ b/firmware/targets/f7/cube/Src/adc.c @@ -0,0 +1,139 @@ +/** + ****************************************************************************** + * @file adc.c + * @brief This file provides code for the configuration + * of the ADC instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + ADC_ChannelConfTypeDef sConfig = {0}; + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + /** 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(); + } + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ + +} + +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****/ diff --git a/firmware/targets/f7/cube/Src/aes.c b/firmware/targets/f7/cube/Src/aes.c new file mode 100644 index 00000000..06d5aacb --- /dev/null +++ b/firmware/targets/f7/cube/Src/aes.c @@ -0,0 +1,147 @@ +/** + ****************************************************************************** + * @file aes.c + * @brief This file provides code for the configuration + * of the AES instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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) +{ + + /* USER CODE BEGIN AES1_Init 0 */ + + /* USER CODE END AES1_Init 0 */ + + /* USER CODE BEGIN AES1_Init 1 */ + + /* USER CODE END AES1_Init 1 */ + 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(); + } + /* USER CODE BEGIN AES1_Init 2 */ + + /* USER CODE END AES1_Init 2 */ + +} +/* AES2 init function */ +void MX_AES2_Init(void) +{ + + /* USER CODE BEGIN AES2_Init 0 */ + + /* USER CODE END AES2_Init 0 */ + + /* USER CODE BEGIN AES2_Init 1 */ + + /* USER CODE END AES2_Init 1 */ + 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(); + } + /* USER CODE BEGIN AES2_Init 2 */ + + /* USER CODE END AES2_Init 2 */ + +} + +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****/ diff --git a/firmware/targets/f7/cube/Src/app_freertos.c b/firmware/targets/f7/cube/Src/app_freertos.c new file mode 100644 index 00000000..1d39e0a9 --- /dev/null +++ b/firmware/targets/f7/cube/Src/app_freertos.c @@ -0,0 +1,183 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : app_freertos.c + * Description : Code for freertos applications + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 "FreeRTOS.h" +#include "task.h" +#include "main.h" +#include "cmsis_os.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN Variables */ + +/* USER CODE END Variables */ +/* Definitions for app_main */ +osThreadId_t app_mainHandle; +const osThreadAttr_t app_main_attributes = { + .name = "app_main", + .priority = (osPriority_t) osPriorityNormal, + .stack_size = 1024 * 4 +}; + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN FunctionPrototypes */ + +/* USER CODE END FunctionPrototypes */ + +void app(void *argument); + +void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ + +/* Hook prototypes */ +void configureTimerForRunTimeStats(void); +unsigned long getRunTimeCounterValue(void); +void vApplicationIdleHook(void); +void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName); + +/* USER CODE BEGIN 1 */ +/* Functions needed when configGENERATE_RUN_TIME_STATS is on */ +__weak void configureTimerForRunTimeStats(void) +{ + +} + +__weak unsigned long getRunTimeCounterValue(void) +{ +return 0; +} +/* USER CODE END 1 */ + +/* USER CODE BEGIN 2 */ +void vApplicationIdleHook( void ) +{ + /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set + to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle + task. It is essential that code added to this hook function never attempts + to block in any way (for example, call xQueueReceive() with a block time + specified, or call vTaskDelay()). If the application makes use of the + vTaskDelete() API function (as this demo application does) then it is also + important that vApplicationIdleHook() is permitted to return to its calling + function, because it is the responsibility of the idle task to clean up + memory allocated by the kernel to any task that has since been deleted. */ +} +/* USER CODE END 2 */ + +/* USER CODE BEGIN 4 */ +void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) +{ + /* Run time stack overflow checking is performed if + configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is + called if a stack overflow is detected. */ +} +/* USER CODE END 4 */ + +/* USER CODE BEGIN VPORT_SUPPORT_TICKS_AND_SLEEP */ +__weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) +{ + // Generated when configUSE_TICKLESS_IDLE == 2. + // Function called in tasks.c (in portTASK_FUNCTION). + // TO BE COMPLETED or TO BE REPLACED by a user one, overriding that weak one. +} +/* USER CODE END VPORT_SUPPORT_TICKS_AND_SLEEP */ + +/** + * @brief FreeRTOS initialization + * @param None + * @retval None + */ +void MX_FREERTOS_Init(void) { + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* USER CODE BEGIN RTOS_MUTEX */ + /* add mutexes, ... */ + /* USER CODE END RTOS_MUTEX */ + + /* USER CODE BEGIN RTOS_SEMAPHORES */ + /* add semaphores, ... */ + /* USER CODE END RTOS_SEMAPHORES */ + + /* USER CODE BEGIN RTOS_TIMERS */ + /* start timers, add new ones, ... */ + /* USER CODE END RTOS_TIMERS */ + + /* USER CODE BEGIN RTOS_QUEUES */ + /* add queues, ... */ + /* USER CODE END RTOS_QUEUES */ + + /* Create the thread(s) */ + /* creation of app_main */ + app_mainHandle = osThreadNew(app, NULL, &app_main_attributes); + + /* USER CODE BEGIN RTOS_THREADS */ + /* add threads, ... */ + /* USER CODE END RTOS_THREADS */ + + /* USER CODE BEGIN RTOS_EVENTS */ + /* add events, ... */ + /* USER CODE END RTOS_EVENTS */ + +} + +/* USER CODE BEGIN Header_app */ +/** + * @brief Function implementing the app_main thread. + * @param argument: Not used + * @retval None + */ +/* USER CODE END Header_app */ +__weak void app(void *argument) +{ + /* USER CODE BEGIN app */ + /* Infinite loop */ + for(;;) + { + osDelay(1); + } + /* USER CODE END app */ +} + +/* Private application code --------------------------------------------------*/ +/* USER CODE BEGIN Application */ + +/* USER CODE END Application */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/comp.c b/firmware/targets/f7/cube/Src/comp.c new file mode 100644 index 00000000..00f9fa66 --- /dev/null +++ b/firmware/targets/f7/cube/Src/comp.c @@ -0,0 +1,113 @@ +/** + ****************************************************************************** + * @file comp.c + * @brief This file provides code for the configuration + * of the COMP instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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) +{ + + /* USER CODE BEGIN COMP1_Init 0 */ + + /* USER CODE END COMP1_Init 0 */ + + /* USER CODE BEGIN COMP1_Init 1 */ + + /* USER CODE END COMP1_Init 1 */ + 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(); + } + /* USER CODE BEGIN COMP1_Init 2 */ + + /* USER CODE END COMP1_Init 2 */ + +} + +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****/ diff --git a/firmware/targets/f7/cube/Src/crc.c b/firmware/targets/f7/cube/Src/crc.c new file mode 100644 index 00000000..be2138ec --- /dev/null +++ b/firmware/targets/f7/cube/Src/crc.c @@ -0,0 +1,92 @@ +/** + ****************************************************************************** + * @file crc.c + * @brief This file provides code for the configuration + * of the CRC instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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) +{ + + /* USER CODE BEGIN CRC_Init 0 */ + + /* USER CODE END CRC_Init 0 */ + + /* USER CODE BEGIN CRC_Init 1 */ + + /* USER CODE END CRC_Init 1 */ + 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(); + } + /* USER CODE BEGIN CRC_Init 2 */ + + /* USER CODE END CRC_Init 2 */ + +} + +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****/ diff --git a/firmware/targets/f7/cube/Src/gpio.c b/firmware/targets/f7/cube/Src/gpio.c new file mode 100644 index 00000000..743c1f27 --- /dev/null +++ b/firmware/targets/f7/cube/Src/gpio.c @@ -0,0 +1,181 @@ +/** + ****************************************************************************** + * @file gpio.c + * @brief This file provides code for the configuration + * of all used GPIO pins. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 "gpio.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure GPIO */ +/*----------------------------------------------------------------------------*/ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** Configure pins as + * Analog + * Input + * Output + * EVENT_OUT + * EXTI +*/ +void MX_GPIO_Init(void) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOA, RFID_PULL_Pin|VIBRO_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin, GPIO_PIN_SET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(RF_SW_0_GPIO_Port, RF_SW_0_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOB, DISPLAY_RST_Pin|DISPLAY_DI_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(NFC_CS_GPIO_Port, NFC_CS_Pin, GPIO_PIN_SET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOC, DISPLAY_CS_Pin|SD_CS_Pin, GPIO_PIN_SET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(CC1101_CS_GPIO_Port, CC1101_CS_Pin, GPIO_PIN_SET); + + /*Configure GPIO pin : PtPin */ + GPIO_InitStruct.Pin = BUTTON_BACK_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(BUTTON_BACK_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : PtPin */ + GPIO_InitStruct.Pin = BUTTON_OK_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(BUTTON_OK_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : PCPin PCPin PCPin */ + GPIO_InitStruct.Pin = PC0_Pin|PC1_Pin|PC3_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /*Configure GPIO pins : PAPin PAPin PAPin PAPin + PAPin */ + GPIO_InitStruct.Pin = CC1101_G0_Pin|PA4_Pin|PA6_Pin|PA7_Pin + |RFID_CARRIER_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pins : PAPin PAPin */ + GPIO_InitStruct.Pin = RFID_PULL_Pin|VIBRO_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pin : PtPin */ + GPIO_InitStruct.Pin = PERIPH_POWER_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(PERIPH_POWER_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : PCPin PCPin */ + GPIO_InitStruct.Pin = RF_SW_0_Pin|DISPLAY_CS_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /*Configure GPIO pins : PBPin PBPin PBPin */ + GPIO_InitStruct.Pin = PB2_Pin|iBTN_Pin|PB3_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /*Configure GPIO pins : PBPin PBPin PBPin */ + GPIO_InitStruct.Pin = BUTTON_UP_Pin|BUTTON_LEFT_Pin|BUTTON_RIGHT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /*Configure GPIO pins : PBPin PBPin */ + GPIO_InitStruct.Pin = DISPLAY_RST_Pin|DISPLAY_DI_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /*Configure GPIO pin : PtPin */ + GPIO_InitStruct.Pin = NFC_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(NFC_CS_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : PCPin PCPin */ + GPIO_InitStruct.Pin = BUTTON_DOWN_Pin|SD_CD_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /*Configure GPIO pin : PtPin */ + 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); + + /*Configure GPIO pin : PtPin */ + GPIO_InitStruct.Pin = CC1101_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(CC1101_CS_GPIO_Port, &GPIO_InitStruct); + + /* EXTI interrupt init*/ + HAL_NVIC_SetPriority(EXTI3_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(EXTI3_IRQn); + + HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); + +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/i2c.c b/firmware/targets/f7/cube/Src/i2c.c new file mode 100644 index 00000000..507de62c --- /dev/null +++ b/firmware/targets/f7/cube/Src/i2c.c @@ -0,0 +1,83 @@ +/** + ****************************************************************************** + * @file i2c.c + * @brief This file provides code for the configuration + * of the I2C instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 "i2c.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* I2C1 init function */ +void MX_I2C1_Init(void) +{ + + /* USER CODE BEGIN I2C1_Init 0 */ + + /* USER CODE END I2C1_Init 0 */ + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**I2C1 GPIO Configuration + PA9 ------> I2C1_SCL + PA10 ------> I2C1_SDA + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_9|LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_4; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + + /* USER CODE BEGIN I2C1_Init 1 */ + + /* USER CODE END I2C1_Init 1 */ + /** I2C Initialization + */ + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.Timing = 0x10707DBC; + 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); + /* USER CODE BEGIN I2C1_Init 2 */ + + /* USER CODE END I2C1_Init 2 */ + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/main.c b/firmware/targets/f7/cube/Src/main.c new file mode 100644 index 00000000..c8cada7b --- /dev/null +++ b/firmware/targets/f7/cube/Src/main.c @@ -0,0 +1,290 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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" +#include "cmsis_os.h" +#include "adc.h" +#include "aes.h" +#include "comp.h" +#include "crc.h" +#include "i2c.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" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +void MX_FREERTOS_Init(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_ADC1_Init(); + MX_I2C1_Init(); + MX_RTC_Init(); + MX_SPI1_Init(); + MX_SPI2_Init(); + MX_USB_Device_Init(); + MX_TIM1_Init(); + MX_TIM2_Init(); + MX_TIM16_Init(); + MX_COMP1_Init(); + MX_RF_Init(); + MX_PKA_Init(); + MX_RNG_Init(); + MX_AES1_Init(); + MX_AES2_Init(); + MX_CRC_Init(); + MX_USART1_UART_Init(); + /* USER CODE BEGIN 2 */ + + /* USER CODE END 2 */ + + /* Init scheduler */ + osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */ + MX_FREERTOS_Init(); + /* Start scheduler */ + osKernelStart(); + + /* We should never get here as control is now taken by the scheduler */ + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) + { + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); + while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_3) + { + } + + /* HSE configuration and activation */ + LL_RCC_HSE_Enable(); + while(LL_RCC_HSE_IsReady() != 1) + { + } + + /* HSI configuration and activation */ + LL_RCC_HSI_Enable(); + while(LL_RCC_HSI_IsReady() != 1) + { + } + + LL_PWR_EnableBkUpAccess(); + if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) + { + LL_RCC_ForceBackupDomainReset(); + LL_RCC_ReleaseBackupDomainReset(); + } + LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_MEDIUMLOW); + LL_RCC_LSE_Enable(); + + /* Wait till LSE is ready */ + while(LL_RCC_LSE_IsReady() != 1) + { + } + + LL_RCC_HSE_EnableCSS(); + LL_RCC_LSE_EnableCSS(); + /* Main PLL configuration and activation */ + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 8, LL_RCC_PLLR_DIV_2); + LL_RCC_PLL_Enable(); + LL_RCC_PLL_EnableDomain_SYS(); + while(LL_RCC_PLL_IsReady() != 1) + { + } + + LL_RCC_PLLSAI1_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 6, LL_RCC_PLLSAI1Q_DIV_2); + LL_RCC_PLLSAI1_ConfigDomain_ADC(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 6, LL_RCC_PLLSAI1R_DIV_2); + LL_RCC_PLLSAI1_Enable(); + LL_RCC_PLLSAI1_EnableDomain_48M(); + LL_RCC_PLLSAI1_EnableDomain_ADC(); + + /* Wait till PLLSAI1 is ready */ + while(LL_RCC_PLLSAI1_IsReady() != 1) + { + } + + /* Sysclk activation on the main PLL */ + /* Set CPU1 prescaler*/ + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + + /* Set CPU2 prescaler*/ + LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) + { + } + + /* Set AHB SHARED prescaler*/ + LL_RCC_SetAHB4Prescaler(LL_RCC_SYSCLK_DIV_1); + + /* Set APB1 prescaler*/ + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + + /* Set APB2 prescaler*/ + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); + + /* Disable MSI */ + LL_RCC_MSI_Disable(); + while(LL_RCC_MSI_IsReady() != 0) + { + } + + /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */ + LL_SetSystemCoreClock(64000000); + + /* Update the time base */ + if (HAL_InitTick (TICK_INT_PRIORITY) != HAL_OK) + { + Error_Handler(); + } + if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) + { + LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); + } + LL_RCC_EnableRTC(); + LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); + LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1); + LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); + LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); + LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1); + LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_PLLSAI1); + LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); + LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1); + LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); + /* USER CODE BEGIN Smps */ + + /* USER CODE END Smps */ +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#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, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/pka.c b/firmware/targets/f7/cube/Src/pka.c new file mode 100644 index 00000000..9728cf5e --- /dev/null +++ b/firmware/targets/f7/cube/Src/pka.c @@ -0,0 +1,87 @@ +/** + ****************************************************************************** + * @file pka.c + * @brief This file provides code for the configuration + * of the PKA instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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) +{ + + /* USER CODE BEGIN PKA_Init 0 */ + + /* USER CODE END PKA_Init 0 */ + + /* USER CODE BEGIN PKA_Init 1 */ + + /* USER CODE END PKA_Init 1 */ + hpka.Instance = PKA; + if (HAL_PKA_Init(&hpka) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN PKA_Init 2 */ + + /* USER CODE END PKA_Init 2 */ + +} + +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****/ diff --git a/firmware/targets/f7/cube/Src/rf.c b/firmware/targets/f7/cube/Src/rf.c new file mode 100644 index 00000000..5682dd9d --- /dev/null +++ b/firmware/targets/f7/cube/Src/rf.c @@ -0,0 +1,48 @@ +/** + ****************************************************************************** + * @file rf.c + * @brief This file provides code for the configuration + * of the RF instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 RF_Init 0 */ + + /* USER CODE END RF_Init 0 */ + + /* USER CODE BEGIN RF_Init 1 */ + + /* USER CODE END RF_Init 1 */ + /* USER CODE BEGIN RF_Init 2 */ + + /* USER CODE END RF_Init 2 */ + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/rng.c b/firmware/targets/f7/cube/Src/rng.c new file mode 100644 index 00000000..ba70ae7b --- /dev/null +++ b/firmware/targets/f7/cube/Src/rng.c @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * @file rng.c + * @brief This file provides code for the configuration + * of the RNG instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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) +{ + + /* USER CODE BEGIN RNG_Init 0 */ + + /* USER CODE END RNG_Init 0 */ + + /* USER CODE BEGIN RNG_Init 1 */ + + /* USER CODE END RNG_Init 1 */ + hrng.Instance = RNG; + hrng.Init.ClockErrorDetection = RNG_CED_ENABLE; + if (HAL_RNG_Init(&hrng) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN RNG_Init 2 */ + + /* USER CODE END RNG_Init 2 */ + +} + +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****/ diff --git a/firmware/targets/f7/cube/Src/rtc.c b/firmware/targets/f7/cube/Src/rtc.c new file mode 100644 index 00000000..2aaa7897 --- /dev/null +++ b/firmware/targets/f7/cube/Src/rtc.c @@ -0,0 +1,134 @@ +/** + ****************************************************************************** + * @file rtc.c + * @brief This file provides code for the configuration + * of the RTC instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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) +{ + + /* USER CODE BEGIN RTC_Init 0 */ + + /* USER CODE END RTC_Init 0 */ + + RTC_TimeTypeDef sTime = {0}; + RTC_DateTypeDef sDate = {0}; + + /* USER CODE BEGIN RTC_Init 1 */ + + /* USER CODE END RTC_Init 1 */ + /** 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 */ + + /* 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(); + } + /* USER CODE BEGIN RTC_Init 2 */ + + /* USER CODE END RTC_Init 2 */ + +} + +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****/ diff --git a/firmware/targets/f7/cube/Src/spi.c b/firmware/targets/f7/cube/Src/spi.c new file mode 100644 index 00000000..81864c8b --- /dev/null +++ b/firmware/targets/f7/cube/Src/spi.c @@ -0,0 +1,232 @@ +/** + ****************************************************************************** + * @file spi.c + * @brief This file provides code for the configuration + * of the SPI instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +SPI_HandleTypeDef hspi1; +SPI_HandleTypeDef hspi2; + +/* SPI1 init function */ +void MX_SPI1_Init(void) +{ + + /* USER CODE BEGIN SPI1_Init 0 */ + + /* USER CODE END SPI1_Init 0 */ + + /* USER CODE BEGIN SPI1_Init 1 */ + + /* USER CODE END SPI1_Init 1 */ + 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(); + } + /* USER CODE BEGIN SPI1_Init 2 */ + + /* USER CODE END SPI1_Init 2 */ + +} +/* SPI2 init function */ +void MX_SPI2_Init(void) +{ + + /* USER CODE BEGIN SPI2_Init 0 */ + + /* USER CODE END SPI2_Init 0 */ + + /* USER CODE BEGIN SPI2_Init 1 */ + + /* USER CODE END SPI2_Init 1 */ + 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(); + } + /* USER CODE BEGIN SPI2_Init 2 */ + + /* USER CODE END SPI2_Init 2 */ + +} + +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 = SPI_D_MISO_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_MISO_GPIO_Port, &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 */ + + /* 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(SPI_D_MISO_GPIO_Port, SPI_D_MISO_Pin); + + 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 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/stm32wbxx_hal_msp.c b/firmware/targets/f7/cube/Src/stm32wbxx_hal_msp.c new file mode 100644 index 00000000..48894f2f --- /dev/null +++ b/firmware/targets/f7/cube/Src/stm32wbxx_hal_msp.c @@ -0,0 +1,93 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbxx_hal_msp.c + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Src/stm32wbxx_it.c b/firmware/targets/f7/cube/Src/stm32wbxx_it.c new file mode 100644 index 00000000..707f5e06 --- /dev/null +++ b/firmware/targets/f7/cube/Src/stm32wbxx_it.c @@ -0,0 +1,326 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbxx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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" +#include "stm32wbxx_it.h" +#include "FreeRTOS.h" +#include "task.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +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; +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) + { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32WBxx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32wbxx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles RTC tamper and time stamp, CSS on LSE interrupts through EXTI line 18. + */ +void TAMP_STAMP_LSECSS_IRQHandler(void) +{ + /* USER CODE BEGIN TAMP_STAMP_LSECSS_IRQn 0 */ + + /* USER CODE END TAMP_STAMP_LSECSS_IRQn 0 */ + /* USER CODE BEGIN TAMP_STAMP_LSECSS_IRQn 1 */ + + /* USER CODE END TAMP_STAMP_LSECSS_IRQn 1 */ +} + +/** + * @brief This function handles RCC global interrupt. + */ +void RCC_IRQHandler(void) +{ + /* USER CODE BEGIN RCC_IRQn 0 */ + + /* USER CODE END RCC_IRQn 0 */ + /* USER CODE BEGIN RCC_IRQn 1 */ + + /* USER CODE END RCC_IRQn 1 */ +} + +/** + * @brief This function handles EXTI line3 interrupt. + */ +void EXTI3_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI3_IRQn 0 */ + + /* USER CODE END EXTI3_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); + /* USER CODE BEGIN EXTI3_IRQn 1 */ + + /* USER CODE END EXTI3_IRQn 1 */ +} + +/** + * @brief This function handles ADC1 global interrupt. + */ +void ADC1_IRQHandler(void) +{ + /* USER CODE BEGIN ADC1_IRQn 0 */ + + /* USER CODE END ADC1_IRQn 0 */ + HAL_ADC_IRQHandler(&hadc1); + /* USER CODE BEGIN ADC1_IRQn 1 */ + + /* USER CODE END ADC1_IRQn 1 */ +} + +/** + * @brief This function handles USB low priority interrupt, USB wake-up interrupt through EXTI line 28. + */ +void USB_LP_IRQHandler(void) +{ + /* USER CODE BEGIN USB_LP_IRQn 0 */ + + /* USER CODE END USB_LP_IRQn 0 */ + HAL_PCD_IRQHandler(&hpcd_USB_FS); + /* USER CODE BEGIN USB_LP_IRQn 1 */ + + /* USER CODE END USB_LP_IRQn 1 */ +} + +/** + * @brief This function handles COMP1 and COMP2 interrupts through EXTI lines 20 and 21. + */ +void COMP_IRQHandler(void) +{ + /* USER CODE BEGIN COMP_IRQn 0 */ + + /* USER CODE END COMP_IRQn 0 */ + HAL_COMP_IRQHandler(&hcomp1); + /* USER CODE BEGIN COMP_IRQn 1 */ + + /* USER CODE END COMP_IRQn 1 */ +} + +/** + * @brief This function handles TIM1 trigger and commutation interrupts and TIM17 global interrupt. + */ +void TIM1_TRG_COM_TIM17_IRQHandler(void) +{ + /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 0 */ + + /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 0 */ + HAL_TIM_IRQHandler(&htim1); + /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 1 */ + + /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 1 */ +} + +/** + * @brief This function handles TIM2 global interrupt. + */ +void TIM2_IRQHandler(void) +{ + /* USER CODE BEGIN TIM2_IRQn 0 */ + + /* USER CODE END TIM2_IRQn 0 */ + HAL_TIM_IRQHandler(&htim2); + /* USER CODE BEGIN TIM2_IRQn 1 */ + + /* USER CODE END TIM2_IRQn 1 */ +} + +/** + * @brief This function handles EXTI line[15:10] interrupts. + */ +void EXTI15_10_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI15_10_IRQn 0 */ + + /* USER CODE END EXTI15_10_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); + /* USER CODE BEGIN EXTI15_10_IRQn 1 */ + + /* USER CODE END EXTI15_10_IRQn 1 */ +} + +/** + * @brief This function handles HSEM global interrupt. + */ +void HSEM_IRQHandler(void) +{ + /* USER CODE BEGIN HSEM_IRQn 0 */ + + /* USER CODE END HSEM_IRQn 0 */ + HAL_HSEM_IRQHandler(); + /* USER CODE BEGIN HSEM_IRQn 1 */ + + /* USER CODE END HSEM_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/system_stm32wbxx.c b/firmware/targets/f7/cube/Src/system_stm32wbxx.c new file mode 100644 index 00000000..d0ff7d2d --- /dev/null +++ b/firmware/targets/f7/cube/Src/system_stm32wbxx.c @@ -0,0 +1,368 @@ +/** + ****************************************************************************** + * @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 + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @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 + * @{ + */ + +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line if you need to relocate CPU1 CM4 and/or CPU2 + CM0+ vector table anywhere in Sram or Flash. Else vector table will be kept + at address 0x00 which correspond to automatic remap of boot address selected */ +/* #define USER_VECT_TAB_ADDRESS */ +#if defined(USER_VECT_TAB_ADDRESS) + /*!< Uncomment this line for user vector table remap in Sram else user remap + will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS SRAM1_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +#else +#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +#endif +#endif + +/** + * @} + */ + +/** @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) || defined (STM32WB15xx) || defined (STM32WB10xx) + 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) +{ +#if defined(USER_VECT_TAB_ADDRESS) + /* Configure the Vector Table location add offset address ------------------*/ + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; +#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****/ diff --git a/firmware/targets/f7/cube/Src/tim.c b/firmware/targets/f7/cube/Src/tim.c new file mode 100644 index 00000000..1c38c1d7 --- /dev/null +++ b/firmware/targets/f7/cube/Src/tim.c @@ -0,0 +1,394 @@ +/** + ****************************************************************************** + * @file tim.c + * @brief This file provides code for the configuration + * of the TIM instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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) +{ + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + 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(); + } + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ + HAL_TIM_MspPostInit(&htim1); + +} +/* TIM2 init function */ +void MX_TIM2_Init(void) +{ + + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_IC_InitTypeDef sConfigIC = {0}; + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + 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(); + } + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ + +} +/* TIM16 init function */ +void MX_TIM16_Init(void) +{ + + /* USER CODE BEGIN TIM16_Init 0 */ + + /* USER CODE END TIM16_Init 0 */ + + TIM_OC_InitTypeDef sConfigOC = {0}; + TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; + + /* USER CODE BEGIN TIM16_Init 1 */ + + /* USER CODE END TIM16_Init 1 */ + 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(); + } + /* USER CODE BEGIN TIM16_Init 2 */ + + /* USER CODE END TIM16_Init 2 */ + 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, 5, 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****/ diff --git a/firmware/targets/f7/cube/Src/usart.c b/firmware/targets/f7/cube/Src/usart.c new file mode 100644 index 00000000..0a0466dc --- /dev/null +++ b/firmware/targets/f7/cube/Src/usart.c @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * @file usart.c + * @brief This file provides code for the configuration + * of the USART instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 "usart.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* USART1 init function */ + +void MX_USART1_UART_Init(void) +{ + + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + + LL_USART_InitTypeDef USART_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + /**USART1 GPIO Configuration + PB6 ------> USART1_TX + PB7 ------> USART1_RX + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN USART1_Init 1 */ + + /* USER CODE END USART1_Init 1 */ + USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; + USART_InitStruct.BaudRate = 115200; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; + LL_USART_Init(USART1, &USART_InitStruct); + LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); + LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); + LL_USART_DisableFIFO(USART1); + LL_USART_EnableAutoBaudRate(USART1); + LL_USART_SetAutoBaudRateMode(USART1, LL_USART_AUTOBAUD_DETECT_ON_STARTBIT); + LL_USART_ConfigAsyncMode(USART1); + + /* USER CODE BEGIN WKUPType USART1 */ + + /* USER CODE END WKUPType USART1 */ + + LL_USART_Enable(USART1); + + /* Polling USART1 initialisation */ + while(!(LL_USART_IsActiveFlag_TEACK(USART1))) + { + } + /* USER CODE BEGIN USART1_Init 2 */ + + /* USER CODE END USART1_Init 2 */ + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/usb_device.c b/firmware/targets/f7/cube/Src/usb_device.c new file mode 100644 index 00000000..8871a778 --- /dev/null +++ b/firmware/targets/f7/cube/Src/usb_device.c @@ -0,0 +1,99 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usb_device.c + * @version : v3.0_Cube + * @brief : This file implements the USB Device + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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****/ diff --git a/firmware/targets/f7/cube/Src/usbd_cdc_if.c b/firmware/targets/f7/cube/Src/usbd_cdc_if.c new file mode 100644 index 00000000..d52d1e3e --- /dev/null +++ b/firmware/targets/f7/cube/Src/usbd_cdc_if.c @@ -0,0 +1,331 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_cdc_if.c + * @version : v3.0_Cube + * @brief : Usb device for Virtual Com Port. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 */ + +/* 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); + 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 */ + 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 */ + switch(cmd) + { + case CDC_SEND_ENCAPSULATED_COMMAND: + + break; + + case CDC_GET_ENCAPSULATED_RESPONSE: + + break; + + case CDC_SET_COMM_FEATURE: + + break; + + case CDC_GET_COMM_FEATURE: + + break; + + case CDC_CLEAR_COMM_FEATURE: + + break; + + /*******************************************************************************/ + /* 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). */ + /*******************************************************************************/ + case CDC_SET_LINE_CODING: + + break; + + case CDC_GET_LINE_CODING: + + break; + + case CDC_SET_CONTROL_LINE_STATE: + + break; + + case CDC_SEND_BREAK: + + break; + + default: + break; + } + + 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 */ + USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); + 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; + } + USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len); + result = USBD_CDC_TransmitPacket(&hUsbDeviceFS); + /* USER CODE END 7 */ + return result; +} + +/** + * @brief CDC_TransmitCplt_FS + * Data transmitted 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(Len); + UNUSED(epnum); + /* USER CODE END 13 */ + return result; +} + +/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */ + +/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/usbd_conf.c b/firmware/targets/f7/cube/Src/usbd_conf.c new file mode 100644 index 00000000..033e619a --- /dev/null +++ b/firmware/targets/f7/cube/Src/usbd_conf.c @@ -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 + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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 transferred packet size. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval Received 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 Returns 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****/ diff --git a/firmware/targets/f7/cube/Src/usbd_desc.c b/firmware/targets/f7/cube/Src/usbd_desc.c new file mode 100644 index 00000000..26f4b7c5 --- /dev/null +++ b/firmware/targets/f7/cube/Src/usbd_desc.c @@ -0,0 +1,396 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_desc.c + * @version : v3.0_Cube + * @brief : This file implements the USB device descriptors. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * 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" + +/* 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" +#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 identifier 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 */ + 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****/ diff --git a/firmware/targets/f7/cube/f7.ioc b/firmware/targets/f7/cube/f7.ioc new file mode 100644 index 00000000..e55ecca4 --- /dev/null +++ b/firmware/targets/f7/cube/f7.ioc @@ -0,0 +1,598 @@ +#MicroXplorer Configuration settings - do not modify +ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_14 +ADC1.ContinuousConvMode=DISABLE +ADC1.EnableAnalogWatchDog1=false +ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,master,EnableAnalogWatchDog1,ContinuousConvMode +ADC1.NbrOfConversionFlag=1 +ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.Rank-0\#ChannelRegularConversion=1 +ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5 +ADC1.master=1 +COMP1.Hysteresis=COMP_HYSTERESIS_HIGH +COMP1.IPParameters=TriggerMode,Hysteresis,Mode +COMP1.Mode=COMP_POWERMODE_MEDIUMSPEED +COMP1.TriggerMode=COMP_TRIGGERMODE_IT_RISING_FALLING +FREERTOS.FootprintOK=true +FREERTOS.HEAP_NUMBER=4 +FREERTOS.INCLUDE_vTaskCleanUpResources=1 +FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE,HEAP_NUMBER,configUSE_TIMERS,configUSE_IDLE_HOOK,FootprintOK,configCHECK_FOR_STACK_OVERFLOW,configRECORD_STACK_HIGH_ADDRESS,configGENERATE_RUN_TIME_STATS,configENABLE_FPU,configUSE_TICKLESS_IDLE,configENABLE_BACKWARD_COMPATIBILITY,INCLUDE_vTaskCleanUpResources,configTICK_RATE_HZ +FREERTOS.Tasks01=app_main,24,1024,app,As weak,NULL,Dynamic,NULL,NULL +FREERTOS.configCHECK_FOR_STACK_OVERFLOW=1 +FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=0 +FREERTOS.configENABLE_FPU=1 +FREERTOS.configGENERATE_RUN_TIME_STATS=1 +FREERTOS.configRECORD_STACK_HIGH_ADDRESS=1 +FREERTOS.configTICK_RATE_HZ=1000 +FREERTOS.configTOTAL_HEAP_SIZE=40960 +FREERTOS.configUSE_IDLE_HOOK=1 +FREERTOS.configUSE_TICKLESS_IDLE=2 +FREERTOS.configUSE_TIMERS=1 +File.Version=6 +GPIO.groupedBy=Show All +I2C1.CustomTiming=Disabled +I2C1.I2C_Fall_Time=0 +I2C1.I2C_Rise_Time=0 +I2C1.IPParameters=Timing,CustomTiming,I2C_Rise_Time,I2C_Fall_Time +I2C1.Timing=0x10707DBC +KeepUserPlacement=false +Mcu.Family=STM32WB +Mcu.IP0=ADC1 +Mcu.IP1=AES1 +Mcu.IP10=RCC +Mcu.IP11=RF +Mcu.IP12=RNG +Mcu.IP13=RTC +Mcu.IP14=SPI1 +Mcu.IP15=SPI2 +Mcu.IP16=SYS +Mcu.IP17=TIM1 +Mcu.IP18=TIM2 +Mcu.IP19=TIM16 +Mcu.IP2=AES2 +Mcu.IP20=USART1 +Mcu.IP21=USB +Mcu.IP22=USB_DEVICE +Mcu.IP3=COMP1 +Mcu.IP4=CRC +Mcu.IP5=FREERTOS +Mcu.IP6=HSEM +Mcu.IP7=I2C1 +Mcu.IP8=NVIC +Mcu.IP9=PKA +Mcu.IPNb=23 +Mcu.Name=STM32WB55RGVx +Mcu.Package=VFQFPN68 +Mcu.Pin0=PC13 +Mcu.Pin1=PC14-OSC32_IN +Mcu.Pin10=PA0 +Mcu.Pin11=PA1 +Mcu.Pin12=PA2 +Mcu.Pin13=PA3 +Mcu.Pin14=PA4 +Mcu.Pin15=PA5 +Mcu.Pin16=PA6 +Mcu.Pin17=PA7 +Mcu.Pin18=PA8 +Mcu.Pin19=PA9 +Mcu.Pin2=PC15-OSC32_OUT +Mcu.Pin20=PC4 +Mcu.Pin21=PC5 +Mcu.Pin22=PB2 +Mcu.Pin23=PB10 +Mcu.Pin24=PB11 +Mcu.Pin25=RF1 +Mcu.Pin26=OSC_OUT +Mcu.Pin27=OSC_IN +Mcu.Pin28=PB0 +Mcu.Pin29=PB1 +Mcu.Pin3=PH3-BOOT0 +Mcu.Pin30=PE4 +Mcu.Pin31=PB12 +Mcu.Pin32=PB13 +Mcu.Pin33=PB14 +Mcu.Pin34=PB15 +Mcu.Pin35=PC6 +Mcu.Pin36=PA10 +Mcu.Pin37=PA11 +Mcu.Pin38=PA12 +Mcu.Pin39=PA13 +Mcu.Pin4=PB8 +Mcu.Pin40=PA14 +Mcu.Pin41=PA15 +Mcu.Pin42=PC10 +Mcu.Pin43=PC11 +Mcu.Pin44=PC12 +Mcu.Pin45=PD0 +Mcu.Pin46=PD1 +Mcu.Pin47=PB3 +Mcu.Pin48=PB4 +Mcu.Pin49=PB5 +Mcu.Pin5=PB9 +Mcu.Pin50=PB6 +Mcu.Pin51=PB7 +Mcu.Pin52=VP_ADC1_TempSens_Input +Mcu.Pin53=VP_ADC1_Vref_Input +Mcu.Pin54=VP_AES1_VS_AES +Mcu.Pin55=VP_AES2_VS_AES +Mcu.Pin56=VP_COMP1_VS_VREFINT14 +Mcu.Pin57=VP_CRC_VS_CRC +Mcu.Pin58=VP_FREERTOS_VS_CMSIS_V2 +Mcu.Pin59=VP_HSEM_VS_HSEM +Mcu.Pin6=PC0 +Mcu.Pin60=VP_PKA_VS_PKA +Mcu.Pin61=VP_RNG_VS_RNG +Mcu.Pin62=VP_RTC_VS_RTC_Activate +Mcu.Pin63=VP_RTC_VS_RTC_Calendar +Mcu.Pin64=VP_SYS_VS_Systick +Mcu.Pin65=VP_TIM1_VS_ClockSourceINT +Mcu.Pin66=VP_TIM2_VS_ClockSourceINT +Mcu.Pin67=VP_TIM16_VS_ClockSourceINT +Mcu.Pin68=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS +Mcu.Pin7=PC1 +Mcu.Pin8=PC2 +Mcu.Pin9=PC3 +Mcu.PinsNb=69 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32WB55RGVx +MxCube.Version=6.3.0 +MxDb.Version=DB.6.0.30 +NVIC.ADC1_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.COMP_IRQn=true\:5\:0\:true\:false\:true\:false\:false\:true +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.EXTI15_10_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true +NVIC.EXTI3_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true +NVIC.ForceEnableDMAVector=true +NVIC.HSEM_IRQn=true\:5\:0\:true\:false\:true\:false\:false\:true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true +NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.RCC_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:false +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false +NVIC.SavedPendsvIrqHandlerGenerated=false +NVIC.SavedSvcallIrqHandlerGenerated=false +NVIC.SavedSystickIrqHandlerGenerated=true +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:false +NVIC.TAMP_STAMP_LSECSS_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true +NVIC.TIM1_TRG_COM_TIM17_IRQn=true\:5\:0\:false\:false\:true\:false\:false\:true +NVIC.TIM2_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true +NVIC.USB_LP_IRQn=true\:5\:0\:true\:false\:true\:false\:false\:true +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +OSC_IN.GPIOParameters=GPIO_Label +OSC_IN.GPIO_Label=QUARTZ_32KHZ_IN +OSC_IN.Locked=true +OSC_IN.Mode=HSE-External-Oscillator +OSC_IN.Signal=RCC_OSC_IN +OSC_OUT.GPIOParameters=GPIO_Label +OSC_OUT.GPIO_Label=QUARTZ_32KHZ_OUT +OSC_OUT.Locked=true +OSC_OUT.Mode=HSE-External-Oscillator +OSC_OUT.Signal=RCC_OSC_OUT +PA0.GPIOParameters=GPIO_Label +PA0.GPIO_Label=IR_RX +PA0.Signal=S_TIM2_CH1 +PA1.GPIOParameters=GPIO_Label +PA1.GPIO_Label=CC1101_G0 +PA1.Locked=true +PA1.Signal=GPIO_Analog +PA10.GPIOParameters=GPIO_Speed,GPIO_Label,GPIO_Pu +PA10.GPIO_Label=I2C_SDA +PA10.GPIO_Pu=GPIO_PULLUP +PA10.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA10.Locked=true +PA10.Mode=I2C +PA10.Signal=I2C1_SDA +PA11.GPIOParameters=GPIO_Speed +PA11.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA11.Locked=true +PA11.Mode=Device +PA11.Signal=USB_DM +PA12.GPIOParameters=GPIO_Speed +PA12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA12.Locked=true +PA12.Mode=Device +PA12.Signal=USB_DP +PA13.Locked=true +PA13.Mode=Serial_Wire +PA13.Signal=SYS_JTMS-SWDIO +PA14.Locked=true +PA14.Mode=Serial_Wire +PA14.Signal=SYS_JTCK-SWCLK +PA15.GPIOParameters=GPIO_Label +PA15.GPIO_Label=RFID_CARRIER +PA15.Locked=true +PA15.Signal=GPIO_Analog +PA2.GPIOParameters=GPIO_Label +PA2.GPIO_Label=RFID_PULL +PA2.Locked=true +PA2.Signal=GPIO_Output +PA3.GPIOParameters=GPIO_Speed,PinState,GPIO_Label,GPIO_ModeDefaultOutputPP +PA3.GPIO_Label=PERIPH_POWER +PA3.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_OD +PA3.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PA3.Locked=true +PA3.PinState=GPIO_PIN_SET +PA3.Signal=GPIO_Output +PA4.GPIOParameters=GPIO_Label +PA4.GPIO_Label=PA4 +PA4.Signal=GPIO_Analog +PA5.GPIOParameters=GPIO_Label +PA5.GPIO_Label=SPI_R_SCK +PA5.Locked=true +PA5.Mode=Full_Duplex_Master +PA5.Signal=SPI1_SCK +PA6.GPIOParameters=GPIO_Label +PA6.GPIO_Label=PA6 +PA6.Signal=GPIO_Analog +PA7.GPIOParameters=GPIO_Label +PA7.GPIO_Label=PA7 +PA7.Signal=GPIO_Analog +PA8.GPIOParameters=GPIO_Label +PA8.GPIO_Label=VIBRO +PA8.Locked=true +PA8.Signal=GPIO_Output +PA9.GPIOParameters=GPIO_Speed,GPIO_Label,GPIO_Pu +PA9.GPIO_Label=I2C_SCL +PA9.GPIO_Pu=GPIO_PULLUP +PA9.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA9.Locked=true +PA9.Mode=I2C +PA9.Signal=I2C1_SCL +PB0.GPIOParameters=GPIO_Label +PB0.GPIO_Label=DISPLAY_RST +PB0.Locked=true +PB0.Signal=GPIO_Output +PB1.GPIOParameters=GPIO_Label +PB1.GPIO_Label=DISPLAY_DI +PB1.Locked=true +PB1.Signal=GPIO_Output +PB10.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI +PB10.GPIO_Label=BUTTON_UP +PB10.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING +PB10.GPIO_PuPd=GPIO_PULLUP +PB10.Locked=true +PB10.Signal=GPXTI10 +PB11.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI +PB11.GPIO_Label=BUTTON_LEFT +PB11.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING +PB11.GPIO_PuPd=GPIO_PULLUP +PB11.Locked=true +PB11.Signal=GPXTI11 +PB12.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI +PB12.GPIO_Label=BUTTON_RIGHT +PB12.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING +PB12.GPIO_PuPd=GPIO_PULLUP +PB12.Locked=true +PB12.Signal=GPXTI12 +PB13.GPIOParameters=GPIO_Label +PB13.GPIO_Label=RFID_OUT +PB13.Locked=true +PB13.Mode=Output Compare1 CH1N +PB13.Signal=TIM1_CH1N +PB14.GPIOParameters=GPIO_Label +PB14.GPIO_Label=iBTN +PB14.Signal=GPIO_Analog +PB15.GPIOParameters=GPIO_Label +PB15.GPIO_Label=SPI_D_MOSI +PB15.Locked=true +PB15.Mode=Full_Duplex_Master +PB15.Signal=SPI2_MOSI +PB2.GPIOParameters=GPIO_Label +PB2.GPIO_Label=PB2 +PB2.Signal=GPIO_Analog +PB3.GPIOParameters=GPIO_Label +PB3.GPIO_Label=PB3 +PB3.Locked=true +PB3.Signal=GPIO_Analog +PB4.GPIOParameters=GPIO_Label +PB4.GPIO_Label=SPI_R_MISO +PB4.Locked=true +PB4.Mode=Full_Duplex_Master +PB4.Signal=SPI1_MISO +PB5.GPIOParameters=GPIO_Label +PB5.GPIO_Label=SPI_R_MOSI +PB5.Locked=true +PB5.Mode=Full_Duplex_Master +PB5.Signal=SPI1_MOSI +PB6.Locked=true +PB6.Mode=Asynchronous +PB6.Signal=USART1_TX +PB7.Locked=true +PB7.Mode=Asynchronous +PB7.Signal=USART1_RX +PB8.GPIOParameters=GPIO_Label +PB8.GPIO_Label=SPEAKER +PB8.Locked=true +PB8.Signal=S_TIM16_CH1 +PB9.GPIOParameters=GPIO_Label +PB9.GPIO_Label=IR_TX +PB9.Locked=true +PB9.Mode=PWM Generation3 CH3N +PB9.Signal=TIM1_CH3N +PC0.GPIOParameters=GPIO_Label +PC0.GPIO_Label=PC0 +PC0.Locked=true +PC0.Signal=GPIO_Analog +PC1.GPIOParameters=GPIO_Label +PC1.GPIO_Label=PC1 +PC1.Locked=true +PC1.Signal=GPIO_Analog +PC10.GPIOParameters=GPIO_Label +PC10.GPIO_Label=SD_CD +PC10.Locked=true +PC10.Signal=GPIO_Input +PC11.GPIOParameters=PinState,GPIO_Label +PC11.GPIO_Label=DISPLAY_CS +PC11.Locked=true +PC11.PinState=GPIO_PIN_SET +PC11.Signal=GPIO_Output +PC12.GPIOParameters=GPIO_Speed,PinState,GPIO_Label +PC12.GPIO_Label=SD_CS +PC12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PC12.Locked=true +PC12.PinState=GPIO_PIN_SET +PC12.Signal=GPIO_Output +PC13.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI +PC13.GPIO_Label=BUTTON_BACK +PC13.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING +PC13.GPIO_PuPd=GPIO_PULLUP +PC13.Locked=true +PC13.Signal=GPXTI13 +PC14-OSC32_IN.GPIOParameters=GPIO_Label +PC14-OSC32_IN.GPIO_Label=QUARTZ_32MHZ_IN +PC14-OSC32_IN.Locked=true +PC14-OSC32_IN.Mode=LSE-External-Oscillator +PC14-OSC32_IN.Signal=RCC_OSC32_IN +PC15-OSC32_OUT.GPIOParameters=GPIO_Label +PC15-OSC32_OUT.GPIO_Label=QUARTZ_32MHZ_OUT +PC15-OSC32_OUT.Locked=true +PC15-OSC32_OUT.Mode=LSE-External-Oscillator +PC15-OSC32_OUT.Signal=RCC_OSC32_OUT +PC2.GPIOParameters=GPIO_Label +PC2.GPIO_Label=SPI_D_MISO +PC2.Locked=true +PC2.Mode=Full_Duplex_Master +PC2.Signal=SPI2_MISO +PC3.GPIOParameters=GPIO_Label +PC3.GPIO_Label=PC3 +PC3.Signal=GPIO_Analog +PC4.GPIOParameters=GPIO_Label +PC4.GPIO_Label=RF_SW_0 +PC4.Locked=true +PC4.Signal=GPIO_Output +PC5.GPIOParameters=GPIO_Label +PC5.GPIO_Label=RFID_RF_IN +PC5.Locked=true +PC5.Signal=SharedAnalog_PC5 +PC6.GPIOParameters=GPIO_Label +PC6.GPIO_Label=BUTTON_DOWN +PC6.Locked=true +PC6.Signal=GPIO_Input +PCC.Ble.ConnectionInterval=1000.0 +PCC.Ble.DataLength=6 +PCC.Ble.IsUsed=false +PCC.Ble.Mode=NOT_SELECTED +PCC.Ble.PowerLevel=Min +PCC.Zigbee.IsUsed=false +PCC.Zigbee.Mode=Sleepy End Device +PCC.Zigbee.Payload=15 +PCC.Zigbee.PoolPeriodicity=480.0 +PCC.Zigbee.PowerLevel=Min +PCC.Zigbee.RequestPeriodicity=1500.0 +PD0.GPIOParameters=GPIO_Speed,PinState,GPIO_Label +PD0.GPIO_Label=CC1101_CS +PD0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PD0.Locked=true +PD0.PinState=GPIO_PIN_SET +PD0.Signal=GPIO_Output +PD1.GPIOParameters=GPIO_Label +PD1.GPIO_Label=SPI_D_SCK +PD1.Locked=true +PD1.Mode=Full_Duplex_Master +PD1.Signal=SPI2_SCK +PE4.GPIOParameters=GPIO_Speed,PinState,GPIO_Label +PE4.GPIO_Label=NFC_CS +PE4.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PE4.Locked=true +PE4.PinState=GPIO_PIN_SET +PE4.Signal=GPIO_Output +PH3-BOOT0.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI +PH3-BOOT0.GPIO_Label=BUTTON_OK +PH3-BOOT0.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING +PH3-BOOT0.Locked=true +PH3-BOOT0.Signal=GPXTI3 +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=true +ProjectManager.CustomerFirmwarePackage=../../../../lib/STM32CubeWB +ProjectManager.DefaultFWLocation=false +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32WB55RGVx +ProjectManager.FirmwarePackage=STM32Cube FW_WB V1.12.1 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x400 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=2 +ProjectManager.MainLocation=Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=f7.ioc +ProjectManager.ProjectName=f7 +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x1000 +ProjectManager.TargetToolchain=Makefile +ProjectManager.ToolChainLocation= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-LL-false,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_I2C1_Init-I2C1-false-LL-true,5-MX_RTC_Init-RTC-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true,8-MX_USB_Device_Init-USB_DEVICE-false-HAL-false,9-MX_TIM1_Init-TIM1-false-HAL-true,10-MX_TIM2_Init-TIM2-false-HAL-true,11-MX_TIM16_Init-TIM16-false-HAL-true,12-MX_COMP1_Init-COMP1-false-HAL-true,13-MX_RF_Init-RF-false-HAL-true,14-MX_PKA_Init-PKA-false-HAL-true,15-MX_RNG_Init-RNG-false-HAL-true,16-MX_AES1_Init-AES1-false-HAL-true,17-MX_AES2_Init-AES2-false-HAL-true,18-MX_CRC_Init-CRC-false-HAL-true,19-MX_USART1_UART_Init-USART1-false-LL-true,0-MX_HSEM_Init-HSEM-false-HAL-true +RCC.ADCFreq_Value=48000000 +RCC.AHB2CLKDivider=RCC_SYSCLK_DIV2 +RCC.AHBFreq_Value=64000000 +RCC.APB1Freq_Value=64000000 +RCC.APB1TimFreq_Value=64000000 +RCC.APB2Freq_Value=64000000 +RCC.APB2TimFreq_Value=64000000 +RCC.APB3Freq_Value=16000000 +RCC.Cortex2Freq_Value=32000000 +RCC.CortexFreq_Value=64000000 +RCC.EnableCSSLSE=true +RCC.EnbaleCSS=true +RCC.FCLK2Freq_Value=32000000 +RCC.FCLKCortexFreq_Value=64000000 +RCC.FamilyName=M +RCC.HCLK2Freq_Value=32000000 +RCC.HCLK3Freq_Value=64000000 +RCC.HCLKFreq_Value=64000000 +RCC.HCLKRFFreq_Value=16000000 +RCC.HSE_VALUE=32000000 +RCC.HSI48_VALUE=48000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=64000000 +RCC.I2C3Freq_Value=64000000 +RCC.IPParameters=ADCFreq_Value,AHB2CLKDivider,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,Cortex2Freq_Value,CortexFreq_Value,EnableCSSLSE,EnbaleCSS,FCLK2Freq_Value,FCLKCortexFreq_Value,FamilyName,HCLK2Freq_Value,HCLK3Freq_Value,HCLKFreq_Value,HCLKRFFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LCDFreq_Value,LPTIM1CLockSelection,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_Drive_Capability,LSE_Timout,LSI_VALUE,MCO1PinFreq_Value,MSIOscState,PLLM,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1N,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PLLSourceVirtual,PREFETCH_ENABLE,PWRFreq_Value,RFWKPClockSelection,RFWKPFreq_Value,RNGCLockSelection,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SMPS1Freq_Value,SMPSCLockSelectionVirtual,SMPSDivider,SMPSFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,USART1Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value +RCC.LCDFreq_Value=32768 +RCC.LPTIM1CLockSelection=RCC_LPTIM1CLKSOURCE_LSE +RCC.LPTIM1Freq_Value=32768 +RCC.LPTIM2Freq_Value=64000000 +RCC.LPUART1Freq_Value=64000000 +RCC.LSCOPinFreq_Value=32000 +RCC.LSE_Drive_Capability=RCC_LSEDRIVE_MEDIUMLOW +RCC.LSE_Timout=1000 +RCC.LSI_VALUE=32000 +RCC.MCO1PinFreq_Value=64000000 +RCC.MSIOscState=DISABLED +RCC.PLLM=RCC_PLLM_DIV2 +RCC.PLLPoutputFreq_Value=64000000 +RCC.PLLQoutputFreq_Value=64000000 +RCC.PLLRCLKFreq_Value=64000000 +RCC.PLLSAI1N=6 +RCC.PLLSAI1PoutputFreq_Value=48000000 +RCC.PLLSAI1QoutputFreq_Value=48000000 +RCC.PLLSAI1RoutputFreq_Value=48000000 +RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE +RCC.PREFETCH_ENABLE=1 +RCC.PWRFreq_Value=64000000 +RCC.RFWKPClockSelection=RCC_RFWKPCLKSOURCE_LSE +RCC.RFWKPFreq_Value=32768 +RCC.RNGCLockSelection=RCC_RNGCLKSOURCE_CLK48 +RCC.RNGFreq_Value=16000000 +RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE +RCC.RTCFreq_Value=32768 +RCC.SAI1Freq_Value=48000000 +RCC.SMPS1Freq_Value=8000000 +RCC.SMPSCLockSelectionVirtual=RCC_SMPSCLKSOURCE_HSE +RCC.SMPSDivider=4 +RCC.SMPSFreq_Value=4000000 +RCC.SYSCLKFreq_VALUE=64000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.USART1Freq_Value=64000000 +RCC.USBFreq_Value=48000000 +RCC.VCOInputFreq_Value=16000000 +RCC.VCOOutputFreq_Value=128000000 +RCC.VCOSAI1OutputFreq_Value=96000000 +RF1.Locked=true +RF1.Mode=RF1_Activate +RF1.Signal=RF_RF1 +SH.GPXTI10.0=GPIO_EXTI10 +SH.GPXTI10.ConfNb=1 +SH.GPXTI11.0=GPIO_EXTI11 +SH.GPXTI11.ConfNb=1 +SH.GPXTI12.0=GPIO_EXTI12 +SH.GPXTI12.ConfNb=1 +SH.GPXTI13.0=GPIO_EXTI13 +SH.GPXTI13.ConfNb=1 +SH.GPXTI3.0=GPIO_EXTI3 +SH.GPXTI3.ConfNb=1 +SH.S_TIM16_CH1.0=TIM16_CH1,PWM Generation1 CH1 +SH.S_TIM16_CH1.ConfNb=1 +SH.S_TIM2_CH1.0=TIM2_CH1,Input_Capture1_from_TI1 +SH.S_TIM2_CH1.1=TIM2_CH1,Input_Capture2_from_TI1 +SH.S_TIM2_CH1.ConfNb=2 +SH.SharedAnalog_PC5.0=COMP1_INP,INP +SH.SharedAnalog_PC5.1=ADC1_IN14,IN14-Single-Ended +SH.SharedAnalog_PC5.ConfNb=2 +SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16 +SPI1.CLKPhase=SPI_PHASE_2EDGE +SPI1.CalculateBaudRate=4.0 MBits/s +SPI1.DataSize=SPI_DATASIZE_8BIT +SPI1.Direction=SPI_DIRECTION_2LINES +SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,CLKPhase,BaudRatePrescaler +SPI1.Mode=SPI_MODE_MASTER +SPI1.VirtualType=VM_MASTER +SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16 +SPI2.CLKPhase=SPI_PHASE_1EDGE +SPI2.CalculateBaudRate=4.0 MBits/s +SPI2.DataSize=SPI_DATASIZE_8BIT +SPI2.Direction=SPI_DIRECTION_2LINES +SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPhase +SPI2.Mode=SPI_MODE_MASTER +SPI2.VirtualType=VM_MASTER +TIM1.Channel-Output\ Compare1\ CH1N=TIM_CHANNEL_1 +TIM1.Channel-PWM\ Generation3\ CH3N=TIM_CHANNEL_3 +TIM1.IPParameters=Channel-Output Compare1 CH1N,Channel-PWM Generation3 CH3N +TIM16.Channel=TIM_CHANNEL_1 +TIM16.IPParameters=Channel,Pulse,Prescaler,Period +TIM16.Period=291 +TIM16.Prescaler=500 - 1 +TIM16.Pulse=145 +TIM2.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM2.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1 +TIM2.Channel-Input_Capture2_from_TI1=TIM_CHANNEL_2 +TIM2.ICPolarity_CH1=TIM_INPUTCHANNELPOLARITY_FALLING +TIM2.IPParameters=Channel-Input_Capture1_from_TI1,ICPolarity_CH1,AutoReloadPreload,Prescaler,Channel-Input_Capture2_from_TI1 +TIM2.Prescaler=64-1 +USART1.AutoBaudRateEnableParam=UART_ADVFEATURE_AUTOBAUDRATE_ENABLE +USART1.IPParameters=VirtualMode-Asynchronous,Mode,AutoBaudRateEnableParam +USART1.Mode=MODE_TX +USART1.VirtualMode-Asynchronous=VM_ASYNC +USB_DEVICE.APP_RX_DATA_SIZE=512 +USB_DEVICE.APP_TX_DATA_SIZE=512 +USB_DEVICE.CLASS_NAME_FS=CDC +USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS,MANUFACTURER_STRING,PRODUCT_STRING_CDC_FS,APP_RX_DATA_SIZE,APP_TX_DATA_SIZE +USB_DEVICE.MANUFACTURER_STRING=Flipper +USB_DEVICE.PRODUCT_STRING_CDC_FS=Flipper Control Virtual ComPort +USB_DEVICE.VirtualMode=Cdc +USB_DEVICE.VirtualModeFS=Cdc_FS +VP_ADC1_TempSens_Input.Mode=IN-TempSens +VP_ADC1_TempSens_Input.Signal=ADC1_TempSens_Input +VP_ADC1_Vref_Input.Mode=IN-Vrefint +VP_ADC1_Vref_Input.Signal=ADC1_Vref_Input +VP_AES1_VS_AES.Mode=AES_Activate +VP_AES1_VS_AES.Signal=AES1_VS_AES +VP_AES2_VS_AES.Mode=AES_Activate +VP_AES2_VS_AES.Signal=AES2_VS_AES +VP_COMP1_VS_VREFINT14.Mode=VREFINT_14 +VP_COMP1_VS_VREFINT14.Signal=COMP1_VS_VREFINT14 +VP_CRC_VS_CRC.Mode=CRC_Activate +VP_CRC_VS_CRC.Signal=CRC_VS_CRC +VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2 +VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2 +VP_HSEM_VS_HSEM.Mode=HSEM_Activate +VP_HSEM_VS_HSEM.Signal=HSEM_VS_HSEM +VP_PKA_VS_PKA.Mode=PKA_Activate +VP_PKA_VS_PKA.Signal=PKA_VS_PKA +VP_RNG_VS_RNG.Mode=RNG_Activate +VP_RNG_VS_RNG.Signal=RNG_VS_RNG +VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled +VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate +VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar +VP_RTC_VS_RTC_Calendar.Signal=RTC_VS_RTC_Calendar +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM16_VS_ClockSourceINT.Mode=Enable_Timer +VP_TIM16_VS_ClockSourceINT.Signal=TIM16_VS_ClockSourceINT +VP_TIM1_VS_ClockSourceINT.Mode=Internal +VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT +VP_TIM2_VS_ClockSourceINT.Mode=Internal +VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT +VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS +VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS +board=custom diff --git a/firmware/targets/f7/cube/startup_stm32wb55xx_cm4.s b/firmware/targets/f7/cube/startup_stm32wb55xx_cm4.s new file mode 100644 index 00000000..c5c2b3fc --- /dev/null +++ b/firmware/targets/f7/cube/startup_stm32wb55xx_cm4.s @@ -0,0 +1,444 @@ +/** + ****************************************************************************** + * @file startup_stm32wb55xx_cm4.s + * @author MCD Application Team + * @brief STM32WB55xx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* start address for the .MB_MEM2 section. defined in linker script */ +.word _sMB_MEM2 +/* end address for the .MB_MEM2 section. defined in linker script */ +.word _eMB_MEM2 + +/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */ +.macro INIT_BSS start, end + ldr r0, =\start + ldr r1, =\end + movs r3, #0 + bl LoopFillZerobss +.endm + +/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */ +.macro INIT_DATA start, end, src + ldr r0, =\start + ldr r1, =\end + ldr r2, =\src + movs r3, #0 + bl LoopCopyDataInit +.endm + +.section .text.data_initializers +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + bx lr + +FillZerobss: + str r3, [r0] + adds r0, r0, #4 + +LoopFillZerobss: + cmp r0, r1 + bcc FillZerobss + bx lr + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + mov sp, r0 /* set stack pointer */ +/* Call the clock system intitialization function.*/ + bl SystemInit + +/* Copy the data segment initializers from flash to SRAM */ + INIT_DATA _sdata, _edata, _sidata + +/* Zero fill the bss segments. */ + INIT_BSS _sbss, _ebss + INIT_BSS _sMB_MEM2, _eMB_MEM2 + +/* Call static constructors */ + bl __libc_init_array +/* Call the application s entry point.*/ + bl main + +LoopForever: + b LoopForever + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex-M4. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_PVM_IRQHandler + .word TAMP_STAMP_LSECSS_IRQHandler + .word RTC_WKUP_IRQHandler + .word FLASH_IRQHandler + .word RCC_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word DMA1_Channel5_IRQHandler + .word DMA1_Channel6_IRQHandler + .word DMA1_Channel7_IRQHandler + .word ADC1_IRQHandler + .word USB_HP_IRQHandler + .word USB_LP_IRQHandler + .word C2SEV_PWR_C2H_IRQHandler + .word COMP_IRQHandler + .word EXTI9_5_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_TIM16_IRQHandler + .word TIM1_TRG_COM_TIM17_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word PKA_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word USART1_IRQHandler + .word LPUART1_IRQHandler + .word SAI1_IRQHandler + .word TSC_IRQHandler + .word EXTI15_10_IRQHandler + .word RTC_Alarm_IRQHandler + .word CRS_IRQHandler + .word PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .word IPCC_C1_RX_IRQHandler + .word IPCC_C1_TX_IRQHandler + .word HSEM_IRQHandler + .word LPTIM1_IRQHandler + .word LPTIM2_IRQHandler + .word LCD_IRQHandler + .word QUADSPI_IRQHandler + .word AES1_IRQHandler + .word AES2_IRQHandler + .word RNG_IRQHandler + .word FPU_IRQHandler + .word DMA2_Channel1_IRQHandler + .word DMA2_Channel2_IRQHandler + .word DMA2_Channel3_IRQHandler + .word DMA2_Channel4_IRQHandler + .word DMA2_Channel5_IRQHandler + .word DMA2_Channel6_IRQHandler + .word DMA2_Channel7_IRQHandler + .word DMAMUX1_OVR_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak TAMP_STAMP_LSECSS_IRQHandler + .thumb_set TAMP_STAMP_LSECSS_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_IRQHandler + .thumb_set DMA1_Channel2_IRQHandler,Default_Handler + + .weak DMA1_Channel3_IRQHandler + .thumb_set DMA1_Channel3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_IRQHandler + .thumb_set DMA1_Channel4_IRQHandler,Default_Handler + + .weak DMA1_Channel5_IRQHandler + .thumb_set DMA1_Channel5_IRQHandler,Default_Handler + + .weak DMA1_Channel6_IRQHandler + .thumb_set DMA1_Channel6_IRQHandler,Default_Handler + + .weak DMA1_Channel7_IRQHandler + .thumb_set DMA1_Channel7_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak USB_HP_IRQHandler + .thumb_set USB_HP_IRQHandler,Default_Handler + + .weak USB_LP_IRQHandler + .thumb_set USB_LP_IRQHandler,Default_Handler + + .weak C2SEV_PWR_C2H_IRQHandler + .thumb_set C2SEV_PWR_C2H_IRQHandler,Default_Handler + + .weak COMP_IRQHandler + .thumb_set COMP_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM16_IRQHandler + .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_TIM17_IRQHandler + .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak TSC_IRQHandler + .thumb_set TSC_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .thumb_set PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,Default_Handler + + .weak IPCC_C1_RX_IRQHandler + .thumb_set IPCC_C1_RX_IRQHandler,Default_Handler + + .weak IPCC_C1_TX_IRQHandler + .thumb_set IPCC_C1_TX_IRQHandler,Default_Handler + + .weak HSEM_IRQHandler + .thumb_set HSEM_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak LCD_IRQHandler + .thumb_set LCD_IRQHandler,Default_Handler + + .weak QUADSPI_IRQHandler + .thumb_set QUADSPI_IRQHandler,Default_Handler + + .weak AES1_IRQHandler + .thumb_set AES1_IRQHandler,Default_Handler + + .weak AES2_IRQHandler + .thumb_set AES2_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak DMA2_Channel1_IRQHandler + .thumb_set DMA2_Channel1_IRQHandler,Default_Handler + + .weak DMA2_Channel2_IRQHandler + .thumb_set DMA2_Channel2_IRQHandler,Default_Handler + + .weak DMA2_Channel3_IRQHandler + .thumb_set DMA2_Channel3_IRQHandler,Default_Handler + + .weak DMA2_Channel4_IRQHandler + .thumb_set DMA2_Channel4_IRQHandler,Default_Handler + + .weak DMA2_Channel5_IRQHandler + .thumb_set DMA2_Channel5_IRQHandler,Default_Handler + + .weak DMA2_Channel6_IRQHandler + .thumb_set DMA2_Channel6_IRQHandler,Default_Handler + + .weak DMA2_Channel7_IRQHandler + .thumb_set DMA2_Channel7_IRQHandler,Default_Handler + + .weak DMAMUX1_OVR_IRQHandler + .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/stm32wb55xx_flash_cm4.ld b/firmware/targets/f7/cube/stm32wb55xx_flash_cm4.ld new file mode 100644 index 00000000..fc975f4a --- /dev/null +++ b/firmware/targets/f7/cube/stm32wb55xx_flash_cm4.ld @@ -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. +** +***************************************************************************** +** +**

© COPYRIGHT(c) 2019 Ac6

+** +** 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 = 0x400; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 +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 +} + + diff --git a/firmware/targets/f7/furi-hal/furi-hal-boot.c b/firmware/targets/f7/furi-hal/furi-hal-boot.c new file mode 100644 index 00000000..978711c5 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-boot.c @@ -0,0 +1,31 @@ +#include +#include +#include + +// Boot request enum +#define BOOT_REQUEST_TAINTED 0x00000000 +#define BOOT_REQUEST_CLEAN 0xDADEDADE +#define BOOT_REQUEST_DFU 0xDF00B000 + +void furi_hal_boot_init() { +#ifndef DEBUG + LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_TAINTED); +#endif + FURI_LOG_I("FuriHalBoot", "Init OK"); +} + +void furi_hal_boot_set_mode(FuriHalBootMode mode) { + if (mode == FuriHalBootModeNormal) { + LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_CLEAN); + } else if (mode == FuriHalBootModeDFU) { + LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU); + } +} + +void furi_hal_boot_set_flags(FuriHalBootFlag flags) { + LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR2, flags); +} + +FuriHalBootFlag furi_hal_boot_get_flags() { + return LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR2); +} \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-bt.c b/firmware/targets/f7/furi-hal/furi-hal-bt.c new file mode 100644 index 00000000..f40f9601 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-bt.c @@ -0,0 +1,144 @@ +#include +#include +#include +#include +#include +#include +#include + +void furi_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 furi_hal_bt_start_app() { + return APP_BLE_Start(); +} + +void furi_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 furi_hal_bt_is_alive() { + return APPE_Status() == BleGlueStatusStarted; +} + +bool furi_hal_bt_wait_startup() { + uint8_t counter = 0; + while (APPE_Status() == BleGlueStatusStartup) { + osDelay(10); + counter++; + if (counter > 1000) { + return false; + } + } + return true; +} + +bool furi_hal_bt_lock_flash() { + if (!furi_hal_bt_wait_startup()) { + 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 furi_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 furi_hal_bt_start_tone_tx(uint8_t channel, uint8_t power) { + aci_hal_set_tx_power_level(0, power); + aci_hal_tone_start(channel, 0); +} + +void furi_hal_bt_stop_tone_tx() { + aci_hal_tone_stop(); +} + +void furi_hal_bt_start_packet_tx(uint8_t channel, uint8_t pattern, uint8_t datarate) { + hci_le_enhanced_transmitter_test(channel, 0x25, pattern, datarate); +} + +void furi_hal_bt_start_packet_rx(uint8_t channel, uint8_t datarate) { + hci_le_enhanced_receiver_test(channel, datarate, 0); +} + +uint16_t furi_hal_bt_stop_packet_test() { + uint16_t num_of_packets = 0; + hci_le_test_end(&num_of_packets); + return num_of_packets; +} + +void furi_hal_bt_start_rx(uint8_t channel) { + aci_hal_rx_start(channel); +} + +float furi_hal_bt_get_rssi() { + float val; + uint8_t rssi_raw[3]; + + if (aci_hal_read_raw_rssi(rssi_raw) != BLE_STATUS_SUCCESS) { + return 0.0f; + } + + // Some ST magic with rssi + uint8_t agc = rssi_raw[2] & 0xFF; + int rssi = (((int)rssi_raw[1] << 8) & 0xFF00) + (rssi_raw[0] & 0xFF); + if(rssi == 0 || agc > 11) { + val = -127.0; + } else { + val = agc * 6.0f - 127.0f; + while(rssi > 30) { + val += 6.0; + rssi >>=1; + } + val += (417 * rssi + 18080) >> 10; + } + return val; +} + +uint32_t furi_hal_bt_get_transmitted_packets() { + uint32_t packets = 0; + aci_hal_le_tx_test_packet_number(&packets); + return packets; +} + +void furi_hal_bt_stop_rx() { + aci_hal_rx_stop(); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-clock.c b/firmware/targets/f7/furi-hal/furi-hal-clock.c new file mode 100644 index 00000000..0ed918e3 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-clock.c @@ -0,0 +1,141 @@ +#include + +#include +#include +#include +#include + +#define HS_CLOCK_IS_READY() (LL_RCC_HSE_IsReady() && LL_RCC_HSI_IsReady()) +#define LS_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady()) + +void furi_hal_clock_init() { + /* Prepare Flash memory for 64mHz system clock */ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); + while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_3); + + /* HSE and HSI configuration and activation */ + LL_RCC_HSE_SetCapacitorTuning(0x26); + LL_RCC_HSE_Enable(); + LL_RCC_HSI_Enable(); + while(!HS_CLOCK_IS_READY()); + LL_RCC_HSE_EnableCSS(); + + /* LSE and LSI1 configuration and activation */ + LL_PWR_EnableBkUpAccess(); + LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH); + LL_RCC_LSE_Enable(); + LL_RCC_LSI1_Enable(); + while(!LS_CLOCK_IS_READY()); + LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_18); /* Why? Because that's why. See RM0434, Table 61. CPU1 vector table. */ + LL_EXTI_EnableRisingTrig_0_31(LL_EXTI_LINE_18); + LL_RCC_EnableIT_LSECSS(); + LL_RCC_LSE_EnableCSS(); + + /* Main PLL configuration and activation */ + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 8, LL_RCC_PLLR_DIV_2); + LL_RCC_PLL_Enable(); + LL_RCC_PLL_EnableDomain_SYS(); + while(LL_RCC_PLL_IsReady() != 1); + + LL_RCC_PLLSAI1_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 6, LL_RCC_PLLSAI1Q_DIV_2); + LL_RCC_PLLSAI1_ConfigDomain_ADC(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 6, LL_RCC_PLLSAI1R_DIV_2); + LL_RCC_PLLSAI1_Enable(); + LL_RCC_PLLSAI1_EnableDomain_48M(); + LL_RCC_PLLSAI1_EnableDomain_ADC(); + while(LL_RCC_PLLSAI1_IsReady() != 1); + + /* Sysclk activation on the main PLL */ + /* Set CPU1 prescaler*/ + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + + /* Set CPU2 prescaler*/ + LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL); + + /* Set AHB SHARED prescaler*/ + LL_RCC_SetAHB4Prescaler(LL_RCC_SYSCLK_DIV_1); + + /* Set APB1 prescaler*/ + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + + /* Set APB2 prescaler*/ + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); + + /* Disable MSI */ + LL_RCC_MSI_Disable(); + while(LL_RCC_MSI_IsReady() != 0); + + /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */ + LL_SetSystemCoreClock(64000000); + + /* Update the time base */ + if (HAL_InitTick (TICK_INT_PRIORITY) != HAL_OK) { + Error_Handler(); + } + + if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) { + LL_RCC_ForceBackupDomainReset(); + LL_RCC_ReleaseBackupDomainReset(); + LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); + } + + LL_RCC_EnableRTC(); + + LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); + LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1); + LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); + LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); + LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1); + LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_PLLSAI1); + LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); + LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1); + LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); + + // AHB1 + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); + + // AHB2 + 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); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + + // APB1 + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + + // APB2 + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); +} + +void furi_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 furi_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); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-clock.h b/firmware/targets/f7/furi-hal/furi-hal-clock.h new file mode 100644 index 00000000..3ec59205 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-clock.h @@ -0,0 +1,10 @@ +#pragma once + +/** Initialize clocks */ +void furi_hal_clock_init(); + +/** Switch to HSI clock */ +void furi_hal_clock_switch_to_hsi(); + +/** Switch to PLL clock */ +void furi_hal_clock_switch_to_pll(); diff --git a/firmware/targets/f7/furi-hal/furi-hal-console.c b/firmware/targets/f7/furi-hal/furi-hal-console.c new file mode 100644 index 00000000..6c67e0c8 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-console.c @@ -0,0 +1,73 @@ +#include + +#include +#include +#include +#include + +#include + +volatile bool furi_hal_console_alive = false; + +void furi_hal_console_init() { + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + LL_USART_InitTypeDef USART_InitStruct = {0}; + USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; + USART_InitStruct.BaudRate = 230400; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; + LL_USART_Init(USART1, &USART_InitStruct); + LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_2); + LL_USART_EnableFIFO(USART1); + LL_USART_ConfigAsyncMode(USART1); + + LL_USART_Enable(USART1); + + while(!LL_USART_IsActiveFlag_TEACK(USART1)) ; + furi_hal_console_alive = true; + + FURI_LOG_I("FuriHalConsole", "Init OK"); +} + +void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { + if (!furi_hal_console_alive) + return; + + while(buffer_size > 0) { + while (!LL_USART_IsActiveFlag_TXE(USART1)); + + LL_USART_TransmitData8(USART1, *buffer); + + buffer++; + buffer_size--; + } + + /* Wait for TC flag to be raised for last char */ + while (!LL_USART_IsActiveFlag_TC(USART1)); +} + +void furi_hal_console_printf(const char format[], ...) { + string_t string; + va_list args; + va_start(args, format); + string_init_vprintf(string, format, args); + va_end(args); + furi_hal_console_tx((const uint8_t*)string_get_cstr(string), string_size(string)); + string_clear(string); +} + +void furi_hal_console_puts(const char *data) { + furi_hal_console_tx((const uint8_t*)data, strlen(data)); +} \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-console.h b/firmware/targets/f7/furi-hal/furi-hal-console.h new file mode 100644 index 00000000..26ca4540 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-console.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void furi_hal_console_init(); + +void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size); + +/** + * Printf-like plain uart interface + * @warning Will not work in ISR context + * @param format + * @param ... + */ +void furi_hal_console_printf(const char format[], ...); + +void furi_hal_console_puts(const char* data); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/furi-hal/furi-hal-delay.c b/firmware/targets/f7/furi-hal/furi-hal-delay.c new file mode 100644 index 00000000..52de8715 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-delay.c @@ -0,0 +1,34 @@ +#include "furi-hal-delay.h" + +#include +#include + +static uint32_t clk_per_microsecond; + +void furi_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; + FURI_LOG_I("FuriHalDelay", "Init OK"); +} + +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); +} + +uint32_t millis(void){ + return HAL_GetTick(); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-flash.c b/firmware/targets/f7/furi-hal/furi-hal-flash.c new file mode 100644 index 00000000..5346965f --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-flash.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +/* Free flash space borders, exported by linker */ +extern const void __free_flash_start__; + +#define FURI_HAL_FLASH_READ_BLOCK 8 +#define FURI_HAL_FLASH_WRITE_BLOCK 8 +#define FURI_HAL_FLASH_PAGE_SIZE 4096 +#define FURI_HAL_FLASH_CYCLES_COUNT 10000 + +size_t furi_hal_flash_get_base() { + return FLASH_BASE; +} + +size_t furi_hal_flash_get_read_block_size() { + return FURI_HAL_FLASH_READ_BLOCK; +} + +size_t furi_hal_flash_get_write_block_size() { + return FURI_HAL_FLASH_WRITE_BLOCK; +} + +size_t furi_hal_flash_get_page_size() { + return FURI_HAL_FLASH_PAGE_SIZE; +} + +size_t furi_hal_flash_get_cycles_count() { + return FURI_HAL_FLASH_CYCLES_COUNT; +} + +const void* furi_hal_flash_get_free_start_address() { + return &__free_flash_start__; +} + +const void* furi_hal_flash_get_free_end_address() { + FLASH_OBProgramInitTypeDef pOBInit; + HAL_FLASHEx_OBGetConfig(&pOBInit); + return (const void *)pOBInit.SecureFlashStartAddr; +} + +size_t furi_hal_flash_get_free_page_start_address() { + size_t start = (size_t)furi_hal_flash_get_free_start_address(); + size_t page_start = start - start % FURI_HAL_FLASH_PAGE_SIZE; + if (page_start != start) { + page_start += FURI_HAL_FLASH_PAGE_SIZE; + } + return page_start; +} + +size_t furi_hal_flash_get_free_page_count() { + size_t end = (size_t)furi_hal_flash_get_free_end_address(); + size_t page_start = (size_t)furi_hal_flash_get_free_page_start_address(); + return (end-page_start) / FURI_HAL_FLASH_PAGE_SIZE; +} + +bool furi_hal_flash_erase(uint8_t page, uint8_t count) { + if (!furi_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); + furi_hal_bt_unlock_flash(); + return status == HAL_OK; +} + +bool furi_hal_flash_write_dword(size_t address, uint64_t data) { + if (!furi_hal_bt_lock_flash()) { + return false; + } + HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data); + furi_hal_bt_unlock_flash(); + return status == HAL_OK; +} + +bool furi_hal_flash_write_dword_from(size_t address, size_t source_address) { + if (!furi_hal_bt_lock_flash()) { + return false; + } + HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address); + furi_hal_bt_unlock_flash(); + return status == HAL_OK; +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-flash.h b/firmware/targets/f7/furi-hal/furi-hal-flash.h new file mode 100644 index 00000000..3ef9b730 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-flash.h @@ -0,0 +1,74 @@ +#pragma once + +#include +#include +#include + +/** Get flash base address + * @return pointer to flash base + */ +size_t furi_hal_flash_get_base(); + +/** Get flash read block size + * @return size in bytes + */ +size_t furi_hal_flash_get_read_block_size(); + +/** Get flash write block size + * @return size in bytes + */ +size_t furi_hal_flash_get_write_block_size(); + +/** Get flash page size + * @return size in bytes + */ +size_t furi_hal_flash_get_page_size(); + +/** Get expected flash cycles count + * @return count of erase-write operations + */ +size_t furi_hal_flash_get_cycles_count(); + +/** Get free flash start address + * @return pointer to free region start + */ +const void* furi_hal_flash_get_free_start_address(); + +/** Get free flash end address + * @return pointer to free region end + */ +const void* furi_hal_flash_get_free_end_address(); + +/** Get first free page start address + * @return first free page memory address + */ +size_t furi_hal_flash_get_free_page_start_address(); + +/** Get free page count + * @return free page count + */ +size_t furi_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 furi_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 furi_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 furi_hal_flash_write_dword_from(size_t address, size_t source_address); diff --git a/firmware/targets/f7/furi-hal/furi-hal-gpio.c b/firmware/targets/f7/furi-hal/furi-hal-gpio.c new file mode 100644 index 00000000..1de1657f --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-gpio.c @@ -0,0 +1,299 @@ +#include +#include +#include + +#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_simple(const GpioPin* gpio, const GpioMode mode) { + hal_gpio_init(gpio, mode, GpioPullNo, GpioSpeedLow); +} + +void hal_gpio_init( + const GpioPin* gpio, + const GpioMode mode, + const GpioPull pull, + const GpioSpeed speed) { + // we cannot set alternate mode in this function + furi_assert(mode != GpioModeAltFunctionPushPull); + furi_assert(mode != GpioModeAltFunctionOpenDrain); + + hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused); +} + +void hal_gpio_init_ex( + const GpioPin* gpio, + const GpioMode mode, + const GpioPull pull, + const GpioSpeed speed, + const GpioAltFn alt_fn) { + 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); + } + } + + if(mode == GpioModeAltFunctionPushPull || mode == GpioModeAltFunctionOpenDrain) { + // 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); + furi_assert(gpio_interrupt[pin_num].callback == NULL); + 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(furi_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 +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-gpio.h b/firmware/targets/f7/furi-hal/furi-hal-gpio.h new file mode 100644 index 00000000..a81afb39 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-gpio.h @@ -0,0 +1,264 @@ +#pragma once +#include "main.h" +#include "stdbool.h" +#include +#include +#include + +#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 */ + + GpioAltFnUnused = 16, /*!< just dummy value */ +} GpioAltFn; + +/** + * Gpio structure + */ +typedef struct { + GPIO_TypeDef* port; + uint16_t pin; +} GpioPin; + +/** + * GPIO initialization function, simple version + * @param gpio GpioPin + * @param mode GpioMode + */ +void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); + +/** + * GPIO initialization function, normal version + * @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 function, extended version + * @param gpio GpioPin + * @param mode GpioMode + * @param pull GpioPull + * @param speed GpioSpeed + * @param alt_fn GpioAltFn + */ +void hal_gpio_init_ex( + 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 diff --git a/firmware/targets/f7/furi-hal/furi-hal-i2c.c b/firmware/targets/f7/furi-hal/furi-hal-i2c.c new file mode 100644 index 00000000..196a2a7b --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-i2c.c @@ -0,0 +1,152 @@ +#include +#include + +#include +#include +#include +#include + +osMutexId_t furi_hal_i2c_mutex = NULL; + +void furi_hal_i2c_init() { + furi_hal_i2c_mutex = osMutexNew(NULL); + furi_check(furi_hal_i2c_mutex); + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); + + 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); + + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + 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; + if (furi_hal_version_get_hw_version() > 10) { + I2C_InitStruct.Timing = POWER_I2C_TIMINGS_400; + } else { + I2C_InitStruct.Timing = POWER_I2C_TIMINGS_100; + } + LL_I2C_Init(POWER_I2C, &I2C_InitStruct); + LL_I2C_EnableAutoEndMode(POWER_I2C); + LL_I2C_SetOwnAddress2(POWER_I2C, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(POWER_I2C); + LL_I2C_DisableGeneralCall(POWER_I2C); + LL_I2C_EnableClockStretching(POWER_I2C); + FURI_LOG_I("FuriHalI2C", "Init OK"); +} + +bool furi_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 furi_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 furi_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(furi_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && + furi_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { + return true; + } else { + return false; + } +} + +void furi_hal_i2c_lock() { + furi_check(osMutexAcquire(furi_hal_i2c_mutex, osWaitForever) == osOK); +} + +void furi_hal_i2c_unlock() { + furi_check(osMutexRelease(furi_hal_i2c_mutex) == osOK); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-ibutton.c b/firmware/targets/f7/furi-hal/furi-hal-ibutton.c new file mode 100644 index 00000000..6e3c8bee --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-ibutton.c @@ -0,0 +1,24 @@ +#include +#include + +void furi_hal_ibutton_start() { + furi_hal_ibutton_pin_high(); + hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioSpeedLow, GpioPullNo); +} + +void furi_hal_ibutton_stop() { + furi_hal_ibutton_pin_high(); + hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioSpeedLow, GpioPullNo); +} + +void furi_hal_ibutton_pin_low() { + hal_gpio_write(&ibutton_gpio, false); +} + +void furi_hal_ibutton_pin_high() { + hal_gpio_write(&ibutton_gpio, true); +} + +bool furi_hal_ibutton_pin_get_level() { + return hal_gpio_read(&ibutton_gpio); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-interrupt.c b/firmware/targets/f7/furi-hal/furi-hal-interrupt.c new file mode 100644 index 00000000..69cdc4b6 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-interrupt.c @@ -0,0 +1,208 @@ +#include "furi-hal-interrupt.h" + +#include +#include +#include + +volatile FuriHalInterruptISR furi_hal_tim_tim2_isr = NULL; +volatile FuriHalInterruptISR furi_hal_tim_tim1_isr = NULL; + +#define FURI_HAL_INTERRUPT_DMA_COUNT 2 +#define FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT 8 + +volatile FuriHalInterruptISR furi_hal_dma_channel_isr[FURI_HAL_INTERRUPT_DMA_COUNT][FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT] = {0}; + +void furi_hal_interrupt_init() { + NVIC_SetPriority(RCC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); + NVIC_EnableIRQ(RCC_IRQn); + + NVIC_SetPriority(TAMP_STAMP_LSECSS_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); + NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn); + + NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(DMA1_Channel1_IRQn); + + FURI_LOG_I("FuriHalInterrupt", "Init OK"); +} + +void furi_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, FuriHalInterruptISR isr) { + if (timer == TIM2) { + if (isr) { + furi_assert(furi_hal_tim_tim2_isr == NULL); + } else { + furi_assert(furi_hal_tim_tim2_isr != NULL); + } + furi_hal_tim_tim2_isr = isr; + } else if (timer == TIM1) { + if (isr) { + furi_assert(furi_hal_tim_tim1_isr == NULL); + } else { + furi_assert(furi_hal_tim_tim1_isr != NULL); + } + furi_hal_tim_tim1_isr = isr; + } else { + furi_check(0); + } +} + +void furi_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, FuriHalInterruptISR isr) { + --channel; // Pascal + furi_check(dma); + furi_check(channel < FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT); + if (dma == DMA1) { + furi_hal_dma_channel_isr[0][channel] = isr; + } else if (dma == DMA2) { + furi_hal_dma_channel_isr[1][channel] = isr; + } else { + furi_check(0); + } +} + +extern void api_interrupt_call(InterruptType type, void* hw); + +/* ST HAL symbols */ + +/* Comparator trigger event */ +void HAL_COMP_TriggerCallback(COMP_HandleTypeDef* hcomp) { + api_interrupt_call(InterruptTypeComparatorTrigger, hcomp); +} + +/* Timer update event */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) { + api_interrupt_call(InterruptTypeTimerUpdate, htim); +} + +/* Timer 2 */ +void TIM2_IRQHandler(void) { + if (furi_hal_tim_tim2_isr) { + furi_hal_tim_tim2_isr(); + } else { + HAL_TIM_IRQHandler(&htim2); + } +} + +/* Timer 1 Update */ +void TIM1_UP_TIM16_IRQHandler(void) { + if (furi_hal_tim_tim1_isr) { + furi_hal_tim_tim1_isr(); + } else { + HAL_TIM_IRQHandler(&htim1); + } +} + +/* DMA 1 */ +void DMA1_Channel1_IRQHandler(void) { + if (furi_hal_dma_channel_isr[0][0]) furi_hal_dma_channel_isr[0][0](); +} + +void DMA1_Channel2_IRQHandler(void) { + if (furi_hal_dma_channel_isr[0][1]) furi_hal_dma_channel_isr[0][1](); +} + +void DMA1_Channel3_IRQHandler(void) { + if (furi_hal_dma_channel_isr[0][2]) furi_hal_dma_channel_isr[0][2](); +} + +void DMA1_Channel4_IRQHandler(void) { + if (furi_hal_dma_channel_isr[0][3]) furi_hal_dma_channel_isr[0][3](); +} + +void DMA1_Channel5_IRQHandler(void) { + if (furi_hal_dma_channel_isr[0][4]) furi_hal_dma_channel_isr[0][4](); +} + +void DMA1_Channel6_IRQHandler(void) { + if (furi_hal_dma_channel_isr[0][5]) furi_hal_dma_channel_isr[0][5](); +} + +void DMA1_Channel7_IRQHandler(void) { + if (furi_hal_dma_channel_isr[0][6]) furi_hal_dma_channel_isr[0][6](); +} + +void DMA1_Channel8_IRQHandler(void) { + if (furi_hal_dma_channel_isr[0][7]) furi_hal_dma_channel_isr[0][7](); +} + +/* DMA 2 */ +void DMA2_Channel1_IRQHandler(void) { + if (furi_hal_dma_channel_isr[1][0]) furi_hal_dma_channel_isr[1][0](); +} + +void DMA2_Channel2_IRQHandler(void) { + if (furi_hal_dma_channel_isr[1][1]) furi_hal_dma_channel_isr[1][1](); +} + +void DMA2_Channel3_IRQHandler(void) { + if (furi_hal_dma_channel_isr[1][2]) furi_hal_dma_channel_isr[1][2](); +} + +void DMA2_Channel4_IRQHandler(void) { + if (furi_hal_dma_channel_isr[1][3]) furi_hal_dma_channel_isr[1][3](); +} + +void DMA2_Channel5_IRQHandler(void) { + if (furi_hal_dma_channel_isr[1][4]) furi_hal_dma_channel_isr[1][4](); +} + +void DMA2_Channel6_IRQHandler(void) { + if (furi_hal_dma_channel_isr[1][5]) furi_hal_dma_channel_isr[1][5](); +} + +void DMA2_Channel7_IRQHandler(void) { + if (furi_hal_dma_channel_isr[1][6]) furi_hal_dma_channel_isr[1][6](); +} + +void DMA2_Channel8_IRQHandler(void) { + if (furi_hal_dma_channel_isr[1][7]) furi_hal_dma_channel_isr[1][7](); +} + + +void TAMP_STAMP_LSECSS_IRQHandler(void) { + if (LL_RCC_IsActiveFlag_LSECSS()) { + LL_RCC_ClearFlag_LSECSS(); + if (!LL_RCC_LSE_IsReady()) { + FURI_LOG_E("FuriHalInterrupt", "LSE CSS fired: resetting system"); + NVIC_SystemReset(); + } else { + FURI_LOG_E("FuriHalInterrupt", "LSE CSS fired: but LSE is alive"); + } + } +} + +void RCC_IRQHandler(void) { +} + + +void NMI_Handler(void) { + if (LL_RCC_IsActiveFlag_HSECSS()) { + LL_RCC_ClearFlag_HSECSS(); + FURI_LOG_E("FuriHalInterrupt", "HSE CSS fired: resetting system"); + NVIC_SystemReset(); + } +} + +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) { + +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-interrupt.h b/firmware/targets/f7/furi-hal/furi-hal-interrupt.h new file mode 100644 index 00000000..693924e6 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-interrupt.h @@ -0,0 +1,34 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Timer ISR */ +typedef void (*FuriHalInterruptISR)(); + +/** Initialize interrupt subsystem */ +void furi_hal_interrupt_init(); + +/** Set DMA Channel ISR + * We don't clear interrupt flags for you, do it by your self. + * @param dma - DMA instance + * @param channel - DMA channel + * @param isr - your interrupt service routine or use NULL to clear + */ +void furi_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, FuriHalInterruptISR isr); + +/** Set Timer ISR + * By default ISR is serviced by ST HAL. Use this function to override it. + * We don't clear interrupt flags for you, do it by your self. + * @param timer - timer instance + * @param isr - your interrupt service routine or use NULL to clear + */ +void furi_hal_interrupt_set_timer_isr(TIM_TypeDef *timer, FuriHalInterruptISR isr); + + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/furi-hal/furi-hal-irda.c b/firmware/targets/f7/furi-hal/furi-hal-irda.c new file mode 100644 index 00000000..a148b44a --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-irda.c @@ -0,0 +1,639 @@ +#include "furi-hal-irda.h" +#include "furi-hal-delay.h" +#include "furi/check.h" +#include "stm32wbxx_ll_dma.h" +#include "sys/_stdint.h" +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#define IRDA_TX_DEBUG 0 + +#if IRDA_TX_DEBUG == 1 +#define gpio_irda_tx gpio_irda_tx_debug +const GpioPin gpio_irda_tx_debug = {.port = GPIOA, .pin = GPIO_PIN_7}; +#endif + +#define IRDA_TIM_TX_DMA_BUFFER_SIZE 200 +#define IRDA_POLARITY_SHIFT 1 + +#define IRDA_TX_CCMR_HIGH (TIM_CCMR2_OC3PE | LL_TIM_OCMODE_PWM2) /* Mark time - enable PWM2 mode */ +#define IRDA_TX_CCMR_LOW (TIM_CCMR2_OC3PE | LL_TIM_OCMODE_FORCED_INACTIVE) /* Space time - force low */ + +typedef struct{ + FuriHalIrdaRxCaptureCallback capture_callback; + void *capture_context; + FuriHalIrdaRxTimeoutCallback timeout_callback; + void *timeout_context; +} IrdaTimRx; + +typedef struct{ + uint8_t* polarity; + uint16_t* data; + size_t size; + bool packet_end; + bool last_packet_end; +} IrdaTxBuf; + +typedef struct { + float cycle_duration; + FuriHalIrdaTxGetDataISRCallback data_callback; + FuriHalIrdaTxSignalSentISRCallback signal_sent_callback; + void* data_context; + void* signal_sent_context; + IrdaTxBuf buffer[2]; + osSemaphoreId_t stop_semaphore; + uint32_t tx_timing_rest_duration; /** if timing is too long (> 0xFFFF), send it in few iterations */ + bool tx_timing_rest_level; + FuriHalIrdaTxGetDataState tx_timing_rest_status; +} IrdaTimTx; + +typedef enum { + IrdaStateIdle, /** Furi Hal Irda is ready to start RX or TX */ + IrdaStateAsyncRx, /** Async RX started */ + IrdaStateAsyncTx, /** Async TX started, DMA and timer is on */ + IrdaStateAsyncTxStopReq, /** Async TX started, async stop request received */ + IrdaStateAsyncTxStopInProgress, /** Async TX started, stop request is processed and we wait for last data to be sent */ + IrdaStateAsyncTxStopped, /** Async TX complete, cleanup needed */ + IrdaStateMAX, +} IrdaState; + +static volatile IrdaState furi_hal_irda_state = IrdaStateIdle; +static IrdaTimTx irda_tim_tx; +static IrdaTimRx irda_tim_rx; + +static void furi_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift); +static void furi_hal_irda_async_tx_free_resources(void); +static void furi_hal_irda_tx_dma_set_polarity(uint8_t buf_num, uint8_t polarity_shift); +static void furi_hal_irda_tx_dma_set_buffer(uint8_t buf_num); +static void furi_hal_irda_tx_fill_buffer_last(uint8_t buf_num); +static uint8_t furi_hal_irda_get_current_dma_tx_buffer(void); +static void furi_hal_irda_tx_dma_polarity_isr(); +static void furi_hal_irda_tx_dma_isr(); + +static void furi_hal_irda_tim_rx_isr() { + static uint32_t previous_captured_ch2 = 0; + + /* Timeout */ + if(LL_TIM_IsActiveFlag_CC3(TIM2)) { + LL_TIM_ClearFlag_CC3(TIM2); + furi_assert(furi_hal_irda_state == IrdaStateAsyncRx); + + /* Timers CNT register starts to counting from 0 to ARR, but it is + * reseted when Channel 1 catches interrupt. It is not reseted by + * channel 2, though, so we have to distract it's values (see TimerIRQSourceCCI1 ISR). + * This can cause false timeout: when time is over, but we started + * receiving new signal few microseconds ago, because CNT register + * is reseted once per period, not per sample. */ + if (LL_GPIO_IsInputPinSet(gpio_irda_rx.port, gpio_irda_rx.pin) != 0) { + if (irda_tim_rx.timeout_callback) + irda_tim_rx.timeout_callback(irda_tim_rx.timeout_context); + } + } + + /* Rising Edge */ + if(LL_TIM_IsActiveFlag_CC1(TIM2)) { + LL_TIM_ClearFlag_CC1(TIM2); + furi_assert(furi_hal_irda_state == IrdaStateAsyncRx); + + if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC1S)) { + /* Low pin level is a Mark state of IRDA signal. Invert level for further processing. */ + uint32_t duration = LL_TIM_IC_GetCaptureCH1(TIM2) - previous_captured_ch2; + if (irda_tim_rx.capture_callback) + irda_tim_rx.capture_callback(irda_tim_rx.capture_context, 1, duration); + } else { + furi_assert(0); + } + } + + /* Falling Edge */ + if(LL_TIM_IsActiveFlag_CC2(TIM2)) { + LL_TIM_ClearFlag_CC2(TIM2); + furi_assert(furi_hal_irda_state == IrdaStateAsyncRx); + + if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC2S)) { + /* High pin level is a Space state of IRDA signal. Invert level for further processing. */ + uint32_t duration = LL_TIM_IC_GetCaptureCH2(TIM2); + previous_captured_ch2 = duration; + if (irda_tim_rx.capture_callback) + irda_tim_rx.capture_callback(irda_tim_rx.capture_context, 0, duration); + } else { + furi_assert(0); + } + } +} + +void furi_hal_irda_async_rx_start(void) { + furi_assert(furi_hal_irda_state == IrdaStateIdle); + + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + + hal_gpio_init_ex(&gpio_irda_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + TIM_InitStruct.Prescaler = 64 - 1; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 0x7FFFFFFE; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM2, &TIM_InitStruct); + + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_DisableARRPreload(TIM2); + LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_TI1FP1); + LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_RESET); + LL_TIM_CC_DisableChannel(TIM2, LL_TIM_CHANNEL_CH2); + LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); + LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING); + LL_TIM_DisableIT_TRIG(TIM2); + LL_TIM_DisableDMAReq_TRIG(TIM2); + LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET); + LL_TIM_EnableMasterSlaveMode(TIM2); + LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI); + LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); + LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); + LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING); + LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI); + LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); + + furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_irda_tim_rx_isr); + furi_hal_irda_state = IrdaStateAsyncRx; + + LL_TIM_EnableIT_CC1(TIM2); + LL_TIM_EnableIT_CC2(TIM2); + LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); + + LL_TIM_SetCounter(TIM2, 0); + LL_TIM_EnableCounter(TIM2); + + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(TIM2_IRQn); +} + +void furi_hal_irda_async_rx_stop(void) { + furi_assert(furi_hal_irda_state == IrdaStateAsyncRx); + LL_TIM_DeInit(TIM2); + furi_hal_interrupt_set_timer_isr(TIM2, NULL); + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); + furi_hal_irda_state = IrdaStateIdle; +} + +void furi_hal_irda_async_rx_set_timeout(uint32_t timeout_us) { + furi_assert(LL_APB1_GRP1_IsEnabledClock(LL_APB1_GRP1_PERIPH_TIM2)); + + LL_TIM_OC_SetCompareCH3(TIM2, timeout_us); + LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE); + LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3); + LL_TIM_EnableIT_CC3(TIM2); +} + +bool furi_hal_irda_is_busy(void) { + return furi_hal_irda_state != IrdaStateIdle; +} + +void furi_hal_irda_async_rx_set_capture_isr_callback(FuriHalIrdaRxCaptureCallback callback, void *ctx) { + irda_tim_rx.capture_callback = callback; + irda_tim_rx.capture_context = ctx; +} + +void furi_hal_irda_async_rx_set_timeout_isr_callback(FuriHalIrdaRxTimeoutCallback callback, void *ctx) { + irda_tim_rx.timeout_callback = callback; + irda_tim_rx.timeout_context = ctx; +} + +static void furi_hal_irda_tx_dma_terminate(void) { + LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_2); + LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_2); + + furi_assert(furi_hal_irda_state == IrdaStateAsyncTxStopInProgress); + + LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2); + LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); + LL_TIM_DisableCounter(TIM1); + osStatus_t status = osSemaphoreRelease(irda_tim_tx.stop_semaphore); + furi_check(status == osOK); + furi_hal_irda_state = IrdaStateAsyncTxStopped; +} + +static uint8_t furi_hal_irda_get_current_dma_tx_buffer(void) { + uint8_t buf_num = 0; + uint32_t buffer_adr = LL_DMA_GetMemoryAddress(DMA1, LL_DMA_CHANNEL_2); + if (buffer_adr == (uint32_t) irda_tim_tx.buffer[0].data) { + buf_num = 0; + } else if (buffer_adr == (uint32_t) irda_tim_tx.buffer[1].data) { + buf_num = 1; + } else { + furi_assert(0); + } + return buf_num; +} + +static void furi_hal_irda_tx_dma_polarity_isr() { + if (LL_DMA_IsActiveFlag_TE1(DMA1)) { + LL_DMA_ClearFlag_TE1(DMA1); + furi_check(0); + } + if (LL_DMA_IsActiveFlag_TC1(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_1)) { + LL_DMA_ClearFlag_TC1(DMA1); + + furi_check((furi_hal_irda_state == IrdaStateAsyncTx) + || (furi_hal_irda_state == IrdaStateAsyncTxStopReq) + || (furi_hal_irda_state == IrdaStateAsyncTxStopInProgress)); + /* actually TC2 is processed and buffer is next buffer */ + uint8_t next_buf_num = furi_hal_irda_get_current_dma_tx_buffer(); + furi_hal_irda_tx_dma_set_polarity(next_buf_num, 0); + } +} + +static void furi_hal_irda_tx_dma_isr() { + if (LL_DMA_IsActiveFlag_TE2(DMA1)) { + LL_DMA_ClearFlag_TE2(DMA1); + furi_check(0); + } + if (LL_DMA_IsActiveFlag_HT2(DMA1) && LL_DMA_IsEnabledIT_HT(DMA1, LL_DMA_CHANNEL_2)) { + LL_DMA_ClearFlag_HT2(DMA1); + uint8_t buf_num = furi_hal_irda_get_current_dma_tx_buffer(); + uint8_t next_buf_num = !buf_num; + if (irda_tim_tx.buffer[buf_num].last_packet_end) { + LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_2); + } else if (!irda_tim_tx.buffer[buf_num].packet_end || (furi_hal_irda_state == IrdaStateAsyncTx)) { + furi_hal_irda_tx_fill_buffer(next_buf_num, 0); + if (irda_tim_tx.buffer[next_buf_num].last_packet_end) { + LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_2); + } + } else if (furi_hal_irda_state == IrdaStateAsyncTxStopReq) { + /* fallthrough */ + } else { + furi_check(0); + } + } + if (LL_DMA_IsActiveFlag_TC2(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_2)) { + LL_DMA_ClearFlag_TC2(DMA1); + furi_check((furi_hal_irda_state == IrdaStateAsyncTxStopInProgress) + || (furi_hal_irda_state == IrdaStateAsyncTxStopReq) + || (furi_hal_irda_state == IrdaStateAsyncTx)); + + uint8_t buf_num = furi_hal_irda_get_current_dma_tx_buffer(); + uint8_t next_buf_num = !buf_num; + if (furi_hal_irda_state == IrdaStateAsyncTxStopInProgress) { + furi_hal_irda_tx_dma_terminate(); + } else if (irda_tim_tx.buffer[buf_num].last_packet_end + || (irda_tim_tx.buffer[buf_num].packet_end && (furi_hal_irda_state == IrdaStateAsyncTxStopReq))) { + furi_hal_irda_state = IrdaStateAsyncTxStopInProgress; + furi_hal_irda_tx_fill_buffer_last(next_buf_num); + furi_hal_irda_tx_dma_set_buffer(next_buf_num); + } else { + /* if it's not end of the packet - continue receiving */ + furi_hal_irda_tx_dma_set_buffer(next_buf_num); + } + if (irda_tim_tx.signal_sent_callback && irda_tim_tx.buffer[buf_num].packet_end && (furi_hal_irda_state != IrdaStateAsyncTxStopped)) { + irda_tim_tx.signal_sent_callback(irda_tim_tx.signal_sent_context); + } + } +} + +static void furi_hal_irda_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) +{ + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1); +/* LL_DBGMCU_APB2_GRP1_FreezePeriph(LL_DBGMCU_APB2_GRP1_TIM1_STOP); */ + + LL_TIM_DisableCounter(TIM1); + LL_TIM_SetRepetitionCounter(TIM1, 0); + LL_TIM_SetCounter(TIM1, 0); + LL_TIM_SetPrescaler(TIM1, 0); + LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP); + LL_TIM_EnableARRPreload(TIM1); + LL_TIM_SetAutoReload(TIM1, __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM1), freq)); +#if IRDA_TX_DEBUG == 1 + LL_TIM_OC_SetCompareCH1(TIM1, ( (LL_TIM_GetAutoReload(TIM1) + 1 ) * (1 - duty_cycle))); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + /* LL_TIM_OCMODE_PWM2 set by DMA */ + LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE); + LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1N); + LL_TIM_DisableIT_CC1(TIM1); +#else + LL_TIM_OC_SetCompareCH3(TIM1, ( (LL_TIM_GetAutoReload(TIM1) + 1 ) * (1 - duty_cycle))); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3); + /* LL_TIM_OCMODE_PWM2 set by DMA */ + LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE); + LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH3); + LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH3N); + LL_TIM_DisableIT_CC3(TIM1); +#endif + LL_TIM_DisableMasterSlaveMode(TIM1); + LL_TIM_EnableAllOutputs(TIM1); + LL_TIM_DisableIT_UPDATE(TIM1); + LL_TIM_EnableDMAReq_UPDATE(TIM1); + + NVIC_SetPriority(TIM1_UP_TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); +} + +static void furi_hal_irda_configure_tim_cmgr2_dma_tx(void) { + LL_C2_AHB1_GRP1_EnableClock(LL_C2_AHB1_GRP1_PERIPH_DMA1); + + LL_DMA_InitTypeDef dma_config = {0}; +#if IRDA_TX_DEBUG == 1 + dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM1->CCMR1); +#else + dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM1->CCMR2); +#endif + dma_config.MemoryOrM2MDstAddress = (uint32_t) NULL; + dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; + dma_config.Mode = LL_DMA_MODE_NORMAL; + dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + /* fill word to have other bits set to 0 */ + dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; + dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; + dma_config.NbData = 0; + dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; + dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; + LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, furi_hal_irda_tx_dma_polarity_isr); + LL_DMA_ClearFlag_TE1(DMA1); + LL_DMA_ClearFlag_TC1(DMA1); + LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); + + NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 4, 0)); + NVIC_EnableIRQ(DMA1_Channel1_IRQn); +} + +static void furi_hal_irda_configure_tim_rcr_dma_tx(void) { + LL_C2_AHB1_GRP1_EnableClock(LL_C2_AHB1_GRP1_PERIPH_DMA1); + + LL_DMA_InitTypeDef dma_config = {0}; + dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM1->RCR); + dma_config.MemoryOrM2MDstAddress = (uint32_t) NULL; + dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; + dma_config.Mode = LL_DMA_MODE_NORMAL; + dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD; + dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD; + dma_config.NbData = 0; + dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; + dma_config.Priority = LL_DMA_PRIORITY_MEDIUM; + LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, furi_hal_irda_tx_dma_isr); + LL_DMA_ClearFlag_TC2(DMA1); + LL_DMA_ClearFlag_HT2(DMA1); + LL_DMA_ClearFlag_TE2(DMA1); + LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2); + LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_2); + LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_2); + + NVIC_SetPriority(DMA1_Channel2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(DMA1_Channel2_IRQn); +} + +static void furi_hal_irda_tx_fill_buffer_last(uint8_t buf_num) { + furi_assert(buf_num < 2); + furi_assert(furi_hal_irda_state != IrdaStateAsyncRx); + furi_assert(furi_hal_irda_state < IrdaStateMAX); + furi_assert(irda_tim_tx.data_callback); + IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; + furi_assert(buffer->data != NULL); + (void)buffer->data; + furi_assert(buffer->polarity != NULL); + (void)buffer->polarity; + + irda_tim_tx.buffer[buf_num].data[0] = 0; // 1 pulse + irda_tim_tx.buffer[buf_num].polarity[0] = IRDA_TX_CCMR_LOW; + irda_tim_tx.buffer[buf_num].data[1] = 0; // 1 pulse + irda_tim_tx.buffer[buf_num].polarity[1] = IRDA_TX_CCMR_LOW; + irda_tim_tx.buffer[buf_num].size = 2; + irda_tim_tx.buffer[buf_num].last_packet_end = true; + irda_tim_tx.buffer[buf_num].packet_end = true; +} + +static void furi_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift) { + furi_assert(buf_num < 2); + furi_assert(furi_hal_irda_state != IrdaStateAsyncRx); + furi_assert(furi_hal_irda_state < IrdaStateMAX); + furi_assert(irda_tim_tx.data_callback); + IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; + furi_assert(buffer->data != NULL); + furi_assert(buffer->polarity != NULL); + + FuriHalIrdaTxGetDataState status = FuriHalIrdaTxGetDataStateOk; + uint32_t duration = 0; + bool level = 0; + size_t *size = &buffer->size; + size_t polarity_counter = 0; + while (polarity_shift--) { + buffer->polarity[polarity_counter++] = IRDA_TX_CCMR_LOW; + } + + for (*size = 0; (*size < IRDA_TIM_TX_DMA_BUFFER_SIZE) && (status == FuriHalIrdaTxGetDataStateOk);) { + if (irda_tim_tx.tx_timing_rest_duration > 0) { + if (irda_tim_tx.tx_timing_rest_duration > 0xFFFF) { + buffer->data[*size] = 0xFFFF; + status = FuriHalIrdaTxGetDataStateOk; + } else { + buffer->data[*size] = irda_tim_tx.tx_timing_rest_duration; + status = irda_tim_tx.tx_timing_rest_status; + } + irda_tim_tx.tx_timing_rest_duration -= buffer->data[*size]; + buffer->polarity[polarity_counter] = irda_tim_tx.tx_timing_rest_level ? IRDA_TX_CCMR_HIGH : IRDA_TX_CCMR_LOW; + ++(*size); + ++polarity_counter; + continue; + } + + status = irda_tim_tx.data_callback(irda_tim_tx.data_context, &duration, &level); + + uint32_t num_of_impulses = roundf(duration / irda_tim_tx.cycle_duration); + + if (num_of_impulses == 0) { + if ((*size == 0) && (status == FuriHalIrdaTxGetDataStateDone)) { + /* if this is one sample in current buffer, but we + * have more to send - continue + */ + status = FuriHalIrdaTxGetDataStateOk; + } + } else if ((num_of_impulses - 1) > 0xFFFF) { + irda_tim_tx.tx_timing_rest_duration = num_of_impulses - 1; + irda_tim_tx.tx_timing_rest_status = status; + irda_tim_tx.tx_timing_rest_level = level; + status = FuriHalIrdaTxGetDataStateOk; + } else { + buffer->polarity[polarity_counter] = level ? IRDA_TX_CCMR_HIGH : IRDA_TX_CCMR_LOW; + buffer->data[*size] = num_of_impulses - 1; + ++(*size); + ++polarity_counter; + } + } + + buffer->last_packet_end = (status == FuriHalIrdaTxGetDataStateLastDone); + buffer->packet_end = buffer->last_packet_end || (status == FuriHalIrdaTxGetDataStateDone); + + if (*size == 0) { + buffer->data[0] = 0; // 1 pulse + buffer->polarity[0] = IRDA_TX_CCMR_LOW; + buffer->size = 1; + } +} + +static void furi_hal_irda_tx_dma_set_polarity(uint8_t buf_num, uint8_t polarity_shift) { + furi_assert(buf_num < 2); + furi_assert(furi_hal_irda_state < IrdaStateMAX); + IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; + furi_assert(buffer->polarity != NULL); + + __disable_irq(); + bool channel_enabled = LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1); + if (channel_enabled) { + LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); + } + LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t) buffer->polarity); + LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, buffer->size + polarity_shift); + if (channel_enabled) { + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); + } + __enable_irq(); +} + +static void furi_hal_irda_tx_dma_set_buffer(uint8_t buf_num) { + furi_assert(buf_num < 2); + furi_assert(furi_hal_irda_state < IrdaStateMAX); + IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; + furi_assert(buffer->data != NULL); + + /* non-circular mode requires disabled channel before setup */ + __disable_irq(); + bool channel_enabled = LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_2); + if (channel_enabled) { + LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2); + } + LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)buffer->data); + LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, buffer->size); + if (channel_enabled) { + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2); + } + __enable_irq(); +} + +static void furi_hal_irda_async_tx_free_resources(void) { + furi_assert((furi_hal_irda_state == IrdaStateIdle) || (furi_hal_irda_state == IrdaStateAsyncTxStopped)); + osStatus_t status; + + hal_gpio_init(&gpio_irda_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, NULL); + LL_TIM_DeInit(TIM1); + LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_TIM1); + LL_C2_AHB1_GRP1_DisableClock(LL_C2_AHB1_GRP1_PERIPH_DMA1); + + status = osSemaphoreDelete(irda_tim_tx.stop_semaphore); + furi_check(status == osOK); + free(irda_tim_tx.buffer[0].data); + free(irda_tim_tx.buffer[1].data); + free(irda_tim_tx.buffer[0].polarity); + free(irda_tim_tx.buffer[1].polarity); + + irda_tim_tx.buffer[0].data = NULL; + irda_tim_tx.buffer[1].data = NULL; + irda_tim_tx.buffer[0].polarity = NULL; + irda_tim_tx.buffer[1].polarity = NULL; +} + +void furi_hal_irda_async_tx_start(uint32_t freq, float duty_cycle) { + if ((duty_cycle > 1) || (duty_cycle <= 0) || (freq > IRDA_MAX_FREQUENCY) || (freq < IRDA_MIN_FREQUENCY) || (irda_tim_tx.data_callback == NULL)) { + furi_check(0); + } + + furi_assert(furi_hal_irda_state == IrdaStateIdle); + furi_assert(irda_tim_tx.buffer[0].data == NULL); + furi_assert(irda_tim_tx.buffer[1].data == NULL); + furi_assert(irda_tim_tx.buffer[0].polarity == NULL); + furi_assert(irda_tim_tx.buffer[1].polarity == NULL); + + size_t alloc_size_data = IRDA_TIM_TX_DMA_BUFFER_SIZE * sizeof(uint16_t); + irda_tim_tx.buffer[0].data = furi_alloc(alloc_size_data); + irda_tim_tx.buffer[1].data = furi_alloc(alloc_size_data); + + size_t alloc_size_polarity = (IRDA_TIM_TX_DMA_BUFFER_SIZE + IRDA_POLARITY_SHIFT) * sizeof(uint8_t); + irda_tim_tx.buffer[0].polarity = furi_alloc(alloc_size_polarity); + irda_tim_tx.buffer[1].polarity = furi_alloc(alloc_size_polarity); + + irda_tim_tx.stop_semaphore = osSemaphoreNew(1, 0, NULL); + irda_tim_tx.cycle_duration = 1000000.0 / freq; + irda_tim_tx.tx_timing_rest_duration = 0; + + furi_hal_irda_tx_fill_buffer(0, IRDA_POLARITY_SHIFT); + + furi_hal_irda_configure_tim_pwm_tx(freq, duty_cycle); + furi_hal_irda_configure_tim_cmgr2_dma_tx(); + furi_hal_irda_configure_tim_rcr_dma_tx(); + furi_hal_irda_tx_dma_set_polarity(0, IRDA_POLARITY_SHIFT); + furi_hal_irda_tx_dma_set_buffer(0); + + furi_hal_irda_state = IrdaStateAsyncTx; + + LL_TIM_ClearFlag_UPDATE(TIM1); + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2); + delay_us(5); + LL_TIM_GenerateEvent_UPDATE(TIM1); /* DMA -> TIMx_RCR */ + delay_us(5); + LL_GPIO_ResetOutputPin(gpio_irda_tx.port, gpio_irda_tx.pin); /* when disable it prevents false pulse */ + hal_gpio_init_ex(&gpio_irda_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1); + + __disable_irq(); + LL_TIM_GenerateEvent_UPDATE(TIM1); /* TIMx_RCR -> Repetition counter */ + LL_TIM_EnableCounter(TIM1); + __enable_irq(); +} + +void furi_hal_irda_async_tx_wait_termination(void) { + furi_assert(furi_hal_irda_state >= IrdaStateAsyncTx); + furi_assert(furi_hal_irda_state < IrdaStateMAX); + + osStatus_t status; + status = osSemaphoreAcquire(irda_tim_tx.stop_semaphore, osWaitForever); + furi_check(status == osOK); + furi_hal_irda_async_tx_free_resources(); + furi_hal_irda_state = IrdaStateIdle; +} + +void furi_hal_irda_async_tx_stop(void) { + furi_assert(furi_hal_irda_state >= IrdaStateAsyncTx); + furi_assert(furi_hal_irda_state < IrdaStateMAX); + + __disable_irq(); + if (furi_hal_irda_state == IrdaStateAsyncTx) + furi_hal_irda_state = IrdaStateAsyncTxStopReq; + __enable_irq(); + + furi_hal_irda_async_tx_wait_termination(); +} + +void furi_hal_irda_async_tx_set_data_isr_callback(FuriHalIrdaTxGetDataISRCallback callback, void* context) { + furi_assert(furi_hal_irda_state == IrdaStateIdle); + irda_tim_tx.data_callback = callback; + irda_tim_tx.data_context = context; +} + +void furi_hal_irda_async_tx_set_signal_sent_isr_callback(FuriHalIrdaTxSignalSentISRCallback callback, void* context) { + irda_tim_tx.signal_sent_callback = callback; + irda_tim_tx.signal_sent_context = context; +} + diff --git a/firmware/targets/f7/furi-hal/furi-hal-light.c b/firmware/targets/f7/furi-hal/furi-hal-light.c new file mode 100644 index 00000000..fba1bec4 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-light.c @@ -0,0 +1,44 @@ +#include +#include + +#define LED_CURRENT_RED 50 +#define LED_CURRENT_GREEN 50 +#define LED_CURRENT_BLUE 50 +#define LED_CURRENT_WHITE 150 + +void furi_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(); + FURI_LOG_I("FuriHalLight", "Init OK"); +} + +void furi_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; + } +} \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-nfc.c b/firmware/targets/f7/furi-hal/furi-hal-nfc.c new file mode 100644 index 00000000..d92e2cad --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-nfc.c @@ -0,0 +1,174 @@ +#include "furi-hal-nfc.h" +#include + +static const uint32_t clocks_in_ms = 64 * 1000; + +void furi_hal_nfc_init() { + ReturnCode ret = rfalNfcInitialize(); + if(ret == ERR_NONE) { + furi_hal_nfc_start_sleep(); + FURI_LOG_I("FuriHalNfc", "Init OK"); + } else { + FURI_LOG_W("FuriHalNfc", "Initialization failed, RFAL returned: %d", ret); + } +} + +bool furi_hal_nfc_is_busy() { + return rfalNfcGetState() != RFAL_NFC_STATE_IDLE; +} + +void furi_hal_nfc_field_on() { + furi_hal_nfc_exit_sleep(); + st25r3916TxRxOn(); +} + +void furi_hal_nfc_field_off() { + st25r3916TxRxOff(); + furi_hal_nfc_start_sleep(); +} + +void furi_hal_nfc_start_sleep() { + rfalLowPowerModeStart(); +} + +void furi_hal_nfc_exit_sleep() { + rfalLowPowerModeStop(); +} + +bool furi_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t timeout, bool deactivate) { + furi_assert(dev_list); + furi_assert(dev_cnt); + + rfalLowPowerModeStop(); + rfalNfcState state = rfalNfcGetState(); + if(state == 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 = NULL; + + uint32_t start = DWT->CYCCNT; + rfalNfcDiscover(¶ms); + while(state != RFAL_NFC_STATE_ACTIVATED) { + rfalNfcWorker(); + state = rfalNfcGetState(); + FURI_LOG_D("HAL NFC", "Current state %d", state); + if(state == RFAL_NFC_STATE_POLL_ACTIVATION) { + start = DWT->CYCCNT; + continue; + } + if(state == RFAL_NFC_STATE_POLL_SELECT) { + rfalNfcSelect(0); + } + if(DWT->CYCCNT - start > timeout * clocks_in_ms) { + rfalNfcDeactivate(true); + FURI_LOG_D("HAL NFC", "Timeout"); + return false; + } + osThreadYield(); + } + rfalNfcGetDevicesFound(dev_list, dev_cnt); + if(deactivate) { + rfalNfcDeactivate(false); + rfalLowPowerModeStart(); + } + return true; +} + +bool furi_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, bool activate_after_sak, uint32_t timeout) { + rfalNfcState state = rfalNfcGetState(); + if(state == RFAL_NFC_STATE_NOTINIT) { + rfalNfcInitialize(); + } else if(state >= RFAL_NFC_STATE_ACTIVATED) { + rfalNfcDeactivate(false); + } + rfalLowPowerModeStop(); + rfalNfcDiscoverParam params = { + .compMode = RFAL_COMPLIANCE_MODE_NFC, + .techs2Find = RFAL_NFC_LISTEN_TECH_A, + .totalDuration = 1000, + .devLimit = 1, + .wakeupEnabled = false, + .wakeupConfigDefault = true, + .nfcfBR = RFAL_BR_212, + .ap2pBR = RFAL_BR_424, + .maxBR = RFAL_BR_KEEP, + .GBLen = RFAL_NFCDEP_GB_MAX_LEN, + .notifyCb = NULL, + .activate_after_sak = activate_after_sak, + }; + params.lmConfigPA.nfcidLen = uid_len; + memcpy(params.lmConfigPA.nfcid, uid, uid_len); + params.lmConfigPA.SENS_RES[0] = atqa[0]; + params.lmConfigPA.SENS_RES[1] = atqa[1]; + params.lmConfigPA.SEL_RES = sak; + rfalNfcDiscover(¶ms); + + uint32_t start = DWT->CYCCNT; + while(state != RFAL_NFC_STATE_ACTIVATED) { + rfalNfcWorker(); + state = rfalNfcGetState(); + if(DWT->CYCCNT - start > timeout * clocks_in_ms) { + rfalNfcDeactivate(true); + return false; + } + osThreadYield(); + } + return true; +} + +bool furi_hal_nfc_get_first_frame(uint8_t** rx_buff, uint16_t** rx_len) { + ReturnCode ret = rfalNfcDataExchangeStart(NULL, 0, rx_buff, rx_len, 0); + return ret == ERR_NONE; +} + +ReturnCode furi_hal_nfc_data_exchange(uint8_t* tx_buff, uint16_t tx_len, uint8_t** rx_buff, uint16_t** rx_len, bool deactivate) { + furi_assert(rx_buff); + furi_assert(rx_len); + + ReturnCode ret; + rfalNfcState state = RFAL_NFC_STATE_ACTIVATED; + ret = rfalNfcDataExchangeStart(tx_buff, tx_len, rx_buff, rx_len, 0); + if(ret != ERR_NONE) { + return ret; + } + uint32_t start = DWT->CYCCNT; + while(state != RFAL_NFC_STATE_DATAEXCHANGE_DONE) { + rfalNfcWorker(); + state = rfalNfcGetState(); + ret = rfalNfcDataExchangeGetStatus(); + if(ret > ERR_SLEEP_REQ) { + return ret; + } + if(ret == ERR_BUSY) { + if(DWT->CYCCNT - start > 1000 * clocks_in_ms) { + return ERR_TIMEOUT; + } + continue; + } else { + start = DWT->CYCCNT; + } + taskYIELD(); + } + if(deactivate) { + rfalNfcDeactivate(false); + rfalLowPowerModeStart(); + } + return ERR_NONE; +} + +void furi_hal_nfc_deactivate() { + rfalNfcDeactivate(false); + rfalLowPowerModeStart(); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-os-timer.h b/firmware/targets/f7/furi-hal/furi-hal-os-timer.h new file mode 100644 index 00000000..f210b539 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-os-timer.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include +#include + +// Timer used for system ticks +#define FURI_HAL_OS_TIMER_MAX 0xFFFF +#define FURI_HAL_OS_TIMER_REG_LOAD_DLY 0x1 +#define FURI_HAL_OS_TIMER LPTIM2 +#define FURI_HAL_OS_TIMER_IRQ LPTIM2_IRQn + +static inline void furi_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(FURI_HAL_OS_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); + NVIC_EnableIRQ(FURI_HAL_OS_TIMER_IRQ); +} + +static inline void furi_hal_os_timer_continuous(uint32_t count) { + // Enable timer + LL_LPTIM_Enable(FURI_HAL_OS_TIMER); + while(!LL_LPTIM_IsEnabled(FURI_HAL_OS_TIMER)); + + // Enable rutoreload match interrupt + LL_LPTIM_EnableIT_ARRM(FURI_HAL_OS_TIMER); + + // Set autoreload and start counter + LL_LPTIM_SetAutoReload(FURI_HAL_OS_TIMER, count); + LL_LPTIM_StartCounter(FURI_HAL_OS_TIMER, LL_LPTIM_OPERATING_MODE_CONTINUOUS); +} + +static inline void furi_hal_os_timer_single(uint32_t count) { + // Enable timer + LL_LPTIM_Enable(FURI_HAL_OS_TIMER); + while(!LL_LPTIM_IsEnabled(FURI_HAL_OS_TIMER)); + + // Enable compare match interrupt + LL_LPTIM_EnableIT_CMPM(FURI_HAL_OS_TIMER); + + // Set compare, autoreload and start counter + // Include some marging to workaround ARRM behaviour + LL_LPTIM_SetCompare(FURI_HAL_OS_TIMER, count-3); + LL_LPTIM_SetAutoReload(FURI_HAL_OS_TIMER, count); + LL_LPTIM_StartCounter(FURI_HAL_OS_TIMER, LL_LPTIM_OPERATING_MODE_ONESHOT); +} + +static inline void furi_hal_os_timer_reset() { + // Hard reset timer + // THE ONLY RELIABLEWAY to stop it according to errata + LL_LPTIM_DeInit(FURI_HAL_OS_TIMER); +} + +static inline uint32_t furi_hal_os_timer_get_cnt() { + uint32_t counter = LL_LPTIM_GetCounter(FURI_HAL_OS_TIMER); + uint32_t counter_shadow = LL_LPTIM_GetCounter(FURI_HAL_OS_TIMER); + while(counter != counter_shadow) { + counter = counter_shadow; + counter_shadow = LL_LPTIM_GetCounter(FURI_HAL_OS_TIMER); + } + return counter; +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-os.c b/firmware/targets/f7/furi-hal/furi-hal-os.c new file mode 100644 index 00000000..eb1811b6 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-os.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include + +#include + +#define FURI_HAL_OS_CLK_FREQUENCY 32768 +#define FURI_HAL_OS_TICK_PER_SECOND 1024 +#define FURI_HAL_OS_CLK_PER_TICK (FURI_HAL_OS_CLK_FREQUENCY / FURI_HAL_OS_TICK_PER_SECOND) +#define FURI_HAL_OS_TICK_PER_EPOCH (FURI_HAL_OS_TIMER_MAX / FURI_HAL_OS_CLK_PER_TICK) +#define FURI_HAL_OS_MAX_SLEEP (FURI_HAL_OS_TICK_PER_EPOCH - 1) + +#ifdef FURI_HAL_OS_DEBUG +#include + +#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 furi_hal_os_timer_callback() { + LL_GPIO_TogglePin(LED_SECOND_PORT, LED_SECOND_PIN); +} +#endif + +extern void xPortSysTickHandler(); + +volatile uint32_t furi_hal_os_skew = 0; + +void furi_hal_os_init() { + LL_DBGMCU_APB1_GRP2_FreezePeriph(LL_DBGMCU_APB1_GRP2_LPTIM2_STOP); + + furi_hal_os_timer_init(); + furi_hal_os_timer_continuous(FURI_HAL_OS_CLK_PER_TICK); + +#ifdef FURI_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(furi_hal_os_timer_callback, osTimerPeriodic, NULL, NULL); + osTimerStart(second_timer, 1024); +#endif + + FURI_LOG_I("FuriHalOs", "Init OK"); +} + +void LPTIM2_IRQHandler(void) { + // Autoreload + if(LL_LPTIM_IsActiveFlag_ARRM(FURI_HAL_OS_TIMER)) { + LL_LPTIM_ClearFLAG_ARRM(FURI_HAL_OS_TIMER); + if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { + #ifdef FURI_HAL_OS_DEBUG + LL_GPIO_TogglePin(LED_TICK_PORT, LED_TICK_PIN); + #endif + xPortSysTickHandler(); + } + } + if(LL_LPTIM_IsActiveFlag_CMPM(FURI_HAL_OS_TIMER)) { + LL_LPTIM_ClearFLAG_CMPM(FURI_HAL_OS_TIMER); + } +} + +static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { + // Stop ticks + furi_hal_os_timer_reset(); + LL_SYSTICK_DisableIT(); + + // Start wakeup timer + furi_hal_os_timer_single(expected_idle_ticks * FURI_HAL_OS_CLK_PER_TICK); + +#ifdef FURI_HAL_OS_DEBUG + LL_GPIO_ResetOutputPin(LED_SLEEP_PORT, LED_SLEEP_PIN); +#endif + + // Go to sleep mode + furi_hal_power_sleep(); + +#ifdef FURI_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 = furi_hal_os_timer_get_cnt() + furi_hal_os_skew; + uint32_t after_tick = after_cnt / FURI_HAL_OS_CLK_PER_TICK; + furi_hal_os_skew = after_cnt % FURI_HAL_OS_CLK_PER_TICK; + + bool cmpm = LL_LPTIM_IsActiveFlag_CMPM(FURI_HAL_OS_TIMER); + bool arrm = LL_LPTIM_IsActiveFlag_ARRM(FURI_HAL_OS_TIMER); + if (cmpm && arrm) after_tick += expected_idle_ticks; + + // Prepare tick timer for new round + furi_hal_os_timer_reset(); + + // Resume ticks + LL_SYSTICK_EnableIT(); + furi_hal_os_timer_continuous(FURI_HAL_OS_CLK_PER_TICK); + + return after_tick; +} + +void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { + if(!furi_hal_power_sleep_available()) { + __WFI(); + return; + } + + // Limit mount of ticks to maximum that timer can count + if (expected_idle_ticks > FURI_HAL_OS_MAX_SLEEP) { + expected_idle_ticks = FURI_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 = furi_hal_os_sleep(expected_idle_ticks); + + // 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); + } + } + + // Reenable IRQ + __enable_irq(); +} + +void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) { + asm("bkpt 1"); + while(1) {}; +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-os.h b/firmware/targets/f7/furi-hal/furi-hal-os.h new file mode 100644 index 00000000..72ae74fc --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-os.h @@ -0,0 +1,17 @@ +#pragma once + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initialize OS helpers + * Configure and start tick timer + */ +void furi_hal_os_init(); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-power.c b/firmware/targets/f7/furi-hal/furi-hal-power.c new file mode 100644 index 00000000..4dd0127f --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-power.c @@ -0,0 +1,280 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +typedef struct { + volatile uint32_t insomnia; + volatile uint32_t deep_insomnia; +} FuriHalPower; + +static volatile FuriHalPower furi_hal_power = { + .insomnia = 0, + .deep_insomnia = 1, +}; + +const ParamCEDV cedv = { + .cedv_conf.gauge_conf = { + .CCT = 1, + .CSYNC = 0, + .EDV_CMP = 0, + .SC = 1, + .FIXED_EDV0 = 1, + .FCC_LIM = 1, + .FC_FOR_VDQ = 1, + .IGNORE_SD = 1, + .SME0 = 0, + }, + .full_charge_cap = 2100, + .design_cap = 2100, + .EDV0 = 3300, + .EDV1 = 3321, + .EDV2 = 3355, + .EMF = 3679, + .C0 = 430, + .C1 = 0, + .R1 = 408, + .R0 = 334, + .T0 = 4626, + .TC = 11, + .DOD0 = 4044, + .DOD10 = 3905, + .DOD20 = 3807, + .DOD30 = 3718, + .DOD40 = 3642, + .DOD50 = 3585, + .DOD60 = 3546, + .DOD70 = 3514, + .DOD80 = 3477, + .DOD90 = 3411, + .DOD100 = 3299, +}; + +void HAL_RCC_CSSCallback(void) { + // TODO: notify user about issue with HSE + furi_hal_power_reset(); +} + +void furi_hal_power_init() { + LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); + LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN); + bq27220_init(&cedv); + bq25896_init(); + FURI_LOG_I("FuriHalPower", "Init OK"); +} + +uint16_t furi_hal_power_insomnia_level() { + return furi_hal_power.insomnia; +} + +void furi_hal_power_insomnia_enter() { + furi_hal_power.insomnia++; +} + +void furi_hal_power_insomnia_exit() { + furi_hal_power.insomnia--; +} + +bool furi_hal_power_sleep_available() { + return furi_hal_power.insomnia == 0; +} + +bool furi_hal_power_deep_sleep_available() { + return furi_hal_bt_is_alive() && furi_hal_power.deep_insomnia == 0; +} + +void furi_hal_power_light_sleep() { + __WFI(); +} + +void furi_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 + furi_hal_clock_switch_to_hsi(); + } + } else { + /** + * The switch on HSI before entering Stop Mode is required + */ + furi_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) { + furi_hal_clock_switch_to_pll(); + } + + LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); +} + +void furi_hal_power_sleep() { + if(furi_hal_power_deep_sleep_available()) { + furi_hal_power_deep_sleep(); + } else { + furi_hal_power_light_sleep(); + } +} + + +uint8_t furi_hal_power_get_pct() { + return bq27220_get_state_of_charge(); +} + +uint8_t furi_hal_power_get_bat_health_pct() { + return bq27220_get_state_of_health(); +} + +bool furi_hal_power_is_charging() { + return bq25896_is_charging(); +} + +void furi_hal_power_off() { + bq25896_poweroff(); +} + +void furi_hal_power_reset() { + NVIC_SystemReset(); +} + +void furi_hal_power_enable_otg() { + bq25896_enable_otg(); +} + +void furi_hal_power_disable_otg() { + bq25896_disable_otg(); +} + +uint32_t furi_hal_power_get_battery_remaining_capacity() { + return bq27220_get_remaining_capacity(); +} + +uint32_t furi_hal_power_get_battery_full_capacity() { + return bq27220_get_full_charge_capacity(); +} + +float furi_hal_power_get_battery_voltage(FuriHalPowerIC ic) { + if (ic == FuriHalPowerICCharger) { + return (float)bq25896_get_vbat_voltage() / 1000.0f; + } else if (ic == FuriHalPowerICFuelGauge) { + return (float)bq27220_get_voltage() / 1000.0f; + } else { + return 0.0f; + } +} + +float furi_hal_power_get_battery_current(FuriHalPowerIC ic) { + if (ic == FuriHalPowerICCharger) { + return (float)bq25896_get_vbat_current() / 1000.0f; + } else if (ic == FuriHalPowerICFuelGauge) { + return (float)bq27220_get_current() / 1000.0f; + } else { + return 0.0f; + } +} + +float furi_hal_power_get_battery_temperature(FuriHalPowerIC ic) { + if (ic == FuriHalPowerICCharger) { + // Linear approximation, +/- 5 C + return (71.0f - (float)bq25896_get_ntc_mpct()/1000) / 0.6f; + } else if (ic == FuriHalPowerICFuelGauge) { + return ((float)bq27220_get_temperature() - 2731.0f) / 10.0f; + } else { + return 0.0f; + } + +} + +float furi_hal_power_get_usb_voltage(){ + return (float)bq25896_get_vbus_voltage() / 1000.0f; +} + +void furi_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)furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge) + ); + } + + 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 furi_hal_power_enable_external_3_3v(){ + LL_GPIO_SetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin); +} + +void furi_hal_power_disable_external_3_3v(){ + LL_GPIO_ResetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-pwm.c b/firmware/targets/f7/furi-hal/furi-hal-pwm.c new file mode 100644 index 00000000..972d28ba --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-pwm.c @@ -0,0 +1,50 @@ +#include "furi-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); +} + diff --git a/firmware/targets/f7/furi-hal/furi-hal-pwm.h b/firmware/targets/f7/furi-hal/furi-hal-pwm.h new file mode 100644 index 00000000..58b5701e --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-pwm.h @@ -0,0 +1,16 @@ +#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); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/furi-hal/furi-hal-resources.c b/firmware/targets/f7/furi-hal/furi-hal-resources.c new file mode 100644 index 00000000..52ea3cf7 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-resources.c @@ -0,0 +1,57 @@ +#include +#include "main.h" +#include + +const InputPin input_pins[] = { + {.port = BUTTON_UP_GPIO_Port, .pin = BUTTON_UP_Pin, .key = InputKeyUp, .inverted = true, .name="Up"}, + {.port = BUTTON_DOWN_GPIO_Port, .pin = BUTTON_DOWN_Pin, .key = InputKeyDown, .inverted = true, .name="Down"}, + {.port = BUTTON_RIGHT_GPIO_Port, + .pin = BUTTON_RIGHT_Pin, + .key = InputKeyRight, + .inverted = true, .name="Right"}, + {.port = BUTTON_LEFT_GPIO_Port, .pin = BUTTON_LEFT_Pin, .key = InputKeyLeft, .inverted = true, .name="Left"}, + {.port = BUTTON_OK_GPIO_Port, .pin = BUTTON_OK_Pin, .key = InputKeyOk, .inverted = false, .name="Ok"}, + {.port = BUTTON_BACK_GPIO_Port, .pin = BUTTON_BACK_Pin, .key = InputKeyBack, .inverted = true, .name="Back"}, +}; + +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}; +const GpioPin gpio_rfid_carrier = {.port = RFID_CARRIER_GPIO_Port, .pin = RFID_CARRIER_Pin}; + +const GpioPin gpio_irda_rx = {.port = IR_RX_GPIO_Port, .pin = IR_RX_Pin}; +const GpioPin gpio_irda_tx = {.port = IR_TX_GPIO_Port, .pin = IR_TX_Pin}; + +const GpioPin gpio_usart_tx = {.port = USART1_TX_Port, .pin = USART1_TX_Pin}; +const GpioPin gpio_usart_rx = {.port = USART1_RX_Port, .pin = USART1_RX_Pin}; diff --git a/firmware/targets/f7/furi-hal/furi-hal-resources.h b/firmware/targets/f7/furi-hal/furi-hal-resources.h new file mode 100644 index 00000000..09af7532 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-resources.h @@ -0,0 +1,105 @@ +#pragma once + +#include "main.h" +#include + +#include +#include + +#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, + * Standard Mode @100kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define POWER_I2C_TIMINGS_100 0x10707DBC + +/** Timing register value is computed with the STM32CubeMX Tool, + * Fast Mode @400kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define POWER_I2C_TIMINGS_400 0x00602173 + +/* 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; + const char* name; +} 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; +extern const GpioPin gpio_rfid_carrier; + +extern const GpioPin gpio_irda_rx; +extern const GpioPin gpio_irda_tx; + +extern const GpioPin gpio_usart_tx; +extern const GpioPin gpio_usart_rx; + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/furi-hal/furi-hal-rfid.c b/firmware/targets/f7/furi-hal/furi-hal-rfid.c new file mode 100644 index 00000000..b4ec96fc --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-rfid.c @@ -0,0 +1,297 @@ +#include +#include +#include + +#include + +#define LFRFID_READ_TIM htim1 +#define LFRFID_READ_CHANNEL TIM_CHANNEL_1 +#define LFRFID_EMULATE_TIM htim2 +#define LFRFID_EMULATE_CHANNEL TIM_CHANNEL_3 + +void furi_hal_rfid_init() { + furi_hal_rfid_pins_reset(); +} + +void furi_hal_rfid_pins_reset() { + // ibutton bus disable + furi_hal_ibutton_stop(); + + // pulldown rfid antenna + hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo); + hal_gpio_write(&gpio_rfid_carrier_out, false); + + // from both sides + hal_gpio_init(&gpio_rfid_pull, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo); + hal_gpio_write(&gpio_rfid_pull, true); + + hal_gpio_init_simple(&gpio_rfid_carrier, GpioModeAnalog); +} + +void furi_hal_rfid_pins_emulate() { + // ibutton low + furi_hal_ibutton_start(); + furi_hal_ibutton_pin_low(); + + // pull pin to timer out + hal_gpio_init_ex( + &gpio_rfid_pull, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + + // pull rfid antenna from carrier side + hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo); + hal_gpio_write(&gpio_rfid_carrier_out, false); + + hal_gpio_init_ex( + &gpio_rfid_carrier, GpioModeAltFunctionPushPull, GpioSpeedLow, GpioPullUp, GpioAltFn2TIM2); +} + +void furi_hal_rfid_pins_read() { + // ibutton low + furi_hal_ibutton_start(); + furi_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_ex( + &gpio_rfid_carrier_out, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedLow, + GpioAltFn1TIM1); + + // comparator in + hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioSpeedLow, GpioPullNo); +} + +void furi_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_READ_TIM.Init.Prescaler = 0; + LFRFID_READ_TIM.Init.CounterMode = TIM_COUNTERMODE_UP; + LFRFID_READ_TIM.Init.Period = period; + LFRFID_READ_TIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + LFRFID_READ_TIM.Init.RepetitionCounter = 0; + LFRFID_READ_TIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if(HAL_TIM_Base_Init(&LFRFID_READ_TIM) != HAL_OK) { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if(HAL_TIM_ConfigClockSource(&LFRFID_READ_TIM, &sClockSourceConfig) != HAL_OK) { + Error_Handler(); + } + if(HAL_TIM_PWM_Init(&LFRFID_READ_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_READ_TIM, &sMasterConfig) != HAL_OK) { + Error_Handler(); + } + + // pwm config + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = (uint32_t)(LFRFID_READ_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_READ_TIM, &sConfigOC, LFRFID_READ_CHANNEL) != 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_READ_TIM, &sBreakDeadTimeConfig) != HAL_OK) { + Error_Handler(); + } +} + +void furi_hal_rfid_tim_read_start() { + HAL_TIMEx_PWMN_Start(&LFRFID_READ_TIM, LFRFID_READ_CHANNEL); +} + +void furi_hal_rfid_tim_read_stop() { + HAL_TIMEx_PWMN_Stop(&LFRFID_READ_TIM, LFRFID_READ_CHANNEL); +} + +void furi_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_EMULATE_TIM.Init.Prescaler = 0; + LFRFID_EMULATE_TIM.Init.CounterMode = TIM_COUNTERMODE_UP; + LFRFID_EMULATE_TIM.Init.Period = 1; + LFRFID_EMULATE_TIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + LFRFID_EMULATE_TIM.Init.RepetitionCounter = 0; + LFRFID_EMULATE_TIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if(HAL_TIM_Base_Init(&LFRFID_EMULATE_TIM) != HAL_OK) { + Error_Handler(); + } + + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2; + sClockSourceConfig.ClockPolarity = TIM_ETRPOLARITY_INVERTED; + sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1; + sClockSourceConfig.ClockFilter = 0; + if(HAL_TIM_ConfigClockSource(&LFRFID_EMULATE_TIM, &sClockSourceConfig) != HAL_OK) { + Error_Handler(); + } + if(HAL_TIM_PWM_Init(&LFRFID_EMULATE_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_EMULATE_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(&LFRFID_EMULATE_TIM, &sConfigOC, LFRFID_EMULATE_CHANNEL) != + 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_EMULATE_TIM, &sBreakDeadTimeConfig) != HAL_OK) { + Error_Handler(); + } +} + +void furi_hal_rfid_tim_emulate_start() { + // TODO make api for interrupts priority + for(size_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { + HAL_NVIC_SetPriority(i, 15, 0); + } + + HAL_NVIC_SetPriority(TIM2_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(TIM2_IRQn); + + HAL_TIM_PWM_Start_IT(&LFRFID_EMULATE_TIM, LFRFID_EMULATE_CHANNEL); + HAL_TIM_Base_Start_IT(&LFRFID_EMULATE_TIM); +} + +void furi_hal_rfid_tim_emulate_stop() { + HAL_TIM_Base_Stop(&LFRFID_EMULATE_TIM); + HAL_TIM_PWM_Stop(&LFRFID_EMULATE_TIM, LFRFID_EMULATE_CHANNEL); +} + +void furi_hal_rfid_tim_reset() { + HAL_TIM_Base_DeInit(&LFRFID_READ_TIM); + LL_TIM_DeInit(TIM1); + LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_TIM1); + HAL_TIM_Base_DeInit(&LFRFID_EMULATE_TIM); + LL_TIM_DeInit(TIM2); + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); +} + +bool furi_hal_rfid_is_tim_emulate(TIM_HandleTypeDef* hw) { + return (hw == &LFRFID_EMULATE_TIM); +} + +void furi_hal_rfid_set_emulate_period(uint32_t period) { + LFRFID_EMULATE_TIM.Instance->ARR = period; +} + +void furi_hal_rfid_set_emulate_pulse(uint32_t pulse) { + switch(LFRFID_EMULATE_CHANNEL) { + case TIM_CHANNEL_1: + LFRFID_EMULATE_TIM.Instance->CCR1 = pulse; + break; + case TIM_CHANNEL_2: + LFRFID_EMULATE_TIM.Instance->CCR2 = pulse; + break; + case TIM_CHANNEL_3: + LFRFID_EMULATE_TIM.Instance->CCR3 = pulse; + break; + case TIM_CHANNEL_4: + LFRFID_EMULATE_TIM.Instance->CCR4 = pulse; + break; + default: + furi_check(0); + break; + } +} + +void furi_hal_rfid_set_read_period(uint32_t period) { + LFRFID_TIM.Instance->ARR = period; +} + +void furi_hal_rfid_set_read_pulse(uint32_t pulse) { + switch(LFRFID_READ_CHANNEL) { + case TIM_CHANNEL_1: + LFRFID_TIM.Instance->CCR1 = pulse; + break; + case TIM_CHANNEL_2: + LFRFID_TIM.Instance->CCR2 = pulse; + break; + case TIM_CHANNEL_3: + LFRFID_TIM.Instance->CCR3 = pulse; + break; + case TIM_CHANNEL_4: + LFRFID_TIM.Instance->CCR4 = pulse; + break; + default: + furi_check(0); + break; + } +} + +void furi_hal_rfid_change_read_config(float freq, float duty_cycle) { + uint32_t period = (uint32_t)((SystemCoreClock) / freq) - 1; + furi_hal_rfid_set_read_period(period); + furi_hal_rfid_set_read_pulse(period * duty_cycle); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-sd.c b/firmware/targets/f7/furi-hal/furi-hal-sd.c new file mode 100644 index 00000000..01cf9339 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-sd.c @@ -0,0 +1,22 @@ +#include "furi-hal-sd.h" +#include +#include + +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; +} \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-config.c b/firmware/targets/f7/furi-hal/furi-hal-spi-config.c new file mode 100644 index 00000000..315d82a2 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-spi-config.c @@ -0,0 +1,103 @@ +#include +#include + +#define SPI_R SPI1 +#define SPI_D SPI2 + +const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_2EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const LL_SPI_InitTypeDef furi_hal_spi_config_display = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV16, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +/** + * SD Card in fast mode (after init) + */ +const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +/** + * SD Card in slow mode (before init) + */ +const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +osMutexId_t spi_mutex_d = NULL; +osMutexId_t spi_mutex_r = NULL; + +const FuriHalSpiBus 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 FuriHalSpiBus 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 FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { + { .bus=&spi_r, .config=&furi_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, + { .bus=&spi_d, .config=&furi_hal_spi_config_display, .chip_select=&gpio_display_cs, }, + { .bus=&spi_d, .config=&furi_hal_spi_config_sd_fast, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_d, .config=&furi_hal_spi_config_sd_slow, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_r, .config=&furi_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, +}; diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-config.h b/firmware/targets/f7/furi-hal/furi-hal-spi-config.h new file mode 100644 index 00000000..3398474a --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-spi-config.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; + +/** FURI HAL SPI BUS handler + * Structure content may change at some point + */ +typedef struct { + const SPI_TypeDef* spi; + const osMutexId_t* mutex; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* clk; +} FuriHalSpiBus; + +/** FURI HAL SPI Device handler + * Structure content may change at some point + */ +typedef struct { + const FuriHalSpiBus* bus; + const LL_SPI_InitTypeDef* config; + const GpioPin* chip_select; +} FuriHalSpiDevice; + +/** FURI HAL SPI Standard Device IDs */ +typedef enum { + FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ + FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ + FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ + FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ + FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ + + FuriHalSpiDeviceIdMax, /** Service Value, do not use */ +} FuriHalSpiDeviceId; + +/** Furi Hal Spi Bus R + * CC1101, Nfc + */ +extern const FuriHalSpiBus spi_r; + +/** Furi Hal Spi Bus D + * Display, SdCard + */ +extern const FuriHalSpiBus spi_d; + +/** Furi Hal Spi devices */ +extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi.c b/firmware/targets/f7/furi-hal/furi-hal-spi.c new file mode 100644 index 00000000..c925abee --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-spi.c @@ -0,0 +1,200 @@ +#include "furi-hal-spi.h" +#include "furi-hal-resources.h" + +#include +#include +#include + +#include +#include +#include + +void furi_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; imutex, osWaitForever) == osOK); +} + +void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { + furi_assert(bus); + furi_check(osMutexRelease(*bus->mutex) == osOK); +} + +void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { + furi_assert(bus); + + LL_SPI_DeInit((SPI_TypeDef*)bus->spi); + LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config); + LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable((SPI_TypeDef*)bus->spi); +} + +void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_TX_FIFO_EMPTY); + while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef *)bus->spi)); + while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { + LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); + } +} + +bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(buffer); + furi_assert(size > 0); + + return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout); +} + +bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(buffer); + furi_assert(size > 0); + bool ret = true; + + while(size > 0) { + if (LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi)) { + LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *buffer); + buffer++; + size--; + } + } + + furi_hal_spi_bus_end_txrx(bus, timeout); + LL_SPI_ClearFlag_OVR((SPI_TypeDef *)bus->spi); + + return ret; +} + +bool furi_hal_spi_bus_trx(const FuriHalSpiBus* 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); + + bool ret = true; + size_t tx_size = size; + bool tx_allowed = true; + + while(size > 0) { + if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi) && tx_allowed) { + LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *tx_buffer); + tx_buffer++; + tx_size--; + tx_allowed = false; + } + + if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef *)bus->spi)) { + *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); + rx_buffer++; + size--; + tx_allowed = true; + } + } + + furi_hal_spi_bus_end_txrx(bus, timeout); + + return ret; +} + +void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) { + furi_assert(device); + furi_assert(device->config); + + furi_hal_spi_bus_configure(device->bus, device->config); +} + +const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { + furi_assert(device_id < FuriHalSpiDeviceIdMax); + + const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; + assert(device); + furi_hal_spi_bus_lock(device->bus); + furi_hal_spi_device_configure(device); + + return device; +} + +void furi_hal_spi_device_return(const FuriHalSpiDevice* device) { + furi_hal_spi_bus_unlock(device->bus); +} + +bool furi_hal_spi_device_rx(const FuriHalSpiDevice* 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 = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool furi_hal_spi_device_tx(const FuriHalSpiDevice* 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 = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool furi_hal_spi_device_trx(const FuriHalSpiDevice* 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 = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi.h b/firmware/targets/f7/furi-hal/furi-hal-spi.h new file mode 100644 index 00000000..638e713a --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-spi.h @@ -0,0 +1,108 @@ +#pragma once +#include "main.h" +#include "furi-hal-spi-config.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Init SPI API + */ +void furi_hal_spi_init(); + +/* Bus Level API */ + +/** Lock SPI bus + * Takes bus mutex, if used + */ +void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); + +/** Unlock SPI bus + * Releases BUS mutex, if used + */ +void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); + +/** + * Configure SPI bus + * @param bus - spi bus handler + * @param config - spi configuration structure + */ +void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); + +/** SPI Receive + * @param bus - spi bus handler + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_bus_rx(const FuriHalSpiBus* 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 furi_hal_spi_bus_tx(const FuriHalSpiBus* 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 furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); + +/* Device Level API */ + +/** Reconfigure SPI bus for device + * @param device - device description + */ +void furi_hal_spi_device_configure(const FuriHalSpiDevice* device); + +/** Get Device handle + * And lock access to the corresponding SPI BUS + * @param device_id - device identifier + * @return device handle + */ +const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id); + +/** Return Device handle + * And unlock access to the corresponding SPI BUS + * @param device - device handle + */ +void furi_hal_spi_device_return(const FuriHalSpiDevice* device); + +/** SPI Recieve + * @param device - device handle + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_device_rx(const FuriHalSpiDevice* 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 furi_hal_spi_device_tx(const FuriHalSpiDevice* 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 furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c new file mode 100644 index 00000000..679eea74 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -0,0 +1,714 @@ +#include "furi-hal-subghz.h" + +#include +#include +#include +#include + +#include +#include +#include + +static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit; + +static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = { + // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration + + /* GPIO GD0 */ + { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + + /* FIFO and internals */ + { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 + + /* Packet engine */ + { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + + /* Frequency Synthesizer Control */ + { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + + // Modem Configuration + { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz + { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz + { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync + { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud + { CC1101_MDMCFG4, 0x67 }, // Rx BW filter is 270.833333kHz + + /* Main Radio Control State Machine */ + { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + + /* Frequency Offset Compensation Configuration */ + { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + + /* Automatic Gain Control */ + { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + + /* Wake on radio and timeouts control */ + { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + + /* Frontend configuration */ + { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] + { CC1101_FREND1, 0xB6 }, // + + /* Frequency Synthesizer Calibration, valid for 433.92 */ + { CC1101_FSCAL3, 0xE9 }, + { CC1101_FSCAL2, 0x2A }, + { CC1101_FSCAL1, 0x00 }, + { CC1101_FSCAL0, 0x1F }, + + /* Magic f4ckery */ + { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value + { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value + { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + + /* End */ + { 0, 0 }, +}; + +static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = { + // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration + + /* GPIO GD0 */ + { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + + /* FIFO and internals */ + { CC1101_FIFOTHR, 0x07 }, // The only important bit is ADC_RETENTION + + /* Packet engine */ + { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + + /* Frequency Synthesizer Control */ + { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + + // Modem Configuration + { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz + { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz + { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync + { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud + { CC1101_MDMCFG4, 0x17 }, // Rx BW filter is 650.000kHz + + /* Main Radio Control State Machine */ + { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + + /* Frequency Offset Compensation Configuration */ + { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + + /* Automatic Gain Control */ + { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + + /* Wake on radio and timeouts control */ + { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + + /* Frontend configuration */ + { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] + { CC1101_FREND1, 0xB6 }, // + + /* Frequency Synthesizer Calibration, valid for 433.92 */ + { CC1101_FSCAL3, 0xE9 }, + { CC1101_FSCAL2, 0x2A }, + { CC1101_FSCAL1, 0x00 }, + { CC1101_FSCAL0, 0x1F }, + + /* Magic f4ckery */ + { CC1101_TEST2, 0x88 }, + { CC1101_TEST1, 0x31 }, + { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + + /* End */ + { 0, 0 }, +}; +static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { + // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration + + /* GPIO GD0 */ + { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + + /* FIFO and internals */ + { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION + + /* Packet engine */ + { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + + /* Frequency Synthesizer Control */ + { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + + // Modem Configuration + { CC1101_MDMCFG0, 0xF8 }, + { CC1101_MDMCFG1, 0x00 }, // No preamble/sync + { CC1101_MDMCFG2, 0x80 }, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) + { CC1101_MDMCFG3, 0x83 }, // Data rate is 9.59587 kBaud + { CC1101_MDMCFG4, 0x88 }, // Rx BW filter is 203.125000kHz + + { CC1101_DEVIATN, 0x14}, //Deviation 4.760742 khz + + /* Main Radio Control State Machine */ + { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + + /* Frequency Offset Compensation Configuration */ + { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + + /* Automatic Gain Control */ + { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + + /* Wake on radio and timeouts control */ + { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + + /* Frontend configuration */ + { CC1101_FREND0, 0x10 }, // Adjusts current TX LO buffer + { CC1101_FREND1, 0xB6 }, // + + /* Frequency Synthesizer Calibration, valid for 433.92 */ + { CC1101_FSCAL3, 0xE9 }, + { CC1101_FSCAL2, 0x2A }, + { CC1101_FSCAL1, 0x00 }, + { CC1101_FSCAL0, 0x1F }, + + /* Magic f4ckery */ + { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value + { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value + { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + + /* End */ + { 0, 0 }, +}; +static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { + 0x00, + 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; +static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { + 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; + +void furi_hal_subghz_init() { + furi_assert(furi_hal_subghz_state == SubGhzStateInit); + furi_hal_subghz_state = SubGhzStateIdle; + + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + +#ifdef FURI_HAL_SUBGHZ_TX_GPIO + hal_gpio_init(&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); +#endif + + // Reset + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + cc1101_reset(device); + cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + + // 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); + + // Go to sleep + cc1101_shutdown(device); + + furi_hal_spi_device_return(device); + FURI_LOG_I("FuriHalSubGhz", "Init OK"); +} + +void furi_hal_subghz_sleep() { + furi_assert(furi_hal_subghz_state == SubGhzStateIdle); + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + + cc1101_switch_to_idle(device); + + cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + cc1101_shutdown(device); + + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_dump_state() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + printf( + "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", + cc1101_get_partnumber(device), + cc1101_get_version(device) + ); + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { + if(preset == FuriHalSubGhzPresetOok650Async) { + furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_650khz_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); + } else if(preset == FuriHalSubGhzPresetOok270Async){ + furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_270khz_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); + } else if(preset == FuriHalSubGhzPreset2FSKAsync){ + furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); + }else { + furi_check(0); + } +} + +uint8_t furi_hal_subghz_get_status() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + CC1101StatusRaw st; + st.status = cc1101_get_status(device); + furi_hal_spi_device_return(device); + return st.status_raw; +} + +void furi_hal_subghz_load_registers(const uint8_t data[][2]) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + cc1101_reset(device); + uint32_t i = 0; + while (data[i][0]) { + cc1101_write_reg(device, data[i][0], data[i][1]); + i++; + } + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_load_patable(const uint8_t data[8]) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + cc1101_set_pa_table(device, data); + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + cc1101_flush_tx(device); + cc1101_write_fifo(device, data, size); + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_flush_rx() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + cc1101_flush_rx(device); + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + cc1101_read_fifo(device, data, size); + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_shutdown() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + // Reset and shutdown + cc1101_shutdown(device); + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_reset() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + cc1101_switch_to_idle(device); + cc1101_reset(device); + cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_idle() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + cc1101_switch_to_idle(device); + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_rx() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + cc1101_switch_to_rx(device); + furi_hal_spi_device_return(device); +} + +void furi_hal_subghz_tx() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + cc1101_switch_to_tx(device); + furi_hal_spi_device_return(device); +} + +float furi_hal_subghz_get_rssi() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + int32_t rssi_dec = cc1101_get_rssi(device); + furi_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; +} + +bool furi_hal_subghz_is_frequency_valid(uint32_t value) { + if(!(value >= 299999755 && value <= 348000335) && + !(value >= 386999938 && value <= 464000000) && + !(value >= 778999847 && value <= 928000000)) { + return false; + } + return true; +} + +uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { + value = furi_hal_subghz_set_frequency(value); + if(value >= 299999755 && value <= 348000335) { + furi_hal_subghz_set_path(FuriHalSubGhzPath315); + } else if(value >= 386999938 && value <= 464000000) { + furi_hal_subghz_set_path(FuriHalSubGhzPath433); + } else if(value >= 778999847 && value <= 928000000) { + furi_hal_subghz_set_path(FuriHalSubGhzPath868); + } else { + furi_check(0); + } + return value; +} + +uint32_t furi_hal_subghz_set_frequency(uint32_t value) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + + uint32_t real_frequency = cc1101_set_frequency(device, value); + cc1101_calibrate(device); + + while(true) { + CC1101Status status = cc1101_get_status(device); + if (status.STATE == CC1101StateIDLE) break; + } + + furi_hal_spi_device_return(device); + + return real_frequency; +} + +void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + if (path == FuriHalSubGhzPath433) { + hal_gpio_write(&gpio_rf_sw_0, 0); + cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + } else if (path == FuriHalSubGhzPath315) { + hal_gpio_write(&gpio_rf_sw_0, 1); + cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + } else if (path == FuriHalSubGhzPath868) { + hal_gpio_write(&gpio_rf_sw_0, 1); + cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + } else if (path == FuriHalSubGhzPathIsolate) { + hal_gpio_write(&gpio_rf_sw_0, 0); + cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + } else { + furi_check(0); + } + furi_hal_spi_device_return(device); +} + +volatile uint32_t furi_hal_subghz_capture_delta_duration = 0; +volatile FuriHalSubGhzCaptureCallback furi_hal_subghz_capture_callback = NULL; +volatile void* furi_hal_subghz_capture_callback_context = NULL; + +static void furi_hal_subghz_capture_ISR() { + // Channel 1 + if(LL_TIM_IsActiveFlag_CC1(TIM2)) { + LL_TIM_ClearFlag_CC1(TIM2); + furi_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2); + if (furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback(true, furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context + ); + } + } + // Channel 2 + if(LL_TIM_IsActiveFlag_CC2(TIM2)) { + LL_TIM_ClearFlag_CC2(TIM2); + if (furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback(false, LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context + ); + } + } +} + + +void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context) { + furi_assert(furi_hal_subghz_state == SubGhzStateIdle); + furi_hal_subghz_state = SubGhzStateAsyncRx; + + furi_hal_subghz_capture_callback = callback; + furi_hal_subghz_capture_callback_context = context; + + hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + + // Timer: base + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 0x7FFFFFFE; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM2, &TIM_InitStruct); + + // Timer: advanced + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_DisableARRPreload(TIM2); + LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_TI2FP2); + LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_RESET); + LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET); + LL_TIM_EnableMasterSlaveMode(TIM2); + LL_TIM_DisableDMAReq_TRIG(TIM2); + LL_TIM_DisableIT_TRIG(TIM2); + + // Timer: channel 1 indirect + LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_INDIRECTTI); + LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); + LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_FALLING); + LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); + + // Timer: channel 2 direct + LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); + LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); + LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); + LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); + + // ISR setup + furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_EnableIRQ(TIM2_IRQn); + + // Interrupts and channels + LL_TIM_EnableIT_CC1(TIM2); + LL_TIM_EnableIT_CC2(TIM2); + LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); + + // Enable NVIC + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_EnableIRQ(TIM2_IRQn); + + // Start timer + LL_TIM_SetCounter(TIM2, 0); + LL_TIM_EnableCounter(TIM2); + + // Switch to RX + furi_hal_subghz_rx(); +} + +void furi_hal_subghz_stop_async_rx() { + furi_assert(furi_hal_subghz_state == SubGhzStateAsyncRx); + furi_hal_subghz_state = SubGhzStateIdle; + + // Shutdown radio + furi_hal_subghz_idle(); + + LL_TIM_DeInit(TIM2); + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); + furi_hal_interrupt_set_timer_isr(TIM2, NULL); + + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); +} + +#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256) +#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL/2) +#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 + +typedef struct { + uint32_t* buffer; + bool flip_flop; + FuriHalSubGhzAsyncTxCallback callback; + void* callback_context; +} FuriHalSubGhzAsyncTx; + +static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0}; + +static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { + while (samples > 0) { + bool is_odd = samples % 2; + LevelDuration ld = furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); + if (level_duration_is_reset(ld)) { + // One more even sample required to end at low level + if (is_odd) { + *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; + buffer++; + samples--; + } + break; + } else { + // Inject guard time if level is incorrect + if (is_odd == level_duration_get_level(ld)) { + *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; + buffer++; + samples--; + } + + uint32_t duration = level_duration_get_duration(ld); + assert(duration > 0); + *buffer = duration; + buffer++; + samples--; + } + } + + memset(buffer, 0, samples * sizeof(uint32_t)); +} + +static void furi_hal_subghz_async_tx_dma_isr() { + furi_assert(furi_hal_subghz_state == SubGhzStateAsyncTx); + if (LL_DMA_IsActiveFlag_HT1(DMA1)) { + LL_DMA_ClearFlag_HT1(DMA1); + furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + } + if (LL_DMA_IsActiveFlag_TC1(DMA1)) { + LL_DMA_ClearFlag_TC1(DMA1); + furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer+API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + } +} + +static void furi_hal_subghz_async_tx_timer_isr() { + if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) { + LL_TIM_ClearFlag_UPDATE(TIM2); + if (LL_TIM_GetAutoReload(TIM2) == 0) { + if (furi_hal_subghz_state == SubGhzStateAsyncTx) { + furi_hal_subghz_state = SubGhzStateAsyncTxLast; + } else { + furi_hal_subghz_state = SubGhzStateAsyncTxEnd; + LL_TIM_DisableCounter(TIM2); + } + } + } +} + +void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* context) { + furi_assert(furi_hal_subghz_state == SubGhzStateIdle); + furi_assert(callback); + + furi_hal_subghz_async_tx.callback = callback; + furi_hal_subghz_async_tx.callback_context = context; + + furi_hal_subghz_state = SubGhzStateAsyncTx; + + furi_hal_subghz_async_tx.buffer = furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); + furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); + + // Connect CC1101_GD0 to TIM2 as output + hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); + + // Configure DMA + LL_DMA_InitTypeDef dma_config = {0}; + dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM2->ARR); + dma_config.MemoryOrM2MDstAddress = (uint32_t)furi_hal_subghz_async_tx.buffer; + dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; + dma_config.Mode = LL_DMA_MODE_CIRCULAR; + dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; + dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; + dma_config.NbData = API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL; + dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; + dma_config.Priority = LL_DMA_MODE_NORMAL; + LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); + LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); + + // Configure TIM2 + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 1000; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM2, &TIM_InitStruct); + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_EnableARRPreload(TIM2); + + // Configure TIM2 CH2 + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_TOGGLE; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 0; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH2); + LL_TIM_DisableMasterSlaveMode(TIM2); + + furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_async_tx_timer_isr); + LL_TIM_EnableIT_UPDATE(TIM2); + LL_TIM_EnableDMAReq_UPDATE(TIM2); + LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); + + // Start counter + LL_TIM_GenerateEvent_UPDATE(TIM2); +#ifdef FURI_HAL_SUBGHZ_TX_GPIO + hal_gpio_write(&FURI_HAL_SUBGHZ_TX_GPIO, true); +#endif + furi_hal_subghz_tx(); + + // Enable NVIC + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_EnableIRQ(TIM2_IRQn); + + LL_TIM_SetCounter(TIM2, 0); + LL_TIM_EnableCounter(TIM2); +} + +bool furi_hal_subghz_is_async_tx_complete() { + return furi_hal_subghz_state == SubGhzStateAsyncTxEnd; +} + +void furi_hal_subghz_stop_async_tx() { + furi_assert( + furi_hal_subghz_state == SubGhzStateAsyncTx + || furi_hal_subghz_state == SubGhzStateAsyncTxLast + || furi_hal_subghz_state == SubGhzStateAsyncTxEnd + ); + + // Shutdown radio + furi_hal_subghz_idle(); +#ifdef FURI_HAL_SUBGHZ_TX_GPIO + hal_gpio_write(&FURI_HAL_SUBGHZ_TX_GPIO, false); +#endif + + // Deinitialize Timer + LL_TIM_DeInit(TIM2); + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); + furi_hal_interrupt_set_timer_isr(TIM2, NULL); + + // Deinitialize DMA + LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_1); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL); + + // Deinitialize GPIO + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + free(furi_hal_subghz_async_tx.buffer); + + furi_hal_subghz_state = SubGhzStateIdle; +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-task.c b/firmware/targets/f7/furi-hal/furi-hal-task.c new file mode 100644 index 00000000..aca197a4 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-task.c @@ -0,0 +1,54 @@ +#include "cmsis_os.h" +#include "furi-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(); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-task.h b/firmware/targets/f7/furi-hal/furi-hal-task.h new file mode 100644 index 00000000..8b157233 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-task.h @@ -0,0 +1,12 @@ +#pragma once +#include "main.h" +#include +#include + +// 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); diff --git a/firmware/targets/f7/furi-hal/furi-hal-vcp.c b/firmware/targets/f7/furi-hal/furi-hal-vcp.c new file mode 100644 index 00000000..88de32b5 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-vcp.c @@ -0,0 +1,128 @@ +#include + +#include +#include +#include + +#define FURI_HAL_VCP_RX_BUFFER_SIZE (APP_RX_DATA_SIZE * 5) + +extern USBD_HandleTypeDef hUsbDeviceFS; + +typedef struct { + volatile bool connected; + + StreamBufferHandle_t rx_stream; + volatile bool rx_stream_full; + + osSemaphoreId_t tx_semaphore; +} FuriHalVcp; + +static FuriHalVcp* furi_hal_vcp = NULL; + +static const uint8_t ascii_soh = 0x01; +static const uint8_t ascii_eot = 0x04; + +void furi_hal_vcp_init() { + furi_hal_vcp = furi_alloc(sizeof(FuriHalVcp)); + furi_hal_vcp->connected = false; + + furi_hal_vcp->rx_stream = xStreamBufferCreate(FURI_HAL_VCP_RX_BUFFER_SIZE, 1); + furi_hal_vcp->rx_stream_full = false; + + furi_hal_vcp->tx_semaphore = osSemaphoreNew(1, 1, NULL); + + FURI_LOG_I("FuriHalVcp", "Init OK"); +} + +size_t furi_hal_vcp_rx(uint8_t* buffer, size_t size) { + furi_assert(furi_hal_vcp); + + size_t received = xStreamBufferReceive(furi_hal_vcp->rx_stream, buffer, size, portMAX_DELAY); + + if(furi_hal_vcp->rx_stream_full + &&xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream) >= APP_RX_DATA_SIZE) { + furi_hal_vcp->rx_stream_full = false; + // data accepted, start waiting for next packet + USBD_CDC_ReceivePacket(&hUsbDeviceFS); + } + + return received; +} + +size_t furi_hal_vcp_rx_with_timeout(uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(furi_hal_vcp); + return xStreamBufferReceive(furi_hal_vcp->rx_stream, buffer, size, timeout); +} + +void furi_hal_vcp_tx(const uint8_t* buffer, size_t size) { + furi_assert(furi_hal_vcp); + + while (size > 0 && furi_hal_vcp->connected) { + furi_check(osSemaphoreAcquire(furi_hal_vcp->tx_semaphore, osWaitForever) == osOK); + if (!furi_hal_vcp->connected) + break; + + 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 { + FURI_LOG_E("FuriHalVcp", "CDC_Transmit_FS failed"); + osDelay(50); + } + } +} + +void furi_hal_vcp_on_usb_resume() { + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); +} + +void furi_hal_vcp_on_usb_suspend() { + if (furi_hal_vcp->connected) { + furi_hal_vcp->connected = false; + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); + } +} + +void furi_hal_vcp_on_cdc_control_line(uint8_t state) { + // bit 0: DTR state, bit 1: RTS state + // bool dtr = state & 0b01; + bool dtr = state & 0b1; + + if (dtr) { + if (!furi_hal_vcp->connected) { + furi_hal_vcp->connected = true; + furi_hal_vcp_on_cdc_rx(&ascii_soh, 1); // SOH + } + } else { + if (furi_hal_vcp->connected) { + furi_hal_vcp_on_cdc_rx(&ascii_eot, 1); // EOT + furi_hal_vcp->connected = false; + } + } + + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); +} + +void furi_hal_vcp_on_cdc_rx(const uint8_t* buffer, size_t size) { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + size_t ret = xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, buffer, size, &xHigherPriorityTaskWoken); + furi_check(ret == size); + + if (xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream) >= APP_RX_DATA_SIZE) { + USBD_CDC_ReceivePacket(&hUsbDeviceFS); + } else { + furi_hal_vcp->rx_stream_full = true; + } + + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +void furi_hal_vcp_on_cdc_tx_complete(size_t size) { + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); +} + diff --git a/firmware/targets/f7/furi-hal/furi-hal-vcp_i.h b/firmware/targets/f7/furi-hal/furi-hal-vcp_i.h new file mode 100644 index 00000000..05ddc6ad --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-vcp_i.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +void furi_hal_vcp_on_usb_resume(); + +void furi_hal_vcp_on_usb_suspend(); + +void furi_hal_vcp_on_cdc_control_line(uint8_t state); + +void furi_hal_vcp_on_cdc_rx(const uint8_t* buffer, size_t size); + +void furi_hal_vcp_on_cdc_tx_complete(size_t size); diff --git a/firmware/targets/f7/furi-hal/furi-hal-version.c b/firmware/targets/f7/furi-hal/furi-hal-version.c new file mode 100644 index 00000000..d2f50039 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-version.c @@ -0,0 +1,242 @@ +#include + +#include +#include +#include + +#include +#include "ble.h" + +#define FURI_HAL_VERSION_OTP_HEADER_MAGIC 0xBABE +#define FURI_HAL_VERSION_NAME_LENGTH 8 +#define FURI_HAL_VERSION_ARRAY_NAME_LENGTH (FURI_HAL_VERSION_NAME_LENGTH + 1) +/** BLE symbol + "Flipper " + name */ +#define FURI_HAL_VERSION_DEVICE_NAME_LENGTH (1 + 8 + FURI_HAL_VERSION_ARRAY_NAME_LENGTH) +#define FURI_HAL_VERSION_OTP_ADDRESS OTP_AREA_BASE + +/** OTP Versions enum */ +typedef enum { + FuriHalVersionOtpVersion0=0x00, + FuriHalVersionOtpVersion1=0x01, + FuriHalVersionOtpVersionEmpty=0xFFFFFFFE, + FuriHalVersionOtpVersionUnknown=0xFFFFFFFF, +} FuriHalVersionOtpVersion; + +/** OTP V0 Structure: prototypes and early EVT */ +typedef struct { + uint8_t board_version; + uint8_t board_target; + uint8_t board_body; + uint8_t board_connect; + uint32_t header_timestamp; + char name[FURI_HAL_VERSION_NAME_LENGTH]; +} FuriHalVersionOTPv0; + +/** OTP V1 Structure: late EVT, DVT, PVT, Production */ +typedef struct { + /* First 64 bits: header */ + uint16_t header_magic; + uint8_t header_version; + uint8_t header_reserved; + uint32_t header_timestamp; + + /* Second 64 bits: board info */ + uint8_t board_version; /** Board version */ + uint8_t board_target; /** Board target firmware */ + uint8_t board_body; /** Board body */ + uint8_t board_connect; /** Board interconnect */ + uint8_t board_color; /** Board color */ + uint8_t board_region; /** Board region */ + uint16_t board_reserved; /** Reserved for future use, 0x0000 */ + + /* Third 64 bits: Unique Device Name */ + char name[FURI_HAL_VERSION_NAME_LENGTH]; /** Unique Device Name */ +} FuriHalVersionOTPv1; + +/** Represenation Model: */ +typedef struct { + FuriHalVersionOtpVersion otp_version; + + uint32_t timestamp; + + uint8_t board_version; /** Board version */ + uint8_t board_target; /** Board target firmware */ + uint8_t board_body; /** Board body */ + uint8_t board_connect; /** Board interconnect */ + uint8_t board_color; /** Board color */ + uint8_t board_region; /** Board region */ + + char name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH]; /** \0 terminated name */ + char device_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; /** device name for special needs */ + uint8_t ble_mac[6]; +} FuriHalVersion; + +static FuriHalVersion furi_hal_version = {0}; + +static FuriHalVersionOtpVersion furi_hal_version_get_otp_version() { + if (*(uint64_t*)FURI_HAL_VERSION_OTP_ADDRESS == 0xFFFFFFFF) { + return FuriHalVersionOtpVersionEmpty; + } else { + if (((FuriHalVersionOTPv1*)FURI_HAL_VERSION_OTP_ADDRESS)->header_magic == FURI_HAL_VERSION_OTP_HEADER_MAGIC) { + return FuriHalVersionOtpVersion1; + } else if (((FuriHalVersionOTPv0*)FURI_HAL_VERSION_OTP_ADDRESS)->board_version <= 10) { + return FuriHalVersionOtpVersion0; + } else { + return FuriHalVersionOtpVersionUnknown; + } + } +} + +static void furi_hal_version_set_name(const char* name) { + if(name != NULL) { + strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); + snprintf( + furi_hal_version.device_name, + FURI_HAL_VERSION_DEVICE_NAME_LENGTH, + "xFlipper %s", + furi_hal_version.name); + } else { + snprintf( + furi_hal_version.device_name, + FURI_HAL_VERSION_DEVICE_NAME_LENGTH, + "xFlipper"); + } + + furi_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; + + // BLE Mac address + uint32_t udn = LL_FLASH_GetUDN(); + uint32_t company_id = LL_FLASH_GetSTCompanyID(); + uint32_t device_id = LL_FLASH_GetDeviceID(); + furi_hal_version.ble_mac[0] = (uint8_t)(udn & 0x000000FF); + furi_hal_version.ble_mac[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 ); + furi_hal_version.ble_mac[2] = (uint8_t)( (udn & 0x00FF0000) >> 16 ); + furi_hal_version.ble_mac[3] = (uint8_t)device_id; + furi_hal_version.ble_mac[4] = (uint8_t)(company_id & 0x000000FF); + furi_hal_version.ble_mac[5] = (uint8_t)( (company_id & 0x0000FF00) >> 8 ); +} + +static void furi_hal_version_load_otp_default() { + furi_hal_version_set_name(NULL); +} + +static void furi_hal_version_load_otp_v0() { + const FuriHalVersionOTPv0* otp = (FuriHalVersionOTPv0*)FURI_HAL_VERSION_OTP_ADDRESS; + + furi_hal_version.timestamp = otp->header_timestamp; + furi_hal_version.board_version = otp->board_version; + furi_hal_version.board_target = otp->board_target; + furi_hal_version.board_body = otp->board_body; + furi_hal_version.board_connect = otp->board_connect; + furi_hal_version.board_color = 0; + furi_hal_version.board_region = 0; + + furi_hal_version_set_name(otp->name); +} + +static void furi_hal_version_load_otp_v1() { + const FuriHalVersionOTPv1* otp = (FuriHalVersionOTPv1*)FURI_HAL_VERSION_OTP_ADDRESS; + + furi_hal_version.timestamp = otp->header_timestamp; + furi_hal_version.board_version = otp->board_version; + furi_hal_version.board_target = otp->board_target; + furi_hal_version.board_body = otp->board_body; + furi_hal_version.board_connect = otp->board_connect; + furi_hal_version.board_color = otp->board_color; + furi_hal_version.board_region = otp->board_region; + + furi_hal_version_set_name(otp->name); +} + +void furi_hal_version_init() { + furi_hal_version.otp_version = furi_hal_version_get_otp_version(); + switch(furi_hal_version.otp_version) { + case FuriHalVersionOtpVersionUnknown: + furi_hal_version_load_otp_default(); + break; + case FuriHalVersionOtpVersionEmpty: + furi_hal_version_load_otp_default(); + break; + case FuriHalVersionOtpVersion0: + furi_hal_version_load_otp_v0(); + break; + case FuriHalVersionOtpVersion1: + furi_hal_version_load_otp_v1(); + break; + default: furi_check(0); + } + FURI_LOG_I("FuriHalVersion", "Init OK"); +} + +bool furi_hal_version_do_i_belong_here() { + return furi_hal_version_get_hw_target() == 7; +} + +const char* furi_hal_version_get_model_name() { + return "Flipper Zero"; +} + +const uint8_t furi_hal_version_get_hw_version() { + return furi_hal_version.board_version; +} + +const uint8_t furi_hal_version_get_hw_target() { + return furi_hal_version.board_target; +} + +const uint8_t furi_hal_version_get_hw_body() { + return furi_hal_version.board_body; +} + +const FuriHalVersionColor furi_hal_version_get_hw_color() { + return furi_hal_version.board_color; +} + +const uint8_t furi_hal_version_get_hw_connect() { + return furi_hal_version.board_connect; +} + +const FuriHalVersionRegion furi_hal_version_get_hw_region() { + return furi_hal_version.board_region; +} + +const uint32_t furi_hal_version_get_hw_timestamp() { + return furi_hal_version.timestamp; +} + +const char* furi_hal_version_get_name_ptr() { + return *furi_hal_version.name == 0x00 ? NULL : furi_hal_version.name; +} + +const char* furi_hal_version_get_device_name_ptr() { + return furi_hal_version.device_name + 1; +} + +const char* furi_hal_version_get_ble_local_device_name_ptr() { + return furi_hal_version.device_name; +} + +const uint8_t* furi_hal_version_get_ble_mac() { + return furi_hal_version.ble_mac; +} + +const struct Version* furi_hal_version_get_firmware_version(void) { + return version_get(); +} + +const struct Version* furi_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 +} + +size_t furi_hal_version_uid_size() { + return 64/8; +} + +const uint8_t* furi_hal_version_uid() { + return (const uint8_t *)UID64_BASE; +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-vibro.c b/firmware/targets/f7/furi-hal/furi-hal-vibro.c new file mode 100644 index 00000000..7dfddd42 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-vibro.c @@ -0,0 +1,13 @@ +#include +#include + +void furi_hal_vibro_init() { + hal_gpio_init(&vibro_gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + hal_gpio_write(&vibro_gpio, false); + FURI_LOG_I("FuriHalVibro", "Init OK"); + +} + +void furi_hal_vibro_on(bool value) { + hal_gpio_write(&vibro_gpio, value); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal.c b/firmware/targets/f7/furi-hal/furi-hal.c new file mode 100644 index 00000000..eebe1423 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal.c @@ -0,0 +1,65 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void furi_hal_init() { + furi_hal_clock_init(); + furi_hal_console_init(); + furi_hal_interrupt_init(); + furi_hal_delay_init(); + + MX_GPIO_Init(); + FURI_LOG_I("HAL", "GPIO OK"); + + MX_RTC_Init(); + FURI_LOG_I("HAL", "RTC OK"); + furi_hal_boot_init(); + furi_hal_version_init(); + + furi_hal_spi_init(); + + 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"); + + // VCP + USB + furi_hal_vcp_init(); + MX_USB_Device_Init(); + FURI_LOG_I("HAL", "USB OK"); + + furi_hal_i2c_init(); + + // High Level + furi_hal_power_init(); + furi_hal_light_init(); + furi_hal_vibro_init(); + furi_hal_subghz_init(); + furi_hal_nfc_init(); + furi_hal_rfid_init(); + + // FreeRTOS glue + furi_hal_os_init(); +} diff --git a/firmware/targets/f7/startup_stm32wb55xx_cm4.s b/firmware/targets/f7/startup_stm32wb55xx_cm4.s new file mode 100644 index 00000000..c5c2b3fc --- /dev/null +++ b/firmware/targets/f7/startup_stm32wb55xx_cm4.s @@ -0,0 +1,444 @@ +/** + ****************************************************************************** + * @file startup_stm32wb55xx_cm4.s + * @author MCD Application Team + * @brief STM32WB55xx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* start address for the .MB_MEM2 section. defined in linker script */ +.word _sMB_MEM2 +/* end address for the .MB_MEM2 section. defined in linker script */ +.word _eMB_MEM2 + +/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */ +.macro INIT_BSS start, end + ldr r0, =\start + ldr r1, =\end + movs r3, #0 + bl LoopFillZerobss +.endm + +/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */ +.macro INIT_DATA start, end, src + ldr r0, =\start + ldr r1, =\end + ldr r2, =\src + movs r3, #0 + bl LoopCopyDataInit +.endm + +.section .text.data_initializers +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + bx lr + +FillZerobss: + str r3, [r0] + adds r0, r0, #4 + +LoopFillZerobss: + cmp r0, r1 + bcc FillZerobss + bx lr + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + mov sp, r0 /* set stack pointer */ +/* Call the clock system intitialization function.*/ + bl SystemInit + +/* Copy the data segment initializers from flash to SRAM */ + INIT_DATA _sdata, _edata, _sidata + +/* Zero fill the bss segments. */ + INIT_BSS _sbss, _ebss + INIT_BSS _sMB_MEM2, _eMB_MEM2 + +/* Call static constructors */ + bl __libc_init_array +/* Call the application s entry point.*/ + bl main + +LoopForever: + b LoopForever + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex-M4. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_PVM_IRQHandler + .word TAMP_STAMP_LSECSS_IRQHandler + .word RTC_WKUP_IRQHandler + .word FLASH_IRQHandler + .word RCC_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word DMA1_Channel5_IRQHandler + .word DMA1_Channel6_IRQHandler + .word DMA1_Channel7_IRQHandler + .word ADC1_IRQHandler + .word USB_HP_IRQHandler + .word USB_LP_IRQHandler + .word C2SEV_PWR_C2H_IRQHandler + .word COMP_IRQHandler + .word EXTI9_5_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_TIM16_IRQHandler + .word TIM1_TRG_COM_TIM17_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word PKA_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word USART1_IRQHandler + .word LPUART1_IRQHandler + .word SAI1_IRQHandler + .word TSC_IRQHandler + .word EXTI15_10_IRQHandler + .word RTC_Alarm_IRQHandler + .word CRS_IRQHandler + .word PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .word IPCC_C1_RX_IRQHandler + .word IPCC_C1_TX_IRQHandler + .word HSEM_IRQHandler + .word LPTIM1_IRQHandler + .word LPTIM2_IRQHandler + .word LCD_IRQHandler + .word QUADSPI_IRQHandler + .word AES1_IRQHandler + .word AES2_IRQHandler + .word RNG_IRQHandler + .word FPU_IRQHandler + .word DMA2_Channel1_IRQHandler + .word DMA2_Channel2_IRQHandler + .word DMA2_Channel3_IRQHandler + .word DMA2_Channel4_IRQHandler + .word DMA2_Channel5_IRQHandler + .word DMA2_Channel6_IRQHandler + .word DMA2_Channel7_IRQHandler + .word DMAMUX1_OVR_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak TAMP_STAMP_LSECSS_IRQHandler + .thumb_set TAMP_STAMP_LSECSS_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_IRQHandler + .thumb_set DMA1_Channel2_IRQHandler,Default_Handler + + .weak DMA1_Channel3_IRQHandler + .thumb_set DMA1_Channel3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_IRQHandler + .thumb_set DMA1_Channel4_IRQHandler,Default_Handler + + .weak DMA1_Channel5_IRQHandler + .thumb_set DMA1_Channel5_IRQHandler,Default_Handler + + .weak DMA1_Channel6_IRQHandler + .thumb_set DMA1_Channel6_IRQHandler,Default_Handler + + .weak DMA1_Channel7_IRQHandler + .thumb_set DMA1_Channel7_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak USB_HP_IRQHandler + .thumb_set USB_HP_IRQHandler,Default_Handler + + .weak USB_LP_IRQHandler + .thumb_set USB_LP_IRQHandler,Default_Handler + + .weak C2SEV_PWR_C2H_IRQHandler + .thumb_set C2SEV_PWR_C2H_IRQHandler,Default_Handler + + .weak COMP_IRQHandler + .thumb_set COMP_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM16_IRQHandler + .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_TIM17_IRQHandler + .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak TSC_IRQHandler + .thumb_set TSC_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .thumb_set PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,Default_Handler + + .weak IPCC_C1_RX_IRQHandler + .thumb_set IPCC_C1_RX_IRQHandler,Default_Handler + + .weak IPCC_C1_TX_IRQHandler + .thumb_set IPCC_C1_TX_IRQHandler,Default_Handler + + .weak HSEM_IRQHandler + .thumb_set HSEM_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak LCD_IRQHandler + .thumb_set LCD_IRQHandler,Default_Handler + + .weak QUADSPI_IRQHandler + .thumb_set QUADSPI_IRQHandler,Default_Handler + + .weak AES1_IRQHandler + .thumb_set AES1_IRQHandler,Default_Handler + + .weak AES2_IRQHandler + .thumb_set AES2_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak DMA2_Channel1_IRQHandler + .thumb_set DMA2_Channel1_IRQHandler,Default_Handler + + .weak DMA2_Channel2_IRQHandler + .thumb_set DMA2_Channel2_IRQHandler,Default_Handler + + .weak DMA2_Channel3_IRQHandler + .thumb_set DMA2_Channel3_IRQHandler,Default_Handler + + .weak DMA2_Channel4_IRQHandler + .thumb_set DMA2_Channel4_IRQHandler,Default_Handler + + .weak DMA2_Channel5_IRQHandler + .thumb_set DMA2_Channel5_IRQHandler,Default_Handler + + .weak DMA2_Channel6_IRQHandler + .thumb_set DMA2_Channel6_IRQHandler,Default_Handler + + .weak DMA2_Channel7_IRQHandler + .thumb_set DMA2_Channel7_IRQHandler,Default_Handler + + .weak DMAMUX1_OVR_IRQHandler + .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/stm32wb55xx_flash_cm4_boot.ld b/firmware/targets/f7/stm32wb55xx_flash_cm4_boot.ld new file mode 100644 index 00000000..6d55107e --- /dev/null +++ b/firmware/targets/f7/stm32wb55xx_flash_cm4_boot.ld @@ -0,0 +1,192 @@ +/** +***************************************************************************** +** +** 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. +** +***************************************************************************** +** +**

© COPYRIGHT(c) 2019 Ac6

+** +** 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 = 0x400; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 992K +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 +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); + __heap_start__ = .; + . = ORIGIN(RAM1) + LENGTH(RAM1) - _Min_Stack_Size; + __heap_end__ = .; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM1 + + /* Free Flash space, that can be used for internal storage */ + .free_flash(NOLOAD): + { + __free_flash_start__ = .; + . = ORIGIN(FLASH) + LENGTH(FLASH); + } >FLASH + + /* 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 +} + + diff --git a/firmware/targets/f7/stm32wb55xx_flash_cm4_no_boot.ld b/firmware/targets/f7/stm32wb55xx_flash_cm4_no_boot.ld new file mode 100644 index 00000000..c03809f3 --- /dev/null +++ b/firmware/targets/f7/stm32wb55xx_flash_cm4_no_boot.ld @@ -0,0 +1,192 @@ +/** +***************************************************************************** +** +** 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. +** +***************************************************************************** +** +**

© COPYRIGHT(c) 2019 Ac6

+** +** 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 = 0x400; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 +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); + __heap_start__ = .; + . = ORIGIN(RAM1) + LENGTH(RAM1) - _Min_Stack_Size; + __heap_end__ = .; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM1 + + /* Free Flash space, that can be used for internal storage */ + .free_flash(NOLOAD): + { + __free_flash_start__ = .; + . = ORIGIN(FLASH) + LENGTH(FLASH); + } >FLASH + + /* 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 +} + + diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk new file mode 100644 index 00000000..d020c155 --- /dev/null +++ b/firmware/targets/f7/target.mk @@ -0,0 +1,169 @@ +TOOLCHAIN = arm + +BOOT_ADDRESS = 0x08000000 +FW_ADDRESS = 0x08008000 +OS_OFFSET = 0x00008000 +FLASH_ADDRESS = 0x08008000 + +NO_BOOTLOADER ?= 0 +ifeq ($(NO_BOOTLOADER), 1) +BOOT_ADDRESS = 0x08000000 +FW_ADDRESS = 0x08000000 +OS_OFFSET = 0x00000000 +FLASH_ADDRESS = 0x08000000 +CFLAGS += -DNO_BOOTLOADER +endif + +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 + +CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions +LDFLAGS += -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group + +MXPROJECT_DIR = $(TARGET_DIR) + +# Entry Point +ASM_SOURCES += $(MXPROJECT_DIR)/startup_stm32wb55xx_cm4.s + +# STM32WB HAL +CUBE_DIR = ../lib/STM32CubeWB +CFLAGS += \ + -DUSE_FULL_LL_DRIVER \ + -DUSE_HAL_DRIVER \ + -DHAVE_FREERTOS +CFLAGS += \ + -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc \ + -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc/Legacy \ + -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Include \ + -I$(CUBE_DIR)/Drivers/CMSIS/Include +C_SOURCES += \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_comp.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cortex.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash_ex.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_gpio.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_hsem.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_ipcc.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pka.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc_ex.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rng.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim_ex.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_adc.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_dma.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_lptim.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rcc.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_spi.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_tim.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c + +# FreeRTOS +CFLAGS += \ + -I$(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/include \ + -I$(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ + -I$(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F +C_SOURCES += \ + $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ + $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ + $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/list.c \ + $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/queue.c \ + $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \ + $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ + $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/timers.c \ + $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \ + $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c + +# BLE glue +CFLAGS += \ + -I$(TARGET_DIR)/ble-glue \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_WPAN \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/template \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/utilities \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci +C_SOURCES += \ + $(wildcard $(TARGET_DIR)/ble-glue/*.c) \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/utilities/otp.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/utilities/stm_list.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/utilities/dbg_trace.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/svc/Src/svc_ctl.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/template/osal.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_hci_le.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gap_aci.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gatt_aci.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_hal_aci.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/tl_mbox.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl_if.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl_if.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci/shci.c + +# USB glue +CFLAGS += \ + -I$(TARGET_DIR)/usb-glue \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Inc \ + -I$(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc +C_SOURCES += \ + $(wildcard $(TARGET_DIR)/usb-glue/*.c) \ + $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ + $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c + +# Furi HAL +FURI_HAL_OS_DEBUG ?= 0 +ifeq ($(FURI_HAL_OS_DEBUG), 1) +CFLAGS += -DFURI_HAL_OS_DEBUG +endif + +FURI_HAL_SUBGHZ_TX_GPIO ?= 0 +ifneq ($(FURI_HAL_SUBGHZ_TX_GPIO), 0) +CFLAGS += -DFURI_HAL_SUBGHZ_TX_GPIO=$(FURI_HAL_SUBGHZ_TX_GPIO) +endif + +ifeq ($(INVERT_RFID_IN), 1) +CFLAGS += -DINVERT_RFID_IN +endif + +FURI_HAL_DIR = $(TARGET_DIR)/furi-hal +CFLAGS += -I$(FURI_HAL_DIR) +C_SOURCES += $(wildcard $(FURI_HAL_DIR)/*.c) + +# Other +CFLAGS += \ + -I$(MXPROJECT_DIR)/Inc \ + -I$(MXPROJECT_DIR)/Src/fatfs +C_SOURCES += \ + $(wildcard $(MXPROJECT_DIR)/Src/*.c) \ + $(wildcard $(MXPROJECT_DIR)/Src/fatfs/*.c) + +# Linker options +ifeq ($(NO_BOOTLOADER), 1) +LDFLAGS += -T$(MXPROJECT_DIR)/stm32wb55xx_flash_cm4_no_boot.ld +else +LDFLAGS += -T$(MXPROJECT_DIR)/stm32wb55xx_flash_cm4_boot.ld +endif + +SVD_FILE = ../debug/STM32WB55_CM4.svd diff --git a/firmware/targets/f7/usb-glue/usb_device.c b/firmware/targets/f7/usb-glue/usb_device.c new file mode 100644 index 00000000..84e9143d --- /dev/null +++ b/firmware/targets/f7/usb-glue/usb_device.c @@ -0,0 +1,34 @@ +#include "usb_device.h" + +#include "stm32wbxx.h" +#include "stm32wbxx_hal.h" + +#include "usbd_def.h" +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_cdc.h" +#include "usbd_cdc_if.h" + +extern void Error_Handler(void); + +/* USB Device Core handle declaration. */ +USBD_HandleTypeDef hUsbDeviceFS; + +extern USBD_DescriptorsTypeDef CDC_Desc; + +/** Init USB device Library, add supported class and start the library */ +void MX_USB_Device_Init(void) { + /* 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(); + } +} diff --git a/firmware/targets/f7/usb-glue/usb_device.h b/firmware/targets/f7/usb-glue/usb_device.h new file mode 100644 index 00000000..7d80e348 --- /dev/null +++ b/firmware/targets/f7/usb-glue/usb_device.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus + extern "C" { +#endif + +void MX_USB_Device_Init(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/usb-glue/usbd_cdc_if.c b/firmware/targets/f7/usb-glue/usbd_cdc_if.c new file mode 100644 index 00000000..6b905c84 --- /dev/null +++ b/firmware/targets/f7/usb-glue/usbd_cdc_if.c @@ -0,0 +1,142 @@ +#include "usbd_cdc_if.h" +#include + +extern USBD_HandleTypeDef hUsbDeviceFS; + +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); + +USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = +{ + CDC_Init_FS, + CDC_DeInit_FS, + CDC_Control_FS, + CDC_Receive_FS, + CDC_TransmitCplt_FS +}; + +uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; +uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; + +/** 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) { + /* Set Application Buffers */ + USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0); + USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS); + return (USBD_OK); +} + +/** + * @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) { + return (USBD_OK); +} + +/** 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) { + 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) { + furi_hal_vcp_on_cdc_control_line(((USBD_SetupReqTypedef*)pbuf)->wValue); + } else if (cmd == CDC_SEND_BREAK) { + } else { + } + + return (USBD_OK); +} + +/** 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) { + if (*Len) { + furi_hal_vcp_on_cdc_rx(Buf, *Len); + } else { + USBD_CDC_ReceivePacket(&hUsbDeviceFS); + } + + return (USBD_OK); +} + +/** CDC_Transmit_FS Data to send over USB IN endpoint are sent over CDC interface + * through this function. + * @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; + + 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); + + return result; +} + +/** 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; + + furi_hal_vcp_on_cdc_tx_complete(*Len); + + return result; +} diff --git a/firmware/targets/f7/usb-glue/usbd_cdc_if.h b/firmware/targets/f7/usb-glue/usbd_cdc_if.h new file mode 100644 index 00000000..fc0aefbe --- /dev/null +++ b/firmware/targets/f7/usb-glue/usbd_cdc_if.h @@ -0,0 +1,22 @@ +#pragma once + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc.h" + +/* 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_FS_MAX_PACKET_SIZE +#define APP_TX_DATA_SIZE CDC_DATA_FS_MAX_PACKET_SIZE + +/** CDC Interface callback. */ +extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; + +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/usb-glue/usbd_conf.c b/firmware/targets/f7/usb-glue/usbd_conf.c new file mode 100644 index 00000000..cbc137e5 --- /dev/null +++ b/firmware/targets/f7/usb-glue/usbd_conf.c @@ -0,0 +1,506 @@ +#include "stm32wbxx.h" +#include "stm32wbxx_hal.h" + +#include + +#include "usbd_def.h" +#include "usbd_core.h" +#include "usbd_cdc.h" + +PCD_HandleTypeDef hpcd_USB_FS; +void Error_Handler(void); + +static USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status); + +static void SystemClockConfig_Resume(void); + +void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(pcdHandle->Instance==USB) { + __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); + } +} + +void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) { + if(pcdHandle->Instance==USB) { + /* 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); + } +} + +/** Setup stage callback + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) { + USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup); +} + +/** Data Out stage callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { + USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); +} + +/** Data In stage callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { + USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); +} + +/** SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) { + USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData); +} + +/** Reset callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) { + 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); +} + +/** 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 + */ +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) { + USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData); + + furi_hal_vcp_on_usb_suspend(); + + 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)); + } +} + +/** 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 + */ +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) { + 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(); + } + + furi_hal_vcp_on_usb_resume(); + + USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData); +} + +/** ISOOUTIncomplete callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { + USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); +} + +/** ISOINIncomplete callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { + USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); +} + +/** Connect callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) { + USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData); +} + +/** Disconnect callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) { + USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData); +} + +/** 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 (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) { + Error_Handler(); + } + + HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18); + HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58); + + 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); + + return USBD_OK; +} + +/** 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; +} + +/** 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; +} + +/** 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; +} + +/** 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; +} + +/** 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; +} + +/** 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; +} + +/** 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; +} + +/** 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; + } +} + +/** 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; +} + +/** 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; +} + +/** 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; +} + +/** 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); +} + +/** Send LPM message to user layer + * @param hpcd: PCD handle + * @param msg: LPM message + * @retval None + */ +void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) { + 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; + } +} + +/** Delays routine for the USB Device Library. + * @param Delay: Delay in ms + * @retval None + */ +void USBD_LL_Delay(uint32_t Delay) { + HAL_Delay(Delay); +} + +/** 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; +} + +/** Dummy memory free + * @param p: Pointer to allocated memory address + * @retval None + */ +void USBD_static_free(void *p) { +} + +/** 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) { +} + +/** 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; +} diff --git a/firmware/targets/f7/usb-glue/usbd_conf.h b/firmware/targets/f7/usb-glue/usbd_conf.h new file mode 100644 index 00000000..9e2a86f2 --- /dev/null +++ b/firmware/targets/f7/usb-glue/usbd_conf.h @@ -0,0 +1,73 @@ +#pragma once + +#include +#include +#include +#include "stm32wbxx.h" +#include "stm32wbxx_hal.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#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 0U +#define USBD_SELF_POWERED 0U + +/****************************************/ +/* #define for FS and HS identification */ +#define DEVICE_FS 0 + +/* 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 + +void *USBD_static_malloc(uint32_t size); +void USBD_static_free(void *p); + + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/usb-glue/usbd_desc.c b/firmware/targets/f7/usb-glue/usbd_desc.c new file mode 100644 index 00000000..96cc2cda --- /dev/null +++ b/firmware/targets/f7/usb-glue/usbd_desc.c @@ -0,0 +1,206 @@ +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_conf.h" +#include "furi-hal-version.h" + +#define USBD_VID 1155 +#define USBD_LANGID_STRING 1033 +#define USBD_MANUFACTURER_STRING "Flipper Devices Inc." +#define USBD_PID 22336 +#define USBD_CONFIGURATION_STRING "CDC Config" +#define USBD_INTERFACE_STRING "CDC Interface" + +static void Get_SerialNum(void); +static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len); + +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); + +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 +}; + +/** 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 */ + +/** 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) +}; + +/* Internal string descriptor. */ +__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; + +__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = { + USB_SIZ_STRING_SERIAL, + USB_DESC_TYPE_STRING, +}; + +/** 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; +} + +/** 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; +} + +/** 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) { + USBD_GetString((uint8_t*)furi_hal_version_get_device_name_ptr(), USBD_StrDesc, length); + return USBD_StrDesc; +} + +/** 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; +} + +/** 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(furi_hal_version_get_name_ptr()){ + char buffer[14] = "flip_"; + strncat(buffer, furi_hal_version_get_name_ptr(), 8); + USBD_GetString((uint8_t*) buffer, USBD_StringSerial, length); + } else { + Get_SerialNum(); + } + + return (uint8_t *) USBD_StringSerial; +} + +/** 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; +} + +/** 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; +} + +/** 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); + } +} + +/** 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; + } +} diff --git a/firmware/targets/f7/usb-glue/usbd_desc.h b/firmware/targets/f7/usb-glue/usbd_desc.h new file mode 100644 index 00000000..795b33e4 --- /dev/null +++ b/firmware/targets/f7/usb-glue/usbd_desc.h @@ -0,0 +1,19 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "usbd_def.h" + +#define DEVICE_ID1 (UID_BASE) +#define DEVICE_ID2 (UID_BASE + 0x4) +#define DEVICE_ID3 (UID_BASE + 0x8) + +#define USB_SIZ_STRING_SERIAL 0x1E + +extern USBD_DescriptorsTypeDef CDC_Desc; + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/furi-hal-include/furi-hal-rfid.h b/firmware/targets/furi-hal-include/furi-hal-rfid.h index d0a6aeaa..8c76d66d 100644 --- a/firmware/targets/furi-hal-include/furi-hal-rfid.h +++ b/firmware/targets/furi-hal-include/furi-hal-rfid.h @@ -7,6 +7,9 @@ extern "C" { #endif +/** Initialize RFID subsystem */ +void furi_hal_rfid_init(); + /** * @brief config rfid pins to reset state * diff --git a/scripts/otp.py b/scripts/otp.py index 999e2766..4b42f636 100755 --- a/scripts/otp.py +++ b/scripts/otp.py @@ -70,10 +70,10 @@ class Main: self.args.func() def _add_args(self, parser): - parser.add_argument("--version", type=int, help="Version", default=10) - parser.add_argument("--firmware", type=int, help="Firmware", default=6) - parser.add_argument("--body", type=int, help="Body", default=8) - parser.add_argument("--connect", type=int, help="Connect", default=5) + parser.add_argument("--version", type=int, help="Version", default=11) + parser.add_argument("--firmware", type=int, help="Firmware", default=7) + parser.add_argument("--body", type=int, help="Body", default=9) + parser.add_argument("--connect", type=int, help="Connect", default=6) parser.add_argument("--color", type=str, help="Color", default="unknown") parser.add_argument("--region", type=str, help="Region", default="unknown") parser.add_argument("--name", type=str, help="Name", required=True)