├── debug ├── gdb.cfg ├── ftdi │ ├── ft2232h.cfg │ └── swd.cfg └── rtl8762c.cfg ├── src ├── targets │ ├── 06-i2c_ssd1306 │ │ ├── README.md │ │ ├── mksrc.mk │ │ ├── app_flags.h │ │ ├── ssd1306.h │ │ └── main.c │ ├── 00-blink │ │ ├── mksrc.mk │ │ ├── main.c │ │ └── app_flags.h │ ├── 03-button │ │ ├── mksrc.mk │ │ ├── main.c │ │ └── app_flags.h │ ├── 01-uart_echo │ │ ├── mksrc.mk │ │ ├── app_flags.h │ │ └── main.c │ ├── 04-button_interrupt │ │ ├── mksrc.mk │ │ ├── main.c │ │ └── app_flags.h │ ├── 05-i2c_scan │ │ ├── mksrc.mk │ │ ├── app_flags.h │ │ └── main.c │ ├── 02-uart_pinscan │ │ ├── mksrc.mk │ │ ├── main.c │ │ └── app_flags.h │ └── README.md ├── i2c │ ├── i2c.c │ └── i2c.h ├── rcc │ └── rcc.h ├── uart │ ├── uart.h │ └── uart.c └── pin │ ├── pin.h │ └── pin.c ├── .gitmodules ├── boards ├── FT10 │ ├── board_config.mk │ └── board_config.h ├── EMB1082 │ ├── board_config.mk │ └── board_config.h └── devboard │ ├── board_config.mk │ └── board_config.h ├── mem_define.ld ├── shell.nix ├── .gitignore ├── tools └── crc_patch.py ├── mkenv.mk ├── README.md ├── config ├── ota_bank0_header.c ├── mem_config.h ├── otp_config.h ├── oem_config.c └── flash_map.h ├── rtl8762c.ld ├── mkrules.mk └── Makefile /debug/gdb.cfg: -------------------------------------------------------------------------------- 1 | gdb_memory_map disable 2 | gdb_port pipe 3 | -------------------------------------------------------------------------------- /debug/ftdi/ft2232h.cfg: -------------------------------------------------------------------------------- 1 | interface ftdi 2 | ftdi_vid_pid 0x0403 0x6010 -------------------------------------------------------------------------------- /src/targets/06-i2c_ssd1306/README.md: -------------------------------------------------------------------------------- 1 | [Datasheet](https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf) -------------------------------------------------------------------------------- /src/targets/00-blink/mksrc.mk: -------------------------------------------------------------------------------- 1 | SRC_C += $(wildcard \ 2 | $(TARGET_DIR)/*.c \ 3 | src/pin/*.c \ 4 | ) 5 | -------------------------------------------------------------------------------- /src/targets/03-button/mksrc.mk: -------------------------------------------------------------------------------- 1 | SRC_C += $(wildcard \ 2 | $(TARGET_DIR)/*.c \ 3 | src/pin/*.c \ 4 | ) 5 | -------------------------------------------------------------------------------- /src/targets/01-uart_echo/mksrc.mk: -------------------------------------------------------------------------------- 1 | SRC_C += $(wildcard \ 2 | $(TARGET_DIR)/*.c \ 3 | src/uart/*.c \ 4 | ) 5 | -------------------------------------------------------------------------------- /src/targets/04-button_interrupt/mksrc.mk: -------------------------------------------------------------------------------- 1 | SRC_C += $(wildcard \ 2 | $(TARGET_DIR)/*.c \ 3 | src/pin/*.c \ 4 | ) 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tools/rtltool"] 2 | path = tools/rtltool 3 | url = https://github.com/cyber-murmel/rtltool.git 4 | -------------------------------------------------------------------------------- /boards/FT10/board_config.mk: -------------------------------------------------------------------------------- 1 | FLASH_SIZE = 0x00800000 # 8 MiB 2 | FIRMWARE_SIZE = 0x00019000 # 100 kiB 3 | 4 | PORT ?= /dev/ttyUSB0 5 | -------------------------------------------------------------------------------- /src/targets/05-i2c_scan/mksrc.mk: -------------------------------------------------------------------------------- 1 | SRC_C += $(wildcard \ 2 | $(TARGET_DIR)/*.c \ 3 | src/i2c/*.c \ 4 | src/uart/*.c \ 5 | ) 6 | -------------------------------------------------------------------------------- /boards/EMB1082/board_config.mk: -------------------------------------------------------------------------------- 1 | FLASH_SIZE = 0x00080000 # 512 kiB 2 | FIRMWARE_SIZE = 0x00019000 # 100 kiB 3 | 4 | PORT ?= /dev/ttyACM0 5 | -------------------------------------------------------------------------------- /boards/devboard/board_config.mk: -------------------------------------------------------------------------------- 1 | FLASH_SIZE = 0x00080000 # 512 kiB 2 | FIRMWARE_SIZE = 0x00019000 # 100 kiB 3 | 4 | PORT ?= /dev/ttyACM0 5 | -------------------------------------------------------------------------------- /src/targets/02-uart_pinscan/mksrc.mk: -------------------------------------------------------------------------------- 1 | SRC_C += $(wildcard \ 2 | $(TARGET_DIR)/*.c \ 3 | src/pin/*.c \ 4 | src/uart/*.c \ 5 | ) 6 | -------------------------------------------------------------------------------- /src/targets/06-i2c_ssd1306/mksrc.mk: -------------------------------------------------------------------------------- 1 | SRC_C += $(wildcard \ 2 | $(TARGET_DIR)/*.c \ 3 | src/i2c/*.c \ 4 | src/uart/*.c \ 5 | ) 6 | -------------------------------------------------------------------------------- /mem_define.ld: -------------------------------------------------------------------------------- 1 | APP_ADDR = 0x0080E000; 2 | APP_SIZE = FIRMWARE_SIZE; 3 | APP_GLOBAL_SIZE = (35 * 1024); 4 | SHARE_CACHE_RAM_SIZE = (16 * 1024); 5 | -------------------------------------------------------------------------------- /boards/EMB1082/board_config.h: -------------------------------------------------------------------------------- 1 | #define BOARD_NAME "devboard" 2 | #define MCU_NAME "RTL8762C" 3 | 4 | #define BOARD_TX_PAD (P3_0) 5 | #define BOARD_RX_PAD (P3_1) 6 | 7 | #define LED_PAD (P0_0) 8 | -------------------------------------------------------------------------------- /boards/FT10/board_config.h: -------------------------------------------------------------------------------- 1 | #define BOARD_NAME "FT10 Smartwatch" 2 | #define MCU_NAME "RTL8762C" 3 | 4 | #define BOARD_TX_PAD (P3_0) 5 | #define BOARD_RX_PAD (P3_1) 6 | 7 | #define LED_PAD (H_0) 8 | -------------------------------------------------------------------------------- /src/targets/README.md: -------------------------------------------------------------------------------- 1 | # Targets 2 | Each target directory contains 3 | - application specific source code 4 | - `mksrc.mk` declaring all source files 5 | - `app_flags.h` defining app specific values used by the SDK 6 | -------------------------------------------------------------------------------- /boards/devboard/board_config.h: -------------------------------------------------------------------------------- 1 | #ifndef _BOARDS_DEVBOARD_BOARD_CONFIG_H 2 | #define _BOARDS_DEVBOARD_BOARD_CONFIG_H 3 | 4 | #define BOARD_NAME "devboard" 5 | #define MCU_NAME "RTL8762CKF" 6 | 7 | #include "pin/pin.h" 8 | 9 | #define BOARD_TX_PAD (P3_0) 10 | #define BOARD_RX_PAD (P3_1) 11 | 12 | #define LED_PAD (P4_3) 13 | 14 | #define BUTTON_PAD P1_7 15 | 16 | #endif // _BOARDS_DEVBOARD_BOARD_CONFIG_H 17 | -------------------------------------------------------------------------------- /src/targets/00-blink/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "board_config.h" 4 | #include "pin/pin.h" 5 | 6 | // prevent `warning: function with qualified void return type called` 7 | #define delay_ms(T) (((void (*)(uint32_t))platform_delay_ms)(T)) 8 | 9 | int main(void) 10 | { 11 | pin_t* led_pin_p = &PIN_OUT(&PIN_INSTANCE(LED_PAD)); 12 | 13 | pins_init(); 14 | 15 | pin_init(led_pin_p); 16 | 17 | while (1) { 18 | pin_set(led_pin_p, !pin_get(led_pin_p)); 19 | delay_ms(1000); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { 2 | # nixpkgs 22.11, deterministic. Last updated: 2023-04-12. 3 | pkgs ? import (fetchTarball ("https://github.com/NixOS/nixpkgs/archive/115a96e2ac1e92937cd47c30e073e16dcaaf6247.tar.gz")) { } 4 | }: 5 | 6 | with pkgs; 7 | let 8 | my-python-packages = python-packages: with python-packages; [ 9 | pyserial 10 | crccheck 11 | coloredlogs 12 | ipython 13 | ]; 14 | python-with-my-packages = python3.withPackages my-python-packages; 15 | in 16 | mkShell { 17 | buildInputs = [ 18 | gnumake 19 | gcc-arm-embedded-10 20 | clang-tools 21 | python-with-my-packages 22 | openocd 23 | ]; 24 | } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # Project Specific 55 | build/ 56 | openocd.log 57 | *.bin 58 | 59 | # IDE Specific 60 | .vscode/ 61 | 62 | # SDK Archive 63 | *.zip 64 | /sdk/ 65 | -------------------------------------------------------------------------------- /tools/crc_patch.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | from sys import argv 4 | from struct import pack, unpack 5 | 6 | from crccheck.crc import CrcArc 7 | 8 | if __name__ == "__main__": 9 | with open(argv[1], "rb+") as file: 10 | file.seek(0x4) 11 | id = unpack(" 2 | 3 | #include "board_config.h" 4 | #include "pin/pin.h" 5 | 6 | #include 7 | 8 | int main(void) 9 | { 10 | pin_t board_pins[(sizeof(pin_instances) / sizeof(pin_instances[0]))]; 11 | pin_t* button_pin_p = &PIN_IN(&PIN_INSTANCE(BUTTON_PAD)); 12 | 13 | pins_init(); 14 | 15 | for (int idx = 0; idx < (sizeof(pin_instances) / sizeof(pin_instances[0])); idx++) { 16 | if (BUTTON_PAD != pin_instances[idx].pad) { 17 | pin_t* pin_p = &board_pins[idx]; 18 | 19 | *pin_p = PIN_OUT(&pin_instances[idx]); 20 | pin_p->value = 0; 21 | 22 | pin_init(pin_p); 23 | } 24 | } 25 | 26 | pin_init(button_pin_p); 27 | 28 | while (1) { 29 | for (int idx = 0; idx < (sizeof(pin_instances) / sizeof(pin_instances[0])); idx++) { 30 | if (BUTTON_PAD != pin_instances[idx].pad) { 31 | pin_t* pin_p = &board_pins[idx]; 32 | 33 | while (pin_get(button_pin_p)) 34 | ; 35 | 36 | pin_set(pin_p, !pin_get(pin_p)); 37 | 38 | while (!pin_get(button_pin_p)) 39 | ; 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/targets/04-button_interrupt/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "board_config.h" 4 | #include "pin/pin.h" 5 | 6 | #include 7 | 8 | static pin_t board_pins[(sizeof(pin_instances) / sizeof(pin_instances[0]))]; 9 | static volatile int pin_idx = 0; 10 | 11 | void button_interrupt_handler(uint8_t pad, bool state, uint32_t tick) 12 | { 13 | if (BUTTON_PAD != pin_instances[pin_idx].pad) { 14 | pin_t* pin_p = &board_pins[pin_idx]; 15 | pin_set(pin_p, !pin_get(pin_p)); 16 | } 17 | 18 | if (pin_idx < ((sizeof(pin_instances) / sizeof(pin_instances[0])) - 1)) { 19 | pin_idx++; 20 | } else { 21 | pin_idx = 0; 22 | } 23 | } 24 | 25 | int main(void) 26 | { 27 | pin_t button_pin = PIN_IN_IRQ(&PIN_INSTANCE_IRQ(BUTTON_PAD)); 28 | 29 | pins_init(); 30 | 31 | for (int idx = 0; idx < (sizeof(pin_instances) / sizeof(pin_instances[0])); idx++) { 32 | if (BUTTON_PAD != pin_instances[idx].pad) { 33 | pin_t* pin_p = &board_pins[idx]; 34 | 35 | *pin_p = PIN_OUT(&pin_instances[idx]); 36 | pin_p->value = 0; 37 | 38 | pin_init(pin_p); 39 | } 40 | } 41 | 42 | pins_set_interrupt_handler(button_interrupt_handler); 43 | 44 | pin_init(&button_pin); 45 | __enable_irq(); 46 | 47 | while (1) { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /debug/ftdi/swd.cfg: -------------------------------------------------------------------------------- 1 | source [find interface/ftdi/swd-resistor-hack.cfg] 2 | # 3 | ## Connect TDI to SWDIO via a suitable series resistor (220-470 Ohm or 4 | ## so depending on the drive capability of the target and adapter); 5 | ## connect TDO directly to SWDIO. 6 | ## 7 | ## You also need to have reliable GND connection between the target and 8 | ## adapter. Vref of the adapter should be supplied with a voltage equal 9 | ## to the target's (preferrably connect it to Vcc). You can also 10 | ## optionally connect nSRST. Leave everything else unconnected. 11 | ## 12 | ## FTDI Target 13 | ## ---- ------ 14 | ## 1 - Vref ----------------- Vcc 15 | ## 3 - nTRST - 16 | ## 4 - GND ----------------- GND 17 | ## 5 - TDI ---/\470 Ohm/\--- SWDIO 18 | ## 7 - TMS - 19 | ## 9 - TCK ----------------- SWCLK 20 | ## 11 - RTCK - 21 | ## 13 - TDO ----------------- SWDIO 22 | ## 15 - nSRST - - - - - - - - - nRESET 23 | # 24 | ftdi_layout_init 0x0018 0x05fb 25 | # 26 | ## direction 0x05fb = 0000010111111011 27 | ## data 0x0018 = 0000000000011000 28 | ## ^^^ 29 | ## ||+-TCK [AB]DBUS0 30 | ## |+--TDI [AB]DBUS1 31 | ## +---TDO [AB]DBUS2 32 | # 33 | # make available to GDB 34 | gdb_memory_map disable 35 | gdb_port pipe 36 | -------------------------------------------------------------------------------- /debug/rtl8762c.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # rtl8762c target 3 | # 4 | 5 | source [find target/swj-dp.tcl] 6 | 7 | if { [info exists CHIPNAME] } { 8 | set _CHIPNAME $CHIPNAME 9 | } else { 10 | set _CHIPNAME rtl8762c 11 | } 12 | 13 | # Work-area is a space in RAM used for flash programming 14 | # By default use 2kB 15 | if { [info exists WORKSIZE] } { 16 | set _WORKSIZE $WORKSIZE 17 | } else { 18 | set _WORKSIZE 0x4000 19 | } 20 | if { [info exists WORKBASE] } { 21 | set _WORKBASE $WORKBASE 22 | } else { 23 | set _WORKBASE 0x00200000 24 | } 25 | 26 | if { [info exists CPUTAPID] } { 27 | set _CPUTAPID $CPUTAPID 28 | } else { 29 | set _CPUTAPID 0x2ba01477 30 | } 31 | 32 | if { [info exists ENDIAN] } { 33 | set _ENDIAN $ENDIAN 34 | } else { 35 | set _ENDIAN little 36 | } 37 | 38 | if {[using_hla]} { 39 | swj_newdap $_CHIPNAME.core cpu -expected-id $_CPUTAPID 40 | } else { 41 | swj_newdap $_CHIPNAME.core cpu -dp-id $_CPUTAPID -instance-id 0 42 | } 43 | 44 | set _TARGETNAME $_CHIPNAME.core 45 | dap create $_TARGETNAME.dap -chain-position $_CHIPNAME.core.cpu 46 | target create $_TARGETNAME cortex_m -endian $_ENDIAN -coreid 0 -dap $_TARGETNAME.dap -rtos hwthread 47 | $_TARGETNAME configure -work-area-phys $_WORKBASE -work-area-size $_WORKSIZE -work-area-backup 0 48 | 49 | target smp $_TARGETNAME 50 | 51 | adapter speed 1000 52 | 53 | set _FLASHNAME $_CHIPNAME.flash 54 | flash bank $_FLASHNAME efm32 0x00800000 0x80000 0 0 $_TARGETNAME 55 | 56 | if {![using_hla]} { 57 | # if srst is not fitted use SYSRESETREQ to 58 | # perform a soft reset 59 | cortex_m reset_config sysresetreq 60 | } 61 | 62 | # hardware breakpoints required 63 | gdb_breakpoint_override hard 64 | -------------------------------------------------------------------------------- /mkenv.mk: -------------------------------------------------------------------------------- 1 | ifneq ($(lastword a b),b) 2 | $(error These Makefiles require make 3.81 or newer) 3 | endif 4 | 5 | # Set TOP to be the path to get from the current directory (where make was 6 | # invoked) to the top of the tree. $(lastword $(MAKEFILE_LIST)) returns 7 | # the name of this makefile relative to where make was invoked. 8 | # 9 | # We assume that this file is in the py directory so we use $(dir ) twice 10 | # to get to the top of the tree. 11 | 12 | THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST)) 13 | TOP := $(patsubst %mkenv.mk,%,$(THIS_MAKEFILE)) 14 | 15 | # Turn on increased build verbosity by defining BUILD_VERBOSE in your main 16 | # Makefile or in your environment. You can also use V=1 on the make command 17 | # line. 18 | 19 | ifeq ("$(origin V)", "command line") 20 | BUILD_VERBOSE=$(V) 21 | endif 22 | ifndef BUILD_VERBOSE 23 | $(info Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.) 24 | BUILD_VERBOSE = 0 25 | endif 26 | ifeq ($(BUILD_VERBOSE),0) 27 | Q = @ 28 | else 29 | Q = 30 | endif 31 | 32 | # default settings; can be overridden in main Makefile 33 | 34 | BUILD ?= build 35 | 36 | RM = rm 37 | ECHO = @echo 38 | CP = cp 39 | MKDIR = mkdir 40 | SED = sed 41 | CAT = cat 42 | TOUCH = touch 43 | PYTHON = python3 44 | DD = dd 45 | 46 | AS = $(CROSS_COMPILE)as 47 | CC = $(CROSS_COMPILE)gcc 48 | CXX = $(CROSS_COMPILE)g++ 49 | GDB = $(CROSS_COMPILE)gdb 50 | LD = $(CROSS_COMPILE)ld 51 | OBJCOPY = $(CROSS_COMPILE)objcopy 52 | SIZE = $(CROSS_COMPILE)size 53 | STRIP = $(CROSS_COMPILE)strip 54 | AR = $(CROSS_COMPILE)ar 55 | 56 | all: 57 | 58 | clean: 59 | $(Q)$(RM) -rf $(BUILD) 60 | 61 | .PHONY: all clean 62 | 63 | .DELETE_ON_ERROR: 64 | 65 | MKENV_INCLUDED = 1 66 | -------------------------------------------------------------------------------- /src/targets/02-uart_pinscan/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "board_config.h" 12 | #include "pin/pin.h" 13 | #include "uart/uart.h" 14 | 15 | #define MAIN_TASK_PRIORITY (1) 16 | #define MAIN_TASK_STACK_SIZE (256 * 4) 17 | 18 | void* main_task_p; 19 | 20 | char tx_buf[16]; 21 | 22 | uart_t uart = { 23 | .instance_p = &UART_INSTANCE(0), 24 | .pads = { 25 | .tx = -1, 26 | .rx = -1, 27 | }, 28 | .parity = NO_PARTY, 29 | .stop_bits = STOP_BITS_1, 30 | .word_length = WORD_LENGTH_8, 31 | .tx_buf = { 32 | .size = sizeof(tx_buf), 33 | .data = tx_buf, 34 | }, 35 | }; 36 | // prevent `warning: function with qualified void return type called` 37 | #define delay_ms(T) (((void (*)(uint32_t))platform_delay_ms)(T)) 38 | void main_task(void* p_param) 39 | { 40 | uart_init(&uart); 41 | while (1) { 42 | for (int idx = 0; idx < (sizeof(pin_instances) / sizeof(pin_instances[0])); idx++) { 43 | pin_t pin = { 44 | .instance_p = &pin_instances[idx], 45 | }; 46 | uart.pads.tx = pin.instance_p->pad; 47 | 48 | uart_pinmux(&uart); 49 | 50 | uart_printf(&uart, "%d\r\n", pin.instance_p->pad); 51 | uart_flush(&uart); 52 | 53 | pin_deinit(&pin); 54 | 55 | os_delay(10); 56 | } 57 | } 58 | } 59 | 60 | int main(void) 61 | { 62 | os_task_create(&main_task_p, "main_task", main_task, 0, MAIN_TASK_STACK_SIZE, 63 | MAIN_TASK_PRIORITY); 64 | 65 | os_sched_start(); 66 | } 67 | -------------------------------------------------------------------------------- /src/targets/00-blink/app_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _APP_FLAGS_H_ 2 | #define _APP_FLAGS_H_ 3 | 4 | /** Config APP LE link number */ 5 | #define APP_MAX_LINKS 1 6 | /** Config APP LE bond number */ 7 | #define APP_MAX_BONDS 4 8 | /** Config DLPS: 0-Disable DLPS, 1-Enable DLPS */ 9 | #define F_BT_DLPS_EN 0 10 | /** Config ANCS Client: 0-Not built in, 1-Open ANCS client function */ 11 | #define F_BT_ANCS_CLIENT_SUPPORT 0 12 | #define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1) 13 | #define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0) 14 | /** Config ANCS Client debug log: 0-close, 1-open */ 15 | #define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0) 16 | 17 | /** Flags for activating some undocumented features within the Realtek 18 | * libs. All flags are set to 0 because they were't defined and defaultet to 0. 19 | * Now they must be defined because of activating -Wundefined within the 20 | * makefile to prevent configuration failures without any warnings or errors. 21 | */ 22 | /** Enable write hardfault record to flash. */ 23 | #define ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH 0 24 | /** Before watchdog system reset, write reset reason to specific flash address. 25 | */ 26 | #define WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE 0 27 | /** Internal Realtek lib error dumping of lib on watchdog reset. */ 28 | #define DUMP_INFO_BEFORE_RESET_DISABLE 0 29 | /** Internal Realtek lib debug functionality. */ 30 | #define ENABLE_FLASH_READ_TURN_OFF_RF 0 31 | /** Internal Realtek lib debug functionality. */ 32 | #define ROM_OTA_LINKLOSS_RST 0 33 | 34 | #define OTA_BUF_CHECK_EN 1 35 | #define DFU_TEMP_BUFFER_SIZE (2048) 36 | 37 | /** Enable Debug Monitor Function (include NVIC Enable and DWT configuration). 38 | */ 39 | #define DEBUG_WATCHPOINT_ENABLE 0 40 | 41 | #define F_BT_LE_5_0_AE_ADV_SUPPORT 0 42 | #define F_BT_LE_5_0_AE_SCAN_SUPPORT 0 43 | #define F_BT_LE_6_0_AOA_AOD_SUPPORT 0 44 | 45 | /** Enable multibonding configuration.*/ 46 | // #define BT_STACK_CONFIG_ENABLE 47 | 48 | #endif -------------------------------------------------------------------------------- /src/targets/01-uart_echo/app_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _APP_FLAGS_H_ 2 | #define _APP_FLAGS_H_ 3 | 4 | /** Config APP LE link number */ 5 | #define APP_MAX_LINKS 1 6 | /** Config APP LE bond number */ 7 | #define APP_MAX_BONDS 4 8 | /** Config DLPS: 0-Disable DLPS, 1-Enable DLPS */ 9 | #define F_BT_DLPS_EN 0 10 | /** Config ANCS Client: 0-Not built in, 1-Open ANCS client function */ 11 | #define F_BT_ANCS_CLIENT_SUPPORT 0 12 | #define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1) 13 | #define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0) 14 | /** Config ANCS Client debug log: 0-close, 1-open */ 15 | #define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0) 16 | 17 | /** Flags for activating some undocumented features within the Realtek 18 | * libs. All flags are set to 0 because they were't defined and defaultet to 0. 19 | * Now they must be defined because of activating -Wundefined within the 20 | * makefile to prevent configuration failures without any warnings or errors. 21 | */ 22 | /** Enable write hardfault record to flash. */ 23 | #define ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH 0 24 | /** Before watchdog system reset, write reset reason to specific flash address. 25 | */ 26 | #define WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE 0 27 | /** Internal Realtek lib error dumping of lib on watchdog reset. */ 28 | #define DUMP_INFO_BEFORE_RESET_DISABLE 0 29 | /** Internal Realtek lib debug functionality. */ 30 | #define ENABLE_FLASH_READ_TURN_OFF_RF 0 31 | /** Internal Realtek lib debug functionality. */ 32 | #define ROM_OTA_LINKLOSS_RST 0 33 | 34 | #define OTA_BUF_CHECK_EN 1 35 | #define DFU_TEMP_BUFFER_SIZE (2048) 36 | 37 | /** Enable Debug Monitor Function (include NVIC Enable and DWT configuration). 38 | */ 39 | #define DEBUG_WATCHPOINT_ENABLE 0 40 | 41 | #define F_BT_LE_5_0_AE_ADV_SUPPORT 0 42 | #define F_BT_LE_5_0_AE_SCAN_SUPPORT 0 43 | #define F_BT_LE_6_0_AOA_AOD_SUPPORT 0 44 | 45 | /** Enable multibonding configuration.*/ 46 | // #define BT_STACK_CONFIG_ENABLE 47 | 48 | #endif -------------------------------------------------------------------------------- /src/targets/03-button/app_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _APP_FLAGS_H_ 2 | #define _APP_FLAGS_H_ 3 | 4 | /** Config APP LE link number */ 5 | #define APP_MAX_LINKS 1 6 | /** Config APP LE bond number */ 7 | #define APP_MAX_BONDS 4 8 | /** Config DLPS: 0-Disable DLPS, 1-Enable DLPS */ 9 | #define F_BT_DLPS_EN 0 10 | /** Config ANCS Client: 0-Not built in, 1-Open ANCS client function */ 11 | #define F_BT_ANCS_CLIENT_SUPPORT 0 12 | #define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1) 13 | #define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0) 14 | /** Config ANCS Client debug log: 0-close, 1-open */ 15 | #define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0) 16 | 17 | /** Flags for activating some undocumented features within the Realtek 18 | * libs. All flags are set to 0 because they were't defined and defaultet to 0. 19 | * Now they must be defined because of activating -Wundefined within the 20 | * makefile to prevent configuration failures without any warnings or errors. 21 | */ 22 | /** Enable write hardfault record to flash. */ 23 | #define ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH 0 24 | /** Before watchdog system reset, write reset reason to specific flash address. 25 | */ 26 | #define WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE 0 27 | /** Internal Realtek lib error dumping of lib on watchdog reset. */ 28 | #define DUMP_INFO_BEFORE_RESET_DISABLE 0 29 | /** Internal Realtek lib debug functionality. */ 30 | #define ENABLE_FLASH_READ_TURN_OFF_RF 0 31 | /** Internal Realtek lib debug functionality. */ 32 | #define ROM_OTA_LINKLOSS_RST 0 33 | 34 | #define OTA_BUF_CHECK_EN 1 35 | #define DFU_TEMP_BUFFER_SIZE (2048) 36 | 37 | /** Enable Debug Monitor Function (include NVIC Enable and DWT configuration). 38 | */ 39 | #define DEBUG_WATCHPOINT_ENABLE 0 40 | 41 | #define F_BT_LE_5_0_AE_ADV_SUPPORT 0 42 | #define F_BT_LE_5_0_AE_SCAN_SUPPORT 0 43 | #define F_BT_LE_6_0_AOA_AOD_SUPPORT 0 44 | 45 | /** Enable multibonding configuration.*/ 46 | // #define BT_STACK_CONFIG_ENABLE 47 | 48 | #endif -------------------------------------------------------------------------------- /src/targets/05-i2c_scan/app_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _APP_FLAGS_H_ 2 | #define _APP_FLAGS_H_ 3 | 4 | /** Config APP LE link number */ 5 | #define APP_MAX_LINKS 1 6 | /** Config APP LE bond number */ 7 | #define APP_MAX_BONDS 4 8 | /** Config DLPS: 0-Disable DLPS, 1-Enable DLPS */ 9 | #define F_BT_DLPS_EN 0 10 | /** Config ANCS Client: 0-Not built in, 1-Open ANCS client function */ 11 | #define F_BT_ANCS_CLIENT_SUPPORT 0 12 | #define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1) 13 | #define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0) 14 | /** Config ANCS Client debug log: 0-close, 1-open */ 15 | #define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0) 16 | 17 | /** Flags for activating some undocumented features within the Realtek 18 | * libs. All flags are set to 0 because they were't defined and defaultet to 0. 19 | * Now they must be defined because of activating -Wundefined within the 20 | * makefile to prevent configuration failures without any warnings or errors. 21 | */ 22 | /** Enable write hardfault record to flash. */ 23 | #define ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH 0 24 | /** Before watchdog system reset, write reset reason to specific flash address. 25 | */ 26 | #define WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE 0 27 | /** Internal Realtek lib error dumping of lib on watchdog reset. */ 28 | #define DUMP_INFO_BEFORE_RESET_DISABLE 0 29 | /** Internal Realtek lib debug functionality. */ 30 | #define ENABLE_FLASH_READ_TURN_OFF_RF 0 31 | /** Internal Realtek lib debug functionality. */ 32 | #define ROM_OTA_LINKLOSS_RST 0 33 | 34 | #define OTA_BUF_CHECK_EN 1 35 | #define DFU_TEMP_BUFFER_SIZE (2048) 36 | 37 | /** Enable Debug Monitor Function (include NVIC Enable and DWT configuration). 38 | */ 39 | #define DEBUG_WATCHPOINT_ENABLE 0 40 | 41 | #define F_BT_LE_5_0_AE_ADV_SUPPORT 0 42 | #define F_BT_LE_5_0_AE_SCAN_SUPPORT 0 43 | #define F_BT_LE_6_0_AOA_AOD_SUPPORT 0 44 | 45 | /** Enable multibonding configuration.*/ 46 | // #define BT_STACK_CONFIG_ENABLE 47 | 48 | #endif -------------------------------------------------------------------------------- /src/i2c/i2c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "i2c/i2c.h" 7 | #include "rcc/rcc.h" 8 | 9 | void i2c_init(i2c_t* i2c_p) 10 | { 11 | i2c_pinmux(i2c_p); 12 | 13 | rcc_periph_set(&(i2c_p->instance_p->rcc_periph), ENABLE); 14 | 15 | I2C_InitTypeDef I2C_InitStruct; 16 | I2C_StructInit(&I2C_InitStruct); 17 | 18 | I2C_InitStruct.I2C_ClockSpeed = i2c_p->speed; 19 | I2C_InitStruct.I2C_DeviveMode = i2c_p->mode; 20 | I2C_InitStruct.I2C_AddressMode = i2c_p->address_mode; 21 | I2C_InitStruct.I2C_SlaveAddress = i2c_p->target_address; 22 | I2C_InitStruct.I2C_Ack = i2c_p->ack; 23 | I2C_InitStruct.I2C_RxThresholdLevel = i2c_p->rx_threshold; 24 | 25 | I2C_Init(i2c_p->instance_p->register_p, &I2C_InitStruct); 26 | I2C_Cmd(i2c_p->instance_p->register_p, ENABLE); 27 | } 28 | 29 | void i2c_pinmux(i2c_t* i2c_p) 30 | { 31 | Pad_Config(i2c_p->pads.scl, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH); 32 | // Pad_PullConfigValue(i2c_p->pads.scl, PAD_STRONG_PULL); 33 | Pinmux_Config(i2c_p->pads.scl, i2c_p->instance_p->scl_pin_function); 34 | 35 | Pad_Config(i2c_p->pads.sda, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH); 36 | // Pad_PullConfigValue(i2c_p->pads.sda, PAD_STRONG_PULL); 37 | Pinmux_Config(i2c_p->pads.sda, i2c_p->instance_p->sda_pin_function); 38 | } 39 | 40 | // int i2c_transfer(i2c_t* i2c_p, uint16_t addr, size_t n, i2c_buf_t bufs[], bool write_nread, bool stop) 41 | // { 42 | // I2C_SetSlaveAddress(i2c_p->instance_p->register_p, addr); 43 | 44 | // for (i2c_buf_t* buf_p = bufs; buf_p < (bufs + n); buf_p++) { 45 | // } 46 | // } 47 | 48 | bool i2c_probe(i2c_t* i2c_p, uint16_t addr) 49 | { 50 | uint8_t data = 0; 51 | I2C_SetSlaveAddress(i2c_p->instance_p->register_p, addr); 52 | return (I2C_Success == I2C_MasterRead(i2c_p->instance_p->register_p, &data, 1)); 53 | } 54 | -------------------------------------------------------------------------------- /src/targets/02-uart_pinscan/app_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _APP_FLAGS_H_ 2 | #define _APP_FLAGS_H_ 3 | 4 | /** Config APP LE link number */ 5 | #define APP_MAX_LINKS 1 6 | /** Config APP LE bond number */ 7 | #define APP_MAX_BONDS 4 8 | /** Config DLPS: 0-Disable DLPS, 1-Enable DLPS */ 9 | #define F_BT_DLPS_EN 0 10 | /** Config ANCS Client: 0-Not built in, 1-Open ANCS client function */ 11 | #define F_BT_ANCS_CLIENT_SUPPORT 0 12 | #define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1) 13 | #define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0) 14 | /** Config ANCS Client debug log: 0-close, 1-open */ 15 | #define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0) 16 | 17 | /** Flags for activating some undocumented features within the Realtek 18 | * libs. All flags are set to 0 because they were't defined and defaultet to 0. 19 | * Now they must be defined because of activating -Wundefined within the 20 | * makefile to prevent configuration failures without any warnings or errors. 21 | */ 22 | /** Enable write hardfault record to flash. */ 23 | #define ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH 0 24 | /** Before watchdog system reset, write reset reason to specific flash address. 25 | */ 26 | #define WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE 0 27 | /** Internal Realtek lib error dumping of lib on watchdog reset. */ 28 | #define DUMP_INFO_BEFORE_RESET_DISABLE 0 29 | /** Internal Realtek lib debug functionality. */ 30 | #define ENABLE_FLASH_READ_TURN_OFF_RF 0 31 | /** Internal Realtek lib debug functionality. */ 32 | #define ROM_OTA_LINKLOSS_RST 0 33 | 34 | #define OTA_BUF_CHECK_EN 1 35 | #define DFU_TEMP_BUFFER_SIZE (2048) 36 | 37 | /** Enable Debug Monitor Function (include NVIC Enable and DWT configuration). 38 | */ 39 | #define DEBUG_WATCHPOINT_ENABLE 0 40 | 41 | #define F_BT_LE_5_0_AE_ADV_SUPPORT 0 42 | #define F_BT_LE_5_0_AE_SCAN_SUPPORT 0 43 | #define F_BT_LE_6_0_AOA_AOD_SUPPORT 0 44 | 45 | /** Enable multibonding configuration.*/ 46 | // #define BT_STACK_CONFIG_ENABLE 47 | 48 | #endif -------------------------------------------------------------------------------- /src/targets/06-i2c_ssd1306/app_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _APP_FLAGS_H_ 2 | #define _APP_FLAGS_H_ 3 | 4 | /** Config APP LE link number */ 5 | #define APP_MAX_LINKS 1 6 | /** Config APP LE bond number */ 7 | #define APP_MAX_BONDS 4 8 | /** Config DLPS: 0-Disable DLPS, 1-Enable DLPS */ 9 | #define F_BT_DLPS_EN 0 10 | /** Config ANCS Client: 0-Not built in, 1-Open ANCS client function */ 11 | #define F_BT_ANCS_CLIENT_SUPPORT 0 12 | #define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1) 13 | #define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0) 14 | /** Config ANCS Client debug log: 0-close, 1-open */ 15 | #define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0) 16 | 17 | /** Flags for activating some undocumented features within the Realtek 18 | * libs. All flags are set to 0 because they were't defined and defaultet to 0. 19 | * Now they must be defined because of activating -Wundefined within the 20 | * makefile to prevent configuration failures without any warnings or errors. 21 | */ 22 | /** Enable write hardfault record to flash. */ 23 | #define ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH 0 24 | /** Before watchdog system reset, write reset reason to specific flash address. 25 | */ 26 | #define WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE 0 27 | /** Internal Realtek lib error dumping of lib on watchdog reset. */ 28 | #define DUMP_INFO_BEFORE_RESET_DISABLE 0 29 | /** Internal Realtek lib debug functionality. */ 30 | #define ENABLE_FLASH_READ_TURN_OFF_RF 0 31 | /** Internal Realtek lib debug functionality. */ 32 | #define ROM_OTA_LINKLOSS_RST 0 33 | 34 | #define OTA_BUF_CHECK_EN 1 35 | #define DFU_TEMP_BUFFER_SIZE (2048) 36 | 37 | /** Enable Debug Monitor Function (include NVIC Enable and DWT configuration). 38 | */ 39 | #define DEBUG_WATCHPOINT_ENABLE 0 40 | 41 | #define F_BT_LE_5_0_AE_ADV_SUPPORT 0 42 | #define F_BT_LE_5_0_AE_SCAN_SUPPORT 0 43 | #define F_BT_LE_6_0_AOA_AOD_SUPPORT 0 44 | 45 | /** Enable multibonding configuration.*/ 46 | // #define BT_STACK_CONFIG_ENABLE 47 | 48 | #endif -------------------------------------------------------------------------------- /src/targets/04-button_interrupt/app_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _APP_FLAGS_H_ 2 | #define _APP_FLAGS_H_ 3 | 4 | /** Config APP LE link number */ 5 | #define APP_MAX_LINKS 1 6 | /** Config APP LE bond number */ 7 | #define APP_MAX_BONDS 4 8 | /** Config DLPS: 0-Disable DLPS, 1-Enable DLPS */ 9 | #define F_BT_DLPS_EN 0 10 | /** Config ANCS Client: 0-Not built in, 1-Open ANCS client function */ 11 | #define F_BT_ANCS_CLIENT_SUPPORT 0 12 | #define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1) 13 | #define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0) 14 | /** Config ANCS Client debug log: 0-close, 1-open */ 15 | #define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0) 16 | 17 | /** Flags for activating some undocumented features within the Realtek 18 | * libs. All flags are set to 0 because they were't defined and defaultet to 0. 19 | * Now they must be defined because of activating -Wundefined within the 20 | * makefile to prevent configuration failures without any warnings or errors. 21 | */ 22 | /** Enable write hardfault record to flash. */ 23 | #define ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH 0 24 | /** Before watchdog system reset, write reset reason to specific flash address. 25 | */ 26 | #define WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE 0 27 | /** Internal Realtek lib error dumping of lib on watchdog reset. */ 28 | #define DUMP_INFO_BEFORE_RESET_DISABLE 0 29 | /** Internal Realtek lib debug functionality. */ 30 | #define ENABLE_FLASH_READ_TURN_OFF_RF 0 31 | /** Internal Realtek lib debug functionality. */ 32 | #define ROM_OTA_LINKLOSS_RST 0 33 | 34 | #define OTA_BUF_CHECK_EN 1 35 | #define DFU_TEMP_BUFFER_SIZE (2048) 36 | 37 | /** Enable Debug Monitor Function (include NVIC Enable and DWT configuration). 38 | */ 39 | #define DEBUG_WATCHPOINT_ENABLE 0 40 | 41 | #define F_BT_LE_5_0_AE_ADV_SUPPORT 0 42 | #define F_BT_LE_5_0_AE_SCAN_SUPPORT 0 43 | #define F_BT_LE_6_0_AOA_AOD_SUPPORT 0 44 | 45 | /** Enable multibonding configuration.*/ 46 | // #define BT_STACK_CONFIG_ENABLE 47 | 48 | #endif -------------------------------------------------------------------------------- /src/targets/01-uart_echo/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "board_config.h" 12 | #include "uart/uart.h" 13 | 14 | #define MAIN_TASK_PRIORITY (1) 15 | #define MAIN_TASK_STACK_SIZE (256 * 4) 16 | #define RX_QUEUE_LEN (256) 17 | 18 | void* main_task_p; 19 | void* rx_queue; 20 | 21 | void rx_cb(uart_t* uart_p); 22 | char rx_buf[256], tx_buf[256]; 23 | 24 | uart_t uart = { 25 | .instance_p = &UART_INSTANCE(0), 26 | .pads = { 27 | .tx = BOARD_TX_PAD, 28 | .rx = BOARD_RX_PAD, 29 | }, 30 | .parity = NO_PARTY, 31 | .stop_bits = STOP_BITS_1, 32 | .word_length = WORD_LENGTH_8, 33 | .rx_trigger_level = 29, 34 | .idle_time = IDLE_TIME_2, 35 | .rx_buf = { 36 | .size = sizeof(rx_buf), 37 | .data = rx_buf, 38 | }, 39 | .tx_buf = { 40 | .size = sizeof(tx_buf), 41 | .data = tx_buf, 42 | }, 43 | .rx_cb = rx_cb, 44 | }; 45 | 46 | void main_task(void* p_param) 47 | { 48 | if (false == os_msg_queue_create(&rx_queue, RX_QUEUE_LEN, sizeof(char))) { 49 | // the queue was not created successfully 50 | } 51 | 52 | uart_init(&uart); 53 | 54 | uart_print(&uart, "main task started\r\n"); 55 | 56 | while (1) { 57 | char c; 58 | if (os_msg_recv(rx_queue, &c, 0xFFFFFFFF) == true) { 59 | uart_printn(&uart, &c, 1); 60 | } 61 | } 62 | } 63 | 64 | void rx_cb(uart_t* uart_p) 65 | { 66 | for (unsigned int i = 0; i < uart_p->rx_buf.count; i++) { 67 | if (false == os_msg_send(rx_queue, &uart_p->rx_buf.data[i], 0)) { 68 | // couldn't send to the queue 69 | } 70 | } 71 | uart_p->rx_buf.count = 0; 72 | } 73 | 74 | int main(void) 75 | { 76 | os_task_create(&main_task_p, "main_task", main_task, 0, MAIN_TASK_STACK_SIZE, 77 | MAIN_TASK_PRIORITY); 78 | 79 | os_sched_start(); 80 | } 81 | -------------------------------------------------------------------------------- /src/targets/05-i2c_scan/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "board_config.h" 4 | #include "i2c/i2c.h" 5 | #include "uart/uart.h" 6 | 7 | // prevent `warning: function with qualified void return type called` 8 | #define delay_ms(T) (((void (*)(uint32_t))platform_delay_ms)(T)) 9 | 10 | i2c_t* i2c0 = &(i2c_t) { 11 | .instance_p = &I2C_INSTANCE(0), 12 | .pads = { 13 | .scl = H_2, 14 | .sda = H_1, 15 | }, 16 | .speed = 100000, 17 | .mode = I2C_CONTROLLER, 18 | .address_mode = I2C_ADDRESS_7BIT, 19 | .target_address = 0x50, 20 | .ack = I2C_ACK_ENABLE, 21 | .rx_threshold = 12, 22 | }; 23 | 24 | char tx_buf[256]; 25 | 26 | uart_t uart = { 27 | .instance_p = &UART_INSTANCE(0), 28 | .pads = { 29 | .tx = BOARD_TX_PAD, 30 | .rx = -1, 31 | }, 32 | .parity = NO_PARTY, 33 | .stop_bits = STOP_BITS_1, 34 | .word_length = WORD_LENGTH_8, 35 | .tx_buf = { 36 | .size = sizeof(tx_buf), 37 | .data = tx_buf, 38 | }, 39 | }; 40 | 41 | int main(void) 42 | { 43 | i2c_init(i2c0); 44 | uart_init(&uart); 45 | 46 | delay_ms(2000); 47 | 48 | while (1) { 49 | uart_print(&uart, "\ec"); // clear screen 50 | uart_print(&uart, "scanning i2c\r\n "); 51 | 52 | for (uint16_t i = 0; i < 16; i++) { 53 | uart_printf(&uart, " %x", i); 54 | } 55 | uart_print(&uart, "\r\n"); 56 | 57 | uart_print(&uart, "0 "); 58 | for (uint16_t addr = 1; addr < 128; addr++) { 59 | if (0 == addr % 16) { 60 | uart_printf(&uart, "\r\n%x ", addr / 16); 61 | } 62 | if (i2c_probe(i2c0, addr)) { 63 | uart_printf(&uart, " %02x", addr); 64 | } else { 65 | uart_print(&uart, " --"); 66 | } 67 | } 68 | uart_print(&uart, "\r\n"); 69 | uart_flush(&uart); 70 | 71 | delay_ms(1000); 72 | 73 | for (int i = 0; i < 5; i++) { 74 | uart_print(&uart, "."); 75 | uart_flush(&uart); 76 | delay_ms(1000); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/rcc/rcc.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef _RCC_H 4 | #define _RCC_H 5 | 6 | typedef enum { 7 | ADC_PERIPH = APBPeriph_ADC, 8 | CODEC_PERIPH = APBPeriph_CODEC, 9 | FLASH_PERIPH = APBPeriph_FLASH, 10 | GDMA_PERIPH = APBPeriph_GDMA, 11 | GPIO_PERIPH = APBPeriph_GPIO, 12 | I2C0_PERIPH = APBPeriph_I2C0, 13 | I2C1_PERIPH = APBPeriph_I2C1, 14 | I2S0_PERIPH = APBPeriph_I2S0, 15 | I2S1_PERIPH = APBPeriph_I2S1, 16 | IR_PERIPH = APBPeriph_IR, 17 | KEYSCAN_PERIPH = APBPeriph_KEYSCAN, 18 | LCD_PERIPH = APBPeriph_LCD, 19 | QDEC_PERIPH = APBPeriph_QDEC, 20 | SPI0_PERIPH = APBPeriph_SPI0, 21 | SPI1_PERIPH = APBPeriph_SPI1, 22 | SPI2W_PERIPH = APBPeriph_SPI2W, 23 | TIMER_PERIPH = APBPeriph_TIMER, 24 | UART0_PERIPH = APBPeriph_UART0, 25 | UART1_PERIPH = APBPeriph_UART1, 26 | UART2_PERIPH = APBPeriph_UART2, 27 | } abp_periph_t; 28 | 29 | typedef enum { 30 | ADC_CLOCK = APBPeriph_ADC_CLOCK, 31 | CODEC_CLOCK = APBPeriph_CODEC_CLOCK, 32 | FLASH_CLOCK = APBPeriph_FLASH_CLOCK, 33 | GDMA_CLOCK = APBPeriph_GDMA_CLOCK, 34 | GPIO_CLOCK = APBPeriph_GPIO_CLOCK, 35 | I2C0_CLOCK = APBPeriph_I2C0_CLOCK, 36 | I2C1_CLOCK = APBPeriph_I2C1_CLOCK, 37 | I2S0_CLOCK = APBPeriph_I2S0_CLOCK, 38 | I2S1_CLOCK = APBPeriph_I2S1_CLOCK, 39 | IR_CLOCK = APBPeriph_IR_CLOCK, 40 | KEYSCAN_CLOCK = APBPeriph_KEYSCAN_CLOCK, 41 | LCD_CLOCK = APBPeriph_LCD_CLOCK, 42 | QDEC_CLOCK = APBPeriph_QDEC_CLOCK, 43 | SPI0_CLOCK = APBPeriph_SPI0_CLOCK, 44 | SPI1_CLOCK = APBPeriph_SPI1_CLOCK, 45 | SPI2W_CLOCK = APBPeriph_SPI2W_CLOCK, 46 | TIMER_CLOCK = APBPeriph_TIMER_CLOCK, 47 | UART0_CLOCK = APBPeriph_UART0_CLOCK, 48 | UART1_CLOCK = APBPeriph_UART1_CLOCK, 49 | UART2_CLOCK = APBPeriph_UART2_CLOCK, 50 | } abp_clock_t; 51 | 52 | typedef struct { 53 | const abp_periph_t abp_periph; 54 | const abp_clock_t abp_clock; 55 | } rcc_periph_t; 56 | 57 | #define RCC_PERIPH(PERIPH) \ 58 | { \ 59 | .abp_periph = PERIPH##_PERIPH, .abp_clock = PERIPH##_CLOCK, \ 60 | } 61 | 62 | static inline void rcc_periph_set(const rcc_periph_t* rcc_periph_p, bool state) 63 | { 64 | RCC_PeriphClockCmd(rcc_periph_p->abp_periph, rcc_periph_p->abp_clock, state); 65 | } 66 | 67 | #endif //_RCC_H 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RTL8762C-gcc-examples 2 | Firmware examples for the RTL8762C BLE SoC 3 | 4 | [![hackaday.io](https://img.shields.io/badge/hackaday-io-gold.svg)](https://hackaday.io/project/182205-py-ft10) 5 | 6 | ## Download 7 | To obtain this code, clone this repository recursively. 8 | ```shell 9 | git clone --recurse-submodules https://github.com/cyber-murmel/rtl8762c-gcc-examples.git 10 | ``` 11 | 12 | ### SDK 13 | Register an account at [RealMCU](https://www.realmcu.com) and download the 14 | *RTL8762C SDK GCC(ZIP)* from the [product page](https://www.realmcu.com/en/Home/Product/93cc0582-3a3f-4ea8-82ea-76c6504e478a). 15 | This procedure requires an email account. 16 | 17 | Extract the zip archive and move the `sdk` directory into the root of this repository. 18 | 19 | ```shell 20 | unzip RTL8762C-sdk-gcc-v0.0.5.zip 21 | mv bee2-sdk-gcc-v0.0.5/sdk ./sdk 22 | rm -r bee2-sdk-gcc-v0.0.5 23 | ``` 24 | 25 | ## Toolchain 26 | To build the firmware you need 27 | - GNU Make 4.3 28 | - arm-none-eabi-gcc (GNU Arm Embedded Toolchain 9-2020-q2-update) 9.3.1 20200408 (release) 29 | 30 | ### rtltool 31 | For flashing you need to download and install the dependencies for the rtltool submodule. 32 | Please follow the [installtion section](https://github.com/cyber-murmel/rtltool/blob/main/README.md#installation). 33 | 34 | ### Nix 35 | Users of Nix or NixOS can simply run `nix-shell` to enter an environment with all necessary dependencies. 36 | 37 | ## Building 38 | To build an example, set `TARGET` to one of the directories in [src/targets](src/targets) and run make. 39 | 40 | ```shell 41 | make TARGET=00-blink 42 | ``` 43 | 44 | The default `TARGET` is `00-blink` 45 | 46 | Currently available targets are 47 | - `00-blink` 48 | - `01-uart_echo` 49 | - `02-uart_printf` 50 | 51 | ### Cleanup 52 | It's advised to clean up build results before switching to a different target. 53 | 54 | ```shell 55 | make clean 56 | ``` 57 | 58 | ## Flashing 59 | To flash the firmware onto the board via UART, run 60 | 61 | ```shell 62 | make TARGET=00-blink flash 63 | ``` 64 | 65 | ### Port 66 | The UART port can be be set via the `PORT` variable. 67 | 68 | ```shell 69 | make TARGET=00-blink PORT=/dev/ttyUSB0 flash 70 | ``` 71 | 72 | The default `PORT` is `/dev/ttyUSB1` 73 | 74 | ## Terminal 75 | To open a miniterm session, run 76 | 77 | ```shell 78 | make term 79 | ``` 80 | 81 | The port can be changed in the same way as for [flashing](#port). 82 | -------------------------------------------------------------------------------- /src/i2c/i2c.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "rcc/rcc.h" 6 | 7 | #include 8 | 9 | #ifndef _I2C_H 10 | #define _I2C_H 11 | 12 | typedef enum { 13 | I2C0_CLK_PIN = I2C0_CLK, 14 | I2C0_DAT_PIN = I2C0_DAT, 15 | I2C1_CLK_PIN = I2C1_CLK, 16 | I2C1_DAT_PIN = I2C1_DAT, 17 | } i2c_pin_function_t; 18 | 19 | #define I2C0_CLK 5 20 | #define I2C0_DAT 6 21 | #define I2C1_CLK 7 22 | #define I2C1_DAT 8 23 | 24 | typedef struct { 25 | const uint8_t index; 26 | I2C_TypeDef* register_p; 27 | const rcc_periph_t rcc_periph; 28 | const IRQn_Type irq_channel; 29 | const i2c_pin_function_t scl_pin_function, sda_pin_function; 30 | } i2c_instance_t; 31 | 32 | #define I2C_INSTANCE(INDEX) \ 33 | ((i2c_instance_t) { \ 34 | .index = INDEX, \ 35 | .register_p = (I2C_TypeDef*)I2C##INDEX##_REG_BASE, \ 36 | .rcc_periph = RCC_PERIPH(I2C##INDEX), \ 37 | .irq_channel = I2C##INDEX##_IRQn, \ 38 | .scl_pin_function = I2C##INDEX##_CLK_PIN, \ 39 | .sda_pin_function = I2C##INDEX##_DAT_PIN, \ 40 | }) 41 | 42 | typedef struct { 43 | uint8_t scl; 44 | uint8_t sda; 45 | } i2c_pads_t; 46 | 47 | typedef enum { 48 | I2C_TARGET = I2C_DeviveMode_Slave, 49 | I2C_CONTROLLER = I2C_DeviveMode_Master, 50 | } i2c_mode_t; 51 | 52 | typedef enum { 53 | I2C_ADDRESS_7BIT = I2C_AddressMode_7BIT, 54 | I2C_ADDRESS_10BIT = I2C_AddressMode_10BIT, 55 | } i2c_address_mode_t; 56 | 57 | typedef enum { 58 | I2C_ACK_DISABLE = I2C_Ack_Disable, 59 | I2C_ACK_ENABLE = I2C_Ack_Enable, 60 | } i2c_ack_t; 61 | 62 | typedef struct { 63 | const i2c_instance_t* instance_p; 64 | // I2C_TypeDef* peripheral; 65 | i2c_pads_t pads; 66 | uint32_t speed; 67 | i2c_mode_t mode; 68 | i2c_address_mode_t address_mode; 69 | uint16_t target_address; 70 | i2c_ack_t ack; 71 | uint32_t rx_threshold; 72 | } i2c_t; 73 | 74 | typedef struct { 75 | size_t len; 76 | uint8_t* buf; 77 | } i2c_buf_t; 78 | 79 | void i2c_init(i2c_t* i2c_p); 80 | void i2c_pinmux(i2c_t* i2c_p); 81 | int i2c_transfer(i2c_t* i2c_p, uint16_t addr, size_t n, i2c_buf_t bufs[], bool write_nread, bool stop); 82 | bool i2c_probe(i2c_t* i2c_p, uint16_t addr); 83 | 84 | #endif //_I2C_H 85 | -------------------------------------------------------------------------------- /config/ota_bank0_header.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "config/flash_map.h" 4 | #include "sdk/inc/platform/patch_header_check.h" 5 | 6 | #define STRUCT_ARRAY_SETTER(NAME, FIELD, VALUE) .FIELD = {[0 ... (sizeof(NAME.FIELD)-1)] = VALUE} 7 | 8 | // data structures 9 | #pragma pack(push, 1) 10 | 11 | T_OTA_HEADER_FORMAT ota_header = { 12 | .ctrl_header = { 13 | .ic_type = 5, 14 | .secure_version = 0, 15 | .ctrl_flag.flag_value = { 16 | .xip = 0b1, 17 | .enc = 0b1, 18 | .load_when_boot = 0b1, 19 | .enc_load = 0b1, 20 | .enc_key_select = 0b111, 21 | .not_ready = 0b1, 22 | .not_obsolete = 0b1, 23 | .integrity_check_en_in_boot = 0b1, 24 | .rsvd = 0b111111, 25 | }, 26 | .image_id = OTA, 27 | .crc16 = 0, 28 | .payload_len = 0, 29 | }, 30 | STRUCT_ARRAY_SETTER(ota_header, uuid, 0xff), 31 | .exe_base = 0xFFFFFFFF, 32 | .load_base = 0xFFFFFFFF, 33 | STRUCT_ARRAY_SETTER(ota_header, rsvd0, 0xff), 34 | .auto_enter_dfu_mode_pattern = 0xFFFF, 35 | .single_bank_ota_pattern = 0xFFFF, 36 | .magic_pattern = 0x5A5A12A5, 37 | STRUCT_ARRAY_SETTER(ota_header, rsvd1, 0xff), 38 | .git_ver = { 39 | .ver_info.version = 0xFFFFFFFF, 40 | ._version_commitid = 0xFFFFFFFF, 41 | STRUCT_ARRAY_SETTER(ota_header.git_ver, _customer_name, 0xff), 42 | }, 43 | .rsaPubKey = { 44 | STRUCT_ARRAY_SETTER(ota_header.rsaPubKey, N, 0xff), 45 | STRUCT_ARRAY_SETTER(ota_header.rsaPubKey, E, 0xff), 46 | }, 47 | STRUCT_ARRAY_SETTER(ota_header, sha256, 0xff), 48 | .ver_val = 0x01000001, 49 | .secure_boot_addr = BANK0_SECURE_BOOT_ADDR, 50 | .secure_boot_size = BANK0_SECURE_BOOT_SIZE, 51 | .rom_patch_addr = BANK0_ROM_PATCH_ADDR, 52 | .rom_patch_size = BANK0_ROM_PATCH_SIZE, 53 | .app_addr = BANK0_APP_ADDR, 54 | .app_size = BANK0_APP_SIZE, 55 | .app_data1_addr = BANK0_APP_DATA1_ADDR, 56 | .app_data1_size = BANK0_APP_DATA1_SIZE, 57 | .app_data2_addr = BANK0_APP_DATA2_ADDR, 58 | .app_data2_size = BANK0_APP_DATA2_SIZE, 59 | .app_data3_addr = BANK0_APP_DATA3_ADDR, 60 | .app_data3_size = BANK0_APP_DATA3_SIZE, 61 | .app_data4_addr = BANK0_APP_DATA4_ADDR, 62 | .app_data4_size = BANK0_APP_DATA4_SIZE, 63 | .app_data5_addr = BANK0_APP_DATA5_ADDR, 64 | .app_data5_size = BANK0_APP_DATA5_SIZE, 65 | .app_data6_addr = BANK0_APP_DATA6_ADDR, 66 | .app_data6_size = BANK0_APP_DATA6_SIZE, 67 | }; 68 | 69 | #pragma pack(pop) 70 | -------------------------------------------------------------------------------- /config/mem_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | ***************************************************************************************** 3 | * Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. 4 | ***************************************************************************************** 5 | * @file mem_config.h 6 | * @brief Memory Configuration 7 | * @date 2017.6.6 8 | * @version v1.0 9 | * ************************************************************************************* 10 | * @attention 11 | *

© COPYRIGHT 2017 Realtek Semiconductor 12 | *Corporation

13 | * ************************************************************************************* 14 | */ 15 | 16 | /*============================================================================* 17 | * Define to prevent recursive inclusion 18 | *============================================================================*/ 19 | #ifndef MEM_CONFIG_H 20 | #define MEM_CONFIG_H 21 | 22 | #include "flash_map.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /*============================================================================* 29 | * Code configuration 30 | *============================================================================*/ 31 | /** @brief set app bank to support OTA: 1 is ota bank1, 0 is ota bank0 */ 32 | #define APP_BANK 0 33 | 34 | /** @brief ram code configuration: 1 is ram code, 0 is flash code */ 35 | #define FEATURE_RAM_CODE 1 36 | 37 | /** @brief encrypt app or not */ 38 | #define FEATURE_ENCRYPTION 0 39 | 40 | /*============================================================================* 41 | * data ram layout configuration 42 | *============================================================================*/ 43 | /* Data RAM layout: 112K 44 | example: 45 | 1) reserved for rom and patch: 31K (fixed) 46 | 2) app global + ram code: 35K (adjustable, config APP_GLOBAL_SIZE) 47 | 3) Heap ON: 30K (adjustable, config APP_GLOBAL_SIZE) 48 | 6) patch ram code: 16K (fixed) 49 | */ 50 | 51 | /** @brief data ram size for app global variables and code, could be changed, 52 | * but (APP_GLOBAL_SIZE + HEAP_DATA_ON_SIZE) must be 65k */ 53 | #define APP_GLOBAL_SIZE (30 * 1024) 54 | 55 | /** @brief data ram size for heap, could be changed, but (APP_GLOBAL_SIZE + 56 | * HEAP_DATA_ON_SIZE) must be 65k */ 57 | #define HEAP_DATA_ON_SIZE (65 * 1024 - APP_GLOBAL_SIZE) 58 | 59 | /** @brief shared cache ram size (adjustable, config SHARE_CACHE_RAM_SIZE: 60 | * 0/8KB/16KB) */ 61 | #define SHARE_CACHE_RAM_SIZE (16 * 1024) 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | /** @} */ /* End of group MEM_CONFIG */ 68 | #endif 69 | -------------------------------------------------------------------------------- /src/targets/06-i2c_ssd1306/ssd1306.h: -------------------------------------------------------------------------------- 1 | #ifndef _SSD1306_H 2 | #define _SSD1306_H 3 | 4 | // #include "i2c/i2c.h" 5 | 6 | #define SSD1306_ADDR (0x3c) 7 | 8 | typedef enum { 9 | MEMORYMODE = 0x20, ///< See datasheet 10 | COLUMNADDR = 0x21, ///< See datasheet 11 | PAGEADDR = 0x22, ///< See datasheet 12 | SETCONTRAST = 0x81, ///< See datasheet 13 | CHARGEPUMP = 0x8D, ///< See datasheet 14 | SEGREMAP = 0xA0, ///< See datasheet 15 | DISPLAYALLON_RESUME = 0xA4, ///< See datasheet 16 | DISPLAYALLON = 0xA5, ///< Not currently used 17 | NORMALDISPLAY = 0xA6, ///< See datasheet 18 | INVERTDISPLAY = 0xA7, ///< See datasheet 19 | SETMULTIPLEX = 0xA8, ///< See datasheet 20 | DISPLAYOFF = 0xAE, ///< See datasheet 21 | DISPLAYON = 0xAF, ///< See datasheet 22 | COMSCANINC = 0xC0, ///< Not currently used 23 | COMSCANDEC = 0xC8, ///< See datasheet 24 | SETDISPLAYOFFSET = 0xD3, ///< See datasheet 25 | SETDISPLAYCLOCKDIV = 0xD5, ///< See datasheet 26 | SETPRECHARGE = 0xD9, ///< See datasheet 27 | SETCOMPINS = 0xDA, ///< See datasheet 28 | SETVCOMDETECT = 0xDB, ///< See datasheet 29 | SETLOWCOLUMN = 0x00, ///< Not currently used 30 | SETHIGHCOLUMN = 0x10, ///< Not currently used 31 | SETSTARTLINE = 0x40, ///< See datasheet 32 | EXTERNALVCC = 0x01, ///< External display voltage source 33 | SWITCHCAPVCC = 0x02, ///< Gen. display voltage from 3.3V 34 | RIGHT_HORIZONTAL_SCROLL = 0x26, ///< Init rt scroll 35 | LEFT_HORIZONTAL_SCROLL = 0x27, ///< Init left scroll 36 | VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29, ///< Init diag scroll 37 | VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A, ///< Init diag scroll 38 | DEACTIVATE_SCROLL = 0x2E, ///< Stop scroll 39 | ACTIVATE_SCROLL = 0x2F, ///< Start scroll 40 | SET_VERTICAL_SCROLL_AREA = 0xA3, ///< Set scroll range 41 | 42 | // CHARGEPUMP = 0x8D, 43 | // COLUMNADDR = 0x21, 44 | // COMSCANDEC = 0xC8, 45 | // COMSCANINC = 0xC0, 46 | // DISPLAYALLON = 0xA5, 47 | // DISPLAYALLON_RESUME = 0xA4, 48 | // DISPLAYOFF = 0xAE, 49 | // DISPLAYON = 0xAF, 50 | // EXTERNALVCC = 0x1, 51 | // INVERTDISPLAY = 0xA7, 52 | // MEMORYMODE = 0x20, 53 | // NORMALDISPLAY = 0xA6, 54 | // PAGEADDR = 0x22, 55 | // PAGESTARTADDRESS = 0xB0, 56 | // SEGREMAP = 0xA1, 57 | // SETCOMPINS = 0xDA, 58 | // SETCONTRAST = 0x81, 59 | // SETDISPLAYCLOCKDIV = 0xD5, 60 | // SETDISPLAYOFFSET = 0xD3, 61 | // SETHIGHCOLUMN = 0x10, 62 | // SETLOWCOLUMN = 0x00, 63 | // SETMULTIPLEX = 0xA8, 64 | // SETPRECHARGE = 0xD9, 65 | // SETSEGMENTREMAP = 0xA1, 66 | // SETSTARTLINE = 0x40, 67 | // SETVCOMDETECT = 0xDB, 68 | // SWITCHCAPVCC = 0x2, 69 | } ssd1306_command_t; 70 | 71 | void ssd1306(void); 72 | 73 | #endif //_SSD1306_H 74 | -------------------------------------------------------------------------------- /rtl8762c.ld: -------------------------------------------------------------------------------- 1 | /* Entry Point */ 2 | ENTRY(Reset_Handler) 3 | INPUT(mem_define.ld) 4 | 5 | MEMORY 6 | { 7 | APP_DATA_ON (rwx) : ORIGIN = 0x00207C00, LENGTH = APP_GLOBAL_SIZE 8 | HEAP_DATA_ON (rwx) : ORIGIN = (0x00207C00 + APP_GLOBAL_SIZE) , LENGTH = (65*1024) - APP_GLOBAL_SIZE 9 | CACHE_DATA_ON (rwx) : ORIGIN = 0x0021C000, LENGTH = SHARE_CACHE_RAM_SIZE 10 | APP_FLASH (r) : ORIGIN = APP_ADDR, LENGTH = APP_SIZE 11 | UNINIT_RAM : ORIGIN = 0x00217f00, LENGTH = 256 12 | } 13 | 14 | /* Define output sections */ 15 | SECTIONS 16 | { 17 | . = APP_ADDR; 18 | app.bin APP_ADDR : 19 | { 20 | KEEP(* (.app.flash.header)) 21 | KEEP(* (.app.flash.header.auth)) 22 | }AT > APP_FLASH 23 | APP_FLASH_HEADER_EXT : 24 | { 25 | KEEP(* (.app.flash.header_ext)) 26 | }AT > APP_FLASH 27 | 28 | FLASH_START_ADDR : 29 | { 30 | build/sdk/src/mcu/rtl876x/arm/startup_rtl8762c_gcc.o(RESET) 31 | . = ALIGN(4); 32 | __flash_start_load_ad__ = LOADADDR(FLASH_START_ADDR); 33 | __flash_start_exe_ad__ = ADDR(FLASH_START_ADDR); 34 | }AT > APP_FLASH 35 | 36 | FLASH_TEXT : 37 | { 38 | *(.text*) 39 | . = ALIGN(4); 40 | *(.rodata*) 41 | . = ALIGN(4); 42 | *(.app.flash.text) 43 | *(.app.flash.rodata) 44 | }AT > APP_FLASH 45 | RAM_VECTOR_TABLE 0x00200000: 46 | { 47 | __ram_vector_table_start__ = .; 48 | KEEP(*(VECTOR)) 49 | __ram_vector_table_end__ = .; 50 | }AT > APP_FLASH 51 | __ram_vector_load_ad__ = LOADADDR(RAM_VECTOR_TABLE); 52 | __ram_vector_table_length__ = __ram_vector_table_end__ - __ram_vector_table_start__; 53 | RAM_DATA_ON : 54 | { 55 | . = ALIGN(4); 56 | __ram_dataon_rw_start__ = .; 57 | *(.data*) 58 | * (.ram.dataon.data) 59 | __ram_dataon_rw_end__ = .; 60 | . = ALIGN(4); 61 | } > APP_DATA_ON AT > APP_FLASH 62 | BSS (NOLOAD): 63 | { 64 | . = ALIGN(4); 65 | __ram_dataon_zi_start__ = .; 66 | * (.ram.dataon.bss*) 67 | *(.bss*) 68 | *(COMMON) 69 | . = ALIGN(4); 70 | __ram_dataon_zi_end__ = .; 71 | } > APP_DATA_ON AT > APP_FLASH 72 | __ram_rw_load_ad__ = LOADADDR(RAM_DATA_ON); 73 | __ram_dataon_rw_length__ = __ram_dataon_rw_end__ - __ram_dataon_rw_start__; 74 | __ram_dataon_zi_length__ = __ram_dataon_zi_end__ - __ram_dataon_zi_start__; 75 | 76 | DATA_RAM_UNIT : 77 | { 78 | * (.uninit.ram) 79 | } > UNINIT_RAM AT > APP_FLASH 80 | 81 | HEAP_DATA_ON : 82 | { 83 | __heap_start__ = .; 84 | end = __heap_start__; 85 | _end = end; 86 | __end = end; 87 | KEEP(*(.heap)) 88 | __heap_end__ = .; 89 | __HeapLimit = __heap_end__; 90 | } > HEAP_DATA_ON AT > APP_FLASH 91 | 92 | CACHE_DATA_ON (OVERLAY): 93 | { 94 | __cache_dataon_start__ = . ; 95 | *(.ram.sharecacheram.text) 96 | __cache_dataon_end__ = .; 97 | }>CACHE_DATA_ON AT> APP_FLASH 98 | __cache_dataon_length__ = __cache_dataon_end__ - __cache_dataon_start__; 99 | __cache_data_load_ad__ = LOADADDR(RAM_DATA_ON); 100 | } 101 | -------------------------------------------------------------------------------- /config/otp_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | ***************************************************************************************** 3 | * Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. 4 | ***************************************************************************************** 5 | * @file otp_config.h 6 | * @brief Update Configuration in APP 7 | * @date 2017.6.6 8 | * @version v1.0 9 | * ************************************************************************************* 10 | * @attention 11 | *

© COPYRIGHT 2017 Realtek Semiconductor 12 | *Corporation

13 | * ************************************************************************************* 14 | */ 15 | 16 | /*============================================================================* 17 | * Define to prevent recursive inclusion 18 | *============================================================================*/ 19 | #ifndef OTP_CONFIG_H 20 | #define OTP_CONFIG_H 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #include "rtl876x_wdg.h" 27 | /*============================================================================* 28 | * debug configuration 29 | *============================================================================*/ 30 | /** @brief just for debug */ 31 | #define SYSTEM_TRACE_ENABLE 0 32 | 33 | /*============================================================================* 34 | * flash configuration 35 | *============================================================================*/ 36 | /** @brief support for puran flash*/ 37 | #define FTL_APP_CALLBACK_ENABLE 0 38 | /** @brief as recommended by Realtek*/ 39 | #define DISABLE_FTL_REATURE 0 40 | /** @brief enable BP, set lock level depend on flash layout and selected flash 41 | * id */ 42 | #define FLASH_BLOCK_PROTECT_ENABLE 1 43 | /** @brief modify delay time for wakeup flash from power down mode to standby 44 | * mode*/ 45 | #define AFTER_TOGGLE_CS_DELAY 6 46 | 47 | /*============================================================================* 48 | * platform configuration 49 | *============================================================================*/ 50 | /** @brief default enable swd pinmux */ 51 | #define SWD_PINMUX_ENABLE 1 52 | /** @brief default disable watch dog in rom */ 53 | #define ROM_WATCH_DOG_ENABLE 0 54 | /** @brief set wdg mode, default reset all */ 55 | #define ROM_WATCH_DOG_MODE RESET_ALL 56 | /** @brief as recommended by Realtek*/ 57 | #define XTAL_40M_DELAY_TIME 0 58 | 59 | /*============================================================================* 60 | * upperstack configuration 61 | *============================================================================*/ 62 | // add more here 63 | 64 | /*============================================================================* 65 | * app configuration 66 | *============================================================================*/ 67 | #define OTA_TIMEOUT_TOTAL 240 68 | #define OTA_TIMEOUT_WAIT4_CONN 60 69 | #define OTA_TIMEOUT_WAIT4_IMAGE_TRANS 200 70 | #define OTA_TIMEOUT_CTITTV 0xFF 71 | // add more here 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | /** @} */ /* End of group OTP_CONFIG */ 78 | #endif 79 | -------------------------------------------------------------------------------- /src/targets/06-i2c_ssd1306/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "board_config.h" 5 | #include "i2c/i2c.h" 6 | #include "uart/uart.h" 7 | 8 | #include "ssd1306.h" 9 | 10 | // prevent `warning: function with qualified void return type called` 11 | #define delay_ms(T) (((void (*)(uint32_t))platform_delay_ms)(T)) 12 | 13 | i2c_t* i2c = &(i2c_t) { 14 | .instance_p = &I2C_INSTANCE(0), 15 | .pads = { 16 | .scl = H_2, 17 | .sda = H_1, 18 | }, 19 | .speed = 100000, 20 | .mode = I2C_CONTROLLER, 21 | .address_mode = I2C_ADDRESS_7BIT, 22 | .target_address = SSD1306_ADDR, 23 | .ack = I2C_ACK_ENABLE, 24 | .rx_threshold = 12, 25 | }; 26 | 27 | char tx_buf[256]; 28 | 29 | uart_t uart = { 30 | .instance_p = &UART_INSTANCE(0), 31 | .pads = { 32 | .tx = BOARD_TX_PAD, 33 | .rx = -1, 34 | }, 35 | .parity = NO_PARTY, 36 | .stop_bits = STOP_BITS_1, 37 | .word_length = WORD_LENGTH_8, 38 | .tx_buf = { 39 | .size = sizeof(tx_buf), 40 | .data = tx_buf, 41 | }, 42 | }; 43 | 44 | typedef struct __attribute__((__packed__)) { 45 | unsigned int rsvd: 6; 46 | unsigned int data_ncommand: 1; 47 | unsigned int co: 1; 48 | } control_byte_t; 49 | 50 | struct __attribute__((__packed__)) { 51 | const control_byte_t control_byte; 52 | struct __attribute__((__packed__)) { 53 | const uint8_t cmd; 54 | uint8_t start_addr; 55 | uint8_t end_addr; 56 | } page, column; 57 | } addr_set_sequence = { 58 | .page = { 59 | .cmd = PAGEADDR, 60 | .start_addr = 0, 61 | .end_addr = 64-1, 62 | }, 63 | .column = { 64 | .cmd = COLUMNADDR, 65 | .start_addr = 0, 66 | .end_addr = 128-1, 67 | }, 68 | }; 69 | 70 | struct __attribute__((__packed__)) { 71 | const control_byte_t control_byte; 72 | uint8_t data[128 * 64 / 8]; 73 | } pix_buf_sequence = { 74 | .control_byte.data_ncommand = 1, 75 | .data = { 76 | 0b00000000, 77 | 0b00100000, 78 | 0b01001100, 79 | 0b10001100, 80 | 0b10000000, 81 | 0b10001100, 82 | 0b01001100, 83 | 0b00100000, 84 | }, 85 | }; 86 | 87 | uint8_t init_sequence[] = { 88 | 0x00, // control byte 89 | 90 | DISPLAYOFF, 91 | SETDISPLAYCLOCKDIV, 92 | 0x80, 93 | SETMULTIPLEX, 94 | 64 - 1, 95 | SETDISPLAYOFFSET, 96 | 0, 97 | SETSTARTLINE | 0b0, 98 | CHARGEPUMP, 99 | 0x14, // generate from 3.3V 100 | MEMORYMODE, 101 | 0, 102 | SEGREMAP | 0b1, 103 | COMSCANDEC, 104 | SETCOMPINS, 105 | 0x12, 106 | SETCONTRAST, 107 | 0xCF, 108 | SETPRECHARGE, 109 | 0xF1, 110 | SETVCOMDETECT, 111 | 0x40, 112 | DISPLAYALLON_RESUME, 113 | NORMALDISPLAY, 114 | DEACTIVATE_SCROLL, 115 | DISPLAYON, 116 | }; 117 | 118 | int main(void) 119 | { 120 | i2c_init(i2c); 121 | uart_init(&uart); 122 | 123 | I2C_SetSlaveAddress(i2c->instance_p->register_p, SSD1306_ADDR); 124 | 125 | I2C_MasterWrite(i2c->instance_p->register_p, init_sequence, sizeof(init_sequence)); 126 | I2C_MasterWrite(i2c->instance_p->register_p, (uint8_t *) &addr_set_sequence, sizeof(addr_set_sequence)); 127 | 128 | I2C_MasterWrite(i2c->instance_p->register_p, (uint8_t *) &pix_buf_sequence, sizeof(pix_buf_sequence)); 129 | 130 | while (1) { 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/uart/uart.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #undef parity 4 | #undef idle_time 5 | #undef stopBits 6 | #undef wordLen 7 | #undef rxTriggerLevel 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "rcc/rcc.h" 14 | 15 | #ifndef _UART_H 16 | #define _UART_H 17 | 18 | typedef enum { 19 | UART0_TX_PIN = UART0_TX, 20 | UART0_RX_PIN = UART0_RX, 21 | UART0_CTS_PIN = UART0_CTS, 22 | UART0_RTS_PIN = UART0_RTS, 23 | UART1_TX_PIN = UART1_TX, 24 | UART1_RX_PIN = UART1_RX, 25 | UART1_CTS_PIN = UART1_CTS, 26 | UART1_RTS_PIN = UART1_RTS, 27 | UART2_TX_PIN = UART2_TX, 28 | UART2_RX_PIN = UART2_RX, 29 | UART2_CTS_PIN = UART2_CTS, 30 | UART2_RTS_PIN = UART2_RTS, 31 | HCI_UART_TX_PIN = HCI_UART_TX, 32 | HCI_UART_RX_PIN = HCI_UART_RX, 33 | HCI_UART_CTS_PIN = HCI_UART_CTS, 34 | HCI_UART_RTS_PIN = HCI_UART_RTS, 35 | } uart_pin_function_t; 36 | 37 | typedef struct { 38 | const uint8_t index; 39 | UART_TypeDef* register_p; 40 | const rcc_periph_t rcc_periph; 41 | const IRQn_Type irq_channel; 42 | const uart_pin_function_t tx_pin_function, rx_pin_function, cts_pin_function, rts_pin_function; 43 | } uart_instance_t; 44 | 45 | #define UART_INSTANCE(INDEX) \ 46 | ((uart_instance_t) { \ 47 | .index = INDEX, \ 48 | .register_p = (UART_TypeDef*)UART##INDEX##_REG_BASE, \ 49 | .rcc_periph = RCC_PERIPH(UART##INDEX), \ 50 | .irq_channel = UART##INDEX##_IRQn, \ 51 | .tx_pin_function = UART##INDEX##_TX_PIN, \ 52 | .rx_pin_function = UART##INDEX##_RX_PIN, \ 53 | .cts_pin_function = UART##INDEX##_CTS_PIN, \ 54 | .rts_pin_function = UART##INDEX##_RTS_PIN, \ 55 | }) 56 | 57 | typedef struct { 58 | uint8_t tx; 59 | uint8_t rx; 60 | } uart_pads_t; 61 | 62 | typedef enum { 63 | NO_PARTY = UART_PARITY_NO_PARTY, 64 | PARITY_ODD = UART_PARITY_ODD, 65 | PARITY_EVEN = UART_PARITY_EVEN, 66 | } uart_parity_t; 67 | 68 | typedef enum { 69 | STOP_BITS_1 = UART_STOP_BITS_1, 70 | STOP_BITS_2 = UART_STOP_BITS_2, 71 | } uart_stop_bits_t; 72 | 73 | typedef enum { 74 | WORD_LENGTH_7 = UART_WROD_LENGTH_7BIT, 75 | WORD_LENGTH_8 = UART_WROD_LENGTH_8BIT, 76 | } uart_word_length_t; 77 | 78 | typedef enum { 79 | IDLE_TIME_1 = UART_RX_IDLE_1BYTE, 80 | IDLE_TIME_2 = UART_RX_IDLE_2BYTE, 81 | IDLE_TIME_4 = UART_RX_IDLE_4BYTE, 82 | IDLE_TIME_8 = UART_RX_IDLE_8BYTE, 83 | IDLE_TIME_16 = UART_RX_IDLE_16BYTE, 84 | IDLE_TIME_32 = UART_RX_IDLE_32BYTE, 85 | IDLE_TIME_64 = UART_RX_IDLE_64BYTE, 86 | IDLE_TIME_128 = UART_RX_IDLE_128BYTE, 87 | IDLE_TIME_256 = UART_RX_IDLE_256BYTE, 88 | IDLE_TIME_512 = UART_RX_IDLE_512BYTE, 89 | IDLE_TIME_1024 = UART_RX_IDLE_1024BYTE, 90 | IDLE_TIME_2048 = UART_RX_IDLE_2048BYTE, 91 | IDLE_TIME_4096 = UART_RX_IDLE_4096BYTE, 92 | IDLE_TIME_8192 = UART_RX_IDLE_8192BYTE, 93 | IDLE_TIME_16384 = UART_RX_IDLE_16384BYTE, 94 | IDLE_TIME_32768 = UART_RX_IDLE_32768BYTE, 95 | } uart_idle_time_t; 96 | 97 | typedef struct s_uart_t { 98 | const uart_instance_t* instance_p; 99 | uart_pads_t pads; 100 | uart_parity_t parity; 101 | uart_stop_bits_t stop_bits; 102 | uart_word_length_t word_length; 103 | uint8_t rx_trigger_level; // 1 to 29 104 | uart_idle_time_t idle_time; 105 | struct { 106 | const size_t size; 107 | size_t count; 108 | char* data; 109 | } rx_buf; 110 | struct { 111 | const size_t size; 112 | char* data; 113 | } tx_buf; 114 | void (*rx_cb)(struct s_uart_t* uart_p); 115 | void* mutex_p; 116 | } uart_t; 117 | 118 | bool uart_init(uart_t* uart_p); 119 | void uart_pinmux(uart_t* uart_p); 120 | void uart_flush(const uart_t* uart_p); 121 | bool uart_printn(const uart_t* uart_p, const char* pSend_Buf, size_t vCount); 122 | #define uart_print(_UART, STR) uart_printn(_UART, STR, strlen(STR)) 123 | int uart_printf(const uart_t* uart_p, char* fmt, ...); 124 | 125 | #endif //_UART_H 126 | -------------------------------------------------------------------------------- /mkrules.mk: -------------------------------------------------------------------------------- 1 | ifneq ($(MKENV_INCLUDED),1) 2 | # We assume that mkenv is in the same directory as this file. 3 | THIS_MAKEFILE = $(lastword $(MAKEFILE_LIST)) 4 | include $(dir $(THIS_MAKEFILE))mkenv.mk 5 | endif 6 | 7 | # Extra deps that need to happen before object compilation. 8 | OBJ_EXTRA_ORDER_DEPS = 9 | 10 | # This file expects that OBJ contains a list of all of the object files. 11 | # The directory portion of each object file is used to locate the source 12 | # and should not contain any ..'s but rather be relative to the top of the 13 | # tree. 14 | # 15 | # So for example, py/map.c would have an object file name py/map.o 16 | # The object files will go into the build directory and mantain the same 17 | # directory structure as the source tree. So the final dependency will look 18 | # like this: 19 | # 20 | # build/py/map.o: py/map.c 21 | # 22 | # We set vpath to point to the top of the tree so that the source files 23 | # can be located. By following this scheme, it allows a single build rule 24 | # to be used to compile all .c files. 25 | 26 | vpath %.S . $(TOP) $(USER_C_MODULES) 27 | $(BUILD)/%.o: %.S 28 | $(ECHO) "CC $<" 29 | $(Q)$(CC) $(CFLAGS) -c -o $@ $< 30 | 31 | vpath %.s . $(TOP) $(USER_C_MODULES) 32 | $(BUILD)/%.o: %.s 33 | $(ECHO) "AS $<" 34 | $(Q)$(AS) -o $@ $< 35 | 36 | define compile_c 37 | $(ECHO) "CC $<" 38 | $(Q)$(CC) $(CFLAGS) -c -MD -o $@ $< 39 | @# The following fixes the dependency file. 40 | @# See http://make.paulandlesley.org/autodep.html for details. 41 | @# Regex adjusted from the above to play better with Windows paths, etc. 42 | @$(CP) $(@:.o=.d) $(@:.o=.P); \ 43 | $(SED) -e 's/#.*//' -e 's/^.*: *//' -e 's/ *\\$$//' \ 44 | -e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.d) >> $(@:.o=.P); \ 45 | $(RM) -f $(@:.o=.d) 46 | endef 47 | 48 | define compile_cxx 49 | $(ECHO) "CXX $<" 50 | $(Q)$(CXX) $(CXXFLAGS) -c -MD -o $@ $< 51 | @# The following fixes the dependency file. 52 | @# See http://make.paulandlesley.org/autodep.html for details. 53 | @# Regex adjusted from the above to play better with Windows paths, etc. 54 | @$(CP) $(@:.o=.d) $(@:.o=.P); \ 55 | $(SED) -e 's/#.*//' -e 's/^.*: *//' -e 's/ *\\$$//' \ 56 | -e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.d) >> $(@:.o=.P); \ 57 | $(RM) -f $(@:.o=.d) 58 | endef 59 | 60 | vpath %.c . $(TOP) $(USER_C_MODULES) 61 | $(BUILD)/%.o: %.c 62 | $(call compile_c) 63 | 64 | vpath %.cpp . $(TOP) $(USER_C_MODULES) 65 | $(BUILD)/%.o: %.cpp 66 | $(call compile_cxx) 67 | 68 | $(BUILD)/%.pp: %.c 69 | $(ECHO) "PreProcess $<" 70 | $(Q)$(CPP) $(CFLAGS) -Wp,-C,-dD,-dI -o $@ $< 71 | 72 | # The following rule uses | to create an order only prerequisite. Order only 73 | # prerequisites only get built if they don't exist. They don't cause timestamp 74 | # checking to be performed. 75 | # 76 | # We don't know which source files actually need the generated.h (since 77 | # it is #included from str.h). The compiler generated dependencies will cause 78 | # the right .o's to get recompiled if the generated.h file changes. Adding 79 | # an order-only dependency to all of the .o's will cause the generated .h 80 | # to get built before we try to compile any of them. 81 | 82 | # The logic for qstr regeneration (applied by makeqstrdefs.py) is: 83 | # - if anything in QSTR_GLOBAL_DEPENDENCIES is newer, then process all source files ($^) 84 | # - else, if list of newer prerequisites ($?) is not empty, then process just these ($?) 85 | # - else, process all source files ($^) [this covers "make -B" which can set $? to empty] 86 | # See more information about this process in docs/develop/qstr.rst. 87 | 88 | 89 | # Compressed error strings. 90 | 91 | 92 | # $(sort $(var)) removes duplicates 93 | # 94 | # The net effect of this, is it causes the objects to depend on the 95 | # object directories (but only for existence), and the object directories 96 | # will be created if they don't exist. 97 | OBJ_DIRS = $(sort $(dir $(OBJ))) 98 | $(OBJ): | $(OBJ_DIRS) 99 | $(OBJ_DIRS): 100 | $(MKDIR) -p $@ 101 | 102 | $(HEADER_BUILD): 103 | $(MKDIR) -p $@ 104 | 105 | submodules: 106 | $(ECHO) "Updating submodules: $(GIT_SUBMODULES)" 107 | ifneq ($(GIT_SUBMODULES),) 108 | $(Q)git submodule sync $(addprefix $(TOP)/,$(GIT_SUBMODULES)) 109 | $(Q)git submodule update --init $(addprefix $(TOP)/,$(GIT_SUBMODULES)) 110 | endif 111 | .PHONY: submodules 112 | 113 | print-cfg: 114 | $(ECHO) "BUILD = $(BUILD)" 115 | $(ECHO) "OBJ = $(OBJ)" 116 | .PHONY: print-cfg 117 | 118 | print-def: 119 | @$(ECHO) "The following defines are built into the $(CC) compiler" 120 | $(TOUCH) __empty__.c 121 | @$(CC) -E -Wp,-dM __empty__.c 122 | @$(RM) -f __empty__.c 123 | 124 | -include $(OBJ:.o=.P) 125 | -------------------------------------------------------------------------------- /src/pin/pin.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef _PIN_H 6 | #define _PIN_H 7 | 8 | typedef struct { 9 | const uint8_t pad; 10 | const uint32_t bit; 11 | const IRQn_Type irq; 12 | } pin_instance_t; 13 | 14 | typedef enum { 15 | IN = PAD_OUT_DISABLE, 16 | OUT = PAD_OUT_ENABLE, 17 | } pin_direction_t; 18 | 19 | typedef enum { 20 | PULL_UP = PAD_PULL_UP, 21 | PULL_DOWN = PAD_PULL_DOWN, 22 | PULL_NONE = PAD_PULL_NONE, 23 | } pin_pull_t; 24 | 25 | typedef enum { 26 | WEAK_PULL = PAD_WEAK_PULL, 27 | STRONG_PULL = PAD_STRONG_PULL, 28 | } pin_pull_config_t; 29 | 30 | typedef enum { 31 | SW_MODE = PAD_SW_MODE, 32 | PINMUX_MODE = PAD_PINMUX_MODE, 33 | } pin_mode_t; 34 | 35 | typedef enum { 36 | LEVEL = GPIO_INT_Trigger_LEVEL, 37 | HIGH = GPIO_INT_POLARITY_ACTIVE_HIGH, 38 | } pin_interrupt_level_type_t; 39 | 40 | typedef enum { 41 | LOW = GPIO_INT_POLARITY_ACTIVE_LOW, 42 | EDGE = GPIO_INT_Trigger_EDGE, 43 | BOTH_EDGE = GPIO_INT_BOTH_EDGE, 44 | } pin_interrupt_polarity_t; 45 | 46 | typedef enum { 47 | DEBOUNCE_DISABLE = GPIO_INT_DEBOUNCE_DISABLE, 48 | DEBOUNCE_ENABLE = GPIO_INT_DEBOUNCE_ENABLE, 49 | } pin_interrupt_debounce_t; 50 | 51 | typedef struct { 52 | const IRQn_Type irq; 53 | pin_interrupt_level_type_t level_type; 54 | pin_interrupt_polarity_t polarity; 55 | pin_interrupt_debounce_t debounce; 56 | uint32_t debounce_time_ms; 57 | } pin_interrupt_t; 58 | 59 | typedef struct { 60 | const pin_instance_t* instance_p; 61 | pin_direction_t direction; 62 | pin_pull_t pull; 63 | pin_pull_config_t pull_config; 64 | pin_mode_t mode; 65 | bool value; 66 | pin_interrupt_t* interrupt_p; 67 | } pin_t; 68 | 69 | typedef void (*pin_interrupt_handler_t)(const uint8_t pad, bool state, uint32_t tick); 70 | 71 | extern pin_t all_pins[]; 72 | 73 | extern const pin_instance_t pin_instances[TOTAL_PIN_NUM]; 74 | 75 | #define IRQn_hlp(PAD) GPIO##PAD##_IRQn 76 | #define IRQn(PAD) IRQn_hlp(PAD) 77 | 78 | #define GPIO_BIT(PAD) \ 79 | ((PAD <= P3_6) \ 80 | ? BIT(PAD) \ 81 | : (((PAD <= P4_3) && (PAD >= P4_0)) \ 82 | ? BIT(PAD - 4) \ 83 | : (((PAD == H_0) || (PAD == H_1) || (PAD == H_2)) \ 84 | ? BIT(PAD - 11) \ 85 | : 0xFF))) 86 | 87 | #define PIN_INSTANCE(PAD) \ 88 | ((pin_instance_t) { \ 89 | .pad = PAD, \ 90 | .bit = GPIO_BIT(PAD), \ 91 | }) 92 | 93 | #define PIN_INSTANCE_IRQ(PAD) \ 94 | ((pin_instance_t) { \ 95 | .pad = PAD, \ 96 | .bit = GPIO_BIT(PAD), \ 97 | .irq = IRQn(PAD) }) 98 | 99 | #define PIN_OUT(INSTANCE_P) \ 100 | ((pin_t) { \ 101 | .instance_p = INSTANCE_P, \ 102 | .mode = SW_MODE, \ 103 | .direction = OUT, \ 104 | }) 105 | 106 | #define PIN_IN(INSTANCE_P) \ 107 | ((pin_t) { \ 108 | .instance_p = INSTANCE_P, \ 109 | .mode = PINMUX_MODE, \ 110 | .direction = IN, \ 111 | .pull = PULL_UP, \ 112 | .pull_config = STRONG_PULL, \ 113 | }) 114 | 115 | #define PIN_IN_IRQ(INSTANCE_P) \ 116 | ((pin_t) { \ 117 | .instance_p = INSTANCE_P, \ 118 | .mode = PINMUX_MODE, \ 119 | .direction = IN, \ 120 | .pull = PULL_UP, \ 121 | .pull_config = STRONG_PULL, \ 122 | .interrupt_p = &((pin_interrupt_t) { \ 123 | .level_type = EDGE, \ 124 | .polarity = LOW, \ 125 | .debounce = DEBOUNCE_ENABLE, \ 126 | .debounce_time_ms = 10, \ 127 | }), \ 128 | }) 129 | 130 | void pins_init(); 131 | void pin_init(pin_t* pin_p); 132 | void pin_deinit(pin_t* pin_p); 133 | void pin_configure_output(pin_t* pin_p); 134 | void pin_configure_input(pin_t* pin_p); 135 | void pin_configure_input_interrupt(pin_t* pin_p); 136 | bool pin_get(pin_t* pin_p); 137 | void pin_set(pin_t* pin_p, bool value); 138 | void pins_set_interrupt_handler(pin_interrupt_handler_t interrupt_handler); 139 | 140 | #endif //_PIN_H 141 | -------------------------------------------------------------------------------- /src/uart/uart.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file UART.c 3 | * @ingroup UARTGroup 4 | * @author marble 5 | * @date 2021-05-31 6 | * 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "rcc/rcc.h" 15 | #include "uart/uart.h" 16 | 17 | #define NUM_UARTS (3) 18 | 19 | static uart_t* uarts[NUM_UARTS]; 20 | 21 | bool uart_init(uart_t* uart_p) 22 | { 23 | uarts[uart_p->instance_p->index] = uart_p; 24 | 25 | if (true != os_mutex_create(&(uart_p->mutex_p))) { 26 | // the mutex was not created successfully 27 | return false; 28 | } 29 | 30 | uart_pinmux(uart_p); 31 | 32 | // initialize UART 33 | rcc_periph_set(&(uart_p->instance_p->rcc_periph), ENABLE); 34 | 35 | /* uart init */ 36 | UART_InitTypeDef UART_InitStruct; 37 | UART_StructInit(&UART_InitStruct); 38 | 39 | UART_InitStruct.parity = uart_p->parity; 40 | UART_InitStruct.stopBits = uart_p->stop_bits; 41 | UART_InitStruct.wordLen = uart_p->word_length; 42 | UART_InitStruct.rxTriggerLevel = uart_p->rx_trigger_level; 43 | UART_InitStruct.idle_time = uart_p->idle_time; 44 | 45 | UART_Init(uart_p->instance_p->register_p, &UART_InitStruct); 46 | 47 | if ((0 <= uart_p->pads.rx) && (uart_p->pads.rx < TOTAL_PIN_NUM)) { 48 | // enable rx interrupt and line status interrupt 49 | UART_INTConfig(UART, UART_INT_RD_AVA, ENABLE); 50 | UART_INTConfig(UART, UART_INT_IDLE, ENABLE); 51 | 52 | /* Enable UART IRQ */ 53 | NVIC_InitTypeDef NVIC_InitStruct; 54 | NVIC_InitStruct.NVIC_IRQChannel = uart_p->instance_p->irq_channel; 55 | NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE; 56 | NVIC_InitStruct.NVIC_IRQChannelPriority = 3; 57 | NVIC_Init(&NVIC_InitStruct); 58 | } 59 | 60 | return true; 61 | } 62 | 63 | void uart_pinmux(uart_t* uart_p) 64 | { 65 | if ((0 <= uart_p->pads.tx) && (uart_p->pads.tx < TOTAL_PIN_NUM)) { 66 | Pad_Config(uart_p->pads.tx, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, 67 | PAD_OUT_DISABLE, PAD_OUT_HIGH); 68 | Pinmux_Config(uart_p->pads.tx, uart_p->instance_p->tx_pin_function); 69 | } 70 | 71 | if ((0 <= uart_p->pads.rx) && (uart_p->pads.rx < TOTAL_PIN_NUM)) { 72 | Pad_Config(uart_p->pads.rx, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, 73 | PAD_OUT_DISABLE, PAD_OUT_HIGH); 74 | Pinmux_Config(uart_p->pads.rx, uart_p->instance_p->rx_pin_function); 75 | } 76 | } 77 | 78 | void uart_flush(const uart_t* uart_p) 79 | { 80 | while (UART_GetFlagState(uart_p->instance_p->register_p, 81 | UART_FLAG_THR_TSR_EMPTY) 82 | != SET) 83 | ; 84 | } 85 | 86 | bool uart_printn(const uart_t* uart_p, const char* str, size_t vCount) 87 | { 88 | size_t i = 0; 89 | if (!os_mutex_take(uart_p->mutex_p, 0xffffffff)) { 90 | return false; 91 | } 92 | 93 | uart_flush(uart_p); 94 | 95 | /* send block bytes(16 bytes) */ 96 | for (i = 0; i < (vCount / UART_TX_FIFO_SIZE); i++) { 97 | UART_SendData(uart_p->instance_p->register_p, (const uint8_t*)str + (UART_TX_FIFO_SIZE * i), UART_TX_FIFO_SIZE); 98 | /* wait tx fifo empty */ 99 | uart_flush(uart_p); 100 | } 101 | 102 | /* send left bytes */ 103 | UART_SendData(uart_p->instance_p->register_p, (const uint8_t*)str + (UART_TX_FIFO_SIZE * i), vCount % UART_TX_FIFO_SIZE); 104 | 105 | os_mutex_give(uart_p->mutex_p); 106 | 107 | return true; 108 | } 109 | 110 | int uart_printf(const uart_t* uart_p, char* fmt, ...) 111 | { 112 | int len; 113 | va_list argptr; 114 | 115 | va_start(argptr, fmt); 116 | 117 | len = vsnprintf(uart_p->tx_buf.data, uart_p->tx_buf.size, fmt, argptr); 118 | if (len > 0) { 119 | if (!uart_printn(uart_p, uart_p->tx_buf.data, len)) { 120 | return -1; 121 | } 122 | } 123 | 124 | va_end(argptr); 125 | 126 | return len; 127 | } 128 | 129 | static void _genericUARTHandler(int index) 130 | { 131 | uart_t* uart_p = uarts[index]; 132 | if (NULL == uart_p) { 133 | return; 134 | } 135 | 136 | UART_TypeDef* Register_p = uart_p->instance_p->register_p; 137 | uint16_t rx_len = 0; 138 | /* diable interrups globally to prevent cascades */ 139 | __disable_irq(); 140 | /* Read interrupt id */ 141 | uint32_t int_status = UART_GetIID(Register_p); 142 | /* Disable interrupt */ 143 | UART_INTConfig(Register_p, UART_INT_RD_AVA | UART_INT_LINE_STS, DISABLE); 144 | 145 | if (UART_GetFlagState(Register_p, UART_FLAG_RX_IDLE) == SET) { 146 | /* Clear flag */ 147 | UART_INTConfig(Register_p, UART_INT_IDLE, DISABLE); 148 | /* Send msg to app task */ 149 | if (NULL != uart_p->rx_cb) { 150 | uart_p->rx_cb(uart_p); 151 | } 152 | /* IO_UART_DLPS_Enter_Allowed = true; */ 153 | UART_INTConfig(Register_p, UART_INT_IDLE, ENABLE); 154 | } 155 | 156 | switch (int_status & 0x0E) { 157 | /* Rx time out(0x0C). */ 158 | case UART_INT_ID_RX_TMEOUT: 159 | rx_len = UART_GetRxFIFOLen(Register_p); 160 | UART_ReceiveData(UART, (uint8_t*)&uart_p->rx_buf.data[uart_p->rx_buf.count], rx_len); 161 | uart_p->rx_buf.count += rx_len; 162 | break; 163 | /* Receive line status interrupt(0x06). */ 164 | case UART_INT_ID_LINE_STATUS: 165 | break; 166 | /* Rx data valiable(0x04). */ 167 | case UART_INT_ID_RX_LEVEL_REACH: 168 | rx_len = UART_GetRxFIFOLen(Register_p); 169 | UART_ReceiveData(UART, (uint8_t*)&uart_p->rx_buf.data[uart_p->rx_buf.count], rx_len); 170 | uart_p->rx_buf.count += rx_len; 171 | break; 172 | /* Tx fifo empty(0x02), not enable. */ 173 | case UART_INT_ID_TX_EMPTY: 174 | /* Do nothing */ 175 | break; 176 | default: 177 | break; 178 | } 179 | /* enable interrupt again */ 180 | UART_INTConfig(Register_p, UART_INT_RD_AVA, ENABLE); 181 | /* enable interrups again globally */ 182 | __enable_irq(); 183 | } 184 | 185 | /* attach generic handler to all possible uarts */ 186 | #define UART_HANDLER(INDEX) \ 187 | void UART##INDEX##_Handler(void) \ 188 | { \ 189 | _genericUARTHandler(INDEX); \ 190 | } 191 | 192 | UART_HANDLER(0) 193 | UART_HANDLER(1) 194 | UART_HANDLER(2) 195 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | BOARD ?= EMB1082 2 | BOARD_DIR ?= boards/$(BOARD) 3 | TARGET ?= 00-blink 4 | TARGET_DIR ?= ./src/targets/$(TARGET) 5 | 6 | FTDI_VERSION ?= ft2232h 7 | FTDI_SWD_CHANNEL ?= 0 8 | 9 | ifeq ($(wildcard $(BOARD_DIR)/.),) 10 | $(error Invalid BOARD specified: $(BOARD_DIR)) 11 | endif 12 | 13 | include ./mkenv.mk 14 | include $(BOARD_DIR)/board_config.mk 15 | PORT ?= /dev/ttyUSB1 16 | 17 | CROSS_COMPILE ?= arm-none-eabi- 18 | 19 | DIRS = $(sort \ 20 | ./ \ 21 | ./src/ \ 22 | ./config/ \ 23 | $(BUILD) \ 24 | $(BOARD_DIR) \ 25 | $(TARGET_DIR)/ \ 26 | sdk/inc/ \ 27 | sdk/inc/platform/ \ 28 | sdk/inc/platform/cmsis/ \ 29 | sdk/inc/peripheral/ \ 30 | sdk/inc/bluetooth/profile/ \ 31 | sdk/inc/bluetooth/profile/server/ \ 32 | sdk/inc/bluetooth/gap/ \ 33 | sdk/src/ble/privacy/ \ 34 | sdk/inc/os/ \ 35 | sdk/inc/app/ \ 36 | sdk/src/ble/privacy \ 37 | ) 38 | 39 | INC += $(addprefix -I,$(DIRS)) 40 | 41 | CFLAGS_CORTEX_M4 = -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard 42 | # CFLAGS = $(INC) -Wall -fdata-sections -ffunction-sections -std=c11 $(CFLAGS_CORTEX_M4) $(COPT) 43 | CFLAGS = $(INC) -Wall -fdata-sections -ffunction-sections -std=c99 $(CFLAGS_CORTEX_M4) $(COPT) 44 | LDFLAGS = $(CFLAGS_CORTEX_M4) -specs=nano.specs -Trtl8762c.ld -Wl,-Map=$(basename $@).map,--cref -Wl,--gc-sections -Wl,--defsym=FIRMWARE_SIZE=$(FIRMWARE_SIZE) 45 | 46 | CFLAGS += -include $(TARGET_DIR)/app_flags.h -DFIRMWARE_SIZE=$(FIRMWARE_SIZE) -DFLASH_SIZE=$(FLASH_SIZE) 47 | 48 | # Tune for Debugging or Optimization 49 | ifeq ($(DEBUG), 1) 50 | CFLAGS += -O0 -g -ggdb -gdwarf-2 51 | else 52 | CFLAGS += -Os -DNDEBUG 53 | CFLAGS += -fdata-sections -ffunction-sections 54 | endif 55 | 56 | # Flags for optional C++ source code 57 | CXXFLAGS += $(filter-out -std=c99,$(CFLAGS)) 58 | CXXFLAGS += $(CXXFLAGS_MOD) 59 | 60 | # Flags for user C modules 61 | LDFLAGS += $(LDFLAGS_MOD) 62 | 63 | LIBS = -lc -lm -lnosys sdk/bin/rom_symbol_gcc.axf \ 64 | sdk/bin/auto_k_rf_bonding_lib_DUT.lib \ 65 | sdk/bin/auto_k_rf_bonding_lib_golden.lib \ 66 | sdk/bin/auto_k_rf.lib \ 67 | sdk/bin/bee2_adc_lib.lib \ 68 | sdk/bin/bee2_sdk.lib \ 69 | sdk/bin/electric_rtk_public_meter.lib \ 70 | sdk/bin/gap_bt5.lib \ 71 | sdk/bin/gap_utils.lib \ 72 | sdk/bin/ima_adpcm_lib.lib \ 73 | sdk/bin/msbc_lib.lib \ 74 | sdk/bin/opus_celt_enc_lib.lib \ 75 | sdk/bin/sbc_lib.lib \ 76 | sdk/bin/system_trace.lib \ 77 | 78 | # Source Files 79 | include $(TARGET_DIR)/mksrc.mk 80 | 81 | SRC_S += sdk/src/mcu/rtl876x/arm/startup_rtl8762c_gcc.s 82 | 83 | SRC_C += \ 84 | sdk/src/mcu/rtl876x/system_rtl8762c.c \ 85 | sdk/src/mcu/peripheral/rtl876x_rcc.c \ 86 | sdk/src/mcu/peripheral/rtl876x_gpio.c \ 87 | sdk/src/mcu/peripheral/rtl876x_uart.c \ 88 | sdk/src/mcu/peripheral/rtl876x_i2c.c \ 89 | sdk/src/ble/privacy/privacy_mgnt.c \ 90 | 91 | OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) 92 | OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) 93 | OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) 94 | 95 | OEM_CONFIG ?= $(BUILD)/oem_config.bin 96 | OTA_BANK0_HEADER ?= $(BUILD)/ota_bank0_header.bin 97 | 98 | # vendor binaries 99 | FSBL_VENDOR ?= fsbl_MP_master\#\#_1.1.4.0_c6f6dbf5-6d099f4054016ab6d562698d14e662e9.bin 100 | PATCH_VENDOR ?= Patch_MP_release\#_1.0.611.1_130fa89-1c796670a5129533908722a146121972.bin 101 | FSBL ?= $(BUILD)/fsbl.bin 102 | PATCH ?= $(BUILD)/patch.bin 103 | 104 | # Custom Targets 105 | all: $(BUILD)/firmware.bin 106 | .PHONY: all 107 | 108 | image: $(BUILD)/image.bin 109 | .PHONY: image 110 | 111 | ## Firmware 112 | $(BUILD)/firmware.elf: $(OBJ) 113 | $(ECHO) "LINK $@" 114 | $(Q)$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 115 | $(Q)$(SIZE) $@ 116 | 117 | $(BUILD)/firmware.bin: $(BUILD)/firmware.elf 118 | $(Q)$(OBJCOPY) --output-target=binary $^ $@ 119 | 120 | ## Image 121 | $(BUILD)/image.bin: $(OEM_CONFIG) $(OTA_BANK0_HEADER) $(PATCH) $(FSBL) $(BUILD)/firmware.bin 122 | $(Q)$(DD) if=$(OEM_CONFIG) bs=1 seek=0 of=$@ 123 | $(Q)$(DD) if=$(OTA_BANK0_HEADER) bs=1 seek=4096 of=$@ 124 | $(Q)$(DD) if=$(PATCH) bs=1 seek=8192 of=$@ 125 | $(Q)$(DD) if=$(FSBL) bs=1 seek=49152 of=$@ 126 | $(Q)$(DD) if=$(BUILD)/firmware.bin bs=1 seek=53248 of=$@ 127 | 128 | ### Image Parts 129 | $(BUILD)/oem_config.bin: $(BUILD)/oem_config.o 130 | $(Q)$(OBJCOPY) --output-target=binary $< $@ 131 | $(Q)$(PYTHON) tools/crc_patch.py $@ 132 | 133 | $(BUILD)/oem_config.o: config/oem_config.c | $(BUILD) 134 | $(Q)$(CC) -c -Wno-override-init $(CFLAGS) $< -o $@ 135 | 136 | $(BUILD)/ota_bank0_header.bin: $(BUILD)/ota_bank0_header.o 137 | $(Q)$(OBJCOPY) --output-target=binary $< $@ 138 | $(Q)$(PYTHON) tools/crc_patch.py $@ 139 | 140 | $(BUILD)/ota_bank0_header.o: config/ota_bank0_header.c | $(BUILD) 141 | $(Q)$(CC) -c -Wno-override-init $(CFLAGS) $< -o $@ 142 | 143 | $(BUILD)/fsbl.bin: $(FSBL_VENDOR) | $(BUILD) 144 | $(Q)$(DD) if=$< bs=1 skip=512 of=$@ 145 | 146 | $(BUILD)/patch.bin: $(PATCH_VENDOR) | $(BUILD) 147 | $(Q)$(DD) if=$< bs=1 skip=512 of=$@ 148 | 149 | backup-$(BOARD).bin: | $(BUILD) 150 | $(Q)$(PYTHON) tools/rtltool/rtltool.py --port $(PORT) read_flash 0x00801000 $(FLASH_SIZE) $@ 151 | 152 | # Helper Targets 153 | $(BUILD): 154 | $(Q)$(MKDIR) -p $@ 155 | 156 | debug_pico: $(BUILD)/firmware.elf 157 | $(Q)$(GDB) $< \ 158 | $(addprefix --directory ,$(DIRS)) \ 159 | -ex "target extended-remote | openocd -c 'log_output openocd.log' \ 160 | -f interface/cmsis-dap.cfg \ 161 | -c 'transport select swd' \ 162 | -f debug/rtl8762c.cfg \ 163 | -f debug/gdb.cfg" \ 164 | -ex 'monitor halt' 165 | .PHONY: debug_pico 166 | 167 | debug_ftdi: $(BUILD)/firmware.elf 168 | $(Q)$(GDB) $< \ 169 | $(addprefix --directory ,$(DIRS)) \ 170 | -ex "target extended-remote | openocd -c 'log_output openocd.log' \ 171 | -f debug/ftdi/$(FTDI_VERSION).cfg \ 172 | -c 'ftdi_channel $(FTDI_SWD_CHANNEL)' \ 173 | -f debug/ftdi/swd.cfg \ 174 | -f debug/rtl8762c.cfg" \ 175 | -f debug/gdb.cfg" \ 176 | -ex 'monitor reset halt' \ 177 | -ex 'break main' \ 178 | -ex 'continue' 179 | .PHONY: debug_ftdi 180 | 181 | debug_stlink: $(BUILD)/firmware.elf 182 | $(Q)$(GDB) $< \ 183 | $(addprefix --directory ,$(DIRS)) \ 184 | -ex "target extended-remote | openocd -c 'log_output openocd.log' \ 185 | -f interface/stlink.cfg \ 186 | -f debug/rtl8762c.cfg \ 187 | -f debug/gdb.cfg" \ 188 | -ex 'monitor halt' 189 | .PHONY: debug_stlink 190 | 191 | flash: $(OEM_CONFIG) $(OTA_BANK0_HEADER) $(BUILD)/firmware.bin 192 | $(Q)$(PYTHON) tools/rtltool/rtltool.py --port $(PORT) write_flash \ 193 | 0x00801000 $(OEM_CONFIG) \ 194 | 0x00802000 $(OTA_BANK0_HEADER) \ 195 | 0x0080E000 $(BUILD)/firmware.bin 196 | .PHONY: flash 197 | 198 | flash_image: $(BUILD)/image.bin 199 | $(Q)$(PYTHON) tools/rtltool/rtltool.py --port $(PORT) write_flash 0x00801000 $< 200 | .PHONY: flash 201 | 202 | backup: backup-$(BOARD).bin 203 | .PHONY: backup 204 | 205 | playback: backup-$(BOARD).bin 206 | $(Q)$(PYTHON) tools/rtltool/rtltool.py --port $(PORT) write_flash 0x00801000 $< 207 | .PHONY: playback 208 | 209 | term: 210 | python3 -m serial.tools.miniterm --raw --exit-char 24 --rts 0 $(PORT) 115200 211 | .PHONY: term 212 | 213 | format: 214 | find src/ boards/ -name '*.[ch]' -exec clang-format -i -style=WebKit {} + 215 | .PHONY: format 216 | 217 | include ./mkrules.mk 218 | -------------------------------------------------------------------------------- /config/oem_config.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "config/flash_map.h" 4 | 5 | // parameters 6 | #define BT_MAC_ADDRESS {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff} 7 | 8 | enum { LDO, SWR }; 9 | #define LDO_SWR_MODE LDO 10 | 11 | #define RUN_MODE (NORMAL) 12 | 13 | #define TX_POWER_LE1M (GAIN_7_5_DBM) 14 | 15 | #define OTA_AES_KEY {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F} 16 | 17 | #define XTAL_CAP_CAL (0x48) 18 | 19 | // helpers 20 | #define PRE_OTA_AES_KEY (0x01) 21 | 22 | #if (LDO_SWR_MODE==LDO) 23 | #define LDO_SWR_0 (0x00) 24 | #define LDO_SWR_1 (0x00) 25 | #define LDO_SWR_2 (0x00) 26 | #define LDO_SWR_3 (0x00) 27 | #elif (LDO_SWR_MODE==SWR) 28 | #define LDO_SWR_0 (0x04) 29 | #define LDO_SWR_1 (0x04) 30 | #define LDO_SWR_2 (0x80) 31 | #define LDO_SWR_3 (0x01) 32 | #endif 33 | 34 | #define STRUCT_ARRAY_SETTER(NAME, FIELD, VALUE) .FIELD = {[0 ... (sizeof(NAME.FIELD)-1)] = VALUE} 35 | 36 | // data structures 37 | #pragma pack(push, 1) 38 | 39 | typedef enum { 40 | NORMAL = 0x01, 41 | MP = 0x00, 42 | } run_mode_t; 43 | 44 | typedef enum { 45 | GAIN_NEG20_DBM = 0x30, 46 | GAIN_0_DBM = 0x80, 47 | GAIN_3_DBM = 0x90, 48 | GAIN_4_DBM = 0xa0, 49 | GAIN_7_5_DBM = 0xd0, 50 | } tx_power_t; 51 | 52 | typedef struct { 53 | enum { 54 | BT_MAC_ADDRESS_ID = 0x0033, 55 | XTAL_CAP_CAL_ID = 0x0148, 56 | RUN_MODE_ID = 0x0178, 57 | PRE_OTA_AES_KEY_ID = 0x01B0, 58 | LDO_SWR_0_ID = 0x01F0, 59 | LDO_SWR_1_ID = 0x01F7, 60 | LDO_SWR_2_ID = 0x0208, 61 | LDO_SWR_3_ID = 0x0209, 62 | OTA_AES_KEY_ID = 0x0238, 63 | OTA_BANK0_ADDR_ID = 0x0280, 64 | OTA_BANK0_SIZE_ID = 0x0284, 65 | OTA_BANK1_ADDR_ID = 0x0288, 66 | OTA_BANK1_SIZE_ID = 0x028c, 67 | FTL_ADDR_ID = 0x0290, 68 | FTL_SIZE_ID = 0x0294, 69 | OTA_TMP_ADDR_ID = 0x0298, 70 | OTA_TMP_SIZE_ID = 0x029c, 71 | TX_POWER_LE1M_ID = 0x0347, 72 | TX_POWER_LE2M_ID = 0x0348, 73 | TX_POWER_LE2M_2402MHZ_ID = 0x0349, 74 | TX_POWER_LE2M_2480MHZ_ID = 0x034a, 75 | } id : 16; 76 | unsigned len: 8; 77 | } entry_header_t; 78 | 79 | #define SINGLE_ENTRY_TYPE(type) struct { \ 80 | entry_header_t header; \ 81 | type data; \ 82 | char mask[sizeof(type)]; \ 83 | } 84 | 85 | #define ARRAY_ENTRY_TYPE(length) struct { \ 86 | entry_header_t header; \ 87 | char data[length]; \ 88 | char mask[length]; \ 89 | } 90 | 91 | typedef struct { 92 | char magic[8]; 93 | unsigned size:32; 94 | char _ff0[0x168]; 95 | char hash[32]; 96 | char _ff1[0x26c]; 97 | } header_t; 98 | 99 | typedef struct { 100 | unsigned int magic; 101 | unsigned short len; 102 | 103 | #ifdef BT_MAC_ADDRESS 104 | ARRAY_ENTRY_TYPE(6) mac; 105 | #endif 106 | 107 | #ifdef LDO_SWR_MODE 108 | SINGLE_ENTRY_TYPE(unsigned char) ldo_swr[4]; 109 | #endif 110 | 111 | #ifdef RUN_MODE 112 | SINGLE_ENTRY_TYPE(run_mode_t) run_mode; 113 | #endif 114 | 115 | #ifdef TX_POWER_LE1M 116 | SINGLE_ENTRY_TYPE(tx_power_t) tx_power_le1m; 117 | #endif 118 | 119 | #ifdef OTA_BANK0_ADDR 120 | SINGLE_ENTRY_TYPE(unsigned int) ota_bank0_addr; 121 | #endif 122 | 123 | #ifdef OTA_BANK0_SIZE 124 | SINGLE_ENTRY_TYPE(unsigned int) ota_bank0_size; 125 | #endif 126 | 127 | #ifdef OTA_BANK1_ADDR 128 | SINGLE_ENTRY_TYPE(unsigned int) ota_bank1_addr; 129 | #endif 130 | 131 | #ifdef OTA_BANK1_SIZE 132 | SINGLE_ENTRY_TYPE(unsigned int) ota_bank1_size; 133 | #endif 134 | 135 | #ifdef FTL_ADDR 136 | SINGLE_ENTRY_TYPE(unsigned int) ftl_addr; 137 | #endif 138 | 139 | #ifdef FTL_SIZE 140 | SINGLE_ENTRY_TYPE(unsigned int) ftl_size; 141 | #endif 142 | 143 | #ifdef OTA_TMP_ADDR 144 | SINGLE_ENTRY_TYPE(unsigned int) ota_tmp_addr; 145 | #endif 146 | 147 | #ifdef OTA_TMP_SIZE 148 | SINGLE_ENTRY_TYPE(unsigned int) ota_tmp_size; 149 | #endif 150 | 151 | #ifdef OTA_AES_KEY 152 | SINGLE_ENTRY_TYPE(unsigned char) pre_ota_aes_key; 153 | ARRAY_ENTRY_TYPE(32) ota_aes_key; 154 | #endif 155 | 156 | #ifdef XTAL_CAP_CAL 157 | SINGLE_ENTRY_TYPE(unsigned char) xtal_cap_cal; 158 | #endif 159 | } config_t; 160 | 161 | typedef struct { 162 | header_t header; 163 | config_t config; 164 | } oem_config_t; 165 | 166 | #define ENTRY_VALUE(CONFIG, ENTRY, VALUE) .ENTRY = { \ 167 | .header = { \ 168 | .id = VALUE##_ID, \ 169 | .len = sizeof(CONFIG.ENTRY.data) \ 170 | }, \ 171 | .data = VALUE, \ 172 | .mask = {[0 ... (sizeof(CONFIG.ENTRY.mask)-1)] = 0xFF}, \ 173 | }, 174 | 175 | #define ENTRY_VALUE_MASK(CONFIG, ENTRY, VALUE, MASK) .ENTRY = { \ 176 | .header = { \ 177 | .id = VALUE##_ID, \ 178 | .len = sizeof(CONFIG.ENTRY.data) \ 179 | }, \ 180 | .data = VALUE, \ 181 | .mask = MASK, \ 182 | }, 183 | 184 | oem_config_t oem_config = { 185 | .header = { 186 | .magic = "\x05\x00\xf0\xff\x8d\x27\x00\x00", 187 | .size = sizeof(config_t), 188 | STRUCT_ARRAY_SETTER(oem_config.header, _ff0, 0xff), 189 | STRUCT_ARRAY_SETTER(oem_config.header, hash, 0xff), 190 | STRUCT_ARRAY_SETTER(oem_config.header, _ff1, 0xff), 191 | }, 192 | .config = { 193 | .magic = 0x8721bee2, 194 | // measure from end of len field to end of struct 195 | .len = sizeof(config_t) - offsetof(config_t, len) - sizeof(oem_config.config.len), 196 | 197 | #ifdef BT_MAC_ADDRESS 198 | ENTRY_VALUE(oem_config.config, mac, BT_MAC_ADDRESS) 199 | #endif 200 | 201 | #ifdef LDO_SWR_MODE 202 | ENTRY_VALUE_MASK(oem_config.config, ldo_swr[0], LDO_SWR_0, {0x04}) 203 | ENTRY_VALUE_MASK(oem_config.config, ldo_swr[1], LDO_SWR_1, {0x04}) 204 | ENTRY_VALUE_MASK(oem_config.config, ldo_swr[2], LDO_SWR_2, {0x80}) 205 | ENTRY_VALUE_MASK(oem_config.config, ldo_swr[3], LDO_SWR_3, {0x01}) 206 | #endif 207 | 208 | #ifdef RUN_MODE 209 | ENTRY_VALUE_MASK(oem_config.config, run_mode, RUN_MODE, {0x01}) 210 | #endif 211 | 212 | #ifdef TX_POWER_LE1M 213 | ENTRY_VALUE(oem_config.config, tx_power_le1m, TX_POWER_LE1M) 214 | #endif 215 | 216 | #ifdef OTA_BANK0_ADDR 217 | ENTRY_VALUE(oem_config.config, ota_bank0_addr, OTA_BANK0_ADDR) 218 | #endif 219 | 220 | #ifdef OTA_BANK0_SIZE 221 | ENTRY_VALUE(oem_config.config, ota_bank0_size, OTA_BANK0_SIZE) 222 | #endif 223 | 224 | #ifdef OTA_BANK1_ADDR 225 | ENTRY_VALUE(oem_config.config, ota_bank1_addr, OTA_BANK1_ADDR) 226 | #endif 227 | 228 | #ifdef OTA_BANK1_SIZE 229 | ENTRY_VALUE(oem_config.config, ota_bank1_size, OTA_BANK1_SIZE) 230 | #endif 231 | 232 | #ifdef FTL_ADDR 233 | ENTRY_VALUE(oem_config.config, ftl_addr, FTL_ADDR) 234 | #endif 235 | 236 | #ifdef FTL_SIZE 237 | ENTRY_VALUE(oem_config.config, ftl_size, FTL_SIZE) 238 | #endif 239 | 240 | #ifdef OTA_TMP_ADDR 241 | ENTRY_VALUE(oem_config.config, ota_tmp_addr, OTA_TMP_ADDR) 242 | #endif 243 | 244 | #ifdef OTA_TMP_SIZE 245 | ENTRY_VALUE(oem_config.config, ota_tmp_size, OTA_TMP_SIZE) 246 | #endif 247 | 248 | #ifdef OTA_AES_KEY 249 | ENTRY_VALUE(oem_config.config, pre_ota_aes_key, PRE_OTA_AES_KEY) 250 | ENTRY_VALUE(oem_config.config, ota_aes_key, OTA_AES_KEY) 251 | #endif 252 | 253 | #ifdef XTAL_CAP_CAL 254 | ENTRY_VALUE(oem_config.config, xtal_cap_cal, XTAL_CAP_CAL) 255 | #endif 256 | }, 257 | }; 258 | 259 | #pragma pack(pop) 260 | -------------------------------------------------------------------------------- /src/pin/pin.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "pin/pin.h" 8 | #include "rcc/rcc.h" 9 | 10 | #include 11 | 12 | const pin_instance_t pin_instances[TOTAL_PIN_NUM] = { 13 | [P0_0] = PIN_INSTANCE_IRQ(P0_0), 14 | [P0_1] = PIN_INSTANCE_IRQ(P0_1), 15 | [P0_2] = PIN_INSTANCE_IRQ(P0_2), 16 | [P0_3] = PIN_INSTANCE_IRQ(P0_3), 17 | [P0_4] = PIN_INSTANCE_IRQ(P0_4), 18 | [P0_5] = PIN_INSTANCE_IRQ(P0_5), 19 | [P0_6] = PIN_INSTANCE_IRQ(P0_6), 20 | [P0_7] = PIN_INSTANCE_IRQ(P0_7), 21 | [P1_0] = PIN_INSTANCE_IRQ(P1_0), 22 | [P1_1] = PIN_INSTANCE_IRQ(P1_1), 23 | [P1_2] = PIN_INSTANCE_IRQ(P1_2), 24 | [P1_3] = PIN_INSTANCE_IRQ(P1_3), 25 | [P1_4] = PIN_INSTANCE_IRQ(P1_4), 26 | [P1_5] = PIN_INSTANCE_IRQ(P1_5), 27 | [P1_6] = PIN_INSTANCE_IRQ(P1_6), 28 | [P1_7] = PIN_INSTANCE_IRQ(P1_7), 29 | [P2_0] = PIN_INSTANCE_IRQ(P2_0), 30 | [P2_1] = PIN_INSTANCE_IRQ(P2_1), 31 | [P2_2] = PIN_INSTANCE_IRQ(P2_2), 32 | [P2_3] = PIN_INSTANCE_IRQ(P2_3), 33 | [P2_4] = PIN_INSTANCE_IRQ(P2_4), 34 | [P2_5] = PIN_INSTANCE_IRQ(P2_5), 35 | [P2_6] = PIN_INSTANCE_IRQ(P2_6), 36 | [P2_7] = PIN_INSTANCE_IRQ(P2_7), 37 | [P3_0] = PIN_INSTANCE_IRQ(P3_0), 38 | [P3_1] = PIN_INSTANCE_IRQ(P3_1), 39 | [P3_2] = PIN_INSTANCE_IRQ(P3_2), 40 | [P3_3] = PIN_INSTANCE_IRQ(P3_3), 41 | [P3_4] = PIN_INSTANCE_IRQ(P3_4), 42 | [P3_5] = PIN_INSTANCE_IRQ(P3_5), 43 | [P3_6] = PIN_INSTANCE_IRQ(P3_6), 44 | [P4_0] = PIN_INSTANCE(P4_0), 45 | [P4_1] = PIN_INSTANCE(P4_1), 46 | [P4_2] = PIN_INSTANCE(P4_2), 47 | [P4_3] = PIN_INSTANCE(P4_3), 48 | [H_0] = PIN_INSTANCE(H_0), 49 | [H_1] = PIN_INSTANCE(H_1), 50 | [H_2] = PIN_INSTANCE(H_2), 51 | }; 52 | 53 | static volatile pin_interrupt_handler_t pin_interrupt_handler = NULL; 54 | 55 | void pins_init(void) 56 | { 57 | static const rcc_periph_t GPIO_RCCPeriph = RCC_PERIPH(GPIO); 58 | rcc_periph_set(&GPIO_RCCPeriph, true); 59 | } 60 | 61 | void pin_init(pin_t* pin_p) 62 | { 63 | if ((IN == pin_p->direction) && (SW_MODE == pin_p->mode)) { 64 | // SW mode pins are output only 65 | return; 66 | } 67 | 68 | Pad_Config( 69 | pin_p->instance_p->pad, 70 | pin_p->mode, 71 | PAD_IS_PWRON, 72 | pin_p->pull, 73 | pin_p->direction, 74 | pin_p->value); 75 | 76 | Pad_PullConfigValue(pin_p->instance_p->pad, pin_p->pull_config); 77 | 78 | if (SW_MODE == pin_p->mode) { 79 | Pinmux_Config(pin_p->instance_p->pad, IDLE_MODE); 80 | } else { 81 | GPIO_InitTypeDef Gpio_Struct; 82 | GPIOMode_TypeDef direction = (IN == pin_p->direction) ? GPIO_Mode_IN : GPIO_Mode_OUT; 83 | 84 | GPIO_StructInit(&Gpio_Struct); 85 | Gpio_Struct.GPIO_Pin = pin_p->instance_p->bit; 86 | Gpio_Struct.GPIO_Mode = direction; 87 | if (((GPIOMode_TypeDef)IN == direction) && (NULL != pin_p->interrupt_p)) { 88 | Gpio_Struct.GPIO_ITCmd = ENABLE; 89 | Gpio_Struct.GPIO_ITTrigger = pin_p->interrupt_p->level_type; 90 | Gpio_Struct.GPIO_ITPolarity = pin_p->interrupt_p->polarity; 91 | Gpio_Struct.GPIO_ITDebounce = pin_p->interrupt_p->debounce; 92 | Gpio_Struct.GPIO_DebounceTime = pin_p->interrupt_p->debounce_time_ms; 93 | } 94 | GPIO_Init(&Gpio_Struct); 95 | 96 | if (((GPIOMode_TypeDef)IN == direction) && (NULL != pin_p->interrupt_p)) { 97 | // disable interrupt 98 | GPIO_INTConfig(pin_p->instance_p->bit, DISABLE); 99 | 100 | // configure IRQ 101 | NVIC_InitTypeDef NVIC_InitStruct; 102 | NVIC_InitStruct.NVIC_IRQChannel = pin_p->instance_p->irq; 103 | NVIC_InitStruct.NVIC_IRQChannelPriority = 3; 104 | NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; 105 | NVIC_Init(&NVIC_InitStruct); 106 | 107 | // enable interrupt 108 | GPIO_MaskINTConfig(pin_p->instance_p->bit, DISABLE); 109 | GPIO_INTConfig(pin_p->instance_p->bit, ENABLE); 110 | } else if ((GPIOMode_TypeDef)OUT == direction) { 111 | GPIO_WriteBit(pin_p->instance_p->bit, pin_p->value); 112 | } 113 | 114 | Pinmux_Config(pin_p->instance_p->pad, DWGPIO); 115 | } 116 | } 117 | 118 | void pin_deinit(pin_t* pin_p) 119 | { 120 | GPIO_MaskINTConfig(pin_p->instance_p->bit, ENABLE); 121 | GPIO_INTConfig(pin_p->instance_p->bit, DISABLE); 122 | 123 | Pad_Config(pin_p->instance_p->pad, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, 124 | PAD_OUT_DISABLE, PAD_OUT_HIGH); 125 | Pinmux_Config(pin_p->instance_p->pad, IDLE_MODE); 126 | } 127 | 128 | bool pin_get(pin_t* pin_p) 129 | { 130 | if (SW_MODE == pin_p->mode) { 131 | return pin_p->value; 132 | } else { 133 | if (IN == pin_p->direction) { 134 | return (SET == GPIO_ReadInputDataBit(pin_p->instance_p->bit)); 135 | } else { 136 | return (SET == GPIO_ReadOutputDataBit(pin_p->instance_p->bit)); 137 | } 138 | } 139 | } 140 | 141 | void pin_set(pin_t* pin_p, bool value) 142 | { 143 | if (SW_MODE == pin_p->mode) { 144 | Pad_OutputControlValue(pin_p->instance_p->pad, value); 145 | pin_p->value = value; 146 | } else { 147 | GPIO_WriteBit(pin_p->instance_p->bit, value); 148 | } 149 | } 150 | 151 | void pins_set_interrupt_handler(pin_interrupt_handler_t interrupt_handler) 152 | { 153 | pin_interrupt_handler = interrupt_handler; 154 | } 155 | 156 | static void _generic_pin_interrupt_handler(const uint8_t pad, const uint32_t bit) DATA_RAM_FUNCTION; 157 | static void _generic_pin_interrupt_handler(const uint8_t pad, const uint32_t bit) 158 | { 159 | uint32_t tick; 160 | bool state; 161 | /* disable interrups globally */ 162 | __disable_irq(); 163 | /* store relevant values */ 164 | tick = platform_vendor_tick(); 165 | state = GPIO_ReadInputDataBit(bit); 166 | /* disable interrupt in pin */ 167 | GPIO_INTConfig(bit, DISABLE); 168 | GPIO_MaskINTConfig(bit, ENABLE); 169 | /* mark interrupt as processed */ 170 | GPIO_ClearINTPendingBit(bit); 171 | /* enable interrupt for this pin again */ 172 | GPIO_MaskINTConfig(bit, DISABLE); 173 | GPIO_INTConfig(bit, ENABLE); 174 | /* enable interrupt for this pin again */ 175 | if (NULL != pin_interrupt_handler) { 176 | pin_interrupt_handler(pad, state, tick); 177 | } 178 | /* enable interrups again globally */ 179 | __enable_irq(); 180 | } 181 | 182 | /* attach generic handler to all possible pins */ 183 | #define GPIO_HANDLER_NAME(PAD) GPIO##PAD##_Handler 184 | #define GPIO_HANDLER(PAD) \ 185 | void GPIO_HANDLER_NAME(PAD)(void) DATA_RAM_FUNCTION; \ 186 | void GPIO_HANDLER_NAME(PAD)(void) \ 187 | { \ 188 | _generic_pin_interrupt_handler(PAD, GPIO_BIT(PAD)); \ 189 | } 190 | 191 | GPIO_HANDLER(P0_0) 192 | GPIO_HANDLER(P0_1) 193 | GPIO_HANDLER(P0_2) 194 | GPIO_HANDLER(P0_3) 195 | GPIO_HANDLER(P0_4) 196 | GPIO_HANDLER(P0_5) 197 | GPIO_HANDLER(P0_6) 198 | GPIO_HANDLER(P0_7) 199 | GPIO_HANDLER(P1_0) 200 | GPIO_HANDLER(P1_1) 201 | GPIO_HANDLER(P1_2) 202 | GPIO_HANDLER(P1_3) 203 | GPIO_HANDLER(P1_4) 204 | GPIO_HANDLER(P1_5) 205 | GPIO_HANDLER(P1_6) 206 | GPIO_HANDLER(P1_7) 207 | GPIO_HANDLER(P2_0) 208 | GPIO_HANDLER(P2_1) 209 | GPIO_HANDLER(P2_2) 210 | GPIO_HANDLER(P2_3) 211 | GPIO_HANDLER(P2_4) 212 | GPIO_HANDLER(P2_5) 213 | GPIO_HANDLER(P2_6) 214 | GPIO_HANDLER(P2_7) 215 | GPIO_HANDLER(P3_0) 216 | GPIO_HANDLER(P3_1) 217 | GPIO_HANDLER(P3_2) 218 | GPIO_HANDLER(P3_3) 219 | GPIO_HANDLER(P3_4) 220 | GPIO_HANDLER(P3_5) 221 | GPIO_HANDLER(P3_6) 222 | -------------------------------------------------------------------------------- /config/flash_map.h: -------------------------------------------------------------------------------- 1 | /** 2 | ***************************************************************************************** 3 | * Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. 4 | ***************************************************************************************** 5 | * @file flash_map.h 6 | * @brief Flash Layout Configuration, and flash layout must be changed with 7 | *config file! 8 | * @note flash_map.h must be generated by FlashMapGenerateTool! 9 | * ************************************************************************************* 10 | */ 11 | 12 | #ifndef _FLASH_MAP_H_ 13 | #define _FLASH_MAP_H_ 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /*============================================================================* 20 | * Flash Layout 21 | *============================================================================*/ 22 | /* Flash total size 512KB 23 | example: 24 | 1) Reaerved: 4K (0x00800000) 25 | 2) OEM Header: 4K (0x00801000) 26 | 3) OTA Bank0: 148K (0x00802000) 27 | a) OTA Header 4K (0x00802000) 28 | b) Secure boot loader 4K (0x0080D000) 29 | c) Patch code 40K (0x00803000) 30 | d) APP code 100K (0x0080E000) 31 | e) APP data1 0K (0x00827000) 32 | f) APP data2 0K (0x00827000) 33 | e) APP data3 0K (0x00827000) 34 | f) APP data4 0K (0x00827000) 35 | e) APP data5 0K (0x00827000) 36 | f) APP data6 0K (0x00827000) 37 | 4) OTA Bank1: 0K (0x00827000) 38 | a) OTA Header 0K (0x00000000) 39 | b) Secure boot loader 0K (0x00000000) 40 | c) Patch code 0K (0x00000000) 41 | d) APP code 0K (0x00000000) 42 | e) APP data1 0K (0x00000000) 43 | f) APP data2 0K (0x00000000) 44 | f) APP data3 0K (0x00000000) 45 | f) APP data4 0K (0x00000000) 46 | f) APP data5 0K (0x00000000) 47 | f) APP data6 0K (0x00000000) 48 | 5) FTL: 16K (0x00827000) 49 | 6) OTA Tmp: 100K (0x0082B000) 50 | 7) APP Defined Section: 240K (0x00844000) 51 | */ 52 | 53 | /*============================================================================* 54 | * Flash Layout Configuration (Generated by FlashMapGenerateTool) 55 | *============================================================================*/ 56 | 57 | #define FLASH_ADDR 0x00800000 // Fixed 58 | 59 | /* ========== High Level Flash Layout Configuration ========== */ 60 | #define RESERVED_ADDR (FLASH_ADDR) 61 | #define RESERVED_SIZE 0x00001000 // 4K Bytes 62 | #define OEM_CFG_ADDR (RESERVED_ADDR + RESERVED_SIZE) 63 | #define OEM_CFG_SIZE 0x00001000 // 4K Bytes 64 | #define OTA_BANK0_ADDR (OEM_CFG_ADDR + OEM_CFG_SIZE) 65 | 66 | /* ========== OTA Bank0 Flash Layout Configuration ========== */ 67 | #define BANK0_OTA_HEADER_ADDR (OTA_BANK0_ADDR) 68 | #define BANK0_OTA_HEADER_SIZE 0x00001000 // 4K Bytes 69 | #define BANK0_ROM_PATCH_ADDR (BANK0_OTA_HEADER_ADDR + BANK0_OTA_HEADER_SIZE) 70 | #define BANK0_ROM_PATCH_SIZE 0x0000A000 // 40K Bytes 71 | #define BANK0_SECURE_BOOT_ADDR (BANK0_ROM_PATCH_ADDR + BANK0_ROM_PATCH_SIZE) 72 | #define BANK0_SECURE_BOOT_SIZE 0x00001000 // 4K Bytes 73 | #define BANK0_APP_ADDR (BANK0_SECURE_BOOT_ADDR + BANK0_SECURE_BOOT_SIZE) 74 | #define BANK0_APP_SIZE (FIRMWARE_SIZE) 75 | #define BANK0_APP_DATA1_ADDR (BANK0_APP_ADDR + BANK0_APP_SIZE) 76 | #define BANK0_APP_DATA1_SIZE 0x00000000 // 0K Bytes 77 | #define BANK0_APP_DATA2_ADDR (BANK0_APP_DATA1_ADDR + BANK0_APP_DATA1_SIZE) 78 | #define BANK0_APP_DATA2_SIZE 0x00000000 // 0K Bytes 79 | #define BANK0_APP_DATA3_ADDR (BANK0_APP_DATA2_ADDR + BANK0_APP_DATA2_SIZE) 80 | #define BANK0_APP_DATA3_SIZE 0x00000000 // 0K Bytes 81 | #define BANK0_APP_DATA4_ADDR (BANK0_APP_DATA3_ADDR + BANK0_APP_DATA3_SIZE) 82 | #define BANK0_APP_DATA4_SIZE 0x00000000 // 0K Bytes 83 | #define BANK0_APP_DATA5_ADDR (BANK0_APP_DATA4_ADDR + BANK0_APP_DATA4_SIZE) 84 | #define BANK0_APP_DATA5_SIZE 0x00000000 // 0K Bytes 85 | #define BANK0_APP_DATA6_ADDR (BANK0_APP_DATA5_ADDR + BANK0_APP_DATA5_SIZE) 86 | #define BANK0_APP_DATA6_SIZE 0x00000000 // 0K Bytes 87 | 88 | /* ========== High Level Flash Layout Configuration ========== */ 89 | #define OTA_BANK0_SIZE (BANK0_OTA_HEADER_SIZE \ 90 | + BANK0_SECURE_BOOT_SIZE \ 91 | + BANK0_ROM_PATCH_SIZE \ 92 | + BANK0_APP_SIZE \ 93 | + BANK0_APP_DATA1_SIZE \ 94 | + BANK0_APP_DATA2_SIZE \ 95 | + BANK0_APP_DATA3_SIZE \ 96 | + BANK0_APP_DATA4_SIZE \ 97 | + BANK0_APP_DATA5_SIZE \ 98 | + BANK0_APP_DATA6_SIZE \ 99 | ) // 148K Bytes 100 | #define OTA_BANK1_ADDR (OTA_BANK0_ADDR + OTA_BANK0_SIZE) 101 | 102 | /* ========== OTA Bank1 Flash Layout Configuration ========== */ 103 | #define BANK1_OTA_HEADER_ADDR (OTA_BANK1_ADDR) 104 | #define BANK1_OTA_HEADER_SIZE 0x00000000 // 0K Bytes 105 | #define BANK1_SECURE_BOOT_ADDR (BANK1_OTA_HEADER_ADDR + BANK1_OTA_HEADER_SIZE) 106 | #define BANK1_SECURE_BOOT_SIZE 0x00000000 // 0K Bytes 107 | #define BANK1_ROM_PATCH_ADDR (BANK1_SECURE_BOOT_ADDR + BANK1_SECURE_BOOT_SIZE) 108 | #define BANK1_ROM_PATCH_SIZE 0x00000000 // 0K Bytes 109 | #define BANK1_APP_ADDR (BANK1_ROM_PATCH_ADDR + BANK1_ROM_PATCH_SIZE) 110 | #define BANK1_APP_SIZE 0x00000000 // 0K Bytes 111 | #define BANK1_APP_DATA1_ADDR (BANK1_APP_ADDR + BANK1_APP_SIZE) 112 | #define BANK1_APP_DATA1_SIZE 0x00000000 // 0K Bytes 113 | #define BANK1_APP_DATA2_ADDR (BANK1_APP_DATA1_ADDR+BANK1_APP_DATA1_SIZE) 114 | #define BANK1_APP_DATA2_SIZE 0x00000000 // 0K Bytes 115 | #define BANK1_APP_DATA3_ADDR (BANK1_APP_DATA2_ADDR + BANK1_APP_DATA2_SIZE) 116 | #define BANK1_APP_DATA3_SIZE 0x00000000 // 0K Bytes 117 | #define BANK1_APP_DATA4_ADDR (BANK1_APP_DATA3_ADDR + BANK1_APP_DATA3_SIZE) 118 | #define BANK1_APP_DATA4_SIZE 0x00000000 // 0K Bytes 119 | #define BANK1_APP_DATA5_ADDR (BANK1_APP_DATA4_ADDR + BANK1_APP_DATA4_SIZE) 120 | #define BANK1_APP_DATA5_SIZE 0x00000000 // 0K Bytes 121 | #define BANK1_APP_DATA6_ADDR (BANK1_APP_DATA5_ADDR + BANK1_APP_DATA5_SIZE) 122 | #define BANK1_APP_DATA6_SIZE 0x00000000 // 0K Bytes 123 | 124 | /* ========== High Level Flash Layout Configuration ========== */ 125 | #define OTA_BANK1_SIZE (BANK1_OTA_HEADER_SIZE \ 126 | + BANK1_SECURE_BOOT_SIZE \ 127 | + BANK1_ROM_PATCH_SIZE \ 128 | + BANK1_APP_SIZE \ 129 | + BANK1_APP_DATA1_SIZE \ 130 | + BANK1_APP_DATA2_SIZE \ 131 | + BANK1_APP_DATA3_SIZE \ 132 | + BANK1_APP_DATA4_SIZE \ 133 | + BANK1_APP_DATA5_SIZE \ 134 | + BANK1_APP_DATA6_SIZE \ 135 | ) // 0K Bytes 136 | #define FTL_ADDR (OTA_BANK1_ADDR + OTA_BANK1_SIZE) 137 | #define FTL_SIZE 0x00004000 // 16K Bytes 138 | #define OTA_TMP_ADDR (FTL_ADDR + FTL_SIZE) 139 | #define OTA_TMP_SIZE (BANK0_APP_SIZE) // 100K Bytes 140 | #define BKP_DATA1_ADDR (OTA_TMP_ADDR + OTA_TMP_SIZE) 141 | #define BKP_DATA1_SIZE (FLASH_ADDR + FLASH_SIZE - BKP_DATA1_ADDR) // 240K Bytes 142 | #define BKP_DATA2_ADDR 0x00000000 143 | #define BKP_DATA2_SIZE 0x00000000 // 0K Bytes 144 | 145 | #ifdef __cplusplus 146 | } 147 | #endif 148 | /** @} */ /* _FLASH_MAP_H_ */ 149 | #endif 150 | --------------------------------------------------------------------------------