@ -94,6 +94,161 @@ void MP_WEAK __assert_func(const char *file, int line, const char *func, const c
}
# endif
# if !MICROPY_MIN_USE_STDOUT
void _start ( void ) { main ( 0 , NULL ) ; }
# if MICROPY_MIN_USE_CORTEX_CPU
// this is a minimal IRQ and reset framework for any Cortex-M CPU
extern uint32_t _estack , _sidata , _sdata , _edata , _sbss , _ebss ;
void Reset_Handler ( void ) __attribute__ ( ( naked ) ) ;
void Reset_Handler ( void ) {
// set stack pointer
asm volatile ( " ldr sp, =_estack " ) ;
// copy .data section from flash to RAM
for ( uint32_t * src = & _sidata , * dest = & _sdata ; dest < & _edata ; ) {
* dest + + = * src + + ;
}
// zero out .bss section
for ( uint32_t * dest = & _sbss ; dest < & _ebss ; ) {
* dest + + = 0 ;
}
// jump to board initialisation
void _start ( void ) ;
_start ( ) ;
}
void Default_Handler ( void ) {
for ( ; ; ) {
}
}
uint32_t isr_vector [ ] __attribute__ ( ( section ( " .isr_vector " ) ) ) = {
( uint32_t ) & _estack ,
( uint32_t ) & Reset_Handler ,
( uint32_t ) & Default_Handler , // NMI_Handler
( uint32_t ) & Default_Handler , // HardFault_Handler
( uint32_t ) & Default_Handler , // MemManage_Handler
( uint32_t ) & Default_Handler , // BusFault_Handler
( uint32_t ) & Default_Handler , // UsageFault_Handler
0 ,
0 ,
0 ,
0 ,
( uint32_t ) & Default_Handler , // SVC_Handler
( uint32_t ) & Default_Handler , // DebugMon_Handler
0 ,
( uint32_t ) & Default_Handler , // PendSV_Handler
( uint32_t ) & Default_Handler , // SysTick_Handler
} ;
void _start ( void ) {
// when we get here: stack is initialised, bss is clear, data is copied
// SCB->CCR: enable 8-byte stack alignment for IRQ handlers, in accord with EABI
* ( ( volatile uint32_t * ) 0xe000ed14 ) | = 1 < < 9 ;
// initialise the cpu and peripherals
# if MICROPY_MIN_USE_STM32_MCU
void stm32_init ( void ) ;
stm32_init ( ) ;
# endif
// now that we have a basic system up and running we can call main
main ( 0 , NULL ) ;
// we must not return
for ( ; ; ) {
}
}
# endif
# if MICROPY_MIN_USE_STM32_MCU
// this is minimal set-up code for an STM32 MCU
typedef struct {
volatile uint32_t CR ;
volatile uint32_t PLLCFGR ;
volatile uint32_t CFGR ;
volatile uint32_t CIR ;
uint32_t _1 [ 8 ] ;
volatile uint32_t AHB1ENR ;
volatile uint32_t AHB2ENR ;
volatile uint32_t AHB3ENR ;
uint32_t _2 ;
volatile uint32_t APB1ENR ;
volatile uint32_t APB2ENR ;
} periph_rcc_t ;
typedef struct {
volatile uint32_t MODER ;
volatile uint32_t OTYPER ;
volatile uint32_t OSPEEDR ;
volatile uint32_t PUPDR ;
volatile uint32_t IDR ;
volatile uint32_t ODR ;
volatile uint16_t BSRRL ;
volatile uint16_t BSRRH ;
volatile uint32_t LCKR ;
volatile uint32_t AFR [ 2 ] ;
} periph_gpio_t ;
typedef struct {
volatile uint32_t SR ;
volatile uint32_t DR ;
volatile uint32_t BRR ;
volatile uint32_t CR1 ;
} periph_uart_t ;
# define USART1 ((periph_uart_t*) 0x40011000)
# define GPIOA ((periph_gpio_t*) 0x40020000)
# define GPIOB ((periph_gpio_t*) 0x40020400)
# define RCC ((periph_rcc_t*) 0x40023800)
// simple GPIO interface
# define GPIO_MODE_IN (0)
# define GPIO_MODE_OUT (1)
# define GPIO_MODE_ALT (2)
# define GPIO_PULL_NONE (0)
# define GPIO_PULL_UP (0)
# define GPIO_PULL_DOWN (1)
void gpio_init ( periph_gpio_t * gpio , int pin , int mode , int pull , int alt ) {
gpio - > MODER = ( gpio - > MODER & ~ ( 3 < < ( 2 * pin ) ) ) | ( mode < < ( 2 * pin ) ) ;
// OTYPER is left as default push-pull
// OSPEEDR is left as default low speed
gpio - > PUPDR = ( gpio - > PUPDR & ~ ( 3 < < ( 2 * pin ) ) ) | ( pull < < ( 2 * pin ) ) ;
gpio - > AFR [ pin > > 3 ] = ( gpio - > AFR [ pin > > 3 ] & ~ ( 15 < < ( 4 * ( pin & 7 ) ) ) ) | ( alt < < ( 4 * ( pin & 7 ) ) ) ;
}
# define gpio_get(gpio, pin) ((gpio->IDR >> (pin)) & 1)
# define gpio_set(gpio, pin, value) do { gpio->ODR = (gpio->ODR & ~(1 << (pin))) | (value << pin); } while (0)
# define gpio_low(gpio, pin) do { gpio->BSRRH = (1 << (pin)); } while (0)
# define gpio_high(gpio, pin) do { gpio->BSRRL = (1 << (pin)); } while (0)
void stm32_init ( void ) {
// basic MCU config
RCC - > CR | = ( uint32_t ) 0x00000001 ; // set HSION
RCC - > CFGR = 0x00000000 ; // reset all
RCC - > CR & = ( uint32_t ) 0xfef6ffff ; // reset HSEON, CSSON, PLLON
RCC - > PLLCFGR = 0x24003010 ; // reset PLLCFGR
RCC - > CR & = ( uint32_t ) 0xfffbffff ; // reset HSEBYP
RCC - > CIR = 0x00000000 ; // disable IRQs
// leave the clock as-is (internal 16MHz)
// enable GPIO clocks
RCC - > AHB1ENR | = 0x00000003 ; // GPIOAEN, GPIOBEN
// turn on an LED! (on pyboard it's the red one)
gpio_init ( GPIOA , 13 , GPIO_MODE_OUT , GPIO_PULL_NONE , 0 ) ;
gpio_high ( GPIOA , 13 ) ;
// enable UART1 at 9600 baud (TX=B6, RX=B7)
gpio_init ( GPIOB , 6 , GPIO_MODE_ALT , GPIO_PULL_NONE , 7 ) ;
gpio_init ( GPIOB , 7 , GPIO_MODE_ALT , GPIO_PULL_NONE , 7 ) ;
RCC - > APB2ENR | = 0x00000010 ; // USART1EN
USART1 - > BRR = ( 104 < < 4 ) | 3 ; // 16MHz/(16*104.1875) = 9598 baud
USART1 - > CR1 = 0x0000200c ; // USART enable, tx enable, rx enable
}
# endif