Rewrite linker and startup files

The files previously used were from StmCubeMx and Mbed but they contain
a lots off things that we don't need, like a heap and a space for
special debug symbols
This commit is contained in:
Steins7 2023-03-13 11:37:07 +01:00
parent d1e73a55c6
commit c2aec8e9ed
18 changed files with 304 additions and 2397 deletions

220
linker.ld
View File

@ -1,177 +1,79 @@
/**
******************************************************************************
* @file LinkerScript.ld
* @author Auto-generated by STM32CubeIDE
* @brief Linker script for STM32F103C8Tx Device from STM32F1 series
* 64Kbytes FLASH
* 20Kbytes RAM
/** @file
* Linker to be used with the HBL.
*
* Set heap size, stack size and stack location according
* to application requirements.
*
* Set memory bank area and size if external memory is used
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
* This linker file provides the basic architecture for a projet. Stack size and
* memory layout can be configured at will. Note that this file doesn't provide
* a heap space since the HBL doesn't provide or use any form of dynamic
* allocation.
*/
/* Entry Point */
ENTRY(Reset_Handler)
/*--Configuration-------------------------------------------------------------*/
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
/* minimal stack size */
_min_stack_size = 0x400;
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Memories definition */
/* memory layout of the chip */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 128K
RAM (!rx) : ORIGIN = 0x20000000, LENGTH = 20K
}
/* Sections */
/*--Description---------------------------------------------------------------*/
ENTRY(hdr_reset)
/* end of "RAM" Ram type memory */
_estack = ORIGIN(RAM) + LENGTH(RAM);
/* ROM adress to load data from */
_sromdata = LOADADDR(.data);
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* vector table, cpu will look for it at adress 0 on reset */
.vector_table :
{
KEEP(*(.vector_table))
} > ROM
/* The program code and other data into "FLASH" Rom type memory */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
/* program code */
.text :
{
. = ALIGN(4);
*(.text)
} > ROM
KEEP (*(.init))
KEEP (*(.fini))
/* const data */
.rodata :
{
. = ALIGN(4);
*(.rodata)
} > ROM
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* initialized data from ROM */
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
. = ALIGN(4);
_edata = .;
} > RAM AT > ROM
/* Constant data into "FLASH" Rom type memory */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
/* uninitialized data, zeroed */
.bss :
{
. = ALIGN(4);
*(.bss)
} > RAM
.ARM.extab : {
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >FLASH
.ARM : {
. = ALIGN(4);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(4);
} >FLASH
.preinit_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
} >FLASH
.init_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
} >FLASH
.fini_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
} >FLASH
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections into "RAM" Ram type memory */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section into "RAM" Ram type memory */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough "RAM" Ram type
* memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
/* memory space allocated to stack. The stack is situated at the very end of
* the RAM while this section may not, thus it is only used to enforce a
* minimal stack size */
.stack :
{
. = ALIGN(8);
. = . + _min_stack_size;
} > RAM
}

View File

@ -1,29 +0,0 @@
//------------------------------------------------------------------------------
/* priorities */
#define EXTI0_IRQ_PRIORITY 8
#define EXTI1_IRQ_PRIORITY 8
#define EXTI2_IRQ_PRIORITY 8
#define EXTI3_IRQ_PRIORITY 8
#define EXTI4_IRQ_PRIORITY 8
#define EXTI9_5_IRQ_PRIORITY 8
#define EXTI15_10_IRQ_PRIORITY 8
#define TIM1_IRQ_PRIORITY 4
#define TIM2_IRQ_PRIORITY 4
#define TIM3_IRQ_PRIORITY 4
#define TIM4_IRQ_PRIORITY 4
#define USART1_IRQ_PRIORITY 3
#define USART2_IRQ_PRIORITY 3
#define USART3_IRQ_PRIORITY 3
#define I2C1_IRQ_PRIORITY 2
#define I2C1_IRQERR_PRIORITY 1
#define I2C2_IRQ_PRIORITY 2
#define I2C2_IRQERR_PRIORITY 1
#define SPI1_IRQ_PRIORITY 4
#define SPI2_IRQ_PRIORITY 4
#define ADC1_2_IRQ_PRIORITY 5

View File

@ -1,41 +0,0 @@
#include "adc.h"
extern Clock_t sysclks;
int adc_init(ADC_TypeDef* adc) {
// enable adc clock
if(adc == ADC1) RCC->APB2ENR |= 0x1 << 9;
else if(adc == ADC2) RCC->APB2ENR |= 0x1 << 10;
else return -1; //no such adc
// enable adc
adc->CR2 |= 0x1;
// configure regular channels
adc->CR1 = 0; //reset value
adc->CR1 |= 0x1 << 23; //enable analog watchdog
adc->CR1 |= 0x1 << 11; //discontinuous mode
// set trigger to manual
adc->CR1 |= 0x7 << 3;
adc->SMPR2 |= 0x3FFFFFFF;
// calibrate
adc->CR2 |= 0x1 << 2;
while((adc->CR2 >> 2) & 0x1);
return 0;
}
uint16_t adc_read(ADC_TypeDef* adc, uint8_t channel) {
adc->SQR1 &= ~(0xF << 20); //one conversion only
adc->SQR3 = (adc->SQR3 & ~(0x1F)) | channel; //set channel
//adc->CR2 |= 0x1 << 22; //start convertion
adc->CR2 |= 0x1;
while(!((adc->SR >> 1) & 0x1)); //waiting for convertion
return adc->DR & 0xFFF;
}

View File

@ -1,15 +0,0 @@
#ifndef ADC_H
#define ADC_H
#include "../target/stm32f103xb.h"
#include "../config.h"
#include "rcc.h"
int adc_init(ADC_TypeDef* adc);
uint16_t adc_read(ADC_TypeDef* adc, uint8_t channel);
#endif

View File

@ -1,223 +0,0 @@
//driver header
#include "io.h"
static OnIO io_cb[16]={
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
void EXTI0_IRQHandler() {
if (io_cb[0]) (io_cb[0])();
EXTI->PR = 1<<0;
}
void EXTI1_IRQHandler() {
if (io_cb[1]) (io_cb[1])();
EXTI->PR = 1<<1;
}
void EXTI2_IRQHandler() {
if (io_cb[2]) (io_cb[2])();
EXTI->PR = 1<<2;
}
void EXTI3_IRQHandler() {
if (io_cb[3]) (io_cb[3])();
EXTI->PR = 1<<3;
}
void EXTI4_IRQHandler() {
if (io_cb[4]) (io_cb[4])();
EXTI->PR = 1<<4;
}
void EXTI9_5_IRQHandler() {
if (EXTI->PR & (1<<5)) {
if (io_cb[5]) (io_cb[5])();
EXTI->PR = 1<<5;
} else if (EXTI->PR & (1<<6)) {
if (io_cb[6]) (io_cb[6])();
EXTI->PR = 1<<6;
} else if (EXTI->PR & (1<<7)) {
if (io_cb[7]) (io_cb[7])();
EXTI->PR = 1<<7;
} else if (EXTI->PR & (1<<8)) {
if (io_cb[8]) (io_cb[8])();
EXTI->PR = 1<<8;
} else if (EXTI->PR & (1<<9)) {
if (io_cb[9]) (io_cb[9])();
EXTI->PR = 1<<9;
}
}
void EXTI15_10_IRQHandler() {
if (EXTI->PR & (1<<10)) {
if (io_cb[10]) (io_cb[10])();
EXTI->PR = 1<<10;
} else if (EXTI->PR & (1<<11)) {
if (io_cb[11]) (io_cb[11])();
EXTI->PR = 1<<11;
} else if (EXTI->PR & (1<<12)) {
if (io_cb[12]) (io_cb[12])();
EXTI->PR = 1<<12;
} else if (EXTI->PR & (1<<13)) {
if (io_cb[13]) (io_cb[13])();
EXTI->PR = 1<<13;
} else if (EXTI->PR & (1<<14)) {
if (io_cb[14]) (io_cb[14])();
EXTI->PR = 1<<14;
} else if (EXTI->PR & (1<<15)) {
if (io_cb[15]) (io_cb[15])();
EXTI->PR = 1<<15;
}
}
/* Definitions for EXTI configuration */
enum io_exti_mask {
SYSCFG_EXTI_PA_MASK = 0x0,
SYSCFG_EXTI_PB_MASK = 0x1,
SYSCFG_EXTI_PC_MASK = 0x2,
SYSCFG_EXTI_PD_MASK = 0x3,
SYSCFG_EXTI_PE_MASK = 0x4
};
int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint16_t pin_cfg, OnIO cb) {
// enable GPIOx subsystem clocking
if (gpio == GPIOA) RCC->APB2ENR |= 1<<2;
else if (gpio == GPIOB) RCC->APB2ENR |= 1<<3;
else if (gpio == GPIOC) RCC->APB2ENR |= 1<<4;
else if (gpio == GPIOD) RCC->APB2ENR |= 1<<5;
else if (gpio == GPIOE) RCC->APB2ENR |= 1<<6;
// setup pin mask for crx registers
uint64_t pin_mask = 0;
for(int i=0; i<16; ++i) {
if((pin >> i) & 0x1) pin_mask |= 0x1ll << 4*i;
}
// clear previous data
uint64_t crx = pin_mask * 0x4; //reset value is 0x4
uint16_t odr = pin;
gpio->CRH &= ~(crx >> 32);
gpio->CRL &= ~(crx & 0xFFFFFFFF);
gpio->BSRR |= odr << 16;
// set up the new configuration
crx = pin_mask * (pin_cfg & 0xF);
odr = pin * ((pin_cfg & 0x10) >> 4);
gpio->CRH |= crx >> 32;
gpio->CRL |= crx & 0xFFFFFFFF;
gpio->BSRR |= odr;
//TODO manage alternate functions
// manage IRQs //TODO allow IRQ reset
if (!cb) return 0; //no callback attached
if (pin_cfg & 0x7) return -1; //callback set, but not in input mode
RCC->APB2ENR |= 0x1; //enable AFIO clocking
// prepare mask
uint8_t port_mask = 0;
// uint32_t pin_mask = 0;
if (gpio == GPIOA) port_mask = SYSCFG_EXTI_PA_MASK;
else if (gpio == GPIOB) port_mask = SYSCFG_EXTI_PB_MASK;
else if (gpio == GPIOC) port_mask = SYSCFG_EXTI_PC_MASK;
else if (gpio == GPIOD) port_mask = SYSCFG_EXTI_PD_MASK;
else if (gpio == GPIOE) port_mask = SYSCFG_EXTI_PE_MASK;
// setup external IRQ lines
uint64_t afio_mask;
for(int i=0; i<4; ++i) {
afio_mask = ((pin_mask & (0xFFFFll << (i*16))) >> (i*16)) * port_mask;
if(afio_mask) AFIO->EXTICR[i] |= afio_mask;
}
// clear pending IRQs on concerned lines
EXTI->PR |= pin;
// configure IRQ options and masks
EXTI->IMR |= pin;
if(pin_cfg & 0x100) EXTI->RTSR |= pin;
if(pin_cfg & 0x200) EXTI->FTSR |= pin; //in case both falling and rising
//are set, both will be a trigger
// register IRQ callbacks
for(int i=0; i<16; ++i) {
if((pin >> i) & 0x1) {
io_cb[i] = cb;
// Setup NVIC
switch (i) {
case 0:
NVIC_SetPriority(EXTI0_IRQn, EXTI0_IRQ_PRIORITY);
NVIC_EnableIRQ(EXTI0_IRQn);
break;
case 1:
NVIC_SetPriority(EXTI1_IRQn, EXTI1_IRQ_PRIORITY);
NVIC_EnableIRQ(EXTI1_IRQn);
break;
case 2:
NVIC_SetPriority(EXTI2_IRQn, EXTI2_IRQ_PRIORITY);
NVIC_EnableIRQ(EXTI2_IRQn);
break;
case 3:
NVIC_SetPriority(EXTI3_IRQn, EXTI3_IRQ_PRIORITY);
NVIC_EnableIRQ(EXTI3_IRQn);
break;
case 4:
NVIC_SetPriority(EXTI4_IRQn, EXTI4_IRQ_PRIORITY);
NVIC_EnableIRQ(EXTI4_IRQn);
break;
case 5:
case 6:
case 7:
case 8:
case 9:
NVIC_SetPriority(EXTI9_5_IRQn, EXTI9_5_IRQ_PRIORITY);
NVIC_EnableIRQ(EXTI9_5_IRQn);
break;
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
NVIC_SetPriority(EXTI15_10_IRQn, EXTI15_10_IRQ_PRIORITY);
NVIC_EnableIRQ(EXTI15_10_IRQn);
break;
default:
return -1; //impossible to get there
}
}
}
return 0;
}
uint32_t io_read(GPIO_TypeDef *gpio, uint16_t mask)
{
return gpio->IDR & mask;
}
void io_write(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask)
{
gpio->BSRR = (uint32_t)(mask) << (val ? 0 : 16);
}
void io_write_n(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask)
{
gpio->BSRR = (uint32_t)(mask) << (val ? 16 : 0);
}
void io_set(GPIO_TypeDef *gpio, uint16_t mask)
{
gpio->BSRR = mask;
}
void io_clear(GPIO_TypeDef *gpio, uint16_t mask)
{
gpio->BSRR = (uint32_t)(mask) << 16;
}

View File

@ -1,132 +0,0 @@
#ifndef IO_H
#define IO_H
//std headers
#include <stdlib.h>
#include <stdint.h>
//target header
#include "../target/stm32f103xb.h"
//custom header
#include "../config.h"
//------------------------------------------------------------------------------
/* GPIO pin mask definitions */
enum io_pin {
PIN_0 = (1 << 0),
PIN_1 = (1 << 1),
PIN_2 = (1 << 2),
PIN_3 = (1 << 3),
PIN_4 = (1 << 4),
PIN_5 = (1 << 5),
PIN_6 = (1 << 6),
PIN_7 = (1 << 7),
PIN_8 = (1 << 8),
PIN_9 = (1 << 9),
PIN_10 = (1 << 10),
PIN_11 = (1 << 11),
PIN_12 = (1 << 12),
PIN_13 = (1 << 13),
PIN_14 = (1 << 14),
PIN_15 = (1 << 15),
PIN_ALL = 0xFFFF
};
//------------------------------------------------------------------------------
/* GPIO pin mode definitions */
enum io_mode {
IO_MODE_INPUT = (0x0),
IO_MODE_OUTPUT = (0x1), // 10Mhz max
IO_MODE_OUTPUT_SLOW = (0x3), // 2MHz max
IO_MODE_OUTPUT_FAST = (0x4) // 50 MHz max
};
//------------------------------------------------------------------------------
/* GPIO pin conf definitions */
enum io_conf {
IO_IN_ANALOG = (0b0 << 2),
IO_IN_FLOATING = (0b1 << 2),
IO_IN_PULL_UP = (0b110 << 2),
IO_IN_PULL_DOWN = (0b010 << 2),
IO_OUT_ALT_FNCT = (0b10 << 2),
IO_OUT_PUSH_PULL = (0b0 << 2),
IO_OUT_OPEN_DRAIN = (0b1 << 2)
};
//------------------------------------------------------------------------------
/* GPIO pin clear */
#define IO_CLEAR (0)
//------------------------------------------------------------------------------
/* alternate function selection option */
//TODO not supported for now
//enum io_alt_fnct {
// PIN_OPT_AF0 0x0,
// PIN_OPT_AF1 0x1,
// PIN_OPT_AF2 0x2,
// PIN_OPT_AF3 0x3,
// PIN_OPT_AF4 0x4,
// PIN_OPT_AF5 0x5,
// PIN_OPT_AF6 0x6,
// PIN_OPT_AF7 0x7,
// PIN_OPT_AF8 0x8,
// PIN_OPT_AF9 0x9,
// PIN_OPT_AF10 0xA,
// PIN_OPT_AF11 0xB,
// PIN_OPT_AF12 0xC,
// PIN_OPT_AF13 0xD,
// PIN_OPT_AF14 0xE,
// PIN_OPT_AF15 0xF
//};
//------------------------------------------------------------------------------
/* GPIO IRQ conf definitons */
enum io_irq_conf {
IO_IRQ_EDGE_RISE = (0x1 << 8),
IO_IRQ_EDGE_FALL = (0x2 << 8),
IO_IRQ_EDGE_BOTH = (0x3 << 8)
};
typedef void (*OnIO)();
//------------------------------------------------------------------------------
/* io_configure
*
* configure pins referenced in 'pin_mask' of specified port
* 'gpio' according to 'pin_cfg' and associate a callback
* function 'cb' if not NULL.
* returns 0 if success
*/
int io_configure(GPIO_TypeDef *gpio, uint16_t pin_mask, uint16_t pin_cfg,
OnIO cb);
/* io_read
*
* read 32 bit data from port 'gpio', filter the result with mask
*/
uint32_t io_read(GPIO_TypeDef *gpio, uint16_t mask);
/* io_write
*
* write 16 bit data filtered by mask to port 'gpio'
* '1' in val are written as HIGH level on port pins
*/
void io_write(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask);
/* io_write_n
*
* write 16 bit data filtered by mask to port 'gpio'
* '1' in val are written as LOW level on port pins
*/
void io_write_n(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask);
/* io_set/clear
*
* set or clear outputs according to bit mask
*/
void io_set(GPIO_TypeDef *gpio, uint16_t mask);
void io_clear(GPIO_TypeDef *gpio, uint16_t mask);
#endif

View File

@ -1,186 +0,0 @@
#include "lcd.h"
enum mode {
WRITE,
READ,
UNDEFINED
};
//TODO make the driver dynamic ?
static TIM_TypeDef* timer = 0;
static uint8_t mode = UNDEFINED;
static uint8_t rows = 0;
static uint8_t columns = 0;
static uint8_t rows_offset[4] = {};
//------------------------------------------------------------------------------
// internal functions
int set_mode_read(void) {
// configure pins
if(io_configure(GPIOA, PIN_8 | PIN_12 | PIN_15, IO_MODE_INPUT |
IO_IN_FLOATING, 0)) return -1;
if(io_configure(GPIOB, PIN_3 | PIN_4 | PIN_13 | PIN_14 | PIN_15,
IO_MODE_INPUT | IO_IN_FLOATING, 0)) return -1;
// put lcd in read mode
io_set(GPIOA, PIN_9); // after the pins are ready to recieve voltage
mode = READ;
return 0;
}
int set_mode_write(void) {
// put lcd in write mode
io_clear(GPIOA, PIN_9); //before the pin can send voltage
// configure pins
if(io_configure(GPIOA, PIN_8 | PIN_12 | PIN_15, IO_MODE_OUTPUT |
IO_OUT_PUSH_PULL, 0)) return -1;
if(io_configure(GPIOB, PIN_3 | PIN_4 | PIN_13 | PIN_14 | PIN_15,
IO_MODE_OUTPUT | IO_OUT_PUSH_PULL, 0)) return -1;
mode = WRITE;
return 0;
}
void wait_for_ready(void) {
//TODO debug that
// // configure the lcd
// if(mode != READ) if(set_mode_read()) return;
//
// // read D7 pin
// for(;;) {
// io_set(GPIOA, PIN_11);
// for(int i=0; i<1000; ++i); //timer_wait is overkill here
// if(!io_read(GPIOB, PIN_4)) break;
// io_clear(GPIOA, PIN_11);
// for(int i=0; i<1000; ++i); //same
// }
timer_wait_ms(timer, 2, 0); //wait max delay
}
void write_byte(uint8_t byte) {
// put the lcd bus in write mode
if(mode != WRITE) if(set_mode_write()) return;
// start tranfert
io_set(GPIOA, PIN_11);
timer_wait_us(timer, 1, 0);
// send the data
io_write(GPIOA, (byte >> 0) & 0x1, PIN_8);
io_write(GPIOA, (byte >> 1) & 0x1, PIN_12);
io_write(GPIOB, (byte >> 2) & 0x1, PIN_15);
io_write(GPIOA, (byte >> 3) & 0x1, PIN_15);
io_write(GPIOB, (byte >> 4) & 0x1, PIN_14);
io_write(GPIOB, (byte >> 5) & 0x1, PIN_3);
io_write(GPIOB, (byte >> 6) & 0x1, PIN_13);
io_write(GPIOB, (byte >> 7) & 0x1, PIN_4);
// validate data
io_clear(GPIOA, PIN_11);
}
//------------------------------------------------------------------------------
int lcd_init(TIM_TypeDef* tim, uint8_t col, uint8_t row) {
timer = tim;
columns = col;
rows = row;
rows_offset[0] = 0x00;
rows_offset[1] = 0x40;
rows_offset[2] = 0x00 + columns;
rows_offset[3] = 0x40 + columns;
// disable JTAG, as it utilise needed pins, SWD remains usable in
// synchronous mode
RCC->APB2ENR |= 0x1; //enable AFIO clocking
AFIO->MAPR = (AFIO->MAPR & ~(0x8 << 24)) | 0x2 << 24;
// configure the lcd control pins
if(io_configure(GPIOA, PIN_9 | PIN_10 | PIN_11, IO_MODE_OUTPUT |
IO_OUT_PUSH_PULL, 0)) return -1;
// put the lcd bus in write mode
if(set_mode_write()) return -1; //no check in case the pins were used
//somewhere else
// select instruction register
io_write(GPIOA, LCD_MODE_CMD, PIN_10);
// begin initialisation sequence
timer_wait_ms(timer, 15, 0);
write_byte(LCD_FUNC_SET | LCD_FUNC_8BIT | LCD_FUNC_2LINE |
LCD_FUNC_5x8DOTS);
timer_wait_ms(timer, 5, 0);
write_byte(LCD_FUNC_SET | LCD_FUNC_8BIT | LCD_FUNC_2LINE |
LCD_FUNC_5x8DOTS);
timer_wait_us(timer, 150, 0);
write_byte(LCD_FUNC_SET | LCD_FUNC_8BIT | LCD_FUNC_2LINE |
LCD_FUNC_5x8DOTS);
wait_for_ready();
write_byte(LCD_FUNC_SET | LCD_FUNC_8BIT | LCD_FUNC_2LINE |
LCD_FUNC_5x8DOTS);
wait_for_ready();
write_byte(LCD_DISP_CTRL | LCD_CTRL_DISP_OFF | LCD_CTRL_CUR_OFF |
LCD_CTRL_BLINK_OFF);
wait_for_ready();
write_byte(LCD_CLEAR);
wait_for_ready();
write_byte(LCD_ENTRY | LCD_ENTRY_LEFT | LCD_ENTRY_SHIFT_DEC);
wait_for_ready();
// post initialisation setup
write_byte(LCD_DISP_CTRL | LCD_CTRL_DISP_ON | LCD_CTRL_CUR_ON |
LCD_CTRL_BLINK_ON);
wait_for_ready();
write_byte(LCD_CLEAR);
return 0;
}
void lcd_send_cmd(uint8_t cmd) {
// wait for the screen
wait_for_ready();
// select instruction register
io_write(GPIOA, LCD_MODE_CMD, PIN_10);
// send the command
write_byte(cmd);
}
void lcd_print(const char* txt) {
// prepare data
const char* c = txt;
// wait for the screen
wait_for_ready();
// select data register
io_write(GPIOA, LCD_MODE_DATA, PIN_10);
// send the caracters until end of string
// TODO implement '\n'
while(*c != '\0') {
wait_for_ready();
write_byte(*c);
c++;
}
}
void lcd_print_c(char c) {
// wait for the screen
wait_for_ready();
// select data register
io_write(GPIOA, LCD_MODE_DATA, PIN_10);
// send the caracter
write_byte(c);
}
void lcd_set_cursor(uint8_t col, uint8_t row) {
lcd_send_cmd(LCD_DDRAM_ADDR | (col + rows_offset[row]));
}

View File

@ -1,93 +0,0 @@
#ifndef LCD_H
#define LCD_H
#include "../target/stm32f103xb.h"
#include "../config.h"
#include "timer.h"
#include "io.h"
#include <stdlib.h>
//------------------------------------------------------------------------------
/* LCD mode selection */
enum lcd_register {
LCD_MODE_CMD = 0,
LCD_MODE_DATA = 1
};
//------------------------------------------------------------------------------
/* LCD commands */
enum lcd_command {
LCD_CLEAR = 0x01,
LCD_CUR_HOME = 0x02,
LCD_ENTRY = 0x04,
LCD_DISP_CTRL = 0x08,
LCD_SHIFT = 0x10,
LCD_FUNC_SET = 0x20,
LCD_CGRAM_ADDR = 0x40,
LCD_DDRAM_ADDR = 0x80
};
//------------------------------------------------------------------------------
/* LCD_ENTRY command options */
enum lcd_entry_option {
LCD_ENTRY_RIGHT = 0x00,
LCD_ENTRY_LEFT = 0x02,
LCD_ENTRY_SHIFT_INC = 0x01,
LCD_ENTRY_SHIFT_DEC = 0x00
};
//------------------------------------------------------------------------------
/* LCD_DISP_CTRL command options */
enum lcd_ctrl_option {
LCD_CTRL_DISP_ON = 0x04,
LCD_CTRL_DISP_OFF = 0x00,
LCD_CTRL_CUR_ON = 0x02,
LCD_CTRL_CUR_OFF = 0x00,
LCD_CTRL_BLINK_ON = 0x01,
LCD_CTRL_BLINK_OFF = 0x00
};
//------------------------------------------------------------------------------
/* LCD_SHIFT command options */
enum lcd_shift_option {
LCD_SHIFT_DISP = 0x08,
LCD_SHIFT_CUR = 0x00,
LCD_SHIFT_RIGHT = 0x04,
LCD_SHIFT_LEFT = 0x00
};
//------------------------------------------------------------------------------
/* LCD_FUNC_SET command options */
enum lcd_func_option {
LCD_FUNC_8BIT = 0x10,
LCD_FUNC_4BIT = 0x00,
LCD_FUNC_2LINE = 0x08,
LCD_FUNC_1LINE = 0x00,
LCD_FUNC_5x10DOTS = 0x04,
LCD_FUNC_5x8DOTS = 0x00
};
//------------------------------------------------------------------------------
/** lcd_init
* initialise the lcd, needed before anything else can be done
* the timer is used for delays and can't be in use when lcd functions are
* called
*/
int lcd_init(TIM_TypeDef* tim, uint8_t col, uint8_t row);
/** lcd_send_cmd
* send the specified command to the lcd
*/
void lcd_send_cmd(uint8_t cmd);
/** lcd_print
* print a null-terminated string on the lcd
*/
void lcd_print(const char* txt);
void lcd_print_c(char c);
void lcd_set_cursor(uint8_t col, uint8_t row);
#endif

View File

@ -1,258 +0,0 @@
/*
==============================================================================
##### RCC specific features #####
==============================================================================
[..]
After reset the device is running from Internal High Speed oscillator
(HSI 16MHz) with Flash 0 wait state, Flash prefetch buffer, D-Cache
and I-Cache are disabled, and all peripherals are off except internal
SRAM, Flash and JTAG.
(+) There is no prescaler on High speed (AHB) and Low speed (APB) busses;
all peripherals mapped on these busses are running at HSI speed.
(+) The clock for all peripherals is switched off, except the SRAM and FLASH.
(+) All GPIOs are in input floating state, except the JTAG pins which
are assigned to be used for debug purpose.
[..]
Once the device started from reset, the user application has to:
(+) Configure the clock source to be used to drive the System clock
(if the application needs higher frequency/performance)
(+) Configure the System clock frequency and Flash settings
(+) Configure the AHB and APB busses prescalers
(+) Enable the clock for the peripheral(s) to be used
(+) Configure the clock source(s) for peripherals which clocks are not
derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG)
##### RCC Limitations #####
==============================================================================
[..]
A delay between an RCC peripheral clock enable and the effective peripheral
enabling should be taken into account in order to manage the peripheral
read/write from/to registers.
(+) This delay depends on the peripheral mapping.
(+) If peripheral is mapped on AHB: the delay is 2 AHB clock cycle
after the clock enable bit is set on the hardware register
(+) If peripheral is mapped on APB: the delay is 2 APB clock cycle
after the clock enable bit is set on the hardware register
[..]
Possible Workarounds:
(#) Enable the peripheral clock sometimes before the peripheral read/write
register is required.
(#) For AHB peripheral, insert two dummy read to the peripheral register.
(#) For APB peripheral, insert a dummy read to the peripheral register.
*/
#include "rcc.h"
/* HPRE: AHB high-speed prescaler */
#define RCC_CFGR_HPRE_DIV_NONE 0x0
#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0)
#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1)
#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2)
#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3)
#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4)
#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5)
#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6)
#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7)
/* PPRE1/2: APB high-speed prescalers */
#define RCC_CFGR_PPRE_DIV_NONE 0x0
#define RCC_CFGR_PPRE_DIV_2 0x4
#define RCC_CFGR_PPRE_DIV_4 0x5
#define RCC_CFGR_PPRE_DIV_8 0x6
#define RCC_CFGR_PPRE_DIV_16 0x7
/* PPLMUL: PPL multiplier */
#define RCC_CFGR_PLLMUL(fac) (fac + 2)
/* ADC: ADCPRE prescalers */
#define RCC_CFGR_ADCPRE_DIV_2 0x0
#define RCC_CFGR_ADCPRE_DIV_4 0x1
#define RCC_CFGR_ADCPRE_DIV_6 0x2
#define RCC_CFGR_ADCPRE_DIV_8 0x3
enum rcc_osc {
RCC_HSI,
RCC_HSE,
RCC_PLL,
RCC_LSI,
RCC_LSE
};
struct ClockConfig_t {
uint8_t type;
uint8_t pll_src;
uint8_t pllmul;
uint8_t hpre;
uint8_t ppre1;
uint8_t ppre2;
uint8_t adcpre;
uint32_t flash_cfg;
uint32_t ahb_freq;
uint32_t apb1_freq;
uint32_t apb2_freq;
};
static struct ClockConfig_t _clock_config[] = {
{/* Performance Mode */
.type = RCC_PLL,
.pll_src = RCC_HSE, //8MHz
.pllmul = RCC_CFGR_PLLMUL(9), //freq should noot exceed 72MHz
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_2, //freq should not exceed 36MHz
.ppre2 = RCC_CFGR_PPRE_DIV_NONE,
.adcpre = RCC_CFGR_ADCPRE_DIV_6, //freq should not exceed 14MHz
.flash_cfg = FLASH_ACR_LATENCY_2,
.ahb_freq = 72000000,
.apb1_freq = 36000000,
.apb2_freq = 72000000
},
{/* Powersave Mode */
.type = RCC_HSE,
.hpre = RCC_CFGR_HPRE_DIV_16,
.ppre1 = RCC_CFGR_PPRE_DIV_16,
.ppre2 = RCC_CFGR_PPRE_DIV_16,
.adcpre = RCC_CFGR_ADCPRE_DIV_2,
.flash_cfg = FLASH_ACR_LATENCY_0,
.ahb_freq = 500000,
.apb1_freq = 500000,
.apb2_freq = 500000
}
};
static void rcc_osc_on(enum rcc_osc osc)
{
switch (osc) {
case RCC_HSI:
if (!(RCC->CR & RCC_CR_HSION)) {
RCC->CR |= RCC_CR_HSION;
while ((RCC->CR & RCC_CR_HSIRDY)==0);
}
break;
case RCC_HSE:
if (!(RCC->CR & RCC_CR_HSEON)) {
RCC->CR |= RCC_CR_HSEON;
while ((RCC->CR & RCC_CR_HSERDY)==0);
}
break;
case RCC_PLL:
if (!(RCC->CR & RCC_CR_PLLON)) {
RCC->CR |= RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY)==0);
}
break;
case RCC_LSI:
if (!(RCC->CSR & RCC_CSR_LSION)) {
RCC->CSR |= RCC_CSR_LSION;
while ((RCC->CSR & RCC_CSR_LSIRDY)==0);
}
break;
case RCC_LSE:
if (!(RCC->BDCR & RCC_BDCR_LSEON)) {
RCC->BDCR |= RCC_BDCR_LSEON;
while ((RCC->BDCR & RCC_BDCR_LSERDY)==0);
}
break;
}
}
static void rcc_osc_off(enum rcc_osc osc)
{
switch (osc) {
case RCC_HSI:
RCC->CR &= ~RCC_CR_HSION;
break;
case RCC_HSE:
RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_CSSON);
break;
case RCC_PLL:
RCC->CR &= ~RCC_CR_PLLON;
break;
case RCC_LSI:
RCC->CSR &= ~RCC_CSR_LSION;
break;
case RCC_LSE:
RCC->BDCR &= ~RCC_BDCR_LSEON;
break;
}
}
static void rcc_set_sysclk(enum rcc_osc osc)
{
RCC->CFGR = (RCC->CFGR & ~0x3) | (osc & 3);
while (((RCC->CFGR & 0xC)>>2) != osc);
}
void rcc_config_clock(uint32_t config, Clock_t *sysclks)
{
struct ClockConfig_t *clk;
if (config < CLOCK_CONFIG_END) {
clk=&(_clock_config[config]);
} else {
clk=&(_clock_config[CLOCK_CONFIG_PERFORMANCE]);
}
if (clk->type == RCC_HSE) { // HSE Clock
rcc_osc_on(RCC_HSE);
rcc_set_sysclk(RCC_HSE);
rcc_osc_off(RCC_PLL);
rcc_osc_off(RCC_HSI);
} else if (clk->type == RCC_PLL) {
// enable PWR module clocking
RCC->APB1ENR |= 1<<28;
if (clk->pll_src == RCC_HSE) { // HSE Clock src
rcc_osc_on(RCC_HSE);
} else { // Default: HSI Clock src
rcc_osc_on(RCC_HSI);
}
// configure prescalers for
// AHB: AHBCLK > 25MHz
// APB1: APB1CLK <= 36MHz
// APB2: APB2CLK <= 72MHz
RCC->CFGR = ( RCC->CFGR & ~((0x3F<<8) | (0xF<<4) | (0x3<<14)) ) |
((clk->hpre & 0xF) << 4) |
((clk->ppre1 & 0x7) << 8) |
((clk->ppre2 & 0x7) << 11)|
(clk->adcpre << 14);
// configure PLL
RCC->CFGR &= !(0xF<<18);
RCC->CFGR |= clk->pllmul<<18;
// enable PLL oscillator
rcc_osc_on(RCC_PLL);
// set Flash timings
FLASH->ACR &= !0x8;
FLASH->ACR |= clk->flash_cfg;
//TODO set buffer bits
// connect to PLL
rcc_set_sysclk(RCC_PLL);
// stop unused clock
if ((clk->pll_src == RCC_HSE) && (RCC->CR & RCC_CR_HSION))
rcc_osc_off(RCC_HSI);
else
rcc_osc_off(RCC_HSE);
} else { // Default: HSI Clock
rcc_osc_on(RCC_HSI);
rcc_set_sysclk(RCC_HSI);
rcc_osc_off(RCC_PLL);
rcc_osc_off(RCC_HSE);
}
sysclks->ahb_freq = clk->ahb_freq;
sysclks->apb1_freq = clk->apb1_freq;
sysclks->apb2_freq = clk->apb2_freq;
sysclks->apb1_timer_freq =
clk->ppre1==RCC_CFGR_PPRE_DIV_NONE ? clk->apb1_freq : 2*clk->apb1_freq;
sysclks->apb2_timer_freq =
clk->ppre2==RCC_CFGR_PPRE_DIV_NONE ? clk->apb2_freq : 2*clk->apb2_freq;
}

