Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ jobs:
- make ${MAKEOPTS} -C ports/stm32 BOARD=STM32L476DISC
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_WB55
- make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBD_SF6
- make ${MAKEOPTS} -C ports/stm32/mboot BOARD=NUCLEO_WB55

# qemu-arm port
- stage: test
Expand Down
8 changes: 5 additions & 3 deletions ports/cc3200/mods/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

#include "py/runtime.h"
#include "py/mphal.h"
#include "irq.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
Expand Down Expand Up @@ -69,6 +68,9 @@ extern OsiTaskHandle xSimpleLinkSpawnTaskHndl;
/// \module machine - functions related to the SoC
///

MP_DECLARE_CONST_FUN_OBJ_0(machine_disable_irq_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(machine_enable_irq_obj);

/******************************************************************************/
// MicroPython bindings;

Expand Down Expand Up @@ -176,8 +178,8 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) },
{ MP_ROM_QSTR(MP_QSTR_wake_reason), MP_ROM_PTR(&machine_wake_reason_obj) },

{ MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&pyb_disable_irq_obj) },
{ MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&pyb_enable_irq_obj) },
{ MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) },
{ MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&machine_enable_irq_obj) },

{ MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&pyb_rtc_type) },
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pin_type) },
Expand Down
11 changes: 10 additions & 1 deletion ports/stm32/boards/NUCLEO_WB55/mpconfigboard.mk
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
MCU_SERIES = wb
CMSIS_MCU = STM32WB55xx
AF_FILE = boards/stm32wb55_af.csv
LD_FILES = boards/stm32wb55xg.ld boards/common_basic.ld
STARTUP_FILE = lib/stm32lib/CMSIS/STM32WBxx/Source/Templates/gcc/startup_stm32wb55xx_cm4.o

ifeq ($(USE_MBOOT),1)
# When using Mboot all the text goes together after the bootloader
LD_FILES = boards/stm32wb55xg.ld boards/common_bl.ld
TEXT0_ADDR = 0x08004000
else
# When not using Mboot the text goes at the start of flash
LD_FILES = boards/stm32wb55xg.ld boards/common_basic.ld
TEXT0_ADDR = 0x08000000
endif

# MicroPython settings
MICROPY_PY_BLUETOOTH = 1
MICROPY_BLUETOOTH_NIMBLE = 1
Expand Down
1 change: 1 addition & 0 deletions ports/stm32/boards/stm32wb55xg.ld
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* sectors 0-127 */
FLASH_APP (rx) : ORIGIN = 0x08004000, LENGTH = 496K /* sectors 4-127 */
FLASH_FS (r) : ORIGIN = 0x08080000, LENGTH = 256K /* sectors 128-191 */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K /* SRAM1 */
RAM2A (xrw) : ORIGIN = 0x20030020, LENGTH = 8K /* SRAM2A */
Expand Down
80 changes: 47 additions & 33 deletions ports/stm32/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "py/mpconfig.h"
#include "py/misc.h"
#include "py/mphal.h"
#include "flash.h"

typedef struct {
Expand Down Expand Up @@ -69,10 +70,15 @@ static const flash_layout_t flash_layout[] = {
{ 0x08020000, 0x20000, 3 },
};
#else
// This is for dual-bank mode disabled
static const flash_layout_t flash_layout[] = {
{ 0x08000000, 0x08000, 4 },
{ 0x08020000, 0x20000, 1 },
#if FLASH_SECTOR_TOTAL == 8
{ 0x08040000, 0x40000, 3 },
#else
{ 0x08040000, 0x40000, 7 },
#endif
};
#endif

Expand Down Expand Up @@ -138,6 +144,13 @@ static uint32_t get_page(uint32_t addr) {

#endif

bool flash_is_valid_addr(uint32_t addr) {
uint8_t last = MP_ARRAY_SIZE(flash_layout) - 1;
uint32_t end_of_flash = flash_layout[last].base_address +
flash_layout[last].sector_count * flash_layout[last].sector_size;
return flash_layout[0].base_address <= addr && addr < end_of_flash;
}

uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) {
if (addr >= flash_layout[0].base_address) {
uint32_t sector_index = 0;
Expand All @@ -162,17 +175,18 @@ uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *si
return 0;
}

void flash_erase(uint32_t flash_dest, uint32_t num_word32) {
int flash_erase(uint32_t flash_dest, uint32_t num_word32) {
// check there is something to write
if (num_word32 == 0) {
return;
return 0;
}

// unlock
// Unlock the flash for erase.
HAL_FLASH_Unlock();

FLASH_EraseInitTypeDef EraseInitStruct;
// Clear pending flags (if any) and set up EraseInitStruct.

FLASH_EraseInitTypeDef EraseInitStruct;
#if defined(STM32F0)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
Expand All @@ -190,40 +204,39 @@ void flash_erase(uint32_t flash_dest, uint32_t num_word32) {
EraseInitStruct.NbPages = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
#elif defined(STM32L4)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);

// erase the sector(s)
// The sector returned by flash_get_sector_info can not be used
// as the flash has on each bank 0/1 pages 0..255
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Banks = get_bank(flash_dest);
EraseInitStruct.Page = get_page(flash_dest);
EraseInitStruct.NbPages = get_page(flash_dest + 4 * num_word32 - 1) - EraseInitStruct.Page + 1;
;
#else
// Clear pending flags (if any)

#if defined(STM32H7)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK2);
#else
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
#endif

// erase the sector(s)
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
#if defined(STM32H7)
EraseInitStruct.Banks = get_bank(flash_dest);
#endif
EraseInitStruct.Sector = flash_get_sector_info(flash_dest, NULL, NULL);
EraseInitStruct.NbSectors = flash_get_sector_info(flash_dest + 4 * num_word32 - 1, NULL, NULL) - EraseInitStruct.Sector + 1;

#endif

// Erase the sectors.
uint32_t SectorError = 0;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
// error occurred during sector erase
HAL_FLASH_Lock(); // lock the flash
return;
}
HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);

// Lock the flash after erase.
HAL_FLASH_Lock();

return mp_hal_status_to_neg_errno(status);
}

/*
Expand Down Expand Up @@ -255,38 +268,38 @@ void flash_erase_it(uint32_t flash_dest, uint32_t num_word32) {
}
*/

void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
// Unlock the flash for write.
HAL_FLASH_Unlock();

HAL_StatusTypeDef status = HAL_OK;

#if defined(STM32L4) || defined(STM32WB)

// program the flash uint64 by uint64
for (int i = 0; i < num_word32 / 2; i++) {
uint64_t val = *(uint64_t *)src;
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_dest, val) != HAL_OK) {
// error occurred during flash write
HAL_FLASH_Lock(); // lock the flash
return;
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_dest, val);
if (status != HAL_OK) {
num_word32 = 0; // don't write any odd word after this loop
break;
}
flash_dest += 8;
src += 2;
}
if ((num_word32 & 0x01) == 1) {
uint64_t val = *(uint64_t *)flash_dest;
val = (val & 0xffffffff00000000uL) | (*src);
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_dest, val) != HAL_OK) {
// error occurred during flash write
HAL_FLASH_Lock(); // lock the flash
return;
}
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_dest, val);
}

#elif defined(STM32H7)

// program the flash 256 bits at a time
for (int i = 0; i < num_word32 / 8; i++) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, flash_dest, (uint64_t)(uint32_t)src) != HAL_OK) {
// error occurred during flash write
HAL_FLASH_Lock(); // lock the flash
return;
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, flash_dest, (uint64_t)(uint32_t)src);
if (status != HAL_OK) {
break;
}
flash_dest += 32;
src += 8;
Expand All @@ -296,19 +309,20 @@ void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32)

// program the flash word by word
for (int i = 0; i < num_word32; i++) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, flash_dest, *src) != HAL_OK) {
// error occurred during flash write
HAL_FLASH_Lock(); // lock the flash
return;
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, flash_dest, *src);
if (status != HAL_OK) {
break;
}
flash_dest += 4;
src += 1;
}

#endif

// lock the flash
// Lock the flash after write.
HAL_FLASH_Lock();

return mp_hal_status_to_neg_errno(status);
}

