diff --git a/src/config.h b/src/config.h index e8b1fd9..6026b34 100644 --- a/src/config.h +++ b/src/config.h @@ -9,28 +9,24 @@ #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 USART6_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 I2C3_IRQ_PRIORITY 2 -#define I2C3_IRQERR_PRIORITY 1 #define SPI1_IRQ_PRIORITY 4 #define SPI2_IRQ_PRIORITY 4 -#define SPI3_IRQ_PRIORITY 4 -#define SPI4_IRQ_PRIORITY 4 -#define SPI5_IRQ_PRIORITY 4 -#define ADC1_IRQ_PRIORITY 5 +#define ADC1_2_IRQ_PRIORITY 5 /**************************************************************************** * USART Pin and use configuration diff --git a/src/drivers/io.c b/src/drivers/io.c index 64eaf5f..fb9de25 100644 --- a/src/drivers/io.c +++ b/src/drivers/io.c @@ -95,7 +95,7 @@ void EXTI15_10_IRQHandler() { #define SYSCFG_EXTI_PH_MASK 7 -int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint32_t pin_cfg, OnIO cb) { +int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint8_t pin_cfg, OnIO cb) { // enable GPIOx subsystem clocking if (gpio == GPIOA) RCC->APB2ENR |= 1<<2; @@ -104,128 +104,128 @@ int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint32_t pin_cfg, OnIO cb) { else if (gpio == GPIOD) RCC->APB2ENR |= 1<<5; else if (gpio == GPIOE) RCC->APB2ENR |= 1<<6; - // ssetup the config bits - uint32_t crx = 0; - uint16_t odr = 0; - for(int i=0; i<8; i++) { - if(pin & (1 << i)) { - crx |= (pin_cfg & 0xF) << (4*i); - odr |= (pin_cfg & 0xF0) << i; + // 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; } } - gpio->CRL |= crx; - crx = 0; - for(int i=8; i<16; i++) { - if(pin & (1 << i)) { - crx |= (pin_cfg & 0xF) << (4*(i-8)); - odr |= (pin_cfg & 0xF0) << i; - } - } - gpio->CRH |= crx; - gpio->ODR |= odr; + // clear previous data + uint64_t crx = pin_mask * 0x4; //reset value is 0x4 + uint16_t odr = pin; + gpio->CRH &= ~(crx >> 32); + gpio->CRL &= ~(crx & 0xFFFF); + gpio->BSRR |= odr << 16; - /* - if (!cb) return -1; //no callback attached + // set up the new configuration + crx = pin_mask * (pin_cfg & 0xF); + odr = pin_cfg & 0x10; + gpio->CRH |= crx >> 32; + gpio->CRL |= crx & 0xFFFF; + gpio->BSRR |= odr; + + //if (!cb) return -1; //no callback attached + + return 0; //TODO manage alternate functions - if (pin_cfg & 0x3) return -1; //callback set, but not in input mode - - // ************* Input GPIO + External IRQ ************* - - uint32_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; - - uint32_t bit_mask = 0x1; - - for (int i=0; i<16; i++) { - if (pin_mask & bit_mask) { - // enable clock for SYSCFG, no need for EXTI (interface not clocked) - RCC->APB2ENR = RCC->APB2ENR | (1<<14); - - // configure pin Px_i (4 pin config per EXTICR[] register, 4 bits per pin) - // use port Px and bind Px_i --> EXTIi - // i>>2 = i/4 ; i & 0x3 = i%4 - gpio->EXTICR[i>>2] = (SYSCFG->EXTICR[i>>2] & - ~(0x0000000F << ((i & 3)<<2))) | - (port_mask << ((i & 3)<<2)); - - // allow pin EXTIi to send an IRQ - EXTI->IMR = EXTI->IMR | bit_mask; - // not a wakeup event - EXTI->EMR = EXTI->EMR & (~bit_mask); - - // Configure pin event IRQ on rising (RTSR)/falling (FTSR) edge (rising only here) - if (pin_cfg & PIN_OPT_IRQ_EDGE_RISE) { - EXTI->RTSR = EXTI->RTSR | bit_mask; - } else { - EXTI->RTSR = EXTI->RTSR & (~bit_mask); - } - - if (pin_cfg & PIN_OPT_IRQ_EDGE_FALL) { - EXTI->FTSR = EXTI->FTSR | bit_mask; - } else { - EXTI->FTSR = EXTI->FTSR & (~bit_mask); - } - - io_cb[i] = cb; - - // reset any pending IRQ on PC13 - EXTI->PR = bit_mask; - - // 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 0; -} -} -bit_mask = bit_mask<<1; -} -*/ -return 0; +// if (pin_cfg & 0x3) return -1; //callback set, but not in input mode +// +// // ************* Input GPIO + External IRQ ************* +// +// uint32_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; +// +// uint32_t bit_mask = 0x1; +// +// for (int i=0; i<16; i++) { +// if (pin_mask & bit_mask) { +// // enable clock for SYSCFG, no need for EXTI (interface not clocked) +// RCC->APB2ENR = RCC->APB2ENR | (1<<14); +// +// // configure pin Px_i (4 pin config per EXTICR[] register, 4 bits per pin) +// // use port Px and bind Px_i --> EXTIi +// // i>>2 = i/4 ; i & 0x3 = i%4 +// gpio->EXTICR[i>>2] = (SYSCFG->EXTICR[i>>2] & +// ~(0x0000000F << ((i & 3)<<2))) | +// (port_mask << ((i & 3)<<2)); +// +// // allow pin EXTIi to send an IRQ +// EXTI->IMR = EXTI->IMR | bit_mask; +// // not a wakeup event +// EXTI->EMR = EXTI->EMR & (~bit_mask); +// +// // Configure pin event IRQ on rising (RTSR)/falling (FTSR) edge (rising only here) +// if (pin_cfg & PIN_OPT_IRQ_EDGE_RISE) { +// EXTI->RTSR = EXTI->RTSR | bit_mask; +// } else { +// EXTI->RTSR = EXTI->RTSR & (~bit_mask); +// } +// +// if (pin_cfg & PIN_OPT_IRQ_EDGE_FALL) { +// EXTI->FTSR = EXTI->FTSR | bit_mask; +// } else { +// EXTI->FTSR = EXTI->FTSR & (~bit_mask); +// } +// +// io_cb[i] = cb; +// +// // reset any pending IRQ on PC13 +// EXTI->PR = bit_mask; +// +// // 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 0; +//} +//} +//bit_mask = bit_mask<<1; +//} } diff --git a/src/drivers/io.h b/src/drivers/io.h index 533cff7..8b2cede 100644 --- a/src/drivers/io.h +++ b/src/drivers/io.h @@ -5,76 +5,80 @@ extern "C" { #endif -/* --- GPIO pin mask definitions ---------------------------------------- */ -#define PIN_0 (1 << 0) -#define PIN_1 (1 << 1) -#define PIN_2 (1 << 2) -#define PIN_3 (1 << 3) -#define PIN_4 (1 << 4) -#define PIN_5 (1 << 5) -#define PIN_6 (1 << 6) -#define PIN_7 (1 << 7) -#define PIN_8 (1 << 8) -#define PIN_9 (1 << 9) -#define PIN_10 (1 << 10) -#define PIN_11 (1 << 11) -#define PIN_12 (1 << 12) -#define PIN_13 (1 << 13) -#define PIN_14 (1 << 14) -#define PIN_15 (1 << 15) -#define PIN_ALL 0xFFFF +//------------------------------------------------------------------------------ +/* 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 ---------------------------------------- */ -#define PIN_MODE_INPUT (0) -#define PIN_MODE_OUTPUT (1 << 0) -#define PIN_MODE_ALTFUNC (1 << 3 | 1 << 0) -#define PIN_MODE_ANALOG (0) +//------------------------------------------------------------------------------ +/* 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 option definitions -------------------------------------- */ -/* none for analog pin */ -#define PIN_OPT_NONE (0) +//------------------------------------------------------------------------------ +/* 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) +}; -/* pull up/pull down resistor option */ -#define PIN_OPT_RESISTOR_NONE (1 << 2) -#define PIN_OPT_RESISTOR_PULLUP (1 << 4 | 1 << 3) -#define PIN_OPT_RESISTOR_PULLDOWN (1 << 3) +//------------------------------------------------------------------------------ +/* GPIO pin clear */ +#define IO_CLEAR (0) -/* push-pull/open drain output option */ -#define PIN_OPT_OUTPUT_PUSHPULL (0) -#define PIN_OPT_OUTPUT_OPENDRAIN (1 << 2) - -/* output speed option - * - LOW ~ 2MHz max - * - MEDIUM ~ 10MHz max - * - FAST ~ 50MHz max - **/ -#define PIN_OPT_OUTPUT_SPEED_LOW (10 << 0) -#define PIN_OPT_OUTPUT_SPEED_MEDIUM (1 << 0) -#define PIN_OPT_OUTPUT_SPEED_FAST (11 << 0) - -/* alternate function selection option */ -#define PIN_OPT_AF0 0x0 -#define PIN_OPT_AF1 0x1 -#define PIN_OPT_AF2 0x2 -#define PIN_OPT_AF3 0x3 -#define PIN_OPT_AF4 0x4 -#define PIN_OPT_AF5 0x5 -#define PIN_OPT_AF6 0x6 -#define PIN_OPT_AF7 0x7 -#define PIN_OPT_AF8 0x8 -#define PIN_OPT_AF9 0x9 -#define PIN_OPT_AF10 0xA -#define PIN_OPT_AF11 0xB -#define PIN_OPT_AF12 0xC -#define PIN_OPT_AF13 0xD -#define PIN_OPT_AF14 0xE -#define PIN_OPT_AF15 0xF - -/* irq pin option */ -#define PIN_OPT_IRQ_EDGE_RISE (1 << 12) -#define PIN_OPT_IRQ_EDGE_FALL (2 << 12) -#define PIN_OPT_IRQ_EDGE_BOTH (3 << 12) +//------------------------------------------------------------------------------ +/* 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 +//}; +///* irq pin option */ +//#define PIN_OPT_IRQ_EDGE_RISE (1 << 12) +//#define PIN_OPT_IRQ_EDGE_FALL (2 << 12) +//#define PIN_OPT_IRQ_EDGE_BOTH (3 << 12) +// typedef void (*OnIO)(); /* io_configure @@ -84,7 +88,7 @@ typedef void (*OnIO)(); * function 'cb' if not NULL. * returns 0 if success */ -int io_configure(GPIO_TypeDef *gpio, uint16_t pin_mask, uint32_t pin_cfg, OnIO cb); +int io_configure(GPIO_TypeDef *gpio, uint16_t pin_mask, uint8_t pin_cfg, OnIO cb); /* io_read * diff --git a/src/drivers/rcc.c b/src/drivers/rcc.c index cfa9a04..d2a6d12 100644 --- a/src/drivers/rcc.c +++ b/src/drivers/rcc.c @@ -1,5 +1,5 @@ -/** - ============================================================================== +/* +============================================================================== ##### RCC specific features ##### ============================================================================== [..] @@ -176,11 +176,6 @@ static void rcc_set_sysclk(enum rcc_osc osc) while (((RCC->CFGR & 0xC)>>2) != osc); } -//void SystemInit(void) { -// Clock_t tmp_clk; -// rcc_config_clock(CLOCK_CONFIG_PERFORMANCE, &tmp_clk); -//} - void rcc_config_clock(uint32_t config, Clock_t *sysclks) { struct ClockConfig_t *clk; @@ -245,8 +240,8 @@ void rcc_config_clock(uint32_t config, Clock_t *sysclks) } sysclks->ahb_freq = clk->ahb_freq; sysclks->apb1_freq = clk->apb1_freq; + sysclks->apb2_freq = clk->apb2_freq; //TODO check timer frequencies sysclks->apb1_timer_freq = clk->ppre1==RCC_CFGR_PPRE_DIV_NONE ? clk->apb1_freq : 2*clk->apb1_freq; - sysclks->apb2_freq = clk->apb2_freq; sysclks->apb2_timer_freq = clk->ppre2==RCC_CFGR_PPRE_DIV_NONE ? clk->apb2_freq : 2*clk->apb2_freq; } diff --git a/src/drivers/tags b/src/drivers/tags new file mode 100644 index 0000000..eb79519 --- /dev/null +++ b/src/drivers/tags @@ -0,0 +1,127 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/ +!_TAG_PROGRAM_AUTHOR Universal Ctags Team // +!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ +!_TAG_PROGRAM_URL https://ctags.io/ /official site/ +!_TAG_PROGRAM_VERSION 0.0.0 /3fdf28bc/ +CLOCK_CONFIG_END rcc.h /^ CLOCK_CONFIG_END$/;" e enum:Clock_config +CLOCK_CONFIG_PERFORMANCE rcc.h /^ CLOCK_CONFIG_PERFORMANCE,$/;" e enum:Clock_config +CLOCK_CONFIG_POWERSAVE rcc.h /^ CLOCK_CONFIG_POWERSAVE,$/;" e enum:Clock_config +ClockConfig_t rcc.c /^struct ClockConfig_t {$/;" s file: +Clock_config rcc.h /^enum Clock_config {$/;" g +Clock_t rcc.h /^} Clock_t;$/;" t typeref:struct:_Clock_t +EXTI0_IRQHandler io.c /^void EXTI0_IRQHandler() {$/;" f typeref:typename:void +EXTI15_10_IRQHandler io.c /^void EXTI15_10_IRQHandler() {$/;" f typeref:typename:void +EXTI1_IRQHandler io.c /^void EXTI1_IRQHandler() {$/;" f typeref:typename:void +EXTI2_IRQHandler io.c /^void EXTI2_IRQHandler() {$/;" f typeref:typename:void +EXTI3_IRQHandler io.c /^void EXTI3_IRQHandler() {$/;" f typeref:typename:void +EXTI4_IRQHandler io.c /^void EXTI4_IRQHandler() {$/;" f typeref:typename:void +EXTI9_5_IRQHandler io.c /^void EXTI9_5_IRQHandler() {$/;" f typeref:typename:void +IO_CLEAR io.h /^#define IO_CLEAR /;" d +IO_IN_ANALOG io.h /^ IO_IN_ANALOG = (0b0 << 2),$/;" e enum:io_conf +IO_IN_FLOATING io.h /^ IO_IN_FLOATING = (0b1 << 2),$/;" e enum:io_conf +IO_IN_PULL_DOWN io.h /^ IO_IN_PULL_DOWN = (0b010 << 2),$/;" e enum:io_conf +IO_IN_PULL_UP io.h /^ IO_IN_PULL_UP = (0b110 << 2),$/;" e enum:io_conf +IO_MODE_INPUT io.h /^ IO_MODE_INPUT = (0x0),$/;" e enum:io_mode +IO_MODE_OUTPUT_FAST io.h /^ IO_MODE_OUTPUT_FAST = (0x4) \/\/ 50 MHz max$/;" e enum:io_mode +IO_MODE_OUTPUT_SLOW io.h /^ IO_MODE_OUTPUT_SLOW = (0x3), \/\/ 2MHz max$/;" e enum:io_mode +IO_MODE_OUTPUT io.h /^ IO_MODE_OUTPUT = (0x1), \/\/ 10Mhz max$/;" e enum:io_mode +IO_OUT_ALT_FNCT io.h /^ IO_OUT_ALT_FNCT = (0b10 << 2),$/;" e enum:io_conf +IO_OUT_OPEN_DRAIN io.h /^ IO_OUT_OPEN_DRAIN = (0b1 << 2)$/;" e enum:io_conf +IO_OUT_PUSH_PULL io.h /^ IO_OUT_PUSH_PULL = (0b0 << 2),$/;" e enum:io_conf +OnIO io.h /^typedef void (*OnIO)();$/;" t typeref:typename:void (*)() +OnTick timer.h /^typedef void (*OnTick)(void);$/;" t typeref:typename:void (*)(void) +PIN_0 io.h /^ PIN_0 = (1 << 0),$/;" e enum:io_pin +PIN_10 io.h /^ PIN_10 = (1 << 10),$/;" e enum:io_pin +PIN_11 io.h /^ PIN_11 = (1 << 11),$/;" e enum:io_pin +PIN_12 io.h /^ PIN_12 = (1 << 12),$/;" e enum:io_pin +PIN_13 io.h /^ PIN_13 = (1 << 13),$/;" e enum:io_pin +PIN_14 io.h /^ PIN_14 = (1 << 14),$/;" e enum:io_pin +PIN_15 io.h /^ PIN_15 = (1 << 15),$/;" e enum:io_pin +PIN_1 io.h /^ PIN_1 = (1 << 1),$/;" e enum:io_pin +PIN_2 io.h /^ PIN_2 = (1 << 2),$/;" e enum:io_pin +PIN_3 io.h /^ PIN_3 = (1 << 3),$/;" e enum:io_pin +PIN_4 io.h /^ PIN_4 = (1 << 4),$/;" e enum:io_pin +PIN_5 io.h /^ PIN_5 = (1 << 5),$/;" e enum:io_pin +PIN_6 io.h /^ PIN_6 = (1 << 6),$/;" e enum:io_pin +PIN_7 io.h /^ PIN_7 = (1 << 7),$/;" e enum:io_pin +PIN_8 io.h /^ PIN_8 = (1 << 8),$/;" e enum:io_pin +PIN_9 io.h /^ PIN_9 = (1 << 9),$/;" e enum:io_pin +PIN_ALL io.h /^ PIN_ALL = 0xFFFF$/;" e enum:io_pin +RCC_CFGR_HPRE_DIV_128 rcc.c /^#define RCC_CFGR_HPRE_DIV_128 /;" d file: +RCC_CFGR_HPRE_DIV_16 rcc.c /^#define RCC_CFGR_HPRE_DIV_16 /;" d file: +RCC_CFGR_HPRE_DIV_256 rcc.c /^#define RCC_CFGR_HPRE_DIV_256 /;" d file: +RCC_CFGR_HPRE_DIV_2 rcc.c /^#define RCC_CFGR_HPRE_DIV_2 /;" d file: +RCC_CFGR_HPRE_DIV_4 rcc.c /^#define RCC_CFGR_HPRE_DIV_4 /;" d file: +RCC_CFGR_HPRE_DIV_512 rcc.c /^#define RCC_CFGR_HPRE_DIV_512 /;" d file: +RCC_CFGR_HPRE_DIV_64 rcc.c /^#define RCC_CFGR_HPRE_DIV_64 /;" d file: +RCC_CFGR_HPRE_DIV_8 rcc.c /^#define RCC_CFGR_HPRE_DIV_8 /;" d file: +RCC_CFGR_HPRE_DIV_NONE rcc.c /^#define RCC_CFGR_HPRE_DIV_NONE /;" d file: +RCC_CFGR_PLLMUL rcc.c /^#define RCC_CFGR_PLLMUL(/;" d file: +RCC_CFGR_PPRE_DIV_16 rcc.c /^#define RCC_CFGR_PPRE_DIV_16 /;" d file: +RCC_CFGR_PPRE_DIV_2 rcc.c /^#define RCC_CFGR_PPRE_DIV_2 /;" d file: +RCC_CFGR_PPRE_DIV_4 rcc.c /^#define RCC_CFGR_PPRE_DIV_4 /;" d file: +RCC_CFGR_PPRE_DIV_8 rcc.c /^#define RCC_CFGR_PPRE_DIV_8 /;" d file: +RCC_CFGR_PPRE_DIV_NONE rcc.c /^#define RCC_CFGR_PPRE_DIV_NONE /;" d file: +RCC_HSE rcc.c /^ RCC_HSE,$/;" e enum:rcc_osc file: +RCC_HSI rcc.c /^ RCC_HSI,$/;" e enum:rcc_osc file: +RCC_LSE rcc.c /^ RCC_LSE$/;" e enum:rcc_osc file: +RCC_LSI rcc.c /^ RCC_LSI,$/;" e enum:rcc_osc file: +RCC_PLL rcc.c /^ RCC_PLL,$/;" e enum:rcc_osc file: +SYSCFG_EXTI_PA_MASK io.c /^#define SYSCFG_EXTI_PA_MASK /;" d file: +SYSCFG_EXTI_PB_MASK io.c /^#define SYSCFG_EXTI_PB_MASK /;" d file: +SYSCFG_EXTI_PC_MASK io.c /^#define SYSCFG_EXTI_PC_MASK /;" d file: +SYSCFG_EXTI_PD_MASK io.c /^#define SYSCFG_EXTI_PD_MASK /;" d file: +SYSCFG_EXTI_PE_MASK io.c /^#define SYSCFG_EXTI_PE_MASK /;" d file: +SYSCFG_EXTI_PH_MASK io.c /^#define SYSCFG_EXTI_PH_MASK /;" d file: +TIM1_UP_IRQHandler timer.c /^void TIM1_UP_IRQHandler(void) {$/;" f typeref:typename:void +TIM2_IRQHandler timer.c /^void TIM2_IRQHandler(void) {$/;" f typeref:typename:void +TIM3_IRQHandler timer.c /^void TIM3_IRQHandler(void) {$/;" f typeref:typename:void +TIM4_IRQHandler timer.c /^void TIM4_IRQHandler(void) {$/;" f typeref:typename:void +_Clock_t rcc.h /^typedef struct _Clock_t {$/;" s +_IO_H_ io.h /^#define _IO_H_$/;" d +_RCC_H_ rcc.h /^#define _RCC_H_$/;" d +_TIMER_H_ timer.h /^#define _TIMER_H_$/;" d +_clock_config rcc.c /^static struct ClockConfig_t _clock_config[] = {$/;" v typeref:struct:ClockConfig_t[] file: +ahb_freq rcc.c /^ uint32_t ahb_freq;$/;" m struct:ClockConfig_t typeref:typename:uint32_t file: +ahb_freq rcc.h /^ uint32_t ahb_freq;$/;" m struct:_Clock_t typeref:typename:uint32_t +apb1_freq rcc.c /^ uint32_t apb1_freq;$/;" m struct:ClockConfig_t typeref:typename:uint32_t file: +apb1_freq rcc.h /^ uint32_t apb1_freq;$/;" m struct:_Clock_t typeref:typename:uint32_t +apb1_timer_freq rcc.h /^ uint32_t apb1_timer_freq;$/;" m struct:_Clock_t typeref:typename:uint32_t +apb2_freq rcc.c /^ uint32_t apb2_freq;$/;" m struct:ClockConfig_t typeref:typename:uint32_t file: +apb2_freq rcc.h /^ uint32_t apb2_freq;$/;" m struct:_Clock_t typeref:typename:uint32_t +apb2_timer_freq rcc.h /^ uint32_t apb2_timer_freq;$/;" m struct:_Clock_t typeref:typename:uint32_t +callback1 timer.c /^static OnTick callback1 = 0;$/;" v typeref:typename:OnTick file: +callback2 timer.c /^static OnTick callback2 = 0;$/;" v typeref:typename:OnTick file: +callback3 timer.c /^static OnTick callback3 = 0;$/;" v typeref:typename:OnTick file: +callback4 timer.c /^static OnTick callback4 = 0;$/;" v typeref:typename:OnTick file: +flash_cfg rcc.c /^ uint32_t flash_cfg;$/;" m struct:ClockConfig_t typeref:typename:uint32_t file: +hpre rcc.c /^ uint8_t hpre;$/;" m struct:ClockConfig_t typeref:typename:uint8_t file: +io_cb io.c /^static OnIO io_cb[16]={$/;" v typeref:typename:OnIO[16] file: +io_clear io.c /^void io_clear(GPIO_TypeDef *gpio, uint16_t mask)$/;" f typeref:typename:void +io_conf io.h /^enum io_conf {$/;" g +io_configure io.c /^int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint8_t pin_cfg, OnIO cb) {$/;" f typeref:typename:int +io_mode io.h /^enum io_mode {$/;" g +io_pin io.h /^enum io_pin {$/;" g +io_read io.c /^uint32_t io_read(GPIO_TypeDef *gpio, uint16_t mask)$/;" f typeref:typename:uint32_t +io_set io.c /^void io_set(GPIO_TypeDef *gpio, uint16_t mask)$/;" f typeref:typename:void +io_write_n io.c /^void io_write_n(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask)$/;" f typeref:typename:void +io_write io.c /^void io_write(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask)$/;" f typeref:typename:void +pll_src rcc.c /^ uint8_t pll_src;$/;" m struct:ClockConfig_t typeref:typename:uint8_t file: +pllmul rcc.c /^ uint8_t pllmul;$/;" m struct:ClockConfig_t typeref:typename:uint8_t file: +ppre1 rcc.c /^ uint8_t ppre1;$/;" m struct:ClockConfig_t typeref:typename:uint8_t file: +ppre2 rcc.c /^ uint8_t ppre2;$/;" m struct:ClockConfig_t typeref:typename:uint8_t file: +rcc_config_clock rcc.c /^void rcc_config_clock(uint32_t config, Clock_t *sysclks)$/;" f typeref:typename:void +rcc_osc_off rcc.c /^static void rcc_osc_off(enum rcc_osc osc)$/;" f typeref:typename:void file: +rcc_osc_on rcc.c /^static void rcc_osc_on(enum rcc_osc osc)$/;" f typeref:typename:void file: +rcc_osc rcc.c /^enum rcc_osc {$/;" g file: +rcc_set_sysclk rcc.c /^static void rcc_set_sysclk(enum rcc_osc osc)$/;" f typeref:typename:void file: +timer_config_cb timer.c /^int timer_config_cb(TIM_TypeDef* tmr, OnTick cb) {$/;" f typeref:typename:int +timer_set_period timer.c /^int timer_set_period(TIM_TypeDef *tmr, uint16_t tick) {$/;" f typeref:typename:int +timer_start timer.c /^void timer_start(TIM_TypeDef *tmr) {$/;" f typeref:typename:void +timer_stop timer.c /^void timer_stop(TIM_TypeDef *tmr) {$/;" f typeref:typename:void +timer_tick_init timer.c /^int timer_tick_init(TIM_TypeDef *tmr, uint16_t tick_ms, OnTick cb) {$/;" f typeref:typename:int +timer_wait_ms timer.c /^int timer_wait_ms(TIM_TypeDef* tmr, uint16_t ms, OnTick cb) {$/;" f typeref:typename:int +timer_wait_us timer.c /^int timer_wait_us(TIM_TypeDef* tmr, uint16_t us, OnTick cb) {$/;" f typeref:typename:int +type rcc.c /^ uint8_t type;$/;" m struct:ClockConfig_t typeref:typename:uint8_t file: diff --git a/src/drivers/timer.c b/src/drivers/timer.c index 277ae81..5fc73d4 100644 --- a/src/drivers/timer.c +++ b/src/drivers/timer.c @@ -2,71 +2,231 @@ extern Clock_t sysclks; -/* - * timerX_isr - * timerX ISR (Interrupt Service Routine) +//------------------------------------------------------------------------------ +/** timerX_isr + * timerX ISR (Interrupt Service Routine) */ +static OnTick callback1 = 0; static OnTick callback2 = 0; static OnTick callback3 = 0; static OnTick callback4 = 0; -void TIM2_IRQHandler() { +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 TIM3_IRQHandler(void) { if (callback3) callback3(); TIM3->SR &= ~0x1F; } -void TIM4_IRQHandler() { +void TIM4_IRQHandler(void) { if (callback4) callback4(); TIM4->SR &= ~0x1F; } - -/* - * timer_tick_init - * setup timer to call cb function periodically, each tick_ms - */ -int timer_tick_init(TIM_TypeDef *tmr, uint32_t tick_ms, OnTick cb) { +int timer_config_cb(TIM_TypeDef* tmr, uint32_t* clk, OnTick cb) { IRQn_Type irqn; - uint32_t irq_priority, clk; - //get back the clock frequency - clk = sysclks.apb1_timer_freq; + uint32_t irq_priority; + + // get clocks config + if (tmr == TIM1) { + *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; + + } else if (tmr == TIM2) { + *clk = sysclks.apb1_timer_freq; - if (tmr == TIM2) { // register callback function callback2 = cb; irqn = TIM2_IRQn; irq_priority = TIM2_IRQ_PRIORITY; // enable timer clocking - RCC->APB1ENR |=1<<0; + RCC->APB1ENR |= 1<<0; } else if (tmr == TIM3) { + *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; + RCC->APB1ENR |= 1<<1; } else if (tmr == TIM4) { + *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; + RCC->APB1ENR |= 1<<2; - } else { - return -1; + } else 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 + } + + } else { //non-blocking + if(timer_config_cb(tmr, &clk, cb)) return -1; } + // set mode + tmr->CR1 |= (1<<7); //buffering + tmr->CR1 |= (1<<3); //one pulse mode + + // set period + tmr->ARR = 0xFFFFFFFF; + + // set prescaler 1us + 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 + } + + } else { //non-blocking + if(timer_config_cb(tmr, &clk, cb)) return -1; + } + + // set mode + tmr->CR1 |= (1<<7); //buffering + tmr->CR1 |= (1<<3); //one pulse mode + + // set period + tmr->ARR = 0xFFFFFFFF; + + // 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; + + // get back the clock frequency + if (tmr == TIM1) { + 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; + + } else if (tmr == TIM2) { + 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; + + } else if (tmr == TIM3) { + 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; + + } else if (tmr == TIM4) { + 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; + + } else return -1; + // clear pending interrupts tmr->SR &= !1; @@ -74,55 +234,41 @@ int timer_tick_init(TIM_TypeDef *tmr, uint32_t tick_ms, OnTick cb) { tmr->CR1 = (1<<7); //buffering tmr->DIER = (1<<0); //Enable interrupts - // set prescaler 100us - tmr->PSC = clk/(10000-1); //100µs = (PSC+1)*Tclk + // set prescaler 1ms + tmr->PSC = 8*(clk/1000)-1; //PSC = clk/f - 1 | don't know why 8 times... // set period - if(timer_tick_period(tmr,tick_ms)) return -1; - - //enable counter - tmr->CR1= (1<<0)| tmr->CR1; + if(timer_set_period(tmr,tick_ms)) return -1; if (cb) { - NVIC_SetPriority(irqn,irq_priority); //enable interuptions - NVIC_EnableIRQ(irqn); + NVIC_SetPriority(irqn,irq_priority); + NVIC_EnableIRQ(irqn); //unmask IRQ } return 0; } -/* - * timer_tick_period - * change the tick_ms period - */ -int timer_tick_period(TIM_TypeDef *tmr, uint32_t tick_ms) { +int timer_set_period(TIM_TypeDef *tmr, uint16_t tick) { // set period - tmr->ARR = tick_ms*10-1; //tickms = (ARR+1)Tpsc + tmr->ARR = tick-1; //tickms = (ARR+1)Tpsc - // force update to reset counter and prescaler + // force update to reset counter and apply prescaler tmr->EGR |= 1; return 0; } -/* - * timer_start - * reset & enable counting - */ void timer_start(TIM_TypeDef *tmr) { // force update to reset counter and prescaler tmr->EGR |= 1; // enable counting tmr->CR1 |= 1; + + } -/* - * timer_stop - * stop counting - */ void timer_stop(TIM_TypeDef *tmr) { // disable counting tmr->CR1 &= !1; - } diff --git a/src/drivers/timer.h b/src/drivers/timer.h index 0333ac7..24e5918 100644 --- a/src/drivers/timer.h +++ b/src/drivers/timer.h @@ -11,75 +11,78 @@ extern "C" { typedef void (*OnTick)(void); -/***************************************************************************/ -/* timer_wait_ms - * wait for ms millisecoonds function +//------------------------------------------------------------------------------ +/** timer_wait_ms + * wait for ms milliseconds function */ -int timer_wait_ms(TIM_TypeDef *tmr, uint32_t ms, OnTick cb); +int timer_wait_ms(TIM_TypeDef *tmr, uint16_t ms, OnTick cb); -/* timer_wait_us - * wait for us microsecoonds function +/** timer_wait_us + * wait for us microseconds function */ -int timer_wait_us(TIM_TypeDef *tmr, uint32_t us, OnTick cb); +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 +//------------------------------------------------------------------------------ +/** timer_tick_init + * setup timer to call cb function periodically, each tick_ms */ -int timer_tick_init(TIM_TypeDef *tmr, uint32_t tick_ms, OnTick cb); +int timer_tick_init(TIM_TypeDef *tmr, uint16_t tick_ms, OnTick cb); -/* timer_tick_period - * change the tick_ms period +/** 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_tick_period(TIM_TypeDef *tmr, uint32_t tick_ms); +int timer_set_period(TIM_TypeDef *tmr, uint16_t tick); -/* timer_start - * start counting to generate ticks +/** timer_start + * reset count and start counting */ void timer_start(TIM_TypeDef *tmr); -/* timer_stop - * stop and reset counting +/** timer_stop + * stop counting */ void timer_stop(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) +//------------------------------------------------------------------------------ +//#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) #ifdef __cplusplus } #endif #endif + diff --git a/src/main.c b/src/main.c index f248262..881d620 100644 --- a/src/main.c +++ b/src/main.c @@ -16,13 +16,16 @@ int main(void) { rcc_config_clock(CLOCK_CONFIG_PERFORMANCE, &sysclks); - if(io_configure(GPIOC, PIN_13, PIN_MODE_OUTPUT | PIN_OPT_OUTPUT_PUSHPULL, 0)) return 0; + if(io_configure(GPIOC, PIN_13, IO_MODE_OUTPUT | IO_OUT_PUSH_PULL, 0)) + return 0; io_write(GPIOC, 1, PIN_13); - timer_tick_init(TIM2, 1000, timeout_cb); - timer_start(TIM2); + //timer_tick_init(TIM2, 1000, timeout_cb); + //timer_start(TIM2); for(;;){ + timer_wait_ms(TIM1, 500, 0); + timer_wait_ms(TIM2, 500, timeout_cb); } return 0; diff --git a/src/target/stm32f103xb.h b/src/target/stm32f103xb.h index 5bf8aa0..5d98ae4 100644 --- a/src/target/stm32f103xb.h +++ b/src/target/stm32f103xb.h @@ -543,7 +543,7 @@ typedef struct __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ __IO uint32_t DMAR; /*!< TIM DMA address for full transfer register, Address offset: 0x4C */ __IO uint32_t OR; /*!< TIM option register, Address offset: 0x50 */ -}TIM_TypeDef; +} TIM_TypeDef; /** @@ -10639,4 +10639,4 @@ typedef struct - /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/