View File

@ -1,33 +0,0 @@
#ifndef _RCC_H_
#define _RCC_H_
#include "../target/stm32f103xb.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _Clock_t {
uint32_t ahb_freq;
uint32_t apb1_freq;
uint32_t apb1_timer_freq;
uint32_t apb2_freq;
uint32_t apb2_timer_freq;
} Clock_t;
enum Clock_config {
CLOCK_CONFIG_PERFORMANCE,
CLOCK_CONFIG_POWERSAVE,
CLOCK_CONFIG_END
};
//void SystemInit(void);
void rcc_config_clock(uint32_t config, Clock_t *sysclks);
#
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,20 +0,0 @@
#include "rnd.h"
uint32_t rnd_seed = 251;
void set_rnd_seed(uint32_t seed) {
rnd_seed = seed;
}
uint8_t rnd_byte() {
static uint32_t r = 251;
static uint32_t Y = 7;
if (r==0 || r==1 || r==0xFFFFFFFF) r=251;
r = (9973 * ~r) + ((Y) % 701);
Y = (r>>24) % 255;
return (uint8_t)Y;
}

View File

@ -1,11 +0,0 @@
#ifndef RND_H
#define RND_H
#include "stdint.h"
void set_rnd_seed(uint32_t seed);
uint8_t rnd_byte();
#endif

View File

@ -1,338 +0,0 @@
#include "timer.h"
extern Clock_t sysclks;
//------------------------------------------------------------------------------
static OnTick callback1 = 0;
static OnTick callback2 = 0;
static OnTick callback3 = 0;
static OnTick callback4 = 0;
void TIM1_UP_IRQHandler(void) {
if (callback1) callback1();
TIM1->SR &= ~0x1F;
}
void TIM2_IRQHandler(void) {
if (callback2) callback2();
TIM2->SR &= ~0x1F;
}
void TIM3_IRQHandler(void) {
if (callback3) callback3();
TIM3->SR &= ~0x1F;
}
void TIM4_IRQHandler(void) {
if (callback4) callback4();
TIM4->SR &= ~0x1F;
}
//------------------------------------------------------------------------------
int timer_config_cb(TIM_TypeDef* tmr, uint32_t* clk, OnTick cb) {
IRQn_Type irqn;
uint32_t irq_priority;
switch((uint32_t)tmr) {
case (uint32_t)TIM1:
// get clocks config
*clk = sysclks.apb2_timer_freq;
// register callback function
callback1 = cb;
irqn = TIM1_UP_IRQn; //every update
irq_priority = TIM1_IRQ_PRIORITY;
// enable timer clocking
RCC->APB2ENR |= 1<<11;
break;
case (uint32_t)TIM2:
// get clocks config
*clk = sysclks.apb1_timer_freq;
// register callback function
callback2 = cb;
irqn = TIM2_IRQn;
irq_priority = TIM2_IRQ_PRIORITY;
// enable timer clocking
RCC->APB1ENR |= 1<<0;
break;
case (uint32_t)TIM3:
// get clocks config
*clk = sysclks.apb1_timer_freq;
// register callback function
callback3 = cb;
irqn = TIM3_IRQn;
irq_priority = TIM3_IRQ_PRIORITY;
// enable timer clocking
RCC->APB1ENR |= 1<<1;
break;
case (uint32_t)TIM4:
// get clocks config
*clk = sysclks.apb1_timer_freq;
// register callback function
callback4 = cb;
irqn = TIM4_IRQn;
irq_priority = TIM4_IRQ_PRIORITY;
// enable timer clocking
RCC->APB1ENR |= 1<<2;
break;
default:
return -1;
}
// clear pending interrupts
tmr->SR &= !1;
// Enable interrupts
tmr->DIER = (1<<0);
NVIC_SetPriority(irqn,irq_priority);
NVIC_EnableIRQ(irqn);
return 0;
}
//------------------------------------------------------------------------------
int timer_wait_ms(TIM_TypeDef* tmr, uint16_t ms, OnTick cb) {
uint32_t clk = 0;
if(!cb) { //blocking
//get clocks config
if (tmr == TIM1) {
clk = sysclks.apb2_timer_freq;
RCC->APB2ENR |= 1<<11;
}
else {
clk = sysclks.apb1_timer_freq;
if (tmr == TIM2) RCC->APB1ENR |= 1<<0;
else if (tmr == TIM3) RCC->APB1ENR |= 1<<1;
else if (tmr == TIM4) RCC->APB1ENR |= 1<<2;
else return -1; // no such timer
}
// set period
tmr->ARR = 0xFFFFFFFF;
} else { //non-blocking
if(timer_config_cb(tmr, &clk, cb)) return -1;
// set period
tmr->ARR = ms-1;
}
// set mode
tmr->CR1 = (1<<7) | (1<<2); //buffering and update settings
tmr->CR1 |= (1<<3); //one pulse mode
// set prescaler 1ms
tmr->PSC = 8*(clk/1000)-1; //PSC = clk/f - 1 | don't know why 8 times..
timer_start(tmr);
if(!cb) {
while(tmr->CNT < ms); //waiting for end of delay
}
return 0;
}
int timer_wait_us(TIM_TypeDef* tmr, uint16_t us, OnTick cb) {
uint32_t clk = 0;
if(!cb) { //blocking
//get clocks config
if (tmr == TIM1) {
clk = sysclks.apb2_timer_freq;
RCC->APB2ENR |= 1<<11;
}
else {
clk = sysclks.apb1_timer_freq;
if (tmr == TIM2) RCC->APB1ENR |= 1<<0;
else if (tmr == TIM3) RCC->APB1ENR |= 1<<1;
else if (tmr == TIM4) RCC->APB1ENR |= 1<<2;
else return -1; // no such timer
}
// set period
tmr->ARR = 0xFFFFFFFF;
} else { //non-blocking
if(timer_config_cb(tmr, &clk, cb)) return -1;
// set period
tmr->ARR = us-1;
}
// set mode
tmr->CR1 = (1<<7) | (1<<2); //buffering and update settings
tmr->CR1 |= (1<<3); //one pulse mode
// set prescaler 1us
tmr->PSC = 8*(clk/1000000)-1; //PSC = clk/f - 1 | don't know why 8 times..
timer_start(tmr);
if(!cb) {
while(tmr->CNT < us); //waiting for end of delay
}
return 0;
}
//------------------------------------------------------------------------------
int timer_tick_init(TIM_TypeDef *tmr, uint16_t tick_ms, OnTick cb) {
IRQn_Type irqn;
uint32_t irq_priority, clk;
switch((uint32_t)tmr) {
case (uint32_t)TIM1:
// get back the clock frequency
clk = sysclks.apb2_timer_freq;
// register callback function
callback1 = cb;
irqn = TIM1_UP_IRQn; //every update
irq_priority = TIM1_IRQ_PRIORITY;
// enable timer clocking
RCC->APB2ENR |= 1<<11;
break;
case (uint32_t)TIM2:
// get back the clock frequency
clk = sysclks.apb1_timer_freq;
// register callback function
callback2 = cb;
irqn = TIM2_IRQn;
irq_priority = TIM2_IRQ_PRIORITY;
// enable timer clocking
RCC->APB1ENR |= 1<<0;
break;
case (uint32_t)TIM3:
// get back the clock frequency
clk = sysclks.apb1_timer_freq;
// register callback function
callback3 = cb;
irqn = TIM3_IRQn;
irq_priority = TIM3_IRQ_PRIORITY;
// enable timer clocking
RCC->APB1ENR |= 1<<1;
break;
case (uint32_t)TIM4:
// get back the clock frequency
clk = sysclks.apb1_timer_freq;
// register callback function
callback4 = cb;
irqn = TIM4_IRQn;
irq_priority = TIM4_IRQ_PRIORITY;
// enable timer clocking
RCC->APB1ENR |= 1<<2;
break;
default:
return -1;
}
// clear pending interrupts
tmr->SR &= !1;
// set mode
tmr->CR1 = (1<<7) | (1<<2); //buffering and update settings
tmr->DIER = (1<<0); //Enable interrupts
// set prescaler 0.5ms
tmr->PSC = 8*(clk/2000)-1; //PSC = clk/f - 1 | don't know why 8 times...
// set period
if(timer_set_period(tmr, tick_ms)) return -1;
if (cb) {
NVIC_SetPriority(irqn,irq_priority);
NVIC_EnableIRQ(irqn); //unmask IRQ
}
return 0;
}
int timer_set_period(TIM_TypeDef *tmr, uint16_t tick) {
// set period
tmr->ARR = tick*2-1; //tickms = (ARR+1)Tpsc
// force update to reset counter and apply prescaler
tmr->EGR |= 1;
return 0;
}
void timer_start(TIM_TypeDef *tmr) {
// force update to reset counter and prescaler
tmr->EGR |= 1;
// enable counting
tmr->CR1 |= 1;
}
void timer_stop(TIM_TypeDef *tmr) {
// disable counting
tmr->CR1 &= !1;
}
//------------------------------------------------------------------------------
int timer_enc_init(TIM_TypeDef* tmr) {
// enable timer
switch((uint32_t)tmr) {
case (uint32_t)TIM1:
RCC->APB2ENR |= 1<<11;
break;
case (uint32_t)TIM2:
RCC->APB1ENR |= 1<<0;
break;
case (uint32_t)TIM3:
RCC->APB1ENR |= 1<<1;
break;
case (uint32_t)TIM4:
RCC->APB1ENR |= 1<<2;
break;
default:
return -1; //no such timer
}
//TODO set registers at reset value
tmr->SMCR |= 0x1; //count on only one edge
tmr->ARR = (1 << 16)-1;
// map inputs
tmr->CCMR1 |= 0x9;
tmr->CCMR1 |= 0x9 << 8;
// enable input channels and invert them //TODO add an otpion for that
tmr->CCER |= 0x3;
tmr->CCER |= 0x3 << 4;
tmr->CR1 |= 0x1; //enable timer
return 0;
}