/*
Expand Down
5 changes: 3 additions & 2 deletions ports/stm32/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
#ifndef MICROPY_INCLUDED_STM32_FLASH_H
#define MICROPY_INCLUDED_STM32_FLASH_H

bool flash_is_valid_addr(uint32_t addr);
uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size);
void flash_erase(uint32_t flash_dest, uint32_t num_word32);
void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32);
int flash_erase(uint32_t flash_dest, uint32_t num_word32);
int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32);

#endif // MICROPY_INCLUDED_STM32_FLASH_H
2 changes: 1 addition & 1 deletion ports/stm32/i2cslave.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void i2c_slave_ev_irq_handler(i2c_slave_t *i2c) {
}
}

#elif defined(STM32F7) || defined(STM32H7)
#elif defined(STM32F7) || defined(STM32H7) || defined(STM32WB)

void i2c_slave_init_helper(i2c_slave_t *i2c, int addr) {
i2c->CR1 = I2C_CR1_STOPIE | I2C_CR1_ADDRIE | I2C_CR1_RXIE | I2C_CR1_TXIE;
Expand Down
9 changes: 9 additions & 0 deletions ports/stm32/i2cslave.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@

#include STM32_HAL_H

#if !defined(I2C2_BASE)
// This MCU doesn't have I2C2_BASE, define it so that the i2c_idx calculation works.
#define I2C2_BASE (I2C1_BASE + ((I2C3_BASE - I2C1_BASE) / 2))
#endif

typedef I2C_TypeDef i2c_slave_t;

void i2c_slave_init_helper(i2c_slave_t *i2c, int addr);
Expand All @@ -42,6 +47,10 @@ static inline void i2c_slave_init(i2c_slave_t *i2c, int irqn, int irq_pri, int a
RCC->APB1LENR |= 1 << (RCC_APB1LENR_I2C1EN_Pos + i2c_idx);
volatile uint32_t tmp = RCC->APB1LENR; // Delay after enabling clock
(void)tmp;
#elif defined(STM32WB)
RCC->APB1ENR1 |= 1 << (RCC_APB1ENR1_I2C1EN_Pos + i2c_idx);
volatile uint32_t tmp = RCC->APB1ENR1; // Delay after enabling clock
(void)tmp;
#endif

i2c_slave_init_helper(i2c, addr);
Expand Down
38 changes: 11 additions & 27 deletions ports/stm32/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,28 @@
#include "py/obj.h"
#include "py/mphal.h"
#include "irq.h"

/// \moduleref pyb
#include "modmachine.h"

#if IRQ_ENABLE_STATS
uint32_t irq_stats[IRQ_STATS_MAX] = {0};
#endif

/// \function wfi()
/// Wait for an interrupt.
/// This executies a `wfi` instruction which reduces power consumption
/// of the MCU until an interrupt occurs, at which point execution continues.
STATIC mp_obj_t pyb_wfi(void) {
__WFI();
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(pyb_wfi_obj, pyb_wfi);

/// \function disable_irq()
/// Disable interrupt requests.
/// Returns the previous IRQ state: `False`/`True` for disabled/enabled IRQs
/// respectively. This return value can be passed to enable_irq to restore
/// the IRQ to its original state.
STATIC mp_obj_t pyb_disable_irq(void) {
// disable_irq()
// Disable interrupt requests.
// Returns the previous IRQ state which can be passed to enable_irq.
STATIC mp_obj_t machine_disable_irq(void) {
return mp_obj_new_bool(disable_irq() == IRQ_STATE_ENABLED);
}
MP_DEFINE_CONST_FUN_OBJ_0(pyb_disable_irq_obj, pyb_disable_irq);
MP_DEFINE_CONST_FUN_OBJ_0(machine_disable_irq_obj, machine_disable_irq);

/// \function enable_irq(state=True)
/// Enable interrupt requests.
/// If `state` is `True` (the default value) then IRQs are enabled.
/// If `state` is `False` then IRQs are disabled. The most common use of
/// this function is to pass it the value returned by `disable_irq` to
/// exit a critical section.
STATIC mp_obj_t pyb_enable_irq(uint n_args, const mp_obj_t *arg) {
// enable_irq(state=True)
// Enable interrupt requests, based on the argument, which is usually the
// value returned by a previous call to disable_irq.
STATIC mp_obj_t machine_enable_irq(uint n_args, const mp_obj_t *arg) {
enable_irq((n_args == 0 || mp_obj_is_true(arg[0])) ? IRQ_STATE_ENABLED : IRQ_STATE_DISABLED);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_enable_irq_obj, 0, 1, pyb_enable_irq);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_enable_irq_obj, 0, 1, machine_enable_irq);

#if IRQ_ENABLE_STATS
// return a memoryview of the irq statistics array
Expand Down
7 changes: 1 addition & 6 deletions ports/stm32/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ extern uint32_t irq_stats[IRQ_STATS_MAX];
#define IRQ_EXIT(irq)
#endif

static inline mp_uint_t query_irq(void) {
static inline uint32_t query_irq(void) {
return __get_PRIMASK();
}

Expand Down Expand Up @@ -92,11 +92,6 @@ static inline void restore_irq_pri(uint32_t state) {

#endif

MP_DECLARE_CONST_FUN_OBJ_0(pyb_wfi_obj);
MP_DECLARE_CONST_FUN_OBJ_0(pyb_disable_irq_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_enable_irq_obj);
MP_DECLARE_CONST_FUN_OBJ_0(pyb_irq_stats_obj);

// IRQ priority definitions.
//
// Lower number implies higher interrupt priority.
Expand Down
Loading