I’m using libmaple pure. The code
#include <libmaple/gpio.h>
#include <libmaple/exti.h>
#include <libmaple/rcc.h>
#include <libmaple/libmaple.h>
#include <libmaple/libmaple_types.h>
#include <libmaple/nvic.h>
#include <stdint.h>
//GVars---------------------------------------
volatile int s = 1;
//Functions-----------------------------------
static void myHandler();
int main(void){
RCC_BASE->APB2ENR |= (1 << 3);
//Enabling the clock for PORTB
GPIOB->regs->CRL |= ((1 << 4)|(1 << 5));
GPIOB->regs->CRL &= ~((1 << 7)|(1 << 6));//set PB1 as an output
//set PB8 as an input
gpio_set_mode(GPIOB, 8, GPIO_INPUT_PD);
afio_init();
//Enabling AFIO clock
nvic_init(0x80000000, 0x00);
nvic_globalirq_enable();
nvic_irq_set_priority(NVIC_EXTI_9_5, 0x00);
//Enabling interrupts and configuring priorities
exti_attach_interrupt(AFIO_EXTI_8, AFIO_EXTI_PB, myHandler, EXTI_FALLING);
//setting up the EXTI
//blinky
while(1){
if(s == 1)
{
GPIOB->regs->BSRR = (1 << 1);
delay_us(1000000);
GPIOB->regs->BRR = (1 << 1);
delay_us(1000000);
}
}
}
static void myHandler()
{
s = 0;
}
I’d recommend you abandon using the Arduino API and IDE and use something like CooCox, or Em:Blocks or Eclipse and program using the STM32Cube and the Standard peripheral library.
Actually, even the STM32Cube HAL based SPL may be too slow for you, as thats a bit abtracted as well, so you may nee to program using Coocox etc and directly setup the interrupt vector tables etc youself.
The best reference is the STM32F1 series programming manual RM0008 http://www.st.com/web/en/resource/techn … 171190.pdf
As this give full details how how to program things at a low level to get the highest performance.
You need to set (or unset) the flag in your ISR, and then unset (or set) in your loop, whichever is the opposite of the action in the ISR.
You could write this in a much simpler, more Arduinoesque form, but the code below should do what I think you are trying to do.
#include <libmaple/gpio.h>
#include <libmaple/exti.h>
#include <libmaple/rcc.h>
#include <libmaple/libmaple.h>
#include <libmaple/libmaple_types.h>
#include <libmaple/nvic.h>
#include <stdint.h>
//GVars---------------------------------------
volatile int s = 1;
//Functions-----------------------------------
static void myHandler();
int main(void){
RCC_BASE->APB2ENR |= (1 << 3);
//Enabling the clock for PORTB
GPIOB->regs->CRL |= ((1 << 4)|(1 << 5));
GPIOB->regs->CRL &= ~((1 << 7)|(1 << 6));//set PB1 as an output
//set PB8 as an input
gpio_set_mode(GPIOB, 8, GPIO_INPUT_PD);
afio_init();
//Enabling AFIO clock
nvic_init(0x80000000, 0x00);
nvic_globalirq_enable();
nvic_irq_set_priority(NVIC_EXTI_9_5, 0x00);
//Enabling interrupts and configuring priorities
exti_attach_interrupt(AFIO_EXTI_8, AFIO_EXTI_PB, myHandler, EXTI_FALLING);
//setting up the EXTI
//blinky
while(1){
if(s == 1)
{
s=0;
GPIOB->regs->BSRR = (1 << 1);
delay_us(1000000);
GPIOB->regs->BRR = (1 << 1);
delay_us(1000000);
}
}
}
static void myHandler()
{
s = 1;
}
BTW, I posted an older version of the code, I’ve tried using the algorithm, mine didn’t work, neither does yours…
Try the sketch below. I just tested on my STM32F103RCT6 with a PIR attached to PB8 (your input pin), and an LED on PB0 (my LED pin). You will need to change the LED pin. I’ve added some debug on the USBserial port, but you can change this to a USART port, or simply comment out the serial_debug lines.
(NOTE: You will need to comment the serial_debug out if you don’t attach to the serial debug output, as otherwise it tends to slow the sketch down.)
//
// STM32duino Simple pin interrupt test.
// Pressing the button triggers an interrupt, which sets/unsets the interrupt flag.
// The main loop switches the LED on ot off depending on the interrupt flag
// NOTE: on my board to switch ON the LED, I write a zero to the port pin.Your board may be different.
volatile int buttonISRFlag = LOW; // must declare volatile, since it's
// modified within the blink() handler
#define INPUT_PIN PB8
#define BOARD_LED_PIN PB0
USBSerial serial_debug;
void setup() {
pinMode(BOARD_LED_PIN, OUTPUT);
pinMode(INPUT_PIN, INPUT);
attachInterrupt(INPUT_PIN, blink, CHANGE);
}
void loop() {
// Spit out the current state of the pin, this should follow the state of buttonISRFlag
// There is a delay between the two which is the lenght of time it takes to service the ISR and get back to this point in the loop
// but for our purposes they will appear the same.
serial_debug.print("INPUT_PINP State: ");
serial_debug.println(digitalRead(BOARD_INPUT_PIN));
//
// 1=LED Off, 0=LED on, so we write !buttonISRFlag to the pin.
digitalWrite(BOARD_LED_PIN, !buttonISRFlag);
// Spit out the state of the ISR flag.
serial_debug.print("ISR Flag state: ");
serial_debug.println(buttonISRFlag);
delay(500);
}
void blink() {
buttonISRFlag=!buttonISRFlag;
}
//
// STM32duino Simple pin interrupt test.
// Pressing the button triggers an interrupt, which sets/unsets the interrupt flag.
// The main loop switches the LED on ot off depending on the interrupt flag
// NOTE: on my board to switch ON the LED, I write a zero to the port pin.Your board may be different.
volatile int buttonISRFlag = LOW; // must declare volatile, since it's
// modified within the blink() handler
#define INPUT_PIN PB8
#define BOARD_LED_PIN PB0
USBSerial serial_debug;
void setup() {
// Break down arduino stuff to libmaple equivalent...
// pinMode(BOARD_LED_PIN, OUTPUT);
// gpio_init(gpio_dev * dev)
gpio_init(GPIOB);
// gpio_set_mode(gpio_dev * dev, uint8 pin, gpio_pin_mode mode)
gpio_set_mode(GPIOB, 0, GPIO_OUTPUT_OD);
// Break down arduino stuff to libmaple equivalent...
//pinMode(INPUT_PIN, INPUT);
gpio_set_mode(GPIOB, 8, GPIO_INPUT_FLOATING);
// Break down arduino stuff to libmaple equivalent...
// attachInterrupt(INPUT_PIN, blink, CHANGE);
// afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port)
afio_init();
nvic_globalirq_enable();
exti_attach_interrupt(AFIO_EXTI_8, AFIO_EXTI_PB, blink, EXTI_RISING_FALLING);
afio_exti_select(AFIO_EXTI_8, AFIO_EXTI_PB );
nvic_irq_enable(NVIC_EXTI1);
}
void loop() {
// Spit out the current state of the pin, this should follow the state of buttonISRFlag
// There is a delay between the two which is the lenght of time it takes to service the ISR and get back to this point in the loop
// but for our purposes they will appear the same.
serial_debug.print("INPUT_PIN State: ");
// Read our button
// NOTE: The gpio_read_bit() call doesn't quite do the same as the digitalRead() call
// serial_debug.println(digitalRead(BOARD_INPUT_PIN));
serial_debug.println(gpio_read_bit(GPIOB,8));
// 1=LED Off, 0=LED on, so we write !buttonISRFlag to the pin.
//digitalWrite(BOARD_LED_PIN, !buttonISRFlag);
//gpio_write_bit(gpio_dev * dev, uint8 pin, uint8 val)
gpio_write_bit(GPIOB, 0, !buttonISRFlag);
// Spit out the state of the ISR flag.
serial_debug.print("ISR Flag state: ");
serial_debug.println(buttonISRFlag);
delay(500);
}
void blink() {
buttonISRFlag = !buttonISRFlag;
}
I corrected them. You might wanna take a look at your code
#include <wirish/wirish.h>
volatile int buttonISRFlag = LOW; // must declare volatile, since it's
// modified within the blink() handler
#define INPUT_PIN PB8
void blink();
USBSerial serial_debug;
void setup() {
// Break down arduino stuff to libmaple equivalent...
// pinMode(BOARD_LED_PIN, OUTPUT);
// gpio_init(gpio_dev * dev)
gpio_init(GPIOB);
// gpio_set_mode(gpio_dev * dev, uint8 pin, gpio_pin_mode mode)
gpio_set_mode(GPIOB, 1, GPIO_OUTPUT_PP);
// Break down arduino stuff to libmaple equivalent...
//pinMode(INPUT_PIN, INPUT);
gpio_set_mode(GPIOB, 8, GPIO_INPUT_PD);
// Break down arduino stuff to libmaple equivalent...
// attachInterrupt(INPUT_PIN, blink, CHANGE);
// afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port)
afio_init();
nvic_globalirq_enable();
exti_attach_interrupt(AFIO_EXTI_8, AFIO_EXTI_PB, blink, EXTI_RISING_FALLING);
afio_exti_select(AFIO_EXTI_8, AFIO_EXTI_PB );
nvic_irq_enable(NVIC_EXTI_9_5);
}
void loop() {
// Spit out the current state of the pin, this should follow the state of buttonISRFlag
// There is a delay between the two which is the lenght of time it takes to service the ISR and get back to this point in the loop
// but for our purposes they will appear the same.
serial_debug.print("INPUT_PIN State: ");
// Read our button
// NOTE: The gpio_read_bit() call doesn't quite do the same as the digitalRead() call
// serial_debug.println(digitalRead(BOARD_INPUT_PIN));
serial_debug.println(gpio_read_bit(GPIOB,8));
// 1=LED Off, 0=LED on, so we write !buttonISRFlag to the pin.
//digitalWrite(BOARD_LED_PIN, !buttonISRFlag);
//gpio_write_bit(gpio_dev * dev, uint8 pin, uint8 val)
gpio_write_bit(GPIOB, 1, !buttonISRFlag);
// Spit out the state of the ISR flag.
serial_debug.print("ISR Flag state: ");
serial_debug.println(buttonISRFlag);
delay(500);
}
void blink() {
buttonISRFlag = !buttonISRFlag;
}
int main(void){
init();
setup();
while(1)
loop();
}
I corrected them. You might wanna take a look at your code
#include <wirish/wirish.h>
volatile int buttonISRFlag = LOW; // must declare volatile, since it's
// modified within the blink() handler
#define INPUT_PIN PB8
void blink();
USBSerial serial_debug;
void setup() {
// Break down arduino stuff to libmaple equivalent...
// pinMode(BOARD_LED_PIN, OUTPUT);
// gpio_init(gpio_dev * dev)
gpio_init(GPIOB);
// gpio_set_mode(gpio_dev * dev, uint8 pin, gpio_pin_mode mode)
gpio_set_mode(GPIOB, 1, GPIO_OUTPUT_PP);
// Break down arduino stuff to libmaple equivalent...
//pinMode(INPUT_PIN, INPUT);
gpio_set_mode(GPIOB, 8, GPIO_INPUT_PD);
// Break down arduino stuff to libmaple equivalent...
// attachInterrupt(INPUT_PIN, blink, CHANGE);
// afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port)
afio_init();
nvic_globalirq_enable();
exti_attach_interrupt(AFIO_EXTI_8, AFIO_EXTI_PB, blink, EXTI_RISING_FALLING);
afio_exti_select(AFIO_EXTI_8, AFIO_EXTI_PB );
nvic_irq_enable(NVIC_EXTI_9_5);
}
void loop() {
// Spit out the current state of the pin, this should follow the state of buttonISRFlag
// There is a delay between the two which is the lenght of time it takes to service the ISR and get back to this point in the loop
// but for our purposes they will appear the same.
serial_debug.print("INPUT_PIN State: ");
// Read our button
// NOTE: The gpio_read_bit() call doesn't quite do the same as the digitalRead() call
// serial_debug.println(digitalRead(BOARD_INPUT_PIN));
serial_debug.println(gpio_read_bit(GPIOB,8));
// 1=LED Off, 0=LED on, so we write !buttonISRFlag to the pin.
//digitalWrite(BOARD_LED_PIN, !buttonISRFlag);
//gpio_write_bit(gpio_dev * dev, uint8 pin, uint8 val)
gpio_write_bit(GPIOB, 1, !buttonISRFlag);
// Spit out the state of the ISR flag.
serial_debug.print("ISR Flag state: ");
serial_debug.println(buttonISRFlag);
delay(500);
}
void blink() {
buttonISRFlag = !buttonISRFlag;
}
int main(void){
init();
setup();
while(1)
loop();
}
I look forward to seeing your uberfast version when I get back.
One more thing.. I just spotted this little gem in nvic.h NVIC_USBWAKEUP = 42 -USB wakeup from suspend through EXTI line.
I think I’m going to have to have a play with that.
The BlackMagic Probe (BMP) software is built on top of libopencm3.
-rick
Has a learning curve.
Not Arduino. But the ST HAL libraries have well documented drivers for all on-chip peripherals. And there are API versions for polling, interrupt, and DMA operation.
ST is updating the HALs and CubeMX several times a year and as new MCUs come out.
If you are a very casual “Make” person, and can tolerate the limited choice of I/O in the Arduino world, esp. for STM32s, then the above isn’t for you.
But, if you want to avoid reinventing I/O drivers, or you want to more easily move code between, say, STM32F1xx and STM32F4xx, then IMO the above are the best tools for avocational or professional use.
compiler project output for GCC with Eclipse or IAR/Keil which have free versions for code < 32KB.
And they’re free.
I’ve already posted, basically the same thing. But the OP seems to want to use Arduino API and yet still have fast responses.
Personally, I think they may be able to resolve their speed problems in one place, but sooner or later they will find another place the Arduino API is too slow.
I’ve already posted, basically the same thing. But the OP seems to want to use Arduino API and yet still have fast responses.
Personally, I think they may be able to resolve their speed problems in one place, but sooner or later they will find another place the Arduino API is too slow.
<…>
If I need to control rocket telemetry or bit bang high speed protocols, I may struggle to do it with native Arduino code. Having said that, with more controllers now targeted by the ‘diono method, additional Arduino hardware choices mean that if you want it quicker, you might be better to simply port to a quicker processor.



