414 lines
15 KiB
C++
414 lines
15 KiB
C++
// ArduinoCompat/wirish.cpp
|
|
//
|
|
// Arduino-like API for STM32F4 Discovery and similar
|
|
// using STM32F4xx_DSP_StdPeriph_Lib_V1.3.0
|
|
|
|
#include <RadioHead.h>
|
|
#if (RH_PLATFORM == RH_PLATFORM_STM32STD)
|
|
#include <wirish.h>
|
|
|
|
SerialUSBClass SerialUSB;
|
|
|
|
// Describes all the STM32 things we need to know about a digital IO pin to
|
|
// make it input or output or to configure as an interrupt
|
|
typedef struct
|
|
{
|
|
uint32_t ahbperiph;
|
|
GPIO_TypeDef* port;
|
|
uint16_t pin;
|
|
uint8_t extiportsource;
|
|
uint8_t extipinsource;
|
|
} GPIOPin;
|
|
|
|
// These describe the registers and bits for each digital IO pin to allow us to
|
|
// provide Arduino-like pin addressing, digitalRead etc.
|
|
// Indexed by pin number
|
|
GPIOPin pins[] =
|
|
{
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_0, EXTI_PortSourceGPIOA, EXTI_PinSource0 }, // 0 = PA0
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_1, EXTI_PortSourceGPIOA, EXTI_PinSource1 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_2, EXTI_PortSourceGPIOA, EXTI_PinSource2 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_3, EXTI_PortSourceGPIOA, EXTI_PinSource3 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_4, EXTI_PortSourceGPIOA, EXTI_PinSource4 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_5, EXTI_PortSourceGPIOA, EXTI_PinSource5 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_6, EXTI_PortSourceGPIOA, EXTI_PinSource6 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_7, EXTI_PortSourceGPIOA, EXTI_PinSource7 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_8, EXTI_PortSourceGPIOA, EXTI_PinSource8 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_9, EXTI_PortSourceGPIOA, EXTI_PinSource9 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_10, EXTI_PortSourceGPIOA, EXTI_PinSource10 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_11, EXTI_PortSourceGPIOA, EXTI_PinSource11 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_12, EXTI_PortSourceGPIOA, EXTI_PinSource12 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_13, EXTI_PortSourceGPIOA, EXTI_PinSource13 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_14, EXTI_PortSourceGPIOA, EXTI_PinSource14 },
|
|
{ RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_15, EXTI_PortSourceGPIOA, EXTI_PinSource15 }, // 15 = PA15
|
|
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_0, EXTI_PortSourceGPIOB, EXTI_PinSource0 }, // 16 = PB0
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_1, EXTI_PortSourceGPIOB, EXTI_PinSource1 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_2, EXTI_PortSourceGPIOB, EXTI_PinSource2 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_3, EXTI_PortSourceGPIOB, EXTI_PinSource3 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_4, EXTI_PortSourceGPIOB, EXTI_PinSource4 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_5, EXTI_PortSourceGPIOB, EXTI_PinSource5 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_6, EXTI_PortSourceGPIOB, EXTI_PinSource6 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_7, EXTI_PortSourceGPIOB, EXTI_PinSource7 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_8, EXTI_PortSourceGPIOB, EXTI_PinSource8 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_9, EXTI_PortSourceGPIOB, EXTI_PinSource9 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_10, EXTI_PortSourceGPIOB, EXTI_PinSource10 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_11, EXTI_PortSourceGPIOB, EXTI_PinSource11 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_12, EXTI_PortSourceGPIOB, EXTI_PinSource12 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_13, EXTI_PortSourceGPIOB, EXTI_PinSource13 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_14, EXTI_PortSourceGPIOB, EXTI_PinSource14 },
|
|
{ RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_15, EXTI_PortSourceGPIOB, EXTI_PinSource15 }, // 31 = PB15
|
|
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_0, EXTI_PortSourceGPIOC, EXTI_PinSource0 }, // 32 = PC0
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_1, EXTI_PortSourceGPIOC, EXTI_PinSource1 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_2, EXTI_PortSourceGPIOC, EXTI_PinSource2 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_3, EXTI_PortSourceGPIOC, EXTI_PinSource3 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_4, EXTI_PortSourceGPIOC, EXTI_PinSource4 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_5, EXTI_PortSourceGPIOC, EXTI_PinSource5 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_6, EXTI_PortSourceGPIOC, EXTI_PinSource6 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_7, EXTI_PortSourceGPIOC, EXTI_PinSource7 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_8, EXTI_PortSourceGPIOC, EXTI_PinSource8 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_9, EXTI_PortSourceGPIOC, EXTI_PinSource9 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_10, EXTI_PortSourceGPIOC, EXTI_PinSource10 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_11, EXTI_PortSourceGPIOC, EXTI_PinSource11 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_12, EXTI_PortSourceGPIOC, EXTI_PinSource12 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_13, EXTI_PortSourceGPIOC, EXTI_PinSource13 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_14, EXTI_PortSourceGPIOC, EXTI_PinSource14 },
|
|
{ RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_15, EXTI_PortSourceGPIOC, EXTI_PinSource15 }, // 47 = PC15
|
|
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_0, EXTI_PortSourceGPIOD, EXTI_PinSource0 }, // 48 = PD0
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_1, EXTI_PortSourceGPIOD, EXTI_PinSource1 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_2, EXTI_PortSourceGPIOD, EXTI_PinSource2 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_3, EXTI_PortSourceGPIOD, EXTI_PinSource3 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_4, EXTI_PortSourceGPIOD, EXTI_PinSource4 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_5, EXTI_PortSourceGPIOD, EXTI_PinSource5 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_6, EXTI_PortSourceGPIOD, EXTI_PinSource6 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_7, EXTI_PortSourceGPIOD, EXTI_PinSource7 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_8, EXTI_PortSourceGPIOD, EXTI_PinSource8 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_9, EXTI_PortSourceGPIOD, EXTI_PinSource9 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_10, EXTI_PortSourceGPIOD, EXTI_PinSource10 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_11, EXTI_PortSourceGPIOD, EXTI_PinSource11 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_12, EXTI_PortSourceGPIOD, EXTI_PinSource12 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_13, EXTI_PortSourceGPIOD, EXTI_PinSource13 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_14, EXTI_PortSourceGPIOD, EXTI_PinSource14 },
|
|
{ RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_15, EXTI_PortSourceGPIOD, EXTI_PinSource15 }, // 63 = PD15
|
|
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_0, EXTI_PortSourceGPIOE, EXTI_PinSource0 }, // 64 = PE0
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_1, EXTI_PortSourceGPIOE, EXTI_PinSource1 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_2, EXTI_PortSourceGPIOE, EXTI_PinSource2 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_3, EXTI_PortSourceGPIOE, EXTI_PinSource3 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_4, EXTI_PortSourceGPIOE, EXTI_PinSource4 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_5, EXTI_PortSourceGPIOE, EXTI_PinSource5 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_6, EXTI_PortSourceGPIOE, EXTI_PinSource6 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_7, EXTI_PortSourceGPIOE, EXTI_PinSource7 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_8, EXTI_PortSourceGPIOE, EXTI_PinSource8 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_9, EXTI_PortSourceGPIOE, EXTI_PinSource9 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_10, EXTI_PortSourceGPIOE, EXTI_PinSource10 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_11, EXTI_PortSourceGPIOE, EXTI_PinSource11 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_12, EXTI_PortSourceGPIOE, EXTI_PinSource12 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_13, EXTI_PortSourceGPIOE, EXTI_PinSource13 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_14, EXTI_PortSourceGPIOE, EXTI_PinSource14 },
|
|
{ RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_15, EXTI_PortSourceGPIOE, EXTI_PinSource15 }, // 79 = PE15
|
|
|
|
};
|
|
#define NUM_PINS (sizeof(pins) / sizeof(GPIOPin))
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t extiline;
|
|
uint8_t extiirqn;
|
|
void (*handler)(void);
|
|
} IRQLine;
|
|
|
|
// IRQ line data indexed by pin source number with its port
|
|
// and the programmable handler that will handle interrupts on that line
|
|
IRQLine irqlines[] =
|
|
{
|
|
{ EXTI_Line0, EXTI0_IRQn, 0 },
|
|
{ EXTI_Line1, EXTI1_IRQn, 0 },
|
|
{ EXTI_Line2, EXTI2_IRQn, 0 },
|
|
{ EXTI_Line3, EXTI3_IRQn, 0 },
|
|
{ EXTI_Line4, EXTI4_IRQn, 0 },
|
|
{ EXTI_Line5, EXTI9_5_IRQn, 0 },
|
|
{ EXTI_Line6, EXTI9_5_IRQn, 0 },
|
|
{ EXTI_Line7, EXTI9_5_IRQn, 0 },
|
|
{ EXTI_Line8, EXTI9_5_IRQn, 0 },
|
|
{ EXTI_Line9, EXTI9_5_IRQn, 0 },
|
|
{ EXTI_Line10, EXTI15_10_IRQn, 0 },
|
|
{ EXTI_Line11, EXTI15_10_IRQn, 0 },
|
|
{ EXTI_Line12, EXTI15_10_IRQn, 0 },
|
|
{ EXTI_Line13, EXTI15_10_IRQn, 0 },
|
|
{ EXTI_Line14, EXTI15_10_IRQn, 0 },
|
|
{ EXTI_Line15, EXTI15_10_IRQn, 0 },
|
|
};
|
|
|
|
#define NUM_IRQ_LINES (sizeof(irqlines) / sizeof(IRQLine))
|
|
|
|
// Functions we expect to find in the sketch
|
|
extern void setup();
|
|
extern void loop();
|
|
|
|
volatile unsigned long systick_count = 0;
|
|
|
|
void SysTickConfig()
|
|
{
|
|
/* Setup SysTick Timer for 1ms interrupts */
|
|
if (SysTick_Config(SystemCoreClock / 1000))
|
|
{
|
|
/* Capture error */
|
|
while (1);
|
|
}
|
|
|
|
/* Configure the SysTick handler priority */
|
|
NVIC_SetPriority(SysTick_IRQn, 0x0);
|
|
// SysTick_Handler will now be called every 1 ms
|
|
}
|
|
|
|
// These interrupt handlers have to be extern C else they dont get linked in to the interrupt vectors
|
|
extern "C"
|
|
{
|
|
// Called every 1 ms
|
|
void SysTick_Handler(void)
|
|
{
|
|
systick_count++;
|
|
}
|
|
|
|
// Interrupt handlers for optional external GPIO interrupts
|
|
void EXTI0_IRQHandler(void)
|
|
{
|
|
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
|
|
{
|
|
if (irqlines[0].handler)
|
|
irqlines[0].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line0);
|
|
}
|
|
}
|
|
void EXTI1_IRQHandler(void)
|
|
{
|
|
if (EXTI_GetITStatus(EXTI_Line1) != RESET)
|
|
{
|
|
if (irqlines[1].handler)
|
|
irqlines[1].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line1);
|
|
}
|
|
}
|
|
void EXTI2_IRQHandler(void)
|
|
{
|
|
if (EXTI_GetITStatus(EXTI_Line2) != RESET)
|
|
{
|
|
if (irqlines[2].handler)
|
|
irqlines[2].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line2);
|
|
}
|
|
}
|
|
void EXTI3_IRQHandler(void)
|
|
{
|
|
if (EXTI_GetITStatus(EXTI_Line3) != RESET)
|
|
{
|
|
if (irqlines[3].handler)
|
|
irqlines[3].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line3);
|
|
}
|
|
}
|
|
void EXTI4_IRQHandler(void)
|
|
{
|
|
if (EXTI_GetITStatus(EXTI_Line4) != RESET)
|
|
{
|
|
if (irqlines[4].handler)
|
|
irqlines[4].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line4);
|
|
}
|
|
}
|
|
void EXTI9_5_IRQHandler(void)
|
|
{
|
|
if (EXTI_GetITStatus(EXTI_Line5) != RESET)
|
|
{
|
|
if (irqlines[5].handler)
|
|
irqlines[5].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line5);
|
|
}
|
|
if (EXTI_GetITStatus(EXTI_Line6) != RESET)
|
|
{
|
|
if (irqlines[6].handler)
|
|
irqlines[6].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line6);
|
|
}
|
|
if (EXTI_GetITStatus(EXTI_Line7) != RESET)
|
|
{
|
|
if (irqlines[7].handler)
|
|
irqlines[7].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line7);
|
|
}
|
|
if (EXTI_GetITStatus(EXTI_Line8) != RESET)
|
|
{
|
|
if (irqlines[8].handler)
|
|
irqlines[8].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line8);
|
|
}
|
|
if (EXTI_GetITStatus(EXTI_Line9) != RESET)
|
|
{
|
|
if (irqlines[9].handler)
|
|
irqlines[9].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line9);
|
|
}
|
|
}
|
|
void EXTI15_10_IRQHandler(void)
|
|
{
|
|
if (EXTI_GetITStatus(EXTI_Line10) != RESET)
|
|
{
|
|
if (irqlines[10].handler)
|
|
irqlines[10].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line10);
|
|
}
|
|
if (EXTI_GetITStatus(EXTI_Line11) != RESET)
|
|
{
|
|
if (irqlines[11].handler)
|
|
irqlines[11].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line11);
|
|
}
|
|
if (EXTI_GetITStatus(EXTI_Line12) != RESET)
|
|
{
|
|
if (irqlines[12].handler)
|
|
irqlines[12].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line12);
|
|
}
|
|
if (EXTI_GetITStatus(EXTI_Line13) != RESET)
|
|
{
|
|
if (irqlines[13].handler)
|
|
irqlines[13].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line13);
|
|
}
|
|
if (EXTI_GetITStatus(EXTI_Line14) != RESET)
|
|
{
|
|
if (irqlines[14].handler)
|
|
irqlines[14].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line14);
|
|
}
|
|
if (EXTI_GetITStatus(EXTI_Line15) != RESET)
|
|
{
|
|
if (irqlines[15].handler)
|
|
irqlines[15].handler();
|
|
EXTI_ClearITPendingBit(EXTI_Line15);
|
|
}
|
|
}
|
|
}
|
|
|
|
// The sketch we want to run
|
|
//#include "examples/rf22/rf22_client/rf22_client.pde"
|
|
|
|
// Run the Arduino standard functions in the main loop
|
|
int main(int argc, char** argv)
|
|
{
|
|
SysTickConfig();
|
|
// Seed the random number generator
|
|
// srand(getpid() ^ (unsigned) time(NULL)/2);
|
|
setup();
|
|
while (1)
|
|
loop();
|
|
}
|
|
|
|
void pinMode(uint8_t pin, WiringPinMode mode)
|
|
{
|
|
if (pin > NUM_PINS)
|
|
return;
|
|
// Enable the GPIO clock
|
|
RCC_AHB1PeriphClockCmd(pins[pin].ahbperiph, ENABLE);
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
GPIO_InitStructure.GPIO_Pin = pins[pin].pin;
|
|
if (mode == INPUT)
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // REVISIT
|
|
else if (mode == OUTPUT)
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // REVISIT
|
|
else
|
|
return; // Unknown so far
|
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
GPIO_Init(pins[pin].port, &GPIO_InitStructure);
|
|
}
|
|
|
|
// This takes about 150ns on STM32F4 Discovery
|
|
void digitalWrite(uint8_t pin, uint8_t val)
|
|
{
|
|
if (pin > NUM_PINS)
|
|
return;
|
|
if (val)
|
|
GPIO_SetBits(pins[pin].port, pins[pin].pin);
|
|
else
|
|
GPIO_ResetBits(pins[pin].port, pins[pin].pin);
|
|
}
|
|
|
|
uint8_t digitalRead(uint8_t pin)
|
|
{
|
|
if (pin > NUM_PINS)
|
|
return 0;
|
|
return GPIO_ReadInputDataBit(pins[pin].port, pins[pin].pin);
|
|
}
|
|
|
|
void attachInterrupt(uint8_t pin, void (*handler)(void), int mode)
|
|
{
|
|
EXTI_InitTypeDef EXTI_InitStructure;
|
|
NVIC_InitTypeDef NVIC_InitStructure;
|
|
|
|
// Record the handler to call when the interrupt occurs
|
|
irqlines[pins[pin].extipinsource].handler = handler;
|
|
|
|
/* Connect EXTI Line to GPIO Pin */
|
|
SYSCFG_EXTILineConfig(pins[pin].extiportsource, pins[pin].extipinsource);
|
|
|
|
/* Configure EXTI line */
|
|
EXTI_InitStructure.EXTI_Line = irqlines[pins[pin].extipinsource].extiline;
|
|
|
|
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
|
if (mode == RISING)
|
|
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
|
else if (mode == FALLING)
|
|
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
|
|
else if (mode == CHANGE)
|
|
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
|
|
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
|
EXTI_Init(&EXTI_InitStructure);
|
|
|
|
/* Enable and set EXTI Interrupt to the lowest priority */
|
|
NVIC_InitStructure.NVIC_IRQChannel = irqlines[pins[pin].extipinsource].extiirqn;
|
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
|
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
|
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
|
NVIC_Init(&NVIC_InitStructure);
|
|
|
|
// The relevant EXTI?_IRQHandler
|
|
// will now be called when the pin makes the selected transition
|
|
}
|
|
|
|
void delay(unsigned long ms)
|
|
{
|
|
unsigned long start = millis();
|
|
|
|
while (millis() - start < ms)
|
|
;
|
|
}
|
|
|
|
unsigned long millis()
|
|
{
|
|
return systick_count;
|
|
}
|
|
|
|
long random(long from, long to)
|
|
{
|
|
return from + (RNG_GetRandomNumber() % (to - from));
|
|
}
|
|
|
|
long random(long to)
|
|
{
|
|
return random(0, to);
|
|
}
|
|
|
|
extern "C"
|
|
{
|
|
// These need to be in C land for correct linking
|
|
void _init() {}
|
|
void _fini() {}
|
|
}
|
|
|
|
#endif
|