Skip to content

Commit

Permalink
Add IO, EXTI and RCC implementation
Browse files Browse the repository at this point in the history
New files are added
exti.h contains both old and new implemnetation (to be removed soon)
Available IO pins are defined for all targets (should be checked against schematics)
Implemented priority handling for EXTI (history rewrite)
  • Loading branch information
ledvinap committed Jun 9, 2016
1 parent c4cdf32 commit 1bf5737
Show file tree
Hide file tree
Showing 32 changed files with 2,030 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Makefile
Expand Up @@ -256,6 +256,9 @@ COMMON_SRC = build_config.c \
flight/mixer.c \
flight/servos.c \
drivers/bus_i2c_soft.c \
drivers/exti.c \
drivers/io.c \
drivers/rcc.c \
drivers/serial.c \
drivers/sound_beeper.c \
drivers/system.c \
Expand Down
22 changes: 22 additions & 0 deletions src/main/common/utils.h
Expand Up @@ -18,6 +18,7 @@
#pragma once

#include <stddef.h>
#include <stdint.h>

#define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
#define ARRAYEND(x) (&(x)[ARRAYLEN(x)])
Expand All @@ -28,6 +29,13 @@
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

#define EXPAND_I(x) x
#define EXPAND(x) EXPAND_I(x)

#define UNUSED(x) (void)(x)
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))

#define BIT(x) (1 << (x))
/*
http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html
*/
Expand All @@ -36,6 +44,20 @@

#define UNUSED(x) (void)(x)

/*
* https://groups.google.com/forum/?hl=en#!msg/comp.lang.c/attFnqwhvGk/sGBKXvIkY3AJ
* Return (v ? floor(log2(v)) : 0) when 0 <= v < 1<<[8, 16, 32, 64].
* Inefficient algorithm, intended for compile-time constants.
*/
#define LOG2_8BIT(v) (8 - 90/(((v)/4+14)|1) - 2/((v)/2+1))
#define LOG2_16BIT(v) (8*((v)>255) + LOG2_8BIT((v) >>8*((v)>255)))
#define LOG2_32BIT(v) (16*((v)>65535L) + LOG2_16BIT((v)*1L >>16*((v)>65535L)))
#define LOG2_64BIT(v) \
(32*((v)/2L>>31 > 0) \
+ LOG2_32BIT((v)*1L >>16*((v)/2L>>31 > 0) \
>>16*((v)/2L>>31 > 0)))


#if 0
// ISO C version, but no type checking
#define container_of(ptr, type, member) \
Expand Down
174 changes: 174 additions & 0 deletions src/main/drivers/exti.c
@@ -0,0 +1,174 @@
#include <string.h>
#include <stdbool.h>
#include <stdint.h>

#include "platform.h"

#include "drivers/nvic.h"
#include "drivers/io_impl.h"

#include "exti.h"

#ifdef USE_EXTI

typedef struct {
extiCallbackRec_t* handler;
} extiChannelRec_t;

extiChannelRec_t extiChannelRecs[16];

// IRQ gouping, same on 103 and 303
#define EXTI_IRQ_GROUPS 7
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
static const uint8_t extiGroups[16] = { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 };
static uint8_t extiGroupPriority[EXTI_IRQ_GROUPS];

#if defined(STM32F10X)
static const uint8_t extiGroupIRQn[EXTI_IRQ_GROUPS] = {
EXTI0_IRQn, EXTI1_IRQn, EXTI2_IRQn, EXTI3_IRQn, EXTI4_IRQn,
EXTI9_5_IRQn, EXTI15_10_IRQn
};
#elif defined(STM32F303xC)
static const uint8_t extiGroupIRQn[EXTI_IRQ_GROUPS] = {
EXTI0_IRQn, EXTI1_IRQn, EXTI2_TS_IRQn, EXTI3_IRQn, EXTI4_IRQn,
EXTI9_5_IRQn, EXTI15_10_IRQn
};
#else
# warning "Unsupported CPU"
#endif




void EXTIInit(void)
{
#ifdef STM32F10X
// enable AFIO for EXTI support
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
#endif
#ifdef STM32F303xC
/* Enable SYSCFG clock otherwise the EXTI irq handlers are not called */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
#endif
memset(extiChannelRecs, 0, sizeof(extiChannelRecs));
memset(extiGroupPriority, 0xff, sizeof(extiGroupPriority));
}

void EXTIHandlerInit(extiCallbackRec_t *self, extiHandlerCallback *fn)
{
self->fn = fn;
}

