mirror of https://github.com/ARMmbed/mbed-os.git
[NUCLEO_F103RB] Improvement of gpio and gpio_irq api
parent
a088e343a6
commit
d14992dcfd
|
@ -29,6 +29,9 @@
|
||||||
*/
|
*/
|
||||||
#include "gpio_api.h"
|
#include "gpio_api.h"
|
||||||
#include "pinmap.h"
|
#include "pinmap.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
|
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||||
|
|
||||||
uint32_t gpio_set(PinName pin) {
|
uint32_t gpio_set(PinName pin) {
|
||||||
if (pin == NC) return 0;
|
if (pin == NC) return 0;
|
||||||
|
@ -39,12 +42,15 @@ uint32_t gpio_set(PinName pin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
|
void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
|
||||||
|
GPIO_TypeDef *gpio;
|
||||||
|
|
||||||
if (pin == NC) return;
|
if (pin == NC) return;
|
||||||
|
|
||||||
uint32_t port_index = STM_PORT(pin);
|
uint32_t port_index = STM_PORT(pin);
|
||||||
|
|
||||||
// Get GPIO structure base address
|
// Enable GPIO clock
|
||||||
GPIO_TypeDef *gpio = (GPIO_TypeDef *)(GPIOA_BASE + (port_index << 10));
|
uint32_t gpio_add = Set_GPIO_Clock(port_index);
|
||||||
|
gpio = (GPIO_TypeDef *)gpio_add;
|
||||||
|
|
||||||
// Fill GPIO object structure for future use
|
// Fill GPIO object structure for future use
|
||||||
obj->pin = pin;
|
obj->pin = pin;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "cmsis.h"
|
#include "cmsis.h"
|
||||||
|
|
||||||
#include "gpio_irq_api.h"
|
#include "gpio_irq_api.h"
|
||||||
|
#include "pinmap.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
#define EDGE_NONE (0)
|
#define EDGE_NONE (0)
|
||||||
|
@ -38,130 +39,86 @@
|
||||||
#define EDGE_FALL (2)
|
#define EDGE_FALL (2)
|
||||||
#define EDGE_BOTH (3)
|
#define EDGE_BOTH (3)
|
||||||
|
|
||||||
#define CHANNEL_NUM (16)
|
#define CHANNEL_NUM (4)
|
||||||
|
|
||||||
static uint32_t channel_ids[CHANNEL_NUM] = {0};
|
static uint32_t channel_ids[CHANNEL_NUM] = {0, 0, 0, 0};
|
||||||
|
static uint32_t channel_gpio[CHANNEL_NUM] = {0, 0, 0, 0};
|
||||||
|
static uint32_t channel_pin[CHANNEL_NUM] = {0, 0, 0, 0};
|
||||||
|
|
||||||
static gpio_irq_handler irq_handler;
|
static gpio_irq_handler irq_handler;
|
||||||
|
|
||||||
static void handle_interrupt_in(uint32_t channel) {
|
static void handle_interrupt_in(uint32_t irq_index) {
|
||||||
if (channel_ids[channel] == 0) return;
|
|
||||||
|
|
||||||
uint32_t exti_line = (uint32_t)(1 << channel);
|
// Retrieve the gpio and pin that generate the irq
|
||||||
if (EXTI_GetITStatus(exti_line) != RESET)
|
GPIO_TypeDef *gpio = (GPIO_TypeDef *)(channel_gpio[irq_index]);
|
||||||
|
uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]);
|
||||||
|
|
||||||
|
// Clear interrupt flag
|
||||||
|
if (EXTI_GetITStatus(pin) != RESET)
|
||||||
{
|
{
|
||||||
EXTI_ClearITPendingBit(exti_line);
|
EXTI_ClearITPendingBit(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warning:
|
if (channel_ids[irq_index] == 0) return;
|
||||||
// On this device we don't know if a rising or falling event occured.
|
|
||||||
// In case both rise and fall events are set, only the FALL event will be reported.
|
// Check which edge has generated the irq
|
||||||
if (EXTI->FTSR & (uint32_t)(1 << channel)) {
|
if ((gpio->IDR & pin) == 0) {
|
||||||
irq_handler(channel_ids[channel], IRQ_FALL);
|
irq_handler(channel_ids[irq_index], IRQ_FALL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
irq_handler(channel_ids[channel], IRQ_RISE);
|
irq_handler(channel_ids[irq_index], IRQ_RISE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The irq_index is passed to the function
|
||||||
static void gpio_irq0(void) {handle_interrupt_in(0);}
|
static void gpio_irq0(void) {handle_interrupt_in(0);}
|
||||||
static void gpio_irq1(void) {handle_interrupt_in(1);}
|
static void gpio_irq1(void) {handle_interrupt_in(1);}
|
||||||
static void gpio_irq2(void) {handle_interrupt_in(2);}
|
static void gpio_irq2(void) {handle_interrupt_in(2);}
|
||||||
static void gpio_irq3(void) {handle_interrupt_in(3);}
|
static void gpio_irq3(void) {handle_interrupt_in(3);}
|
||||||
static void gpio_irq4(void) {handle_interrupt_in(4);}
|
|
||||||
static void gpio_irq5(void) {handle_interrupt_in(5);}
|
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||||
static void gpio_irq6(void) {handle_interrupt_in(6);}
|
|
||||||
static void gpio_irq7(void) {handle_interrupt_in(7);}
|
|
||||||
static void gpio_irq8(void) {handle_interrupt_in(8);}
|
|
||||||
static void gpio_irq9(void) {handle_interrupt_in(9);}
|
|
||||||
static void gpio_irq10(void) {handle_interrupt_in(10);}
|
|
||||||
static void gpio_irq11(void) {handle_interrupt_in(11);}
|
|
||||||
static void gpio_irq12(void) {handle_interrupt_in(12);}
|
|
||||||
static void gpio_irq13(void) {handle_interrupt_in(13);}
|
|
||||||
static void gpio_irq14(void) {handle_interrupt_in(14);}
|
|
||||||
static void gpio_irq15(void) {handle_interrupt_in(15);}
|
|
||||||
|
|
||||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
|
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
|
||||||
IRQn_Type irq_n = (IRQn_Type)0;
|
IRQn_Type irq_n = (IRQn_Type)0;
|
||||||
uint32_t vector = 0;
|
uint32_t vector = 0;
|
||||||
|
uint32_t irq_index;
|
||||||
|
|
||||||
if (pin == NC) return -1;
|
if (pin == NC) return -1;
|
||||||
|
|
||||||
uint32_t port_index = STM_PORT(pin);
|
uint32_t port_index = STM_PORT(pin);
|
||||||
uint32_t pin_index = STM_PIN(pin);
|
uint32_t pin_index = STM_PIN(pin);
|
||||||
|
|
||||||
// Select irq number and vector
|
// Select irq number and interrupt routine
|
||||||
switch (pin_index) {
|
switch (pin) {
|
||||||
case 0:
|
case PC_13: // User button
|
||||||
irq_n = EXTI0_IRQn;
|
irq_n = EXTI15_10_IRQn;
|
||||||
vector = (uint32_t)&gpio_irq0;
|
vector = (uint32_t)&gpio_irq0;
|
||||||
|
irq_index = 0;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case PB_3:
|
||||||
irq_n = EXTI1_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
irq_n = EXTI2_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq2;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
irq_n = EXTI3_IRQn;
|
irq_n = EXTI3_IRQn;
|
||||||
vector = (uint32_t)&gpio_irq3;
|
vector = (uint32_t)&gpio_irq1;
|
||||||
|
irq_index = 1;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case PB_4:
|
||||||
irq_n = EXTI4_IRQn;
|
irq_n = EXTI4_IRQn;
|
||||||
vector = (uint32_t)&gpio_irq4;
|
vector = (uint32_t)&gpio_irq2;
|
||||||
|
irq_index = 2;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case PB_5:
|
||||||
irq_n = EXTI9_5_IRQn;
|
irq_n = EXTI9_5_IRQn;
|
||||||
vector = (uint32_t)&gpio_irq5;
|
vector = (uint32_t)&gpio_irq3;
|
||||||
break;
|
irq_index = 3;
|
||||||
case 6:
|
|
||||||
irq_n = EXTI9_5_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq6;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
irq_n = EXTI9_5_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq7;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
irq_n = EXTI9_5_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq8;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
irq_n = EXTI9_5_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq9;
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
irq_n = EXTI15_10_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq10;
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
irq_n = EXTI15_10_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq11;
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
irq_n = EXTI15_10_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq12;
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
irq_n = EXTI15_10_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq13;
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
irq_n = EXTI15_10_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq14;
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
irq_n = EXTI15_10_IRQn;
|
|
||||||
vector = (uint32_t)&gpio_irq15;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
error("This pin is not supported with InterruptIn.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable GPIO and AFIO clocks
|
// Enable GPIO clock
|
||||||
RCC_APB2PeriphClockCmd((uint32_t)(RCC_APB2Periph_GPIOA << port_index), ENABLE);
|
uint32_t gpio_add = Set_GPIO_Clock(port_index);
|
||||||
|
|
||||||
|
// Enable AFIO clock
|
||||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
||||||
|
|
||||||
// Connect EXTI line to pin
|
// Connect EXTI line to pin
|
||||||
|
@ -186,12 +143,13 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
|
||||||
NVIC_SetVector(irq_n, vector);
|
NVIC_SetVector(irq_n, vector);
|
||||||
NVIC_EnableIRQ(irq_n);
|
NVIC_EnableIRQ(irq_n);
|
||||||
|
|
||||||
// Save for future use
|
// Save informations for future use
|
||||||
obj->ch = pin_index;
|
|
||||||
obj->irq_n = irq_n;
|
obj->irq_n = irq_n;
|
||||||
|
obj->irq_index = irq_index;
|
||||||
obj->event = EDGE_NONE;
|
obj->event = EDGE_NONE;
|
||||||
|
channel_ids[irq_index] = id;
|
||||||
channel_ids[obj->ch] = id;
|
channel_gpio[irq_index] = gpio_add;
|
||||||
|
channel_pin[irq_index] = pin_index;
|
||||||
|
|
||||||
irq_handler = handler;
|
irq_handler = handler;
|
||||||
|
|
||||||
|
@ -199,7 +157,9 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_irq_free(gpio_irq_t *obj) {
|
void gpio_irq_free(gpio_irq_t *obj) {
|
||||||
channel_ids[obj->ch] = 0;
|
channel_ids[obj->irq_index] = 0;
|
||||||
|
channel_gpio[obj->irq_index] = 0;
|
||||||
|
channel_pin[obj->irq_index] = 0;
|
||||||
// Disable EXTI line
|
// Disable EXTI line
|
||||||
EXTI_InitTypeDef EXTI_InitStructure;
|
EXTI_InitTypeDef EXTI_InitStructure;
|
||||||
EXTI_StructInit(&EXTI_InitStructure);
|
EXTI_StructInit(&EXTI_InitStructure);
|
||||||
|
@ -210,7 +170,9 @@ void gpio_irq_free(gpio_irq_t *obj) {
|
||||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
|
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
|
||||||
EXTI_InitTypeDef EXTI_InitStructure;
|
EXTI_InitTypeDef EXTI_InitStructure;
|
||||||
|
|
||||||
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << obj->ch);
|
uint32_t pin_index = channel_pin[obj->irq_index];
|
||||||
|
|
||||||
|
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index);
|
||||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||||
|
|
||||||
if (event == IRQ_RISE) {
|
if (event == IRQ_RISE) {
|
||||||
|
|
|
@ -40,9 +40,9 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct gpio_irq_s {
|
struct gpio_irq_s {
|
||||||
uint32_t ch;
|
|
||||||
IRQn_Type irq_n;
|
IRQn_Type irq_n;
|
||||||
uint32_t event; // 0=none, 1=rise, 2=fall, 3=rise+fall
|
uint32_t irq_index;
|
||||||
|
uint32_t event;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct port_s {
|
struct port_s {
|
||||||
|
|
|
@ -43,28 +43,58 @@ static const uint32_t AF_mapping[] = {
|
||||||
GPIO_Remap_I2C1 // 8
|
GPIO_Remap_I2C1 // 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Not an API function
|
||||||
|
// Enable GPIO clock and return GPIO base address
|
||||||
|
uint32_t Set_GPIO_Clock(uint32_t port_idx) {
|
||||||
|
uint32_t gpio_add = 0;
|
||||||
|
switch (port_idx) {
|
||||||
|
case PortA:
|
||||||
|
gpio_add = GPIOA_BASE;
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||||
|
break;
|
||||||
|
case PortB:
|
||||||
|
gpio_add = GPIOB_BASE;
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||||
|
break;
|
||||||
|
case PortC:
|
||||||
|
gpio_add = GPIOC_BASE;
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
|
||||||
|
break;
|
||||||
|
case PortD:
|
||||||
|
gpio_add = GPIOD_BASE;
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Port number is not correct.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return gpio_add;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the pin function (input, output, alternate function or analog) + output speed + AF
|
* Configure pin (input, output, alternate function or analog) + output speed + AF
|
||||||
*/
|
*/
|
||||||
void pin_function(PinName pin, int data) {
|
void pin_function(PinName pin, int data) {
|
||||||
|
GPIO_TypeDef *gpio;
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
|
||||||
if (pin == NC) return;
|
if (pin == NC) return;
|
||||||
|
|
||||||
// Get the pin mode and alternate-function number
|
// Get the pin informations
|
||||||
uint32_t mode = STM_PIN_MODE(data);
|
uint32_t mode = STM_PIN_MODE(data);
|
||||||
uint32_t afnum = STM_PIN_AFNUM(data);
|
uint32_t afnum = STM_PIN_AFNUM(data);
|
||||||
|
|
||||||
uint32_t port_index = STM_PORT(pin);
|
uint32_t port_index = STM_PORT(pin);
|
||||||
uint32_t pin_index = STM_PIN(pin);
|
uint32_t pin_index = STM_PIN(pin);
|
||||||
|
|
||||||
// Get GPIO structure base address
|
// Enable GPIO clock
|
||||||
GPIO_TypeDef *gpio = ((GPIO_TypeDef *)(GPIOA_BASE + (port_index << 10)));
|
uint32_t gpio_add = Set_GPIO_Clock(port_index);
|
||||||
|
gpio = (GPIO_TypeDef *)gpio_add;
|
||||||
|
|
||||||
// Enable GPIO and AFIO clocks
|
// Enable AFIO clock
|
||||||
RCC_APB2PeriphClockCmd((uint32_t)(RCC_APB2Periph_GPIOA << port_index), ENABLE);
|
|
||||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
||||||
|
|
||||||
// Configure GPIO
|
// Configure GPIO
|
||||||
GPIO_InitTypeDef GPIO_InitStructure;
|
|
||||||
GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index);
|
GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index);
|
||||||
GPIO_InitStructure.GPIO_Mode = (GPIOMode_TypeDef)mode;
|
GPIO_InitStructure.GPIO_Mode = (GPIOMode_TypeDef)mode;
|
||||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
@ -86,21 +116,20 @@ void pin_function(PinName pin, int data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the pin mode (open-drain/push-pull + pull-up/pull-down)
|
* Configure pin pull-up/pull-down
|
||||||
*/
|
*/
|
||||||
void pin_mode(PinName pin, PinMode mode) {
|
void pin_mode(PinName pin, PinMode mode) {
|
||||||
if (pin == NC) return;
|
GPIO_TypeDef *gpio;
|
||||||
|
|
||||||
GPIO_InitTypeDef GPIO_InitStructure;
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
|
||||||
|
if (pin == NC) return;
|
||||||
|
|
||||||
uint32_t port_index = STM_PORT(pin);
|
uint32_t port_index = STM_PORT(pin);
|
||||||
uint32_t pin_index = STM_PIN(pin);
|
uint32_t pin_index = STM_PIN(pin);
|
||||||
|
|
||||||
// Get GPIO structure base address
|
|
||||||
GPIO_TypeDef *gpio = ((GPIO_TypeDef *)(GPIOA_BASE + (port_index << 10)));
|
|
||||||
|
|
||||||
// Enable GPIO clock
|
// Enable GPIO clock
|
||||||
RCC_APB2PeriphClockCmd((uint32_t)(RCC_APB2Periph_GPIOA << port_index), ENABLE);
|
uint32_t gpio_add = Set_GPIO_Clock(port_index);
|
||||||
|
gpio = (GPIO_TypeDef *)gpio_add;
|
||||||
|
|
||||||
// Configure open-drain and pull-up/down
|
// Configure open-drain and pull-up/down
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
|
|
@ -30,9 +30,12 @@
|
||||||
#include "port_api.h"
|
#include "port_api.h"
|
||||||
#include "pinmap.h"
|
#include "pinmap.h"
|
||||||
#include "gpio_api.h"
|
#include "gpio_api.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
#if DEVICE_PORTIN || DEVICE_PORTOUT
|
#if DEVICE_PORTIN || DEVICE_PORTOUT
|
||||||
|
|
||||||
|
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
|
||||||
|
|
||||||
// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...)
|
// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...)
|
||||||
// low nibble = pin number
|
// low nibble = pin number
|
||||||
PinName port_pin(PortName port, int pin_n) {
|
PinName port_pin(PortName port, int pin_n) {
|
||||||
|
@ -40,14 +43,13 @@ PinName port_pin(PortName port, int pin_n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
|
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
|
||||||
|
GPIO_TypeDef *gpio;
|
||||||
|
|
||||||
uint32_t port_index = (uint32_t)port; // (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...)
|
uint32_t port_index = (uint32_t)port; // (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...)
|
||||||
|
|
||||||
// Enable GPIO clock
|
// Enable GPIO clock
|
||||||
RCC_APB2PeriphClockCmd((RCC_APB2Periph_GPIOA << port_index), ENABLE);
|
uint32_t gpio_add = Set_GPIO_Clock(port_index);
|
||||||
|
gpio = (GPIO_TypeDef *)gpio_add;
|
||||||
// Get GPIO structure base address
|
|
||||||
GPIO_TypeDef *gpio = (GPIO_TypeDef *)(GPIOA_BASE + (port_index << 10));
|
|
||||||
|
|
||||||
// Fill PORT object structure for future use
|
// Fill PORT object structure for future use
|
||||||
obj->port = port;
|
obj->port = port;
|
||||||
|
|
|
@ -34,11 +34,11 @@
|
||||||
|
|
||||||
#define TIM_MST TIM1
|
#define TIM_MST TIM1
|
||||||
#define TIM_MST_IRQ TIM1_CC_IRQn
|
#define TIM_MST_IRQ TIM1_CC_IRQn
|
||||||
#define TIM_MST_RCC RCC_APB2Periph_TIM1
|
#define TIM_MST_RCC RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE)
|
||||||
|
|
||||||
#define TIM_SLV TIM4
|
#define TIM_SLV TIM4
|
||||||
#define TIM_SLV_IRQ TIM4_IRQn
|
#define TIM_SLV_IRQ TIM4_IRQn
|
||||||
#define TIM_SLV_RCC RCC_APB1Periph_TIM4
|
#define TIM_SLV_RCC RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE)
|
||||||
|
|
||||||
#define MST_SLV_ITR TIM_TS_ITR0
|
#define MST_SLV_ITR TIM_TS_ITR0
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ void us_ticker_init(void) {
|
||||||
us_ticker_inited = 1;
|
us_ticker_inited = 1;
|
||||||
|
|
||||||
// Enable Timers clock
|
// Enable Timers clock
|
||||||
RCC_APB2PeriphClockCmd(TIM_MST_RCC, ENABLE);
|
TIM_MST_RCC;
|
||||||
RCC_APB1PeriphClockCmd(TIM_SLV_RCC, ENABLE);
|
TIM_SLV_RCC;
|
||||||
|
|
||||||
// Master and Slave timers time base configuration
|
// Master and Slave timers time base configuration
|
||||||
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||||
|
@ -94,9 +94,11 @@ uint32_t us_ticker_read() {
|
||||||
// previous (incorrect) value of Slave and the new value of Master, which would return a
|
// previous (incorrect) value of Slave and the new value of Master, which would return a
|
||||||
// value in the past. Avoid this by computing consecutive values of the timer until they
|
// value in the past. Avoid this by computing consecutive values of the timer until they
|
||||||
// are properly ordered.
|
// are properly ordered.
|
||||||
counter = counter2 = (uint32_t)((uint32_t)TIM_GetCounter(TIM_SLV) << 16) + (uint32_t)TIM_GetCounter(TIM_MST);
|
counter = (uint32_t)((uint32_t)TIM_GetCounter(TIM_SLV) << 16);
|
||||||
|
counter += (uint32_t)TIM_GetCounter(TIM_MST);
|
||||||
while (1) {
|
while (1) {
|
||||||
counter2 = (uint32_t)((uint32_t)TIM_GetCounter(TIM_SLV) << 16) + (uint32_t)TIM_GetCounter(TIM_MST);
|
counter2 = (uint32_t)((uint32_t)TIM_GetCounter(TIM_SLV) << 16);
|
||||||
|
counter2 += (uint32_t)TIM_GetCounter(TIM_MST);
|
||||||
if (counter2 > counter) {
|
if (counter2 > counter) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue