Skip to content

Sync with pebble main branch #144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 67 commits into
base: main
Choose a base branch
from
Open
Changes from 5 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
df810e0
Add SF32LB support.
gangheivt Mar 14, 2025
8ca4082
Merge branch 'main' of github.com:gangheivt/pebble-firmware
gangheivt Mar 15, 2025
39b4d25
Add SifliSDK
gangheivt Mar 15, 2025
4fd1a1b
Add missing repo
gangheivt Mar 16, 2025
3a864dc
Add missing repo
gangheivt Mar 16, 2025
ccf0205
Merge branch 'main' of github.com:gangheivt/pebble-firmware
gangheivt Mar 16, 2025
9c45699
Update siflisdk submodule URL
rabbitsaviola Mar 17, 2025
77fd82f
Merge remote-tracking branch 'pebble-dev/main'
HalfSweet Mar 24, 2025
79feff9
feat: add uart interface
HalfSweet Mar 26, 2025
ae16881
feat: impl flash
HalfSweet Mar 26, 2025
ca3851d
fix: add DBG uart define
HalfSweet Mar 26, 2025
d2df064
Merge pull request #2 from HalfSweet/main
rabbitsaviola Mar 31, 2025
c4912de
Update ld file and add some stubs
rabbitsaviola Mar 31, 2025
056e231
Add flag to make NMI_Handler overrided
rabbitsaviola Mar 31, 2025
bbad477
fix: startup
HalfSweet Apr 1, 2025
a2d3552
fix: sf32lb52 not use accessory
HalfSweet Apr 3, 2025
db65f56
Add Bluetooth init code for SF32LB
gangheivt Apr 7, 2025
6a5bddf
Merge branch 'main' into main
gangheivt Apr 7, 2025
cd7e83b
Merge branch 'main' of github.com:gangheivt/pebble-firmware
gangheivt Apr 7, 2025
8b5bb18
Fix compile issue after merging.
gangheivt Apr 7, 2025
479a240
fix: flash stub
HalfSweet Apr 7, 2025
2c0bc5b
Rename platform name to obelix
gangheivt Apr 7, 2025
2cea1eb
Add pebble Bluetooth HCI driver for Sf32lb。
gangheivt Apr 9, 2025
7e9f7f8
Update SiFli SDK submodule
gangheivt Apr 9, 2025
137eb19
Merge branch 'pebble-dev:main' into main
gangheivt Apr 9, 2025
c4cf17e
update: freertos
HalfSweet Apr 9, 2025
f450a9a
update: sifli-sdk
HalfSweet Apr 9, 2025
fa56dab
feat: flash driver
HalfSweet Apr 9, 2025
e26f7ce
fix: flash clock div
HalfSweet Apr 9, 2025
f83a5a9
fix: no log error
HalfSweet Apr 9, 2025
9c678af
fix: flash region
HalfSweet Apr 9, 2025
731aacf
feat: sf32lb int flash region
HalfSweet Apr 11, 2025
ff03dca
bluetooth-fw/nimble: add support for store gen key callback
gmarull Apr 9, 2025
aaaaf6d
fw/services/bluetooth: drop ble root key generation support
gmarull Apr 9, 2025
751404b
fw/services/bluetooth: format bluetooth_ctl.c
gmarull Apr 9, 2025
a71ea95
fw/drivers: de-hack asterix driver build
gmarull Apr 9, 2025
dfbda6f
fw/drivers/nrf5/qspi: delete dead code
gmarull Apr 10, 2025
ac1df70
fw/drivers: fix asterix flash driver
gmarull Apr 10, 2025
bcdbfc9
fw/drivers/flash/qspi: drop dead code
gmarull Apr 10, 2025
5ff1daa
fw/drivers/flash: allow specifying quad mode parameters
gmarull Apr 10, 2025
e813326
fw/drivers/flash/gd25lq255e: add quad mode parameters
gmarull Apr 10, 2025
a2de141
fw/drivers/flash: allow specifying all read/write op codes
gmarull Apr 10, 2025
6354c48
fw/drivers/flash/gd25lq255e: add additional read/write op codes
gmarull Apr 10, 2025
c3fe291
fw/drivers/flash: allow specifying read/write 'mode'
gmarull Apr 10, 2025
b976ce0
fw/drivers/nrf5/qspi: respect device read/write 'mode'
gmarull Apr 10, 2025
131dd34
fw/drivers/flash: use rdsr1/2 naming for status registers
gmarull Apr 10, 2025
d39b636
fw/drivers/flash: add support for wrsr op code
gmarull Apr 10, 2025
c274473
fw/drivers/flash/gd25lq255e: specify wrsr
gmarull Apr 10, 2025
fb46bf3
fw/drivers/flash: add support for wrsr2 op code
gmarull Apr 10, 2025
88b12ea
fw/drivers/nrf5/qspi: format file
gmarull Apr 10, 2025
48ec07a
fw/drivers/nrf5/qspi: add support for QE bit setting
gmarull Apr 10, 2025
b22bdad
boards/asterix: add missing QSPI pins
gmarull Apr 10, 2025
13c691f
fw/boards/asterix: use READ4IO/PP4O for QSPI flash
gmarull Apr 10, 2025
52d6b5f
fw/drivers/flash: format a few files
gmarull Apr 10, 2025
c256d03
boards/asterix: format file
gmarull Apr 10, 2025
fbb298b
third_party/hal_sifli: Fix build error caused by typo in wscript
rabbitsaviola Apr 16, 2025
4bd0f70
chore: DBG_UART use USART1
HalfSweet Apr 16, 2025
b04d450
Update display setting.
gangheivt Apr 17, 2025
a97cf83
Add LCPU image
gangheivt Apr 18, 2025
cb780e5
Disable bt hci for booting.
gangheivt Apr 19, 2025
1096130
add i2c and jdi driver
w200024212 Apr 23, 2025
c0f209a
feat: add rtc drivers
HalfSweet Apr 24, 2025
3b9ec1e
Fix HCI transport issue.
gangheivt Apr 25, 2025
35d76fa
Add Sifli download tool
gangheivt Apr 25, 2025
426eb6f
fix: RTC init
Apr 27, 2025
81d1fba
Fix LCPU init issue
gangheivt Apr 27, 2025
3a66611
add i2c_hal for pebble
w200024212 Apr 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/fw/board/board_sf32lb.h
Original file line number Diff line number Diff line change
@@ -36,6 +36,17 @@ typedef enum {
// This is generated in order to faciliate the check within the IRQ_MAP macro below
#include "bf0_hal.h"

// This is generated in order to faciliate the check within the IRQ_MAP macro below
enum {
#define IRQ_DEF(num, irq) IS_VALID_IRQ__##irq,
#if defined(MICRO_FAMILY_SF32LB)
# include "irq_sf32lb.def"
#else
# error need IRQ table for new micro family
#endif
#undef IRQ_DEF
};

//! Creates a trampoline to the interrupt handler defined within the driver
#define IRQ_MAP(irq, handler, device) \
void irq##_IRQHandler(void) { \
23 changes: 23 additions & 0 deletions src/fw/board/boards/board_em_lb525.c
Original file line number Diff line number Diff line change
@@ -15,4 +15,27 @@
*/

#include "board/board.h"
#include "drivers/sf32lb/uart_definitions.h"

static UARTDeviceState s_dbg_uart_state;
static UART_HandleTypeDef s_dbg_uart_handle = {.Instance = USART3,
.Init = {
.WordLength = UART_WORDLENGTH_8B,
.StopBits = UART_STOPBITS_1,
.Parity = UART_PARITY_NONE,
.HwFlowCtl = UART_HWCONTROL_NONE,
.OverSampling = UART_OVERSAMPLING_16,
}};
static DMA_HandleTypeDef s_dbg_uart_rx_dma_handle = {
.Instance = DMA1_Channel1,
};
static UARTDevice DBG_UART_DEVICE = {.state = &s_dbg_uart_state,
.tx_gpio = PAD_PA20,
.rx_gpio = PAD_PA27, // TODO: Setting GPIOs to actual values
.periph = &s_dbg_uart_handle,
.rx_dma = &s_dbg_uart_rx_dma_handle,
.irq_priority = 1};
UARTDevice *const DBG_UART = &DBG_UART_DEVICE;
IRQ_MAP(USART3, uart_irq_handler, DBG_UART);

void DMAC1_CH1_IRQHandler(void) { HAL_DMA_IRQHandler(&s_dbg_uart_rx_dma_handle); }
63 changes: 63 additions & 0 deletions src/fw/drivers/flash/sf32lb52_int_flash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include "board/board.h"
#include "drivers/flash/flash_impl.h"
#include "drivers/flash/qspi_flash.h"
#include "drivers/flash/qspi_flash_part_definitions.h"
#include "flash_region/flash_region.h"
#include "system/passert.h"
#include "system/status_codes.h"
#include "util/math.h"

bool flash_check_whoami(void) { return true; }

FlashAddress flash_impl_get_sector_base_address(FlashAddress addr) {
return (addr & SECTOR_ADDR_MASK);
}

FlashAddress flash_impl_get_subsector_base_address(FlashAddress addr) {
return (addr & SUBSECTOR_ADDR_MASK);
}

void flash_impl_enable_write_protection(void) {}

status_t flash_impl_write_protect(FlashAddress start_sector, FlashAddress end_sector) {
return S_SUCCESS;
}

status_t flash_impl_unprotect(void) { return S_SUCCESS; }

status_t flash_impl_init(bool coredump_mode) { return S_SUCCESS; }

status_t flash_impl_get_erase_status(void) { return S_SUCCESS; }

status_t flash_impl_erase_subsector_begin(FlashAddress subsector_addr) { return S_SUCCESS; }
status_t flash_impl_erase_sector_begin(FlashAddress sector_addr) { return S_SUCCESS; }

status_t flash_impl_erase_suspend(FlashAddress sector_addr) { return S_SUCCESS; }

status_t flash_impl_erase_resume(FlashAddress sector_addr) { return S_SUCCESS; }

status_t flash_impl_read_sync(void *buffer_ptr, FlashAddress start_addr, size_t buffer_size) {
PBL_ASSERT(buffer_size > 0, "flash_impl_read_sync() called with 0 bytes to read");
return S_SUCCESS;
}

int flash_impl_write_page_begin(const void *buffer, const FlashAddress start_addr, size_t len) {
return S_SUCCESS;
}

status_t flash_impl_get_write_status(void) { return S_SUCCESS; }

status_t flash_impl_enter_low_power_mode(void) { return S_SUCCESS; }
status_t flash_impl_exit_low_power_mode(void) { return S_SUCCESS; }

status_t flash_impl_set_burst_mode(bool burst_mode) {
// NYI
return S_SUCCESS;
}

status_t flash_impl_blank_check_sector(FlashAddress addr) { return S_SUCCESS; }
status_t flash_impl_blank_check_subsector(FlashAddress addr) { return S_SUCCESS; }

uint32_t flash_impl_get_typical_sector_erase_duration_ms(void) { return 150; }

uint32_t flash_impl_get_typical_subsector_erase_duration_ms(void) { return 50; }
347 changes: 347 additions & 0 deletions src/fw/drivers/sf32lb/uart.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,347 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "drivers/uart.h"

#include "FreeRTOS.h"
#include "bf0_hal.h"
#include "drivers/dma.h"
#include "drivers/gpio.h"
#include "drivers/periph_config.h"
#include "system/passert.h"
#include "uart_definitions.h"

typedef enum {
UART_FullDuplex = 0,
UART_TxOnly,
UART_RxOnly,
} UARTInitMode_t;

typedef struct {
pin_function tx_pin_fun;
pin_function rx_pin_fun;
} UARTPinFunction_t;

static IRQn_Type get_uart_irqn(UART_HandleTypeDef *uart) {
IRQn_Type irqn;
if (uart->Instance == USART1) {
irqn = USART1_IRQn;
} else if (uart->Instance == USART2) {
irqn = USART2_IRQn;
} else if (uart->Instance == USART3) {
irqn = USART3_IRQn;
}
#ifdef USART4
else if (uart->Instance == USART4) {
irqn = USART4_IRQn;
}
#endif
#ifdef USART5
else if (uart->Instance == USART5) {
irqn = USART5_IRQn;
}
#endif
#ifdef USART6
else if (uart->Instance == USART6) {
irqn = USART6_IRQn;
}
#endif
else {
WTF;
}
return irqn;
}

static IRQn_Type get_dma_channel_irqn(DMA_HandleTypeDef *dma) {
IRQn_Type irqn;
if (dma->Instance == DMA1_Channel1) {
irqn = DMAC1_CH1_IRQn;
} else if (dma->Instance == DMA1_Channel2) {
irqn = DMAC1_CH2_IRQn;
} else if (dma->Instance == DMA1_Channel3) {
irqn = DMAC1_CH3_IRQn;
} else if (dma->Instance == DMA1_Channel4) {
irqn = DMAC1_CH4_IRQn;
} else if (dma->Instance == DMA1_Channel5) {
irqn = DMAC1_CH5_IRQn;
} else if (dma->Instance == DMA1_Channel6) {
irqn = DMAC1_CH6_IRQn;
} else if (dma->Instance == DMA1_Channel7) {
irqn = DMAC1_CH7_IRQn;
} else if (dma->Instance == DMA2_Channel1) {
irqn = DMAC2_CH1_IRQn;
} else if (dma->Instance == DMA2_Channel2) {
irqn = DMAC2_CH2_IRQn;
} else if (dma->Instance == DMA2_Channel3) {
irqn = DMAC2_CH3_IRQn;
} else if (dma->Instance == DMA2_Channel4) {
irqn = DMAC2_CH4_IRQn;
} else if (dma->Instance == DMA2_Channel5) {
irqn = DMAC2_CH5_IRQn;
} else if (dma->Instance == DMA2_Channel6) {
irqn = DMAC2_CH6_IRQn;
} else if (dma->Instance == DMA2_Channel7) {
irqn = DMAC2_CH7_IRQn;
} else {
WTF;
}
return irqn;
}

static UARTPinFunction_t get_uart_pin_fun(UART_HandleTypeDef *uart) {
UARTPinFunction_t pin_fun = {0};
if (uart->Instance == USART1) {
pin_fun.tx_pin_fun = USART1_TXD;
pin_fun.rx_pin_fun = USART1_RXD;
} else if (uart->Instance == USART2) {
pin_fun.tx_pin_fun = USART2_TXD;
pin_fun.rx_pin_fun = USART2_RXD;
} else if (uart->Instance == USART3) {
pin_fun.tx_pin_fun = USART3_TXD;
pin_fun.rx_pin_fun = USART3_RXD;
}
#ifdef USART4
else if (uart->Instance == USART4) {
pin_fun.tx_pin_fun = USART4_TXD;
pin_fun.rx_pin_fun = USART4_RXD;
}
#endif
#ifdef USART5
else if (uart->Instance == USART5) {
pin_fun.tx_pin_fun = USART5_TXD;
pin_fun.rx_pin_fun = USART5_RXD;
}
#endif
#ifdef USART6
else if (uart->Instance == USART6) {
pin_fun.tx_pin_fun = USART6_TXD;
pin_fun.rx_pin_fun = USART6_RXD;
}
#endif
else {
WTF;
}
return pin_fun;
}

static void prv_init(UARTDevice *dev, UARTInitMode_t mode) {
if (HAL_UART_Init(dev->periph) != HAL_OK) {
// Initialization Error
WTF;
}

UARTPinFunction_t pin_fun = get_uart_pin_fun(dev->periph);
switch (mode) {
case UART_FullDuplex:
HAL_PIN_Set(dev->tx_gpio, pin_fun.tx_pin_fun, PIN_PULLUP, 1);
HAL_PIN_Set(dev->rx_gpio, pin_fun.rx_pin_fun, PIN_PULLUP, 1);
break;
case UART_TxOnly:
HAL_PIN_Set(dev->tx_gpio, pin_fun.tx_pin_fun, PIN_PULLUP, 1);
break;
case UART_RxOnly:
HAL_PIN_Set(dev->rx_gpio, pin_fun.rx_pin_fun, PIN_PULLUP, 1);
break;
default:
break;
}
dev->state->initialized = true;
if (dev->rx_dma) {
// initialize the DMA request
__HAL_LINKDMA(dev->periph, hdmarx, *dev->rx_dma);
IRQn_Type dma_irqn = get_dma_channel_irqn(dev->rx_dma);
HAL_NVIC_SetPriority(dma_irqn, 0, 0);
HAL_NVIC_EnableIRQ(dma_irqn);
__HAL_UART_ENABLE_IT(dev->periph, UART_IT_IDLE);
}
}

void uart_init(UARTDevice *dev) { prv_init(dev, UART_FullDuplex); }

void uart_init_open_drain(UARTDevice *dev) { WTF; }

void uart_init_tx_only(UARTDevice *dev) { prv_init(dev, UART_TxOnly); }

void uart_init_rx_only(UARTDevice *dev) { prv_init(dev, UART_RxOnly); }

void uart_deinit(UARTDevice *dev) { HAL_UART_DeInit(dev->periph); }

void uart_set_baud_rate(UARTDevice *dev, uint32_t baud_rate) {
PBL_ASSERTN(dev->state->initialized);
HAL_UART_DeInit(dev->periph);
dev->periph->Init.BaudRate = baud_rate;
if (HAL_UART_Init(dev->periph) != HAL_OK) {
// Initialization Error
WTF;
}
}

// Read / Write APIs
////////////////////////////////////////////////////////////////////////////////

void uart_write_byte(UARTDevice *dev, uint8_t data) {
HAL_UART_Transmit(dev->periph, &data, 1, 1000);
}

uint8_t uart_read_byte(UARTDevice *dev) {
uint8_t data;
HAL_UART_Receive(dev->periph, &data, 1, 1000);
return data;
}

bool uart_is_rx_ready(UARTDevice *dev) {
return READ_REG(dev->periph->Instance->ISR) & USART_ISR_RXNE;
}

bool uart_has_rx_overrun(UARTDevice *dev) {
return READ_REG(dev->periph->Instance->ISR) & USART_ISR_ORE;
}

bool uart_has_rx_framing_error(UARTDevice *dev) {
return READ_REG(dev->periph->Instance->ISR) & USART_ISR_FE;
}

bool uart_is_tx_ready(UARTDevice *dev) {
return READ_REG(dev->periph->Instance->ISR) & USART_ISR_TXE;
}

bool uart_is_tx_complete(UARTDevice *dev) {
return READ_REG(dev->periph->Instance->ISR) & USART_ISR_TC;
}

void uart_wait_for_tx_complete(UARTDevice *dev) {
while (!uart_is_tx_complete(dev)) continue;
}

// Interrupts
////////////////////////////////////////////////////////////////////////////////

static void prv_set_interrupt_enabled(UARTDevice *dev, bool enabled) {
if (enabled) {
PBL_ASSERTN(dev->state->tx_irq_handler || dev->state->rx_irq_handler);
// enable the interrupt
IRQn_Type uart_irqn = get_uart_irqn(dev->periph);
HAL_NVIC_SetPriority(uart_irqn, dev->irq_priority, 0);
HAL_NVIC_EnableIRQ(uart_irqn);
} else {
// disable the interrupt
HAL_NVIC_DisableIRQ(get_uart_irqn(dev->periph));
}
}

void uart_set_rx_interrupt_handler(UARTDevice *dev, UARTRXInterruptHandler irq_handler) {
PBL_ASSERTN(dev->state->initialized);
dev->state->rx_irq_handler = irq_handler;
}

void uart_set_tx_interrupt_handler(UARTDevice *dev, UARTTXInterruptHandler irq_handler) {
PBL_ASSERTN(dev->state->initialized);
dev->state->tx_irq_handler = irq_handler;
}

void uart_set_rx_interrupt_enabled(UARTDevice *dev, bool enabled) {
PBL_ASSERTN(dev->state->initialized);
if (enabled) {
dev->state->rx_int_enabled = true;
SET_BIT(dev->periph->Instance->CR1, USART_CR1_RXNEIE);
prv_set_interrupt_enabled(dev, true);
} else {
// disable interrupt if TX is also disabled
prv_set_interrupt_enabled(dev, dev->state->tx_int_enabled);
CLEAR_BIT(dev->periph->Instance->CR1, USART_CR1_RXNEIE);
dev->state->rx_int_enabled = false;
}
}

void uart_set_tx_interrupt_enabled(UARTDevice *dev, bool enabled) {
PBL_ASSERTN(dev->state->initialized);
if (enabled) {
dev->state->tx_int_enabled = true;
SET_BIT(dev->periph->Instance->CR1, USART_CR1_TXEIE);
prv_set_interrupt_enabled(dev, true);
} else {
// disable interrupt if RX is also disabled
prv_set_interrupt_enabled(dev, dev->state->rx_int_enabled);
CLEAR_BIT(dev->periph->Instance->CR1, USART_CR1_TXEIE);
dev->state->tx_int_enabled = false;
}
}

void uart_irq_handler(UARTDevice *dev) {
PBL_ASSERTN(dev->state->initialized);
bool should_context_switch = false;
if (dev->state->rx_irq_handler && dev->state->rx_int_enabled) {
const UARTRXErrorFlags err_flags = {
.overrun_error = uart_has_rx_overrun(dev),
.framing_error = uart_has_rx_framing_error(dev),
};
if (dev->state->rx_dma_buffer) {
// process bytes from the DMA buffer
const uint32_t dma_length = dev->state->rx_dma_length;
const uint32_t next_idx = dma_length - __HAL_DMA_GET_COUNTER(dev->rx_dma);
// make sure we didn't underflow the index
PBL_ASSERTN(next_idx < dma_length);
while (dev->state->rx_dma_index != next_idx) {
const uint8_t data = dev->state->rx_dma_buffer[dev->state->rx_dma_index];
if (dev->state->rx_irq_handler(dev, data, &err_flags)) {
should_context_switch = true;
}
if (++dev->state->rx_dma_index == dma_length) {
dev->state->rx_dma_index = 0;
}
}
// explicitly clear error flags since we're not reading from the data register
uart_clear_all_interrupt_flags(dev);

__HAL_UART_CLEAR_IDLEFLAG(dev->periph); // IDLEFLAG needs to be cleaned manually
} else {
const bool has_byte = uart_is_rx_ready(dev);
// read the data register regardless to clear the error flags
const uint8_t data = uart_read_byte(dev);
if (has_byte) {
if (dev->state->rx_irq_handler(dev, data, &err_flags)) {
should_context_switch = true;
}
}
}
}
if (dev->state->tx_irq_handler && dev->state->tx_int_enabled && uart_is_tx_ready(dev)) {
if (dev->state->tx_irq_handler(dev)) {
should_context_switch = true;
}
}
portEND_SWITCHING_ISR(should_context_switch);
}

void uart_clear_all_interrupt_flags(UARTDevice *dev) {
dev->periph->Instance->ISR &= ~(USART_ISR_TXE | USART_ISR_RXNE | USART_ISR_ORE);
}

// DMA
////////////////////////////////////////////////////////////////////////////////

void uart_start_rx_dma(UARTDevice *dev, void *buffer, uint32_t length) {
HAL_UART_DmaTransmit(dev->periph, buffer, length, DMA_PERIPH_TO_MEMORY);
}

void uart_stop_rx_dma(UARTDevice *dev) {
HAL_UART_DMAPause(dev->periph);
}

void uart_clear_rx_dma_buffer(UARTDevice *dev) {
dev->state->rx_dma_index =
dev->state->rx_dma_length - __HAL_DMA_GET_COUNTER(dev->rx_dma);
}
31 changes: 31 additions & 0 deletions src/fw/drivers/sf32lb/uart_definitions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <stdbool.h>
#include <stdint.h>

#include "board/board.h"
#include "drivers/uart.h"

typedef struct UARTState {
bool initialized;
UARTRXInterruptHandler rx_irq_handler;
UARTTXInterruptHandler tx_irq_handler;
bool rx_int_enabled;
bool tx_int_enabled;
uint8_t *rx_dma_buffer;
uint32_t rx_dma_length;
uint32_t rx_dma_index;
} UARTDeviceState;

typedef const struct UARTDevice {
UARTDeviceState *state;
bool half_duplex;
uint32_t tx_gpio;
uint32_t rx_gpio;
UART_HandleTypeDef *periph;
DMA_HandleTypeDef *rx_dma;
uint8_t irq_priority;
} UARTDevice;

// thinly wrapped by the IRQ handler in board_*.c
void uart_irq_handler(UARTDevice *dev);
4 changes: 2 additions & 2 deletions src/fw/drivers/wscript_build
Original file line number Diff line number Diff line change
@@ -1240,7 +1240,7 @@ if mcu_family == 'SF32LB':
'flash/cd_flash_driver.c',
'battery/battery_common.c',
'sf32lb/stubs/battery.c',
#'flash/xt25f64b.c',
'flash/sf32lb52_int_flash.c',
'task_watchdog.c',
'sf32lb/stubs/watchdog.c',
'sf32lb/stubs/display.c',
@@ -1262,7 +1262,7 @@ if mcu_family == 'SF32LB':
#'nrf5/button.c',
#'nrf5/debounced_button.c',
#'nrf5/exti.c',
#'nrf5/uart.c',
'sf32lb/uart.c',
#'nrf5/gpio.c',
#'nrf5/i2c_hal.c',
#'nrf5/spi.c',
99 changes: 99 additions & 0 deletions src/fw/irq_sf32lb.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
IRQ_DEF(0, AON) // Interrupt 0
IRQ_DEF(1, ble_isr) // Interrupt 1
IRQ_DEF(2, DMAC2_CH1) // Interrupt 2
IRQ_DEF(3, DMAC2_CH2) // Interrupt 3
IRQ_DEF(4, DMAC2_CH3) // Interrupt 4
IRQ_DEF(5, DMAC2_CH4) // Interrupt 5
IRQ_DEF(6, DMAC2_CH5) // Interrupt 6
IRQ_DEF(7, DMAC2_CH6) // Interrupt 7
IRQ_DEF(8, DMAC2_CH7) // Interrupt 8
IRQ_DEF(9, DMAC2_CH8) // Interrupt 9
IRQ_DEF(10, PATCH) // Interrupt 10
IRQ_DEF(11, dm_isr) // Interrupt 11
IRQ_DEF(12, USART4) // Interrupt 12
IRQ_DEF(13, USART5) // Interrupt 13
IRQ_DEF(14, SECU2) // Interrupt 14
IRQ_DEF(15, bt_isr) // Interrupt 15
IRQ_DEF(16, BTIM3) // Interrupt 16
IRQ_DEF(17, BTIM4) // Interrupt 17
IRQ_DEF(18, PTC2) // Interrupt 18
IRQ_DEF(19, LPTIM3) // Interrupt 19
IRQ_DEF(20, GPIO2) // Interrupt 20
IRQ_DEF(21, HPSYS0) // Interrupt 21
IRQ_DEF(22, HPSYS1) // Interrupt 22
IRQ_DEF(23, Interrupt23) // Interrupt 23
IRQ_DEF(24, Interrupt24) // Interrupt 24
IRQ_DEF(25, Interrupt25) // Interrupt 25
IRQ_DEF(26, Interrupt26) // Interrupt 26
IRQ_DEF(27, Interrupt27) // Interrupt 27
IRQ_DEF(28, Interrupt28) // Interrupt 28
IRQ_DEF(29, Interrupt29) // Interrupt 29
IRQ_DEF(30, Interrupt30) // Interrupt 30
IRQ_DEF(31, Interrupt31) // Interrupt 31
IRQ_DEF(32, Interrupt32) // Interrupt 32
IRQ_DEF(33, Interrupt33) // Interrupt 33
IRQ_DEF(34, Interrupt34) // Interrupt 34
IRQ_DEF(35, Interrupt35) // Interrupt 35
IRQ_DEF(36, Interrupt36) // Interrupt 36
IRQ_DEF(37, Interrupt37) // Interrupt 37
IRQ_DEF(38, Interrupt38) // Interrupt 38
IRQ_DEF(39, Interrupt39) // Interrupt 39
IRQ_DEF(40, Interrupt40) // Interrupt 40
IRQ_DEF(41, Interrupt41) // Interrupt 41
IRQ_DEF(42, Interrupt42) // Interrupt 42
IRQ_DEF(43, Interrupt43) // Interrupt 43
IRQ_DEF(44, Interrupt44) // Interrupt 44
IRQ_DEF(45, Interrupt45) // Interrupt 45
IRQ_DEF(46, LPTIM1) // Interrupt 46
IRQ_DEF(47, LPTIM2) // Interrupt 47
IRQ_DEF(48, PMUC) // Interrupt 48
IRQ_DEF(49, RTC) // Interrupt 49
IRQ_DEF(50, DMAC1_CH1) // Interrupt 50
IRQ_DEF(51, DMAC1_CH2) // Interrupt 51
IRQ_DEF(52, DMAC1_CH3) // Interrupt 52
IRQ_DEF(53, DMAC1_CH4) // Interrupt 53
IRQ_DEF(54, DMAC1_CH5) // Interrupt 54
IRQ_DEF(55, DMAC1_CH6) // Interrupt 55
IRQ_DEF(56, DMAC1_CH7) // Interrupt 56
IRQ_DEF(57, DMAC1_CH8) // Interrupt 57
IRQ_DEF(58, LCPU2HCPU) // Interrupt 58
IRQ_DEF(59, USART1) // Interrupt 59
IRQ_DEF(60, SPI1) // Interrupt 60
IRQ_DEF(61, I2C1) // Interrupt 61
IRQ_DEF(62, EPIC) // Interrupt 62
IRQ_DEF(63, LCDC1) // Interrupt 63
IRQ_DEF(64, I2S1) // Interrupt 64
IRQ_DEF(65, GPADC) // Interrupt 65
IRQ_DEF(66, EFUSEC) // Interrupt 66
IRQ_DEF(67, AES) // Interrupt 67
IRQ_DEF(68, PTC1) // Interrupt 68
IRQ_DEF(69, TRNG) // Interrupt 69
IRQ_DEF(70, GPTIM1) // Interrupt 70
IRQ_DEF(71, GPTIM2) // Interrupt 71
IRQ_DEF(72, BTIM1) // Interrupt 72
IRQ_DEF(73, BTIM2) // Interrupt 73
IRQ_DEF(74, USART2) // Interrupt 74
IRQ_DEF(75, SPI2) // Interrupt 75
IRQ_DEF(76, I2C2) // Interrupt 76
IRQ_DEF(77, EXTDMA) // Interrupt 77
IRQ_DEF(78, I2C4) // Interrupt 78
IRQ_DEF(79, SDMMC1) // Interrupt 79
IRQ_DEF(80, Interrupt80) // Interrupt 80
IRQ_DEF(81, Interrupt81) // Interrupt 81
IRQ_DEF(82, PDM1) // Interrupt 82
IRQ_DEF(83, Interrupt83) // Interrupt 83
IRQ_DEF(84, GPIO1) // Interrupt 84
IRQ_DEF(85, QSPI1) // Interrupt 85
IRQ_DEF(86, QSPI2) // Interrupt 86
IRQ_DEF(87, Interrupt87) // Interrupt 87
IRQ_DEF(88, Interrupt88) // Interrupt 88
IRQ_DEF(89, EZIP) // Interrupt 89
IRQ_DEF(90, AUDPRC) // Interrupt 90
IRQ_DEF(91, TSEN) // Interrupt 91
IRQ_DEF(92, USBC) // Interrupt 92
IRQ_DEF(93, I2C3) // Interrupt 93
IRQ_DEF(94, ATIM1) // Interrupt 94
IRQ_DEF(95, USART3) // Interrupt 95
IRQ_DEF(96, AUD_HP) // Interrupt 96
IRQ_DEF(97, Interrupt97) // Interrupt 97
IRQ_DEF(98, SECU1) // Interrupt 98
1 change: 1 addition & 0 deletions src/fw/vector_table.c
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@ ALIAS("Default_Handler") void SysTick_Handler(void);
#if defined(MICRO_FAMILY_NRF52840)
# include "irq_nrf52840.def"
#elif defined(MICRO_FAMILY_SF32LB)
# include "irq_sf32lb.def"
#else
# include "irq_stm32.def"
#endif
2 changes: 1 addition & 1 deletion third_party/freertos/FreeRTOS-Kernel
1 change: 1 addition & 0 deletions third_party/freertos/wscript
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ def build(bld):
freertos_port_name = 'ARM_CM4F'
elif bld.env.MICRO_FAMILY == 'SF32LB':
freertos_port_name = 'ARM_CM4F'
use_timers = True
else:
bld.fatal('Unrecognized env.MICRO_FAMILY value %r' %
bld.env.MICRO_FAMILY)