View File

@ -1,89 +0,0 @@
#ifndef TIMER_H
#define TIMER_H
#include "../target/stm32f103xb.h"
#include "../config.h"
#include "rcc.h"
typedef void (*OnTick)(void);
//------------------------------------------------------------------------------
/** timer_wait_ms
* wait for ms milliseconds function
*/
int timer_wait_ms(TIM_TypeDef *tmr, uint16_t ms, OnTick cb);
/** timer_wait_us
* wait for us microseconds function
*/
int timer_wait_us(TIM_TypeDef *tmr, uint16_t us, OnTick cb);
//------------------------------------------------------------------------------
/** timer_tick_init
* setup timer to call cb function periodically, each tick_ms
*/
int timer_tick_init(TIM_TypeDef *tmr, uint16_t tick_ms, OnTick cb);
/** timer_set_period
* change the period, in ms when called after tick_init,
* otherwise in whatever unit the timer is configured
* reset count when used
*/
int timer_set_period(TIM_TypeDef *tmr, uint16_t tick);
/** timer_start
* reset count and start counting
*/
void timer_start(TIM_TypeDef *tmr);
/** timer_stop
* stop counting
*/
void timer_stop(TIM_TypeDef *tmr);
//------------------------------------------------------------------------------
/** timer_enc_init
* setup timer to read encoder output and keep track of it's position in the
* CNT register whithout using CPU time
*/
int timer_enc_init(TIM_TypeDef* tmr);
//------------------------------------------------------------------------------
//#define PWM_CHANNEL_1 0
//#define PWM_CHANNEL_2 1
//#define PWM_CHANNEL_3 2
//#define PWM_CHANNEL_4 3
//
///** pwm_init
// * setup pwm timer period, each tick_ms
// */
//int pwm_init(TIM_TypeDef *pwm, uint32_t period_ms, OnTick cb);
//
///** pwm_channel_enable
// * set up pwm channel
// */
//int pwm_channel_enable(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle, uint32_t oe);
//
///** pwm_channel_disable
// * disable pwm channel
// */
//int pwm_channel_disable(TIM_TypeDef *pwm, uint32_t channel);
//
///** pwm_channel_set
// * set up dutycycle for pwm channel
// */
//int pwm_channel_set(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle);
//
///** pwm_start
// * start counting
// */
//#define pwm_start(pwm) timer_start(pwm)
//
///** pwm_stop
// * stop and reset counting
// */
//#define pwm_stop(pwm) timer_stop(pwm)
#endif

View File

@ -1,238 +0,0 @@
/**
******************************************************************************
* @file stm32f1xx.h
* @author MCD Application Team
* @version V4.2.0
* @date 31-March-2017
* @brief CMSIS STM32F1xx Device Peripheral Access Layer Header File.
*
* The file is the unique include file that the application programmer
* is using in the C source code, usually in main.c. This file contains:
* - Configuration section that allows to select:
* - The STM32F1xx device used in the target application
* - To use or not the peripherals drivers in application code(i.e.
* code will be based on direct access to peripherals registers
* rather than drivers API), this option is controlled by
* "#define USE_HAL_DRIVER"
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f1xx
* @{
*/
#ifndef __STM32F1XX_H
#define __STM32F1XX_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** @addtogroup Library_configuration_section
* @{
*/
/**
* @brief STM32 Family
*/
#if !defined (STM32F1)
#define STM32F1
#endif /* STM32F1 */
/* Uncomment the line below according to the target STM32L device used in your
application
*/
#if !defined (STM32F100xB) && !defined (STM32F100xE) && !defined (STM32F101x6) && \
!defined (STM32F101xB) && !defined (STM32F101xE) && !defined (STM32F101xG) && !defined (STM32F102x6) && !defined (STM32F102xB) && !defined (STM32F103x6) && \
!defined (STM32F103xB) && !defined (STM32F103xE) && !defined (STM32F103xG) && !defined (STM32F105xC) && !defined (STM32F107xC)
/* #define STM32F100xB */ /*!< STM32F100C4, STM32F100R4, STM32F100C6, STM32F100R6, STM32F100C8, STM32F100R8, STM32F100V8, STM32F100CB, STM32F100RB and STM32F100VB */
/* #define STM32F100xE */ /*!< STM32F100RC, STM32F100VC, STM32F100ZC, STM32F100RD, STM32F100VD, STM32F100ZD, STM32F100RE, STM32F100VE and STM32F100ZE */
/* #define STM32F101x6 */ /*!< STM32F101C4, STM32F101R4, STM32F101T4, STM32F101C6, STM32F101R6 and STM32F101T6 Devices */
/* #define STM32F101xB */ /*!< STM32F101C8, STM32F101R8, STM32F101T8, STM32F101V8, STM32F101CB, STM32F101RB, STM32F101TB and STM32F101VB */
/* #define STM32F101xE */ /*!< STM32F101RC, STM32F101VC, STM32F101ZC, STM32F101RD, STM32F101VD, STM32F101ZD, STM32F101RE, STM32F101VE and STM32F101ZE */
/* #define STM32F101xG */ /*!< STM32F101RF, STM32F101VF, STM32F101ZF, STM32F101RG, STM32F101VG and STM32F101ZG */
/* #define STM32F102x6 */ /*!< STM32F102C4, STM32F102R4, STM32F102C6 and STM32F102R6 */
/* #define STM32F102xB */ /*!< STM32F102C8, STM32F102R8, STM32F102CB and STM32F102RB */
/* #define STM32F103x6 */ /*!< STM32F103C4, STM32F103R4, STM32F103T4, STM32F103C6, STM32F103R6 and STM32F103T6 */
#define STM32F103xB /*!< STM32F103C8, STM32F103R8, STM32F103T8, STM32F103V8, STM32F103CB, STM32F103RB, STM32F103TB and STM32F103VB */
/* #define STM32F103xE */ /*!< STM32F103RC, STM32F103VC, STM32F103ZC, STM32F103RD, STM32F103VD, STM32F103ZD, STM32F103RE, STM32F103VE and STM32F103ZE */
/* #define STM32F103xG */ /*!< STM32F103RF, STM32F103VF, STM32F103ZF, STM32F103RG, STM32F103VG and STM32F103ZG */
/* #define STM32F105xC */ /*!< STM32F105R8, STM32F105V8, STM32F105RB, STM32F105VB, STM32F105RC and STM32F105VC */
/* #define STM32F107xC */ /*!< STM32F107RB, STM32F107VB, STM32F107RC and STM32F107VC */
#endif
/* Tip: To avoid modifying this file each time you need to switch between these
devices, you can define the device in your toolchain compiler preprocessor.
*/
#if !defined (USE_HAL_DRIVER)
/**
* @brief Comment the line below if you will not use the peripherals drivers.
In this case, these drivers will not be included and the application code will
be based on direct access to peripherals registers
*/
//#define USE_HAL_DRIVER
#endif /* USE_HAL_DRIVER */
/**
* @brief CMSIS Device version number V4.2.0
*/
#define __STM32F1_CMSIS_VERSION_MAIN (0x04) /*!< [31:24] main version */
#define __STM32F1_CMSIS_VERSION_SUB1 (0x02) /*!< [23:16] sub1 version */
#define __STM32F1_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
#define __STM32F1_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */
#define __STM32F1_CMSIS_VERSION ((__STM32F1_CMSIS_VERSION_MAIN << 24)\
|(__STM32F1_CMSIS_VERSION_SUB1 << 16)\
|(__STM32F1_CMSIS_VERSION_SUB2 << 8 )\
|(__STM32F1_CMSIS_VERSION_RC))
/**
* @}
*/
/** @addtogroup Device_Included
* @{
*/
#if defined(STM32F100xB)
#include "stm32f100xb.h"
#elif defined(STM32F100xE)
#include "stm32f100xe.h"
#elif defined(STM32F101x6)
#include "stm32f101x6.h"
#elif defined(STM32F101xB)
#include "stm32f101xb.h"
#elif defined(STM32F101xE)
#include "stm32f101xe.h"
#elif defined(STM32F101xG)
#include "stm32f101xg.h"
#elif defined(STM32F102x6)
#include "stm32f102x6.h"
#elif defined(STM32F102xB)
#include "stm32f102xb.h"
#elif defined(STM32F103x6)
#include "stm32f103x6.h"
#elif defined(STM32F103xB)
#include "stm32f103xb.h"
#elif defined(STM32F103xE)
#include "stm32f103xe.h"
#elif defined(STM32F103xG)
#include "stm32f103xg.h"
#elif defined(STM32F105xC)
#include "stm32f105xc.h"
#elif defined(STM32F107xC)
#include "stm32f107xc.h"
#else
#error "Please select first the target STM32F1xx device used in your application (in stm32f1xx.h file)"
#endif
/**
* @}
*/
/** @addtogroup Exported_types
* @{
*/
typedef enum
{
RESET = 0,
SET = !RESET
} FlagStatus, ITStatus;
typedef enum
{
DISABLE = 0,
ENABLE = !DISABLE
} FunctionalState;
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
typedef enum
{
ERROR = 0,
SUCCESS = !ERROR
} ErrorStatus;
/**
* @}
*/
/** @addtogroup Exported_macros
* @{
*/
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
#define READ_BIT(REG, BIT) ((REG) & (BIT))
#define CLEAR_REG(REG) ((REG) = (0x0))
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
#define READ_REG(REG) ((REG))
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
/**
* @}
*/
#if defined (USE_HAL_DRIVER)
#include "stm32f1xx_hal.h"
#endif /* USE_HAL_DRIVER */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __STM32F1xx_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -1,109 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2017 ARM Limited
*
* 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.
*/
/**
* This file configures the system clock as follows:
*-----------------------------------------------------------------------------
* System clock source | 1- PLL_HSE_EXTC | 3- PLL_HSI
* | (external 8 MHz clock) | (internal 8 MHz)
* | 2- PLL_HSE_XTAL |
* | (external 8 MHz xtal) |
*-----------------------------------------------------------------------------
* SYSCLK(MHz) | 72 | 64
*-----------------------------------------------------------------------------
* AHBCLK (MHz) | 72 | 64
*-----------------------------------------------------------------------------
* APB1CLK (MHz) | 36 | 32
*-----------------------------------------------------------------------------
* APB2CLK (MHz) | 72 | 64
*-----------------------------------------------------------------------------
* USB capable (48 MHz precise clock) | NO | NO
*-----------------------------------------------------------------------------
******************************************************************************
*/
#include "stm32f1xx.h"
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemCoreClock variable.
* @note This function should be used only after reset.
* @param None
* @retval None
*/
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= 0x00000001U;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#if !defined(STM32F105xC) && !defined(STM32F107xC)
RCC->CFGR &= 0xF8FF0000U;
#else
RCC->CFGR &= 0xF0FF0000U;
#endif /* STM32F105xC */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= 0xFEF6FFFFU;
/* Reset HSEBYP bit */
RCC->CR &= 0xFFFBFFFFU;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= 0xFF80FFFFU;
#if defined(STM32F105xC) || defined(STM32F107xC)
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= 0xEBFFFFFFU;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000U;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000U;
#elif defined(STM32F100xB) || defined(STM32F100xE)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000U;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000U;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000U;
#endif /* STM32F105xC */
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}

View File

@ -1,118 +0,0 @@
/**
******************************************************************************
* @file system_stm32f10x.h
* @author MCD Application Team
* @version V4.2.0
* @date 31-March-2017
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f10x_system
* @{
*/
/**
* @brief Define to prevent recursive inclusion
*/
#ifndef __SYSTEM_STM32F10X_H
#define __SYSTEM_STM32F10X_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup STM32F10x_System_Includes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F10x_System_Exported_types
* @{
*/
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */
extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */
/**
* @}
*/
/** @addtogroup STM32F10x_System_Exported_Constants
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F10x_System_Exported_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F10x_System_Exported_Functions
* @{
*/
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
extern void SetSysClock(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /*__SYSTEM_STM32F10X_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

548
startup.s
View File

@ -1,371 +1,309 @@
/**
*************** (C) COPYRIGHT 2016 STMicroelectronics ************************
* @file startup_stm32f103xb.s
* @author MCD Application Team
* @version V4.1.0
* @date 29-April-2016
* @brief STM32F103xB Devices vector table for Atollic toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Configure the clock system
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M3 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
*
* <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/** @file
* Startup script to be used with the HBL
*
* This startup file provides a reset handler to setup the basics for c to run
* (stack pointer, static data, ...) as well as the vector table and the
* differents interrupt handlers that go with it. By default, all handlers use
* the default handler wich is simply and infinite loop
*/
.syntax unified
.cpu cortex-m3
.fpu softvfp
.thumb
.syntax unified
.cpu cortex-m3
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sromdata
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
.equ BootRAM, 0xF108F85F
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr r0, =_estack
mov sp, r0 /* set stack pointer */
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
/* Call the clock system intitialization function.*/
// bl SystemInit
/* Call static constructors */
//bl __libc_init_array
/* Call the application's entry point.*/
bl main
//bl _start
LoopForever:
b LoopForever
.size Reset_Handler, .-Reset_Handler
//--Handler definitions---------------------------------------------------------
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
* Reset handler, first thing executed at boot
* The handler configures the stack pointer and loads data from ROM to RAM
*/
.section .text.hdr_reset
.weak hdr_reset
.type hdr_reset, %function
hdr_reset:
ldr r0, = _estack
mov sp, r0
//load data from ROM to RAM
ldr r1, = _sdata
ldr r2, = _edata
subs r2, r2, r1
bcc startup_init_end
ldr r3, = _sromdata
movs r0, #0
startup_init_loop:
ldr r4, [r3, r0]
str r4, [r1, r0]
adds r0, r0, #4
cmp r0, r2
bcc startup_init_loop
startup_init_end:
b main
b hdr_reset
.size hdr_reset, .-hdr_reset
/**
* Default handler, called on reception of an unexpected interrupt
* This is the handler used by default for all interrupts unless a specific
* handler was defined elsewhere
*/
.section .text.hdr_default, "ax", %progbits
.weak hdr_default
hdr_default:
b hdr_default
.size hdr_default, .-hdr_default
g_pfnVectors:
//--Vector table----------------------------------------------------------------
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler
.word PVD_IRQHandler
.word TAMPER_IRQHandler
.word RTC_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
.word EXTI2_IRQHandler
.word EXTI3_IRQHandler
.word EXTI4_IRQHandler
.word DMA1_Channel1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word DMA1_Channel5_IRQHandler
.word DMA1_Channel6_IRQHandler
.word DMA1_Channel7_IRQHandler
.word ADC1_2_IRQHandler
.word USB_HP_CAN1_TX_IRQHandler
.word USB_LP_CAN1_RX0_IRQHandler
.word CAN1_RX1_IRQHandler
.word CAN1_SCE_IRQHandler
.word EXTI9_5_IRQHandler
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word I2C2_EV_IRQHandler
.word I2C2_ER_IRQHandler
.word SPI1_IRQHandler
.word SPI2_IRQHandler
.word USART1_IRQHandler
.word USART2_IRQHandler
.word USART3_IRQHandler
.word EXTI15_10_IRQHandler
.word RTC_Alarm_IRQHandler
.word USBWakeUp_IRQHandler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word BootRAM /* @0x108. This is for boot in RAM mode for
STM32F10x Medium Density devices. */
.section .vector_table, "a", %progbits
.type vector_table, %object
.size vector_table, .-vector_table
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
vector_table:
.word _estack
.word hdr_reset
.word hdr_nmi
.word hdr_hard_fault
.word hdr_mem_manage
.word hdr_bus_fault
.word hdr_usage_fault
.word 0
.word 0
.word 0
.word 0
.word hdr_svc
.word hdr_debug_monitor
.word 0
.word hdr_pend_sys_service
.word hdr_sys_tick
.word hdr_wwdg
.word hdr_pvd
.word hdr_tamper
.word hdr_rtc
.word hdr_flash
.word hdr_rcc
.word hdr_exti0
.word hdr_exti1
.word hdr_exti2
.word hdr_exti3
.word hdr_exti4
.word hdr_dma_channel1
.word hdr_dma_channel2
.word hdr_dma_channel3
.word hdr_dma_channel4
.word hdr_dma_channel5
.word hdr_dma_channel6
.word hdr_dma_channel7
.word hdr_adc1_2
.word hdr_hp_can_tx
.word hdr_lp_can_rx0
.word hdr_can_rx1
.word hdr_can_sce
.word hdr_exti9_5
.word hdr_tim1_brk
.word hdr_tim1_up
.word hdr_tim1_trg_com
.word hdr_tim1_cc
.word hdr_tim2
.word hdr_tim3
.word hdr_tim4
.word hdr_i2c1_event
.word hdr_i2c1_error
.word hdr_i2c2_event
.word hdr_i2c2_error
.word hdr_spi1
.word hdr_spi2
.word hdr_usart1
.word hdr_usart2
.word hdr_usart3
.word hdr_exti15_10
.word hdr_rtc_alarm
.word hdr_usb_wakeup
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
//--Weak definitions------------------------------------------------------------
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak hdr_nmi
.thumb_set hdr_nmi, hdr_default
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak hdr_hard_fault
.thumb_set hdr_hard_fault, hdr_default
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak hdr_mem_manage
.thumb_set hdr_mem_manage, hdr_default
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak hdr_bus_fault
.thumb_set hdr_bus_fault, hdr_default
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak hdr_usage_fault
.thumb_set hdr_usage_fault, hdr_default
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak hdr_svc
.thumb_set hdr_svc, hdr_default
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak hdr_debug_monitor
.thumb_set hdr_debug_monitor, hdr_default
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak hdr_pend_sys_service
.thumb_set hdr_pend_sys_service, hdr_default
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak hdr_sys_tick
.thumb_set hdr_sys_tick, hdr_default
.weak PVD_IRQHandler
.thumb_set PVD_IRQHandler,Default_Handler
.weak hdr_wwdg
.thumb_set hdr_wwdg, hdr_default
.weak TAMPER_IRQHandler
.thumb_set TAMPER_IRQHandler,Default_Handler
.weak hdr_pvd
.thumb_set hdr_pvd, hdr_default
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Default_Handler
.weak hdr_tamper
.thumb_set hdr_tamper, hdr_default
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak hdr_rtc
.thumb_set hdr_rtc, hdr_default
.weak RCC_IRQHandler
.thumb_set RCC_IRQHandler,Default_Handler
.weak hdr_flash
.thumb_set hdr_flash, hdr_default
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak hdr_rcc
.thumb_set hdr_rcc, hdr_default
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak hdr_exti0
.thumb_set hdr_exti0, hdr_default
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak hdr_exti1
.thumb_set hdr_exti1, hdr_default
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak hdr_exti2
.thumb_set hdr_exti2, hdr_default
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak hdr_exti3
.thumb_set hdr_exti3, hdr_default
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak hdr_exti4
.thumb_set hdr_exti4, hdr_default
.weak DMA1_Channel2_IRQHandler
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
.weak hdr_dma_channel1
.thumb_set hdr_dma_channel1, hdr_default
.weak DMA1_Channel3_IRQHandler
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
.weak hdr_dma_channel2
.thumb_set hdr_dma_channel2, hdr_default
.weak DMA1_Channel4_IRQHandler
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
.weak hdr_dma_channel3
.thumb_set hdr_dma_channel3, hdr_default
.weak DMA1_Channel5_IRQHandler
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
.weak hdr_dma_channel4
.thumb_set hdr_dma_channel4, hdr_default
.weak DMA1_Channel6_IRQHandler
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
.weak hdr_dma_channel5
.thumb_set hdr_dma_channel5, hdr_default
.weak DMA1_Channel7_IRQHandler
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
.weak hdr_dma_channel6
.thumb_set hdr_dma_channel6, hdr_default
.weak ADC1_2_IRQHandler
.thumb_set ADC1_2_IRQHandler,Default_Handler
.weak hdr_dma_channel7
.thumb_set hdr_dma_channel7, hdr_default
.weak USB_HP_CAN1_TX_IRQHandler
.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
.weak hdr_adc1_2
.thumb_set hdr_adc1_2, hdr_default
.weak USB_LP_CAN1_RX0_IRQHandler
.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
.weak hdr_hp_can_tx
.thumb_set hdr_hp_can_tx, hdr_default
.weak CAN1_RX1_IRQHandler
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
.weak hdr_lp_can_rx0
.thumb_set hdr_lp_can_rx0, hdr_default
.weak CAN1_SCE_IRQHandler
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
.weak hdr_can_rx1
.thumb_set hdr_can_rx1, hdr_default
.weak EXTI9_5_IRQHandler
.thumb_set EXTI9_5_IRQHandler,Default_Handler
.weak hdr_can_sce
.thumb_set hdr_can_sce, hdr_default
.weak TIM1_BRK_IRQHandler
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
.weak hdr_exti9_5
.thumb_set hdr_exti9_5, hdr_default
.weak TIM1_UP_IRQHandler
.thumb_set TIM1_UP_IRQHandler,Default_Handler
.weak hdr_tim1_brk
.thumb_set hdr_tim1_brk, hdr_default
.weak TIM1_TRG_COM_IRQHandler
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
.weak hdr_tim1_up
.thumb_set hdr_tim1_up, hdr_default
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak hdr_tim1_trg_com
.thumb_set hdr_tim1_trg_com, hdr_default
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak hdr_tim1_cc
.thumb_set hdr_tim1_cc, hdr_default
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak hdr_tim2
.thumb_set hdr_tim2, hdr_default
.weak TIM4_IRQHandler
.thumb_set TIM4_IRQHandler,Default_Handler
.weak hdr_tim3
.thumb_set hdr_tim3, hdr_default
.weak I2C1_EV_IRQHandler
.thumb_set I2C1_EV_IRQHandler,Default_Handler
.weak hdr_tim4
.thumb_set hdr_tim4, hdr_default
.weak I2C1_ER_IRQHandler
.thumb_set I2C1_ER_IRQHandler,Default_Handler
.weak hdr_i2c1_event
.thumb_set hdr_i2c1_event, hdr_default
.weak I2C2_EV_IRQHandler
.thumb_set I2C2_EV_IRQHandler,Default_Handler
.weak hdr_i2c1_error
.thumb_set hdr_i2c1_error, hdr_default
.weak I2C2_ER_IRQHandler
.thumb_set I2C2_ER_IRQHandler,Default_Handler
.weak hdr_i2c2_event
.thumb_set hdr_i2c2_event, hdr_default
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak hdr_i2c2_error
.thumb_set hdr_i2c2_error, hdr_default
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak hdr_spi1
.thumb_set hdr_spi1, hdr_default
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak hdr_spi2
.thumb_set hdr_spi2, hdr_default
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak hdr_usart1
.thumb_set hdr_usart1, hdr_default
.weak USART3_IRQHandler
.thumb_set USART3_IRQHandler,Default_Handler
.weak hdr_usart2
.thumb_set hdr_usart2, hdr_default
.weak EXTI15_10_IRQHandler
.thumb_set EXTI15_10_IRQHandler,Default_Handler
.weak hdr_usart3
.thumb_set hdr_usart3, hdr_default
.weak RTC_Alarm_IRQHandler
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
.weak hdr_exti15_10
.thumb_set hdr_exti15_10, hdr_default
.weak USBWakeUp_IRQHandler
.thumb_set USBWakeUp_IRQHandler,Default_Handler
.weak hdr_rtc_alarm
.thumb_set hdr_rtc_alarm, hdr_default
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
.weak hdr_usb_wakeup
.thumb_set hdr_usb_wakeup, hdr_default