.syntax unified .cpu cortex-m4 .thumb .set LSE_fitted,0 @ GPIO register map is similiar to STM32F4 chips. @ -> register boundary address pp. 65 in DM00031020.pdf .equ BIT0, 0x00000001 .equ BIT1, 0x00000002 .equ BIT2, 0x00000004 .equ BIT3, 0x00000008 .equ BIT4, 0x00000010 .equ BIT5, 0x00000020 .equ BIT6, 0x00000040 .equ BIT7, 0x00000080 .equ BIT8, 0x00000100 .equ BIT9, 0x00000200 .equ BIT10, 0x00000400 .equ BIT11, 0x00000800 .equ BIT12, 0x00001000 .equ BIT13, 0x00002000 .equ BIT14, 0x00004000 .equ BIT15, 0x00008000 .equ BIT16, 0x00010000 .equ BIT17, 0x00020000 .equ BIT18, 0x00040000 .equ BIT19, 0x00080000 .equ BIT20, 0x00100000 .equ BIT21, 0x00200000 .equ BIT22, 0x00400000 .equ BIT23, 0x00800000 .equ BIT24, 0x01000000 .equ BIT25, 0x02000000 .equ BIT26, 0x04000000 .equ BIT27, 0x08000000 .equ BIT28, 0x10000000 .equ BIT29, 0x20000000 .equ BIT30, 0x40000000 .equ BIT31, 0x80000000 @------------------------------------------------------------------------------- @ Clocks @------------------------------------------------------------------------------- .set HSECLK, 8000000 @ HSE crystal oscillator frequency .set SYSCLK, 168000000 @ main PLL output frequency .set RCLK, 48000000 @ RNG/USB clock frequency @ MISC .set VOS, 1 @ select voltage scale 1 @------------------------------------------------------------------------------- @ Power @------------------------------------------------------------------------------- .set PWR, 0x40007000 @ base address @ register offsets .set PWR_CR, 0x00 @ PWR control register .set PWR_CSR, 0x04 @ PWR control/status register @------------------------------------------------------------------------------- @ Clock configuration for AHB, APB1 and APB2 peripherals @------------------------------------------------------------------------------- .set HPRE, 0 @ AHB clock prescaler = 1 .set HCLK, SYSCLK @ AHB clock .set PPRE1, 5 @ APB low-speed clock prescaler = 4 .set PCLK1, HCLK / 4 @ APB low-speed clock .set PPRE2, 4 @ APB high-speed clock prescaler = 2 .set PCLK2, HCLK / 2 @ APB high-speed clock .set SW, 2 @ clock source (0 = HSI, 1 = HSE, 2 = PLL) .set LSE_fitted, 0 @ set to 1 if 32-KHz crystal fitted .if LSE_fitted .set LSEON, 1 @ enable LSE oscillator .set RTCSEL, 1 @ select LSE as RTC clock source .set RTCPRE, 0 @ RTC clock prescaler off .else .set LSEON, 0 @ disable LSE oscillator .set RTCSEL, 3 @ select HSE as RTC clock source .set RTCPRE, HSECLK / 1000000 @ RTC clock must be 1 MHz .endif .set RTCEN, 1 @ enable RTC clock @------------------------------------------------------------------------------- @ PLL configuration @ @ The critical PLL parameters are checked for validity. @------------------------------------------------------------------------------- @ PLL input divider PLLM (allowed range: 2 - 63) @ PLLM must be chosen so that the PLL input frequency falls in the allowed @ range 1 - 2 MHz .set PLLM, 8 .if PLLM < 2 || PLLM > 63 .error "PLLM out of range" .endif @ PLL input frequency (allowed range: 1 - 2 MHz) .set f_PLLin, HSECLK / PLLM .if f_PLLin < 1000000 || f_PLLin > 2000000 .error "f_PLLin out of range" .endif @ PLL output divider DIVP (allowed values: 2, 4, 6, or 8) @ DIVP must be chosen so that f_VCO falls in the range 192 - 432 MHz .set DIVP, 2 .if DIVP != 2 && DIVP != 4 && DIVP != 6 && DIVP != 8 .error "DIVP out of range" .endif @ VCO frequency (allowed range: 192 - 432 MHz) .set f_VCO, SYSCLK * DIVP .if f_VCO < 192000000 || f_VCO > 432000000 .error "f_VCO out of range" .endif @ PLL multiplier PLLN (allowed range: 192 - 432) .set PLLN, f_VCO / f_PLLin .if PLLN < 192 || PLLN > 432 .error "PLLN out of range" .endif @ PLL divider PLLQ for RNG clock (allowed range: 2 - 15) .set PLLQ, f_VCO / RCLK .if PLLQ < 2 || PLLQ > 15 .error "PLLQ out of range" .endif .set PLLP, (DIVP - 2) / 2 @ PLLP is a 2-bit encoding for DIVP .set PLLSRC, 1 @ PLL clock dource (0 = HSI, 1 = HSE) @ PLL configuration word to be loaded into RCC_PLLCFGR register .set PLLCONF, PLLQ << 24 | PLLSRC << 22 | PLLP << 16 | PLLN << 6 | PLLM .set RCC, 0x40023800 @ base address @ register offsets .set RCC_CR, 0x00 @ RCC clock control register .set RCC_PLLCFGR, 0x04 @ RCC PLL configuration register .set RCC_CFGR, 0x08 @ RCC clock configuration register .set RCC_CIR, 0x0C @ RCC clock interrupt register .set RCC_AHB1RSTR, 0x10 @ AHB1 peripheral reset register .set RCC_AHB2RSTR, 0x14 @ AHB2 peripheral reset register .set RCC_AHB3RSTR, 0x18 @ AHB3 peripheral reset register .set RCC_APB1RSTR, 0x20 @ APB1 peripheral reset register .set RCC_APB2RSTR, 0x24 @ APB2 peripheral reset register .set RCC_AHB1ENR, 0x30 @ AHB1 peripheral clock enable register .set RCC_AHB2ENR, 0x34 @ AHB2 peripheral clock enable register .set RCC_AHB3ENR, 0x38 @ AHB2 peripheral clock enable register .set RCC_APB1ENR, 0x40 @ APB1 peripheral clock enable register .set RCC_APB2ENR, 0x44 @ APB2 peripheral clock enable register .set RCC_AHB1LPENR, 0x50 @ AHB1 peripheral LP mode clock enable register .set RCC_AHB2LPENR, 0x54 @ AHB2 peripheral LP mode clock enable register .set RCC_AHB3LPENR, 0x58 @ AHB3 peripheral LP mode clock enable register .set RCC_APB1LPENR, 0x60 @ APB1 peripheral LP mode clock enable register .set RCC_APB2LPENR, 0x64 @ APB2 peripheral LP mode clock enable register .set RCC_BDCR, 0x70 @ RCC backup domain control register .set RCC_CSR, 0x74 @ RCC clock control & status register .set RCC_SSCGR, 0x80 @ RCC spread spectrum clock generation register .set RCC_PLLI2SCFGR, 0x84 @ RCC I2S PLL configuration register @ USART3 on STM32F4 chips: @ USART3 on STM32F1/STM32F4 chips: pp. 1018 in RM0090 (dm00031020-stm*.pdf) .equ USART3_BASE , 0x40004800 .equ USART3_SR , USART3_BASE + 0x00 .equ USART3_DR , USART3_BASE + 0x04 .equ USART3_BRR , USART3_BASE + 0x08 .equ USART3_CR1 , USART3_BASE + 0x0C .equ USART3_CR2 , USART3_BASE + 0x10 .equ USART3_CR3 , USART3_BASE + 0x14 .equ USART3_GPTR , USART3_BASE + 0x18 @ Flags for USART3_ISR register: .equ RXNE , BIT5 .equ TC , BIT6 .equ TXE , BIT7 @ GPIO register map is similiar to STM32F4 chips. @ -> register boundary address pp. 65 in DM00031020.pdf .equ GPIOE_BASE , 0x40021000 .equ GPIOE_MODER , GPIOE_BASE + 0x00 @ pp. 287 of DM00031020.pdf .equ GPIOE_OTYPER , GPIOE_BASE + 0x04 .equ GPIOE_ODR , GPIOE_BASE + 0x14 .equ GPIOB_BASE, 0x40020400 .equ GPIOB_MODER , GPIOB_BASE + 0x00 @<<<<< .equ GPIOB_AFRL , GPIOB_BASE + 0x20 @<<<<< .equ GPIOB_AFRH , GPIOB_BASE + 0x24 .equ GPIOA_BASE , 0x40020000 .equ GPIOA_MODER , GPIOA_BASE + 0x00 .equ GPIOA_OTYPER , GPIOA_BASE + 0x04 .equ GPIOA_OSPEEDR , GPIOA_BASE + 0x08 .equ GPIOA_PUPDR , GPIOA_BASE + 0x0C .equ GPIOA_IDR , GPIOA_BASE + 0x10 .equ GPIOA_ODR , GPIOA_BASE + 0x14 .equ GPIOA_BSRR , GPIOA_BASE + 0x18 .equ GPIOA_LCKR , GPIOA_BASE + 0x1C .equ GPIOA_AFRL , GPIOA_BASE + 0x20 .equ GPIOA_AFRH , GPIOA_BASE + 0x24 .equ HSERDY , BIT17 .equ HSEON , BIT16 @ USART1 on STM32F4 chips: pp. 1018 in RM0090 (dm00031020-stm*.pdf) (RM0090) .equ USART1_BASE , 0x40011000 .equ USART1_SR , USART1_BASE + 0x00 .equ USART1_DR , USART1_BASE + 0x04 .equ USART1_BRR , USART1_BASE + 0x08 .equ USART1_CR1 , USART1_BASE + 0x0C .equ USART1_CR2 , USART1_BASE + 0x10 .equ USART1_CR3 , USART1_BASE + 0x14 .equ USART1_GPTR , USART1_BASE + 0x18 .equ USART_CR1_UE,BIT13 .equ USART_CR1_TE,BIT3 .equ USART_CR1_RE,BIT2 .ltorg .pool @ GPIO register map is similiar to STM32F4 chips. @ -> register boundary address pp. 65 in DM00031020.pdf .equ GPIOE_BASE , 0x40021000 .equ GPIOE_MODER , GPIOE_BASE + 0x00 @ pp. 287 of DM00031020.pdf .equ GPIOE_OTYPER , GPIOE_BASE + 0x04 .equ GPIOE_ODR , GPIOE_BASE + 0x14 .equ GPIOB_BASE, 0x40020400 .equ GPIOB_MODER , GPIOB_BASE + 0x00 @<<<<< .equ GPIOB_AFRL , GPIOB_BASE + 0x20 @<<<<< .equ GPIOB_AFRH , GPIOB_BASE + 0x24 .equ GPIOA_BASE , 0x40020000 .equ GPIOA_MODER , GPIOA_BASE + 0x00 .equ GPIOA_OTYPER , GPIOA_BASE + 0x04 .equ GPIOA_OSPEEDR , GPIOA_BASE + 0x08 .equ GPIOA_PUPDR , GPIOA_BASE + 0x0C .equ GPIOA_IDR , GPIOA_BASE + 0x10 .equ GPIOA_ODR , GPIOA_BASE + 0x14 .equ GPIOA_BSRR , GPIOA_BASE + 0x18 .equ GPIOA_LCKR , GPIOA_BASE + 0x1C .equ GPIOA_AFRL , GPIOA_BASE + 0x20 .equ GPIOA_AFRH , GPIOA_BASE + 0x24 .equ HSERDY , BIT17 .equ HSEON , BIT16 .equ RamAnfang, 0x20000000 @ Start of RAM Porting: Change this ! .equ returnstackanfang,RamAnfang+0x400 .text .org 0 @ Common vector table for all Cortex M3/M4 targets .word returnstackanfang @ 00: Stack top address .word Reset+1 @ 01: Reset Vector +1 wegen des Thumb-Einsprunges .word faulthandler+1 @ 02: The NMI handler .word faulthandler+1 @ 03: The hard fault handler .word faulthandler+1 @ 04: The MPU fault handler .word faulthandler+1 @ 05: The bus fault handler .word faulthandler+1 @ 06: The usage fault handler .word 0 @ 07: Reserved .word 0 @ 08: Reserved .word 0 @ 09: Reserved .word 0 @ 10: Reserved .word nullhandler+1 @ 11: SVCall handler .word nullhandler+1 @ 12: Debug monitor handler .word 0 @ 13: Reserved .word nullhandler+1 @ 14: The PendSV handler .word irq_vektor_systick+1 @ 15: The SysTick handler @ Bis hierhin ist die Interruptvektortabelle bei allen ARM Cortex Chips gleich. @ Danach geht es mit den Besonderheiten eines jeden Chips los. .org 0x0400 .global Setup_UART,Setup_Clocks,Reset Reset: bl uart_init 1: movs r0,r0 b 1b @ ----------------------------------------------------------------------------- uart_init: @ ----------------------------------------------------------------------------- push {lr} bl Setup_Clocks bl Setup_UART pop {lr} bx lr nullhandler: faulthandler: irq_vektor_systick: 1: nop b 1b .ltorg @ store constants here @ @ ----------------------------------------------------------------------------- Setup_Clocks: @ ----------------------------------------------------------------------------- @ APB1 configuration word to be loaded into RCC_APB1ENR register .set APB1CONF, PWREN << 28 @ Power configuration word to be loaded into PWR_CR register .set PWRCONF, VOS << 14 | DBP << 8 @ clock configuration word to be loaded into RCC_CFGR register .set CLKCONF, PPRE2 << 13 | PPRE1 << 10 | HPRE << 4 | SW @ clock configuration word to be loaded into RCC_BDCR register .set RTCCONF, RTCEN << 15 | RTCSEL << 8 | LSEON @------------------------------------------------------------------------------- @ RAMs and peripherals enable @------------------------------------------------------------------------------- .set CCMRAMEN, 1 @ enable CCM data RAM .set BKPRAMEN, 1 @ enable backup RAM .set PWREN, 1 @ enable power interface .set DBP, 1 @ enable write to backup RAM .set VOS, 1 @ select voltage scale 1 @ AHB1 configuration word to be loaded into RCC_AHB1ENR register .set AHB1CONF, CCMRAMEN << 20 | BKPRAMEN << 18 @ APB1 configuration word to be loaded into RCC_APB1ENR register .set APB1CONF, PWREN << 28 @ Power configuration word to be loaded into PWR_CR register .set PWRCONF, VOS << 14 | DBP << 8 @=============================================================================== @ System initialization @ @ The following steps are performed: @ - enable HSE clock @ - enable LSI clock for IWDG watchdog @ - configure PLL for 168 MHz @ - configure AHB and APB prescalers @ - configure Flash access control @ - select PLL as sytem clock source @ - configure and enable system tick interrupt @ @=============================================================================== @----------------------------------------------------------------------- @ enable HSE oscillator @----------------------------------------------------------------------- ldr r6, = RCC @ RCC base address ldr r0, [r6, #RCC_CR] orr r0, r0, #0x10000 @ set HSEON str r0, [r6, #RCC_CR] @----------------------------------------------------------------------- @ wait until HSE oscillator ready @----------------------------------------------------------------------- 1: ldr r0, [r6, #RCC_CR] tst r0, #0x20000 @ HSERDY set? beq 1b @----------------------------------------------------------------------- @ configure and enable PLL @----------------------------------------------------------------------- ldr r0, = PLLCONF @ PLL configuration word str r0, [r6, #RCC_PLLCFGR] ldr r0, [r6, #RCC_CR] orr r0, r0, #0x1000000 @ set PLLON str r0, [r6, #RCC_CR] @----------------------------------------------------------------------- @ wait until PLL ready @----------------------------------------------------------------------- 2: ldr r0, [r6, #RCC_CR] tst r0, #0x2000000 @ PLLRDY set? beq 2b @----------------------------------------------------------------------- @ configure clock prescalers, select PLL as system clock @----------------------------------------------------------------------- ldr r0, = CLKCONF @ clock configuration word str r0, [r6, #RCC_CFGR] @----------------------------------------------------------------------- @ wait until clock source effective @----------------------------------------------------------------------- 4: ldr r0, [r6, #RCC_CFGR] @ r6 has RCC base address tst r0, #0x08 @ SWS = PLL? beq 4b @----------------------------------------------------------------------- @ enable AHB and APB1 peripherals @----------------------------------------------------------------------- ldr r0, = AHB1CONF @ enable GPIOB and GPIOD str r0, [r6, #RCC_AHB1ENR] @ r6 has RCC base address ldr r0, = APB1CONF @ enable USART3 str r0, [r6, #RCC_APB1ENR] @----------------------------------------------------------------------- @----------------------------------------------------------------------- @ disable write protect of backup domain @----------------------------------------------------------------------- ldr r5, = PWR @ PWR base address ldr r0, = PWRCONF @ enable write to backup RAM str r0, [r5, #PWR_CR] @----------------------------------------------------------------------- @ enable RTC clock @----------------------------------------------------------------------- ldr r0, = RTCCONF @ init backup domain control register str r0, [r6, #RCC_BDCR] @ r6 has RCC base address @ .if LSE_fitted @ wait until LSE oscillator ready 5: ldr r0, [r6, #RCC_BDCR] isb tst r0, #0x02 @ LSERDY set? beq 5b .endif bx lr @ ----------------------------------------------------------------------------- Setup_UART: @ ----------------------------------------------------------------------------- @ Turn on the clocks for all GPIOs. ldr r1, = RCC_AHB1ENR @ p. 242 und p. 266 manual RM00090 (Rev 18) @ dm00031020-stm32f405-415-stm32f407......pdf ldr r0, = BIT20+0x1f @ Enable Port A,B,C,D,E str r0, [r1] @ Set PORTB pins 10 and 11 in alternate function mode ldr r1, = GPIOB_MODER ldr r0, = 0x00A00280 @ 00000280 is Reset value for Port B, and @ switch PB10 and PB11 to alternate function str r0, [r1] @ Set alternate function 1 to enable USART3 pins on Port B ldr r1, = GPIOB_AFRH ldr r0, = 0x00007700 @ Alternate function 1 for TX and RX pins of @ USART3 on PORTB PB10 PB11 (pp. 272) str r0, [r1] @ Turn on the clock for USART3. ldr r1, = RCC_APB1ENR mov r0, #0x00040000 @ USART3EN str r0, [r1] @ fCLK 42MHz @ 0x16c9 364.58333_ 16c0 + 9 @ 115200 Bd ldr r1, = USART3_BRR movs r0, #0x16c0 adds r0,#9 str r0, [r1] @ Enable the USART, TX, and RX circuit ldr r1, =USART3_CR1 ldr r0, =USART_CR1_UE+USART_CR1_TE+USART_CR1_RE @ str r0, [r1] ldr r1,=USART3_DR movs r0,#'X' str r0,[r1] @ Enable PE0 (User Led) to sink mode output and switch on ldr r1, = GPIOE_MODER ldr r0, = 0x01 @ bit PE0 to GP Output str r0,[r1] ldr r1,= GPIOE_OTYPER @ p. 281 ldr r0, = 0x01 @ open-drain str r0,[r1] ldr r1,= GPIOE_ODR @ LED ON ldr r0, = 0x0 str r0,[r1] bx lr .ltorg .end