@ Simple(s) Beispiel @ 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 .equ ITM , 0xE0000000 .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 GPIOD_BASE , 0x40020C00 .equ GPIOD_MODER , GPIOD_BASE + 0x00 @ pp. 287 of DM00031020.pdf .equ GPIOD_OTYPER , GPIOD_BASE + 0x04 .equ GPIOD_ODR , GPIOD_BASE + 0x14 .equ GPIOB_BASE , 0x40020400 .equ GPIOB_MODER , GPIOB_BASE + 0x00 .equ GPIOB_OTYPER , GPIOB_BASE + 0x04 .equ GPIOB_OSPEEDR , GPIOB_BASE + 0x08 .equ GPIOB_PUPDR , GPIOB_BASE + 0x0C .equ GPIOB_IDR , GPIOB_BASE + 0x10 .equ GPIOB_ODR , GPIOB_BASE + 0x14 .equ GPIOB_BSRR , GPIOB_BASE + 0x18 .equ GPIOB_LCKR , GPIOB_BASE + 0x1C .equ GPIOB_AFRL , GPIOB_BASE + 0x20 .equ GPIOB_AFRH , GPIOB_BASE + 0x24 .equ GPIOB_BRR , GPIOB_BASE + 0x28 @******************************************************************************* @ Clocks @******************************************************************************* .set HSECLK, 8000000 @ HSE crystal oscillator frequency .set SYSCLK, 168000000 @ main PLL output frequency .set RCLK, 48000000 @ RNG/USB clock frequency @******************************************************************************* @ 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 @******************************************************************************* @ Clock configuration for AHB, APB1 and APB2 peripherals and RTC @******************************************************************************* .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 LSEON, 1 @ enable LSE oscillator .set RTCSEL, 1 @ select LSE as RTC clock source .set RTCEN, 1 @ enable RTC clock @ 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 @******************************************************************************* @ Flash access control settings @******************************************************************************* .set LATNCY, 5 @ number of wait states (0 - 7) .set DCEN, 1 @ data cache enable .set ICEN, 1 @ instruction cache enable .set PRFTEN, 1 @ prefetch enable @ Flash ACR configuration word to be loaded into FLASH_ACR register .set ACRCONF, DCEN << 10 | ICEN <<9 | PRFTEN << 8 | LATNCY @******************************************************************************* @ Coprocessor access enable (FPU enable) @******************************************************************************* .set CP11, 3 @ enable full access to CP11 .set CP10, 3 @ enable full access to CP10 @ coprocessor access enable word to be loaded into SCB_CPACR register .set CPACEN, CP11 << 22 | CP10 << 20 @******************************************************************************* @ System control and system tick settings @******************************************************************************* .set USGFLTEN, 1 @ enable usage fault handler .set BUSFLTEN, 1 @ enable bus fault handler .set MEMFLTEN, 1 @ enable memory fault handler .set UNALIGNTRP, 1 @ enable trapping unaligned word accesses .set TICKSPS, 1000 @ system ticks/sec .set CLKSOURCE, 1 @ use HCLK .set TICKINT, 1 @ enable tick interrupt .set CNTENB, 1 @ enable counter .set TICKPRI, 15 @ tick exception priority = 15 @ systick configuration word to be loaded into STK_CTRL register .set STKCONF, CLKSOURCE << 2 | TICKINT << 1 | CNTENB @ tick counter reload value to be loaded into STK_LOAD register .set STKRELOAD, HCLK / TICKSPS @ system tick handler priority word to be loaded into SCB_SHPR3 register .set STKHDLPRI, TICKPRI << 28 @ system control configuration word to be loaded into SCB_SHCSR register .set SHCSRCONF, USGFLTEN << 18 | BUSFLTEN << 17 | MEMFLTEN << 16 @ system control configuration word to be loaded into SCB_CCSR register .set CCRCONF, UNALIGNTRP << 3 @ system reset request word to be loaded into SCB_AIRCR register .set SYSRESETREQ, 0x05FA0004 @******************************************************************************* @ Flash interface @******************************************************************************* .set FLASH, 0x40023C00 @ base address @ register offsets .set FLASH_ACR, 0x00 @ Flash access control register .set FLASH_KEYR, 0x04 @ Flash key register .set FLASH_OPTKEYR, 0x08 @ Flash option key register .set FLASH_SR, 0x0C @ Flash status register .set FLASH_CR, 0x10 @ Flash control register .set FLASH_OPTCR, 0x14 @ Flash option control register @******************************************************************************* @ System tick timer @******************************************************************************* .set STK, 0xE000E010 @ base address @ register offsets .set STK_CTRL, 0x00 @ SysTick control and status register .set STK_LOAD, 0x04 @ SysTick reload value register .set STK_VAL, 0x08 @ SysTick current value register .set STK_CALIB, 0x0C @ SysTick calibration value register @ System control registers @******************************************************************************* @ System control block @******************************************************************************* .set SCB, 0xE000ED00 @ base address @ register offsets .set SCB_CPUID, 0x000 @ CPU ID register .set SCB_ICSR, 0x004 @ Interrupt control and state register .set SCB_VTOR, 0x008 @ Vector table offset register .set SCB_AIRCR, 0x00C @ Application interrupt and reset control register .set SCB_SCR, 0x010 @ System control register .set SCB_CCR, 0x014 @ Configuration and control register .set SCB_SHPR1, 0x018 @ System handler priority register 1 .set SCB_SHPR2, 0x01C @ System handler priority register 2 .set SCB_SHPR3, 0x020 @ System handler priority register 3 .set SCB_SHCSR, 0x024 @ System handler control and state register .set SCB_CFSR, 0x028 @ Configurable fault status register (full word) .set SCB_MMSR, 0x028 @ MemManage Fault Status Register (byte) .set SCB_BFSR, 0x029 @ BusFault Status Register (byte) .set SCB_UFSR, 0x02A @ UsageFault Status Register (halfword) .set SCB_HFSR, 0x02C @ Hard fault status register .set SCB_MMFAR, 0x034 @ Memory management fault address register .set SCB_BFAR, 0x038 @ Bus fault address register .set SCB_AFSR, 0x03C @ Auxiliary fault status register .set SCB_CPACR, 0x088 @ Coprocessor access control register .set SCB_FPCCR, 0x234 @ Floating-point context control register .set SCB_FPCAR, 0x238 @ Floating-point context address register .set SCB_FPDSCR, 0x23C @ Floating-point default status control register @******************************************************************************* @ Power @******************************************************************************* .set PWR, 0x40007000 @ base address @ register offsets .set PWR_CR, 0x00 @ PWR control register .set PWR_CSR, 0x04 @ PWR control/status register @ register offsets .set FLASH_ACR, 0x00 @ Flash access control register .set FLASH_KEYR, 0x04 @ Flash key register .set FLASH_OPTKEYR, 0x08 @ Flash option key register .set FLASH_SR, 0x0C @ Flash status register .set FLASH_CR, 0x10 @ Flash control register .set FLASH_OPTCR, 0x14 @ Flash option control register .set RCC, 0x40023800 @ base address .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 .equ RCC_BASE , 0x40023800 @******************************************************************************* @ RAMs and peripherals enable @******************************************************************************* .set CCMRAMEN, 1 @ enable CCM data RAM .set BKPRAMEN, 1 @ enable backup RAM .set GPIOBEN, 1 @ enable GPIOB (PB10 = TX, PB11 = RX) .set GPIODEN, 1 @ enable GPIOD (PD15..PD12 = LEDs) .set USART3EN, 1 @ enable USART3 used for serial port .set PWREN, 1 @ enable power interface .set DBP, 1 @ enable write to backup RAM @ AHB1 configuration word to be loaded into RCC_AHB1ENR register .set AHB1CONF, CCMRAMEN << 20 | BKPRAMEN << 18 | GPIODEN << 3 | GPIOBEN << 1 @ APB1 configuration word to be loaded into RCC_APB1ENR register .set APB1CONF, PWREN << 28 | USART3EN << 18 @ Power configuration word to be loaded into PWR_CR register .set PWRCONF, DBP << 8 .syntax unified .cpu cortex-m4 .fpu fpv4-sp-d16 .thumb .text .pool .global rstHandler,Mstk,defHandler .equ Mstk,0x20000400 .org 0 .word Mstk .word rstHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word 0 .word 0 .word 0 .word 0 .word defHandler + 1 .word defHandler + 1 .word 0 .word defHandler + 1 .word stkHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .word defHandler + 1 .org 0x188 .global stkHandler stkHandler: ldr r1, = SysTicks ldr r0, [r1] add r0, r0, #1 str r0, [r1] bx lr @=============================================================================== .global defHandler defHandler: ldr r3, = ExcFrame mrs r0, ipsr pop {r1} stm r3!, {r0, r1} add sp, sp, #12 stm r3!, {r7 - r11} pop {r0 - r2} stm r3!, {r0 - r2} add r0, sp, #4 ldr r1, [r10] ldr r2, [r11] ldrh r4, [r9] stm r3!, {r0 - r2, r4} b . rstHandler: sub r4, pc, #8 @ mov r1, #1 @ ldr r3, = ResetSrc @ ldr r6, = RCC_BASE @ ldrb r2, [r6, #RCC_CSR + 3] @ cbz r2, 1f @ lsr r2, r2, #1 @ ldr r3, = ResetSrc @ str r2, [r3] @ mov r2, #1 @ strb r2, [r6, #RCC_CSR + 3] bl initSys bl kuku warm: nop b warm @ initSys: cpsid i @ disable interrupts ldr r0, = Mstk @ initialize machine stack mov sp, r0 isb @ 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 Flash access ldr r5, = FLASH @ FLASH base address ldr r0, = ACRCONF @ set ACR configuration word str r0, [r5, #FLASH_ACR] @ verify latency is effective 3: ldr r1, [r5, #FLASH_ACR] @ r5 has base address eor r1, r0 tst r1, #0x07 bne 3b @ 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 LSE oscillator ldr r0, = RTCCONF @ init backup domain control register str r0, [r6, #RCC_BDCR] @ r6 has RCC base address @ wait until LSE oscillator ready 5: ldr r0, [r6, #RCC_BDCR] tst r0, #0x02 @ LSERDY set? @ beq 5b @ !!! @ @ configure GPIO pins for USART3 (PB11 = RX, PB10 = TX) @ ldr r6, = GPIOB @ GPIOB base address @ ldr r0, = GPIOBMODE @ PB11/10 mode = AF @ str r0, [r6, #GPIO_MODER] @ ldr r0, = GPIOBAFH @ PB11/10 AF = USART3 @ str r0, [r6, #GPIO_AFRH] @ enable fault handlers and unaligned memory access ldr r6, = SCB @ SCB base address @ ldr r0, = CCRCONF @ enable trapping unaligned memory access @ str r0, [r6, #SCB_CCR] ldr r0, = SHCSRCONF @ enable fault handlers str r0, [r6, #SCB_SHCSR] @ enable FPU ldr r0, = CPACEN @ enable CP10 and CP11 coprocessors str r0, [r6, #SCB_CPACR] @ r6 has SCB base address dsb @ wait for store to complete isb @ reset pipeline now the FPU is enabled @ set system tick handler priotity ldr r0, = STKHDLPRI @ system tick handler priority str r0, [r6, #SCB_SHPR3] @ configure and enable system tick counter ldr r6, = STK @ STK base address ldr r1, = SysTicks @ r1 points to SysTicks variable mov r0, #0 str r0, [r1] @ clear SysTicks str r0, [r6, #STK_VAL] @ clear tick counter ldr r0, = STKRELOAD @ preset counter with reload value str r0, [r6, #STK_LOAD] ldr r0, = STKCONF @ load systick configuration word str r0, [r6, #STK_CTRL] @ and start counter @ cpsie i @ enable interrupts bx lr @ return kuku: push {r0,r1,lr} @ 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] ldr r1, = GPIOD_MODER ldr r0, = BIT30 @ bit PD15 to GP Output str r0,[r1] ldr r1,= GPIOD_OTYPER @ p. 281 ldr r0, = 0 @ push-pull str r0,[r1] ldr r1,= GPIOD_ODR @ LED ON ldr r0, = BIT15 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] ldr r0,=hello bl ITM_SendString ldr r4,=0xABCDEF01 bl cvthex mov r0,#10 bl putchar pop {r0,r1,pc} .ltorg hello: .asciz "hi!\n" .align 4 .global putchar,ITM_SendString ITM_SendString: @ r0 - address of null-terminated String push {r0,r1,lr} mov r1,r0 1: mov r0,#0 ldrb r0,[r1],#1 cbz r0,2f bl putchar b 1b 2: pop {r0,r1,pc} putchar: push {r0-r1,lr} 1: ldr r1, = ITM ldr r1,[r1] cmp r1,#0 beq 1b ldr r1, = ITM str r0,[r1] pop {r0-r1,pc} .global cvthex cvthex: push {r0,r4,r5,lr} @ Assume number to be converted is in r4. Note r4 is clobbered @ Initialise loop counter mov r5, #8 loop: @ Take most significant nibble from r4 into r0 mov r0, r4, lsr #28 @ Shift r4 for next time mov r4, r4, lsl #4 @ For each nibble (now in r0) convert to ASCII and print add r0, r0, #48 cmp r0, #58 @ did that exceed ASCII '9'? blo 3f add r0, #7 3: bl putchar @ Decrement loop counter, loop if not zero sub r5, #1 cmp r5,#0 bne loop pop {r0,r4,r5,pc} @=============================================================================== .global SysTicks, ResetSrc, TimeSlice, ExcFrame SysTicks: .space 4 ResetSrc: .space 4 TimeSlice: .space 4 ExcFrame: .space 14 * 4 .end