Extended timer driver
+ support for delays, blocking and non-blocking + improved period precision ! timer_delay_us probably not accurate at all
This commit is contained in:
parent
ebdbfaedc1
commit
55de91c274
10
src/config.h
10
src/config.h
@ -9,28 +9,24 @@
|
|||||||
#define EXTI9_5_IRQ_PRIORITY 8
|
#define EXTI9_5_IRQ_PRIORITY 8
|
||||||
#define EXTI15_10_IRQ_PRIORITY 8
|
#define EXTI15_10_IRQ_PRIORITY 8
|
||||||
|
|
||||||
|
#define TIM1_IRQ_PRIORITY 4
|
||||||
#define TIM2_IRQ_PRIORITY 4
|
#define TIM2_IRQ_PRIORITY 4
|
||||||
#define TIM3_IRQ_PRIORITY 4
|
#define TIM3_IRQ_PRIORITY 4
|
||||||
#define TIM4_IRQ_PRIORITY 4
|
#define TIM4_IRQ_PRIORITY 4
|
||||||
|
|
||||||
#define USART1_IRQ_PRIORITY 3
|
#define USART1_IRQ_PRIORITY 3
|
||||||
#define USART2_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_IRQ_PRIORITY 2
|
||||||
#define I2C1_IRQERR_PRIORITY 1
|
#define I2C1_IRQERR_PRIORITY 1
|
||||||
#define I2C2_IRQ_PRIORITY 2
|
#define I2C2_IRQ_PRIORITY 2
|
||||||
#define I2C2_IRQERR_PRIORITY 1
|
#define I2C2_IRQERR_PRIORITY 1
|
||||||
#define I2C3_IRQ_PRIORITY 2
|
|
||||||
#define I2C3_IRQERR_PRIORITY 1
|
|
||||||
|
|
||||||
#define SPI1_IRQ_PRIORITY 4
|
#define SPI1_IRQ_PRIORITY 4
|
||||||
#define SPI2_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
|
* USART Pin and use configuration
|
||||||
|
|||||||
234
src/drivers/io.c
234
src/drivers/io.c
@ -95,7 +95,7 @@ void EXTI15_10_IRQHandler() {
|
|||||||
#define SYSCFG_EXTI_PH_MASK 7
|
#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
|
// enable GPIOx subsystem clocking
|
||||||
if (gpio == GPIOA) RCC->APB2ENR |= 1<<2;
|
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 == GPIOD) RCC->APB2ENR |= 1<<5;
|
||||||
else if (gpio == GPIOE) RCC->APB2ENR |= 1<<6;
|
else if (gpio == GPIOE) RCC->APB2ENR |= 1<<6;
|
||||||
|
|
||||||
// ssetup the config bits
|
// setup pin mask for crx registers
|
||||||
uint32_t crx = 0;
|
uint64_t pin_mask = 0;
|
||||||
uint16_t odr = 0;
|
for(int i=0; i<16; ++i) {
|
||||||
for(int i=0; i<8; i++) {
|
if((pin >> i) & 0x1) {
|
||||||
if(pin & (1 << i)) {
|
pin_mask |= 0x1ll << 4*i;
|
||||||
crx |= (pin_cfg & 0xF) << (4*i);
|
|
||||||
odr |= (pin_cfg & 0xF0) << i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gpio->CRL |= crx;
|
|
||||||
|
|
||||||
crx = 0;
|
// clear previous data
|
||||||
for(int i=8; i<16; i++) {
|
uint64_t crx = pin_mask * 0x4; //reset value is 0x4
|
||||||
if(pin & (1 << i)) {
|
uint16_t odr = pin;
|
||||||
crx |= (pin_cfg & 0xF) << (4*(i-8));
|
gpio->CRH &= ~(crx >> 32);
|
||||||
odr |= (pin_cfg & 0xF0) << i;
|
gpio->CRL &= ~(crx & 0xFFFF);
|
||||||
}
|
gpio->BSRR |= odr << 16;
|
||||||
}
|
|
||||||
gpio->CRH |= crx;
|
|
||||||
gpio->ODR |= odr;
|
|
||||||
|
|
||||||
/*
|
// set up the new configuration
|
||||||
if (!cb) return -1; //no callback attached
|
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
|
//TODO manage alternate functions
|
||||||
if (pin_cfg & 0x3) return -1; //callback set, but not in input mode
|
// if (pin_cfg & 0x3) return -1; //callback set, but not in input mode
|
||||||
|
//
|
||||||
// ************* Input GPIO + External IRQ *************
|
// // ************* Input GPIO + External IRQ *************
|
||||||
|
//
|
||||||
uint32_t port_mask = 0;
|
// uint32_t port_mask = 0;
|
||||||
uint32_t pin_mask = 0;
|
// uint32_t pin_mask = 0;
|
||||||
|
//
|
||||||
if (gpio == GPIOA) port_mask = SYSCFG_EXTI_PA_MASK;
|
// if (gpio == GPIOA) port_mask = SYSCFG_EXTI_PA_MASK;
|
||||||
else if (gpio == GPIOB) port_mask = SYSCFG_EXTI_PB_MASK;
|
// else if (gpio == GPIOB) port_mask = SYSCFG_EXTI_PB_MASK;
|
||||||
else if (gpio == GPIOC) port_mask = SYSCFG_EXTI_PC_MASK;
|
// else if (gpio == GPIOC) port_mask = SYSCFG_EXTI_PC_MASK;
|
||||||
else if (gpio == GPIOD) port_mask = SYSCFG_EXTI_PD_MASK;
|
// else if (gpio == GPIOD) port_mask = SYSCFG_EXTI_PD_MASK;
|
||||||
else if (gpio == GPIOE) port_mask = SYSCFG_EXTI_PE_MASK;
|
// else if (gpio == GPIOE) port_mask = SYSCFG_EXTI_PE_MASK;
|
||||||
|
//
|
||||||
uint32_t bit_mask = 0x1;
|
// uint32_t bit_mask = 0x1;
|
||||||
|
//
|
||||||
for (int i=0; i<16; i++) {
|
// for (int i=0; i<16; i++) {
|
||||||
if (pin_mask & bit_mask) {
|
// if (pin_mask & bit_mask) {
|
||||||
// enable clock for SYSCFG, no need for EXTI (interface not clocked)
|
// // enable clock for SYSCFG, no need for EXTI (interface not clocked)
|
||||||
RCC->APB2ENR = RCC->APB2ENR | (1<<14);
|
// RCC->APB2ENR = RCC->APB2ENR | (1<<14);
|
||||||
|
//
|
||||||
// configure pin Px_i (4 pin config per EXTICR[] register, 4 bits per pin)
|
// // configure pin Px_i (4 pin config per EXTICR[] register, 4 bits per pin)
|
||||||
// use port Px and bind Px_i --> EXTIi
|
// // use port Px and bind Px_i --> EXTIi
|
||||||
// i>>2 = i/4 ; i & 0x3 = i%4
|
// // i>>2 = i/4 ; i & 0x3 = i%4
|
||||||
gpio->EXTICR[i>>2] = (SYSCFG->EXTICR[i>>2] &
|
// gpio->EXTICR[i>>2] = (SYSCFG->EXTICR[i>>2] &
|
||||||
~(0x0000000F << ((i & 3)<<2))) |
|
// ~(0x0000000F << ((i & 3)<<2))) |
|
||||||
(port_mask << ((i & 3)<<2));
|
// (port_mask << ((i & 3)<<2));
|
||||||
|
//
|
||||||
// allow pin EXTIi to send an IRQ
|
// // allow pin EXTIi to send an IRQ
|
||||||
EXTI->IMR = EXTI->IMR | bit_mask;
|
// EXTI->IMR = EXTI->IMR | bit_mask;
|
||||||
// not a wakeup event
|
// // not a wakeup event
|
||||||
EXTI->EMR = EXTI->EMR & (~bit_mask);
|
// EXTI->EMR = EXTI->EMR & (~bit_mask);
|
||||||
|
//
|
||||||
// Configure pin event IRQ on rising (RTSR)/falling (FTSR) edge (rising only here)
|
// // Configure pin event IRQ on rising (RTSR)/falling (FTSR) edge (rising only here)
|
||||||
if (pin_cfg & PIN_OPT_IRQ_EDGE_RISE) {
|
// if (pin_cfg & PIN_OPT_IRQ_EDGE_RISE) {
|
||||||
EXTI->RTSR = EXTI->RTSR | bit_mask;
|
// EXTI->RTSR = EXTI->RTSR | bit_mask;
|
||||||
} else {
|
// } else {
|
||||||
EXTI->RTSR = EXTI->RTSR & (~bit_mask);
|
// EXTI->RTSR = EXTI->RTSR & (~bit_mask);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (pin_cfg & PIN_OPT_IRQ_EDGE_FALL) {
|
// if (pin_cfg & PIN_OPT_IRQ_EDGE_FALL) {
|
||||||
EXTI->FTSR = EXTI->FTSR | bit_mask;
|
// EXTI->FTSR = EXTI->FTSR | bit_mask;
|
||||||
} else {
|
// } else {
|
||||||
EXTI->FTSR = EXTI->FTSR & (~bit_mask);
|
// EXTI->FTSR = EXTI->FTSR & (~bit_mask);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
io_cb[i] = cb;
|
// io_cb[i] = cb;
|
||||||
|
//
|
||||||
// reset any pending IRQ on PC13
|
// // reset any pending IRQ on PC13
|
||||||
EXTI->PR = bit_mask;
|
// EXTI->PR = bit_mask;
|
||||||
|
//
|
||||||
// Setup NVIC
|
// // Setup NVIC
|
||||||
switch (i) {
|
// switch (i) {
|
||||||
case 0:
|
// case 0:
|
||||||
NVIC_SetPriority(EXTI0_IRQn, EXTI0_IRQ_PRIORITY);
|
// NVIC_SetPriority(EXTI0_IRQn, EXTI0_IRQ_PRIORITY);
|
||||||
NVIC_EnableIRQ(EXTI0_IRQn);
|
// NVIC_EnableIRQ(EXTI0_IRQn);
|
||||||
break;
|
// break;
|
||||||
case 1:
|
// case 1:
|
||||||
NVIC_SetPriority(EXTI1_IRQn, EXTI1_IRQ_PRIORITY);
|
// NVIC_SetPriority(EXTI1_IRQn, EXTI1_IRQ_PRIORITY);
|
||||||
NVIC_EnableIRQ(EXTI1_IRQn);
|
// NVIC_EnableIRQ(EXTI1_IRQn);
|
||||||
break;
|
// break;
|
||||||
case 2:
|
// case 2:
|
||||||
NVIC_SetPriority(EXTI2_IRQn, EXTI2_IRQ_PRIORITY);
|
// NVIC_SetPriority(EXTI2_IRQn, EXTI2_IRQ_PRIORITY);
|
||||||
NVIC_EnableIRQ(EXTI2_IRQn);
|
// NVIC_EnableIRQ(EXTI2_IRQn);
|
||||||
break;
|
// break;
|
||||||
case 3:
|
// case 3:
|
||||||
NVIC_SetPriority(EXTI3_IRQn, EXTI3_IRQ_PRIORITY);
|
// NVIC_SetPriority(EXTI3_IRQn, EXTI3_IRQ_PRIORITY);
|
||||||
NVIC_EnableIRQ(EXTI3_IRQn);
|
// NVIC_EnableIRQ(EXTI3_IRQn);
|
||||||
break;
|
// break;
|
||||||
case 4:
|
// case 4:
|
||||||
NVIC_SetPriority(EXTI4_IRQn, EXTI4_IRQ_PRIORITY);
|
// NVIC_SetPriority(EXTI4_IRQn, EXTI4_IRQ_PRIORITY);
|
||||||
NVIC_EnableIRQ(EXTI4_IRQn);
|
// NVIC_EnableIRQ(EXTI4_IRQn);
|
||||||
break;
|
// break;
|
||||||
case 5:
|
// case 5:
|
||||||
case 6:
|
// case 6:
|
||||||
case 7:
|
// case 7:
|
||||||
case 8:
|
// case 8:
|
||||||
case 9:
|
// case 9:
|
||||||
NVIC_SetPriority(EXTI9_5_IRQn, EXTI9_5_IRQ_PRIORITY);
|
// NVIC_SetPriority(EXTI9_5_IRQn, EXTI9_5_IRQ_PRIORITY);
|
||||||
NVIC_EnableIRQ(EXTI9_5_IRQn);
|
// NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||||
break;
|
// break;
|
||||||
case 10:
|
// case 10:
|
||||||
case 11:
|
// case 11:
|
||||||
case 12:
|
// case 12:
|
||||||
case 13:
|
// case 13:
|
||||||
case 14:
|
// case 14:
|
||||||
case 15:
|
// case 15:
|
||||||
NVIC_SetPriority(EXTI15_10_IRQn, EXTI15_10_IRQ_PRIORITY);
|
// NVIC_SetPriority(EXTI15_10_IRQn, EXTI15_10_IRQ_PRIORITY);
|
||||||
NVIC_EnableIRQ(EXTI15_10_IRQn);
|
// NVIC_EnableIRQ(EXTI15_10_IRQn);
|
||||||
break;
|
// break;
|
||||||
default:
|
// default:
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
bit_mask = bit_mask<<1;
|
//bit_mask = bit_mask<<1;
|
||||||
}
|
//}
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
136
src/drivers/io.h
136
src/drivers/io.h
@ -5,76 +5,80 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* --- GPIO pin mask definitions ---------------------------------------- */
|
//------------------------------------------------------------------------------
|
||||||
#define PIN_0 (1 << 0)
|
/* GPIO pin mask definitions */
|
||||||
#define PIN_1 (1 << 1)
|
enum io_pin {
|
||||||
#define PIN_2 (1 << 2)
|
PIN_0 = (1 << 0),
|
||||||
#define PIN_3 (1 << 3)
|
PIN_1 = (1 << 1),
|
||||||
#define PIN_4 (1 << 4)
|
PIN_2 = (1 << 2),
|
||||||
#define PIN_5 (1 << 5)
|
PIN_3 = (1 << 3),
|
||||||
#define PIN_6 (1 << 6)
|
PIN_4 = (1 << 4),
|
||||||
#define PIN_7 (1 << 7)
|
PIN_5 = (1 << 5),
|
||||||
#define PIN_8 (1 << 8)
|
PIN_6 = (1 << 6),
|
||||||
#define PIN_9 (1 << 9)
|
PIN_7 = (1 << 7),
|
||||||
#define PIN_10 (1 << 10)
|
PIN_8 = (1 << 8),
|
||||||
#define PIN_11 (1 << 11)
|
PIN_9 = (1 << 9),
|
||||||
#define PIN_12 (1 << 12)
|
PIN_10 = (1 << 10),
|
||||||
#define PIN_13 (1 << 13)
|
PIN_11 = (1 << 11),
|
||||||
#define PIN_14 (1 << 14)
|
PIN_12 = (1 << 12),
|
||||||
#define PIN_15 (1 << 15)
|
PIN_13 = (1 << 13),
|
||||||
#define PIN_ALL 0xFFFF
|
PIN_14 = (1 << 14),
|
||||||
|
PIN_15 = (1 << 15),
|
||||||
|
PIN_ALL = 0xFFFF
|
||||||
|
};
|
||||||
|
|
||||||
/* --- GPIO pin mode definitions ---------------------------------------- */
|
//------------------------------------------------------------------------------
|
||||||
#define PIN_MODE_INPUT (0)
|
/* GPIO pin mode definitions */
|
||||||
#define PIN_MODE_OUTPUT (1 << 0)
|
enum io_mode {
|
||||||
#define PIN_MODE_ALTFUNC (1 << 3 | 1 << 0)
|
IO_MODE_INPUT = (0x0),
|
||||||
#define PIN_MODE_ANALOG (0)
|
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 */
|
/* GPIO pin conf definitions */
|
||||||
#define PIN_OPT_NONE (0)
|
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)
|
/* GPIO pin clear */
|
||||||
#define PIN_OPT_RESISTOR_PULLUP (1 << 4 | 1 << 3)
|
#define IO_CLEAR (0)
|
||||||
#define PIN_OPT_RESISTOR_PULLDOWN (1 << 3)
|
|
||||||
|
|
||||||
/* push-pull/open drain output option */
|
//------------------------------------------------------------------------------
|
||||||
#define PIN_OPT_OUTPUT_PUSHPULL (0)
|
/* alternate function selection option */
|
||||||
#define PIN_OPT_OUTPUT_OPENDRAIN (1 << 2)
|
//TODO not supported for now
|
||||||
|
//enum io_alt_fnct {
|
||||||
/* output speed option
|
// PIN_OPT_AF0 0x0,
|
||||||
* - LOW ~ 2MHz max
|
// PIN_OPT_AF1 0x1,
|
||||||
* - MEDIUM ~ 10MHz max
|
// PIN_OPT_AF2 0x2,
|
||||||
* - FAST ~ 50MHz max
|
// PIN_OPT_AF3 0x3,
|
||||||
**/
|
// PIN_OPT_AF4 0x4,
|
||||||
#define PIN_OPT_OUTPUT_SPEED_LOW (10 << 0)
|
// PIN_OPT_AF5 0x5,
|
||||||
#define PIN_OPT_OUTPUT_SPEED_MEDIUM (1 << 0)
|
// PIN_OPT_AF6 0x6,
|
||||||
#define PIN_OPT_OUTPUT_SPEED_FAST (11 << 0)
|
// PIN_OPT_AF7 0x7,
|
||||||
|
// PIN_OPT_AF8 0x8,
|
||||||
/* alternate function selection option */
|
// PIN_OPT_AF9 0x9,
|
||||||
#define PIN_OPT_AF0 0x0
|
// PIN_OPT_AF10 0xA,
|
||||||
#define PIN_OPT_AF1 0x1
|
// PIN_OPT_AF11 0xB,
|
||||||
#define PIN_OPT_AF2 0x2
|
// PIN_OPT_AF12 0xC,
|
||||||
#define PIN_OPT_AF3 0x3
|
// PIN_OPT_AF13 0xD,
|
||||||
#define PIN_OPT_AF4 0x4
|
// PIN_OPT_AF14 0xE,
|
||||||
#define PIN_OPT_AF5 0x5
|
// PIN_OPT_AF15 0xF
|
||||||
#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)
|
|
||||||
|
|
||||||
|
///* 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)();
|
typedef void (*OnIO)();
|
||||||
|
|
||||||
/* io_configure
|
/* io_configure
|
||||||
@ -84,7 +88,7 @@ typedef void (*OnIO)();
|
|||||||
* function 'cb' if not NULL.
|
* function 'cb' if not NULL.
|
||||||
* returns 0 if success
|
* 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
|
/* io_read
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/**
|
/*
|
||||||
==============================================================================
|
==============================================================================
|
||||||
##### RCC specific features #####
|
##### RCC specific features #####
|
||||||
==============================================================================
|
==============================================================================
|
||||||
[..]
|
[..]
|
||||||
@ -176,11 +176,6 @@ static void rcc_set_sysclk(enum rcc_osc osc)
|
|||||||
while (((RCC->CFGR & 0xC)>>2) != 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)
|
void rcc_config_clock(uint32_t config, Clock_t *sysclks)
|
||||||
{
|
{
|
||||||
struct ClockConfig_t *clk;
|
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->ahb_freq = clk->ahb_freq;
|
||||||
sysclks->apb1_freq = clk->apb1_freq;
|
sysclks->apb1_freq = clk->apb1_freq;
|
||||||
|
sysclks->apb2_freq = clk->apb2_freq;
|
||||||
//TODO check timer frequencies
|
//TODO check timer frequencies
|
||||||
sysclks->apb1_timer_freq = clk->ppre1==RCC_CFGR_PPRE_DIV_NONE ? clk->apb1_freq : 2*clk->apb1_freq;
|
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;
|
sysclks->apb2_timer_freq = clk->ppre2==RCC_CFGR_PPRE_DIV_NONE ? clk->apb2_freq : 2*clk->apb2_freq;
|
||||||
}
|
}
|
||||||
|
|||||||
127
src/drivers/tags
Normal file
127
src/drivers/tags
Normal file
@ -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:
|
||||||
@ -2,71 +2,231 @@
|
|||||||
|
|
||||||
extern Clock_t sysclks;
|
extern Clock_t sysclks;
|
||||||
|
|
||||||
/*
|
//------------------------------------------------------------------------------
|
||||||
* timerX_isr
|
/** timerX_isr
|
||||||
* timerX ISR (Interrupt Service Routine)
|
* timerX ISR (Interrupt Service Routine)
|
||||||
*/
|
*/
|
||||||
|
static OnTick callback1 = 0;
|
||||||
static OnTick callback2 = 0;
|
static OnTick callback2 = 0;
|
||||||
static OnTick callback3 = 0;
|
static OnTick callback3 = 0;
|
||||||
static OnTick callback4 = 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();
|
if (callback2) callback2();
|
||||||
TIM2->SR &= ~0x1F;
|
TIM2->SR &= ~0x1F;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIM3_IRQHandler() {
|
void TIM3_IRQHandler(void) {
|
||||||
if (callback3) callback3();
|
if (callback3) callback3();
|
||||||
TIM3->SR &= ~0x1F;
|
TIM3->SR &= ~0x1F;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIM4_IRQHandler() {
|
void TIM4_IRQHandler(void) {
|
||||||
if (callback4) callback4();
|
if (callback4) callback4();
|
||||||
TIM4->SR &= ~0x1F;
|
TIM4->SR &= ~0x1F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int timer_config_cb(TIM_TypeDef* tmr, uint32_t* clk, OnTick cb) {
|
||||||
/*
|
|
||||||
* 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) {
|
|
||||||
IRQn_Type irqn;
|
IRQn_Type irqn;
|
||||||
uint32_t irq_priority, clk;
|
uint32_t irq_priority;
|
||||||
//get back the clock frequency
|
|
||||||
clk = sysclks.apb1_timer_freq;
|
// 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
|
// register callback function
|
||||||
callback2 = cb;
|
callback2 = cb;
|
||||||
irqn = TIM2_IRQn;
|
irqn = TIM2_IRQn;
|
||||||
irq_priority = TIM2_IRQ_PRIORITY;
|
irq_priority = TIM2_IRQ_PRIORITY;
|
||||||
|
|
||||||
// enable timer clocking
|
// enable timer clocking
|
||||||
RCC->APB1ENR |=1<<0;
|
RCC->APB1ENR |= 1<<0;
|
||||||
|
|
||||||
} else if (tmr == TIM3) {
|
} else if (tmr == TIM3) {
|
||||||
|
*clk = sysclks.apb1_timer_freq;
|
||||||
|
|
||||||
// register callback function
|
// register callback function
|
||||||
callback3 = cb;
|
callback3 = cb;
|
||||||
irqn = TIM3_IRQn;
|
irqn = TIM3_IRQn;
|
||||||
irq_priority = TIM3_IRQ_PRIORITY;
|
irq_priority = TIM3_IRQ_PRIORITY;
|
||||||
|
|
||||||
// enable timer clocking
|
// enable timer clocking
|
||||||
RCC->APB1ENR |=1<<1;
|
RCC->APB1ENR |= 1<<1;
|
||||||
|
|
||||||
} else if (tmr == TIM4) {
|
} else if (tmr == TIM4) {
|
||||||
|
*clk = sysclks.apb1_timer_freq;
|
||||||
|
|
||||||
// register callback function
|
// register callback function
|
||||||
callback4 = cb;
|
callback4 = cb;
|
||||||
irqn = TIM4_IRQn;
|
irqn = TIM4_IRQn;
|
||||||
irq_priority = TIM4_IRQ_PRIORITY;
|
irq_priority = TIM4_IRQ_PRIORITY;
|
||||||
|
|
||||||
// enable timer clocking
|
// enable timer clocking
|
||||||
RCC->APB1ENR |=1<<2;
|
RCC->APB1ENR |= 1<<2;
|
||||||
|
|
||||||
} else {
|
} else return -1;
|
||||||
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
|
// clear pending interrupts
|
||||||
tmr->SR &= !1;
|
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->CR1 = (1<<7); //buffering
|
||||||
tmr->DIER = (1<<0); //Enable interrupts
|
tmr->DIER = (1<<0); //Enable interrupts
|
||||||
|
|
||||||
// set prescaler 100us
|
// set prescaler 1ms
|
||||||
tmr->PSC = clk/(10000-1); //100µs = (PSC+1)*Tclk
|
tmr->PSC = 8*(clk/1000)-1; //PSC = clk/f - 1 | don't know why 8 times...
|
||||||
|
|
||||||
// set period
|
// set period
|
||||||
if(timer_tick_period(tmr,tick_ms)) return -1;
|
if(timer_set_period(tmr,tick_ms)) return -1;
|
||||||
|
|
||||||
//enable counter
|
|
||||||
tmr->CR1= (1<<0)| tmr->CR1;
|
|
||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
NVIC_SetPriority(irqn,irq_priority); //enable interuptions
|
NVIC_SetPriority(irqn,irq_priority);
|
||||||
NVIC_EnableIRQ(irqn);
|
NVIC_EnableIRQ(irqn); //unmask IRQ
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int timer_set_period(TIM_TypeDef *tmr, uint16_t tick) {
|
||||||
* timer_tick_period
|
|
||||||
* change the tick_ms period
|
|
||||||
*/
|
|
||||||
int timer_tick_period(TIM_TypeDef *tmr, uint32_t tick_ms) {
|
|
||||||
// set period
|
// 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;
|
tmr->EGR |= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* timer_start
|
|
||||||
* reset & enable counting
|
|
||||||
*/
|
|
||||||
void timer_start(TIM_TypeDef *tmr) {
|
void timer_start(TIM_TypeDef *tmr) {
|
||||||
// force update to reset counter and prescaler
|
// force update to reset counter and prescaler
|
||||||
tmr->EGR |= 1;
|
tmr->EGR |= 1;
|
||||||
|
|
||||||
// enable counting
|
// enable counting
|
||||||
tmr->CR1 |= 1;
|
tmr->CR1 |= 1;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* timer_stop
|
|
||||||
* stop counting
|
|
||||||
*/
|
|
||||||
void timer_stop(TIM_TypeDef *tmr) {
|
void timer_stop(TIM_TypeDef *tmr) {
|
||||||
// disable counting
|
// disable counting
|
||||||
tmr->CR1 &= !1;
|
tmr->CR1 &= !1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,75 +11,78 @@ extern "C" {
|
|||||||
|
|
||||||
typedef void (*OnTick)(void);
|
typedef void (*OnTick)(void);
|
||||||
|
|
||||||
/***************************************************************************/
|
//------------------------------------------------------------------------------
|
||||||
/* timer_wait_ms
|
/** timer_wait_ms
|
||||||
* wait for ms millisecoonds function
|
* 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
|
/** timer_wait_us
|
||||||
* wait for us microsecoonds function
|
* 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
|
/** timer_tick_init
|
||||||
* setup timer to call cb function periodically, each tick_ms
|
* 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
|
/** timer_set_period
|
||||||
* change the tick_ms 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
|
/** timer_start
|
||||||
* start counting to generate ticks
|
* reset count and start counting
|
||||||
*/
|
*/
|
||||||
void timer_start(TIM_TypeDef *tmr);
|
void timer_start(TIM_TypeDef *tmr);
|
||||||
|
|
||||||
/* timer_stop
|
/** timer_stop
|
||||||
* stop and reset counting
|
* stop counting
|
||||||
*/
|
*/
|
||||||
void timer_stop(TIM_TypeDef *tmr);
|
void timer_stop(TIM_TypeDef *tmr);
|
||||||
|
|
||||||
/***************************************************************************/
|
//------------------------------------------------------------------------------
|
||||||
#define PWM_CHANNEL_1 0
|
//#define PWM_CHANNEL_1 0
|
||||||
#define PWM_CHANNEL_2 1
|
//#define PWM_CHANNEL_2 1
|
||||||
#define PWM_CHANNEL_3 2
|
//#define PWM_CHANNEL_3 2
|
||||||
#define PWM_CHANNEL_4 3
|
//#define PWM_CHANNEL_4 3
|
||||||
|
//
|
||||||
/* pwm_init
|
///** pwm_init
|
||||||
* setup pwm timer period, each tick_ms
|
// * setup pwm timer period, each tick_ms
|
||||||
*/
|
// */
|
||||||
int pwm_init(TIM_TypeDef *pwm, uint32_t period_ms, OnTick cb);
|
//int pwm_init(TIM_TypeDef *pwm, uint32_t period_ms, OnTick cb);
|
||||||
|
//
|
||||||
/* pwm_channel_enable
|
///** pwm_channel_enable
|
||||||
* set up pwm channel
|
// * set up pwm channel
|
||||||
*/
|
// */
|
||||||
int pwm_channel_enable(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle, uint32_t oe);
|
//int pwm_channel_enable(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle, uint32_t oe);
|
||||||
|
//
|
||||||
/* pwm_channel_disable
|
///** pwm_channel_disable
|
||||||
* disable pwm channel
|
// * disable pwm channel
|
||||||
*/
|
// */
|
||||||
int pwm_channel_disable(TIM_TypeDef *pwm, uint32_t channel);
|
//int pwm_channel_disable(TIM_TypeDef *pwm, uint32_t channel);
|
||||||
|
//
|
||||||
/* pwm_channel_set
|
///** pwm_channel_set
|
||||||
* set up dutycycle for pwm channel
|
// * set up dutycycle for pwm channel
|
||||||
*/
|
// */
|
||||||
int pwm_channel_set(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle);
|
//int pwm_channel_set(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle);
|
||||||
|
//
|
||||||
/* pwm_start
|
///** pwm_start
|
||||||
* start counting
|
// * start counting
|
||||||
*/
|
// */
|
||||||
#define pwm_start(pwm) timer_start(pwm)
|
//#define pwm_start(pwm) timer_start(pwm)
|
||||||
|
//
|
||||||
/* pwm_stop
|
///** pwm_stop
|
||||||
* stop and reset counting
|
// * stop and reset counting
|
||||||
*/
|
// */
|
||||||
#define pwm_stop(pwm) timer_stop(pwm)
|
//#define pwm_stop(pwm) timer_stop(pwm)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -16,13 +16,16 @@ int main(void) {
|
|||||||
|
|
||||||
rcc_config_clock(CLOCK_CONFIG_PERFORMANCE, &sysclks);
|
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);
|
io_write(GPIOC, 1, PIN_13);
|
||||||
|
|
||||||
timer_tick_init(TIM2, 1000, timeout_cb);
|
//timer_tick_init(TIM2, 1000, timeout_cb);
|
||||||
timer_start(TIM2);
|
//timer_start(TIM2);
|
||||||
|
|
||||||
for(;;){
|
for(;;){
|
||||||
|
timer_wait_ms(TIM1, 500, 0);
|
||||||
|
timer_wait_ms(TIM2, 500, timeout_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -543,7 +543,7 @@ typedef struct
|
|||||||
__IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */
|
__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 DMAR; /*!< TIM DMA address for full transfer register, Address offset: 0x4C */
|
||||||
__IO uint32_t OR; /*!< TIM option register, Address offset: 0x50 */
|
__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****/
|
||||||
|
|||||||
Reference in New Issue
Block a user