void EXTIConfig(IO_t io, extiCallbackRec_t *cb, int irqPriority, EXTITrigger_TypeDef trigger)
{
int chIdx;
chIdx = IO_GPIOPinIdx(io);
if(chIdx < 0)
return;
extiChannelRec_t *rec = &extiChannelRecs[chIdx];
int group = extiGroups[chIdx];

rec->handler = cb;
#if defined(STM32F10X)
GPIO_EXTILineConfig(IO_GPIO_PortSource(io), IO_GPIO_PinSource(io));
#elif defined(STM32F303xC)
SYSCFG_EXTILineConfig(IO_EXTI_PortSourceGPIO(io), IO_EXTI_PinSource(io));
#else
# warning "Unsupported CPU"
#endif
uint32_t extiLine = IO_EXTI_Line(io);

EXTI_ClearITPendingBit(extiLine);

EXTI_InitTypeDef EXTIInit;
EXTIInit.EXTI_Line = extiLine;
EXTIInit.EXTI_Mode = EXTI_Mode_Interrupt;
EXTIInit.EXTI_Trigger = trigger;
EXTIInit.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTIInit);

if(extiGroupPriority[group] > irqPriority) {
extiGroupPriority[group] = irqPriority;

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = extiGroupIRQn[group];
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(irqPriority);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(irqPriority);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
}

void EXTIRelease(IO_t io)
{
// don't forget to match cleanup with config
EXTIEnable(io, false);

int chIdx;
chIdx = IO_GPIOPinIdx(io);
if(chIdx < 0)
return;
extiChannelRec_t *rec = &extiChannelRecs[chIdx];
rec->handler = NULL;
}

void EXTIEnable(IO_t io, bool enable)
{
#if defined(STM32F10X)
uint32_t extiLine = IO_EXTI_Line(io);
if(!extiLine)
return;
if(enable)
EXTI->IMR |= extiLine;
else
EXTI->IMR &= ~extiLine;
#elif defined(STM32F303xC)
int extiLine = IO_EXTI_Line(io);
if(extiLine < 0)
return;
// assume extiLine < 32 (valid for all EXTI pins)
if(enable)
EXTI->IMR |= 1 << extiLine;
else
EXTI->IMR &= ~(1 << extiLine);
#else
# error "Unsupported CPU"
#endif
}

void EXTI_IRQHandler(void)
{
uint32_t exti_active = EXTI->IMR & EXTI->PR;

while(exti_active) {
unsigned idx = 31 - __builtin_clz(exti_active);
uint32_t mask = 1 << idx;
extiChannelRecs[idx].handler->fn(extiChannelRecs[idx].handler);
EXTI->PR = mask; // clear pending mask (by writing 1)
exti_active &= ~mask;
}
}

#define _EXTI_IRQ_HANDLER(name) \
void name(void) { \
EXTI_IRQHandler(); \
} \
struct dummy \
/**/


_EXTI_IRQ_HANDLER(EXTI0_IRQHandler);
_EXTI_IRQ_HANDLER(EXTI1_IRQHandler);
#if defined(STM32F10X)
_EXTI_IRQ_HANDLER(EXTI2_IRQHandler);
#elif defined(STM32F303xC)
_EXTI_IRQ_HANDLER(EXTI2_TS_IRQHandler);
#else
# warning "Unsupported CPU"
#endif
_EXTI_IRQ_HANDLER(EXTI3_IRQHandler);
_EXTI_IRQ_HANDLER(EXTI4_IRQHandler);
_EXTI_IRQ_HANDLER(EXTI9_5_IRQHandler);
_EXTI_IRQ_HANDLER(EXTI15_10_IRQHandler);

#endif
17 changes: 17 additions & 0 deletions src/main/drivers/exti.h
Expand Up @@ -18,6 +18,7 @@

#pragma once

// old EXTI interface, to be replaced
typedef struct extiConfig_s {
#ifdef STM32F303
uint32_t gpioAHBPeripherals;
Expand All @@ -33,3 +34,19 @@ typedef struct extiConfig_s {
uint8_t exti_pin_source;
IRQn_Type exti_irqn;
} extiConfig_t;

// new io EXTI interface
#include "drivers/io.h"
typedef struct extiCallbackRec_s extiCallbackRec_t;
typedef void extiHandlerCallback(extiCallbackRec_t *self);

struct extiCallbackRec_s {
extiHandlerCallback *fn;
};

void EXTIInit(void);

void EXTIHandlerInit(extiCallbackRec_t *cb, extiHandlerCallback *fn);
void EXTIConfig(IO_t io, extiCallbackRec_t *cb, int irqPriority, EXTITrigger_TypeDef trigger);
void EXTIRelease(IO_t io);
void EXTIEnable(IO_t io, bool enable);

0 comments on commit 1bf5737

Please sign in to comment.