Compare commits

..

1 Commits

Author SHA1 Message Date
LEdoian 9ba5cff642 Add readme 5 years ago

@ -13,6 +13,6 @@ CPU_FLAGS := -mthumb -mcpu=cortex-m3 -msoft-float -mfix-cortex-m3-ldrd
arm-none-eabi-objcopy -Obinary $*.elf $*.bin arm-none-eabi-objcopy -Obinary $*.elf $*.bin
flash: main.bin flash: main.bin
st-flash --reset write main.bin 0x08000000 st-flash write /dev/stlinkv1_4 main.bin 0x08000000
.PHONY: flash .PHONY: flash

@ -0,0 +1,35 @@
Setup
===
1. Need the "newlib" arm library (else there is no stdint.h &co.)
```sh
pacman -S arm-none-eabi-newlib
```
2. Get Libopencm3
```sh
git submodule init
git submodule update
```
3. Generate headers in Libopencm3
```sh
cd libopencm3
make
cd ..
```
Possibly there are also some udev rules & co, I think they can be acquired from
the `stlink` package.
Usage
===
```
make
```
It does everything. At least for STM32VLDISCOVERY board at my computer.

@ -13,27 +13,22 @@
#include <libopencm3/stm32/gpio.h> #include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/f1/exti.h> #include <libopencm3/stm32/f1/exti.h>
#include <libopencm3/stm32/f1/nvic.h> #include <libopencm3/stm32/f1/nvic.h>
#include <libopencm3/stm32/f1/timer.h>
#include <stdbool.h> #include <stdbool.h>
//#define DELAY 8000000 // Should be a second, or maybe not (second iff 8MHz clk, 1/3second if 24MHz clk) // Too long!! //#define DELAY 8000000 // Should be a second, or maybe not (second iff 8MHz clk, 1/3second if 24MHz clk) // Too long!!
#define DELAY 4000000 // This is bad -- it's a value that was found to be OK
#define STM32F1 1 // Needed for libopencm3 #define STM32F1 1 // Needed for libopencm3
void setup_system (void) { volatile enum {FORWARD, BACKWARD} direction;
volatile bool running = false;
void setup (void) { // All the blackbox code
// Set up clock // Set up clock
rcc_clock_setup_in_hse_8mhz_out_24mhz(); rcc_clock_setup_in_hse_8mhz_out_24mhz();
}
void setup_gpio_out (void) { // Enable the two GPIOs
// Enable clock for GPIO C
rcc_periph_clock_enable(RCC_GPIOC); rcc_periph_clock_enable(RCC_GPIOC);
// GPIO C8 amd C9 are the two LEDs
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO8 | GPIO9);
}
void setup_exti0_in (void) {
// Enable clock for GPIO A
rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOA);
// Enable AFIO (we need that to map GPIO to EXTI) // Enable AFIO (we need that to map GPIO to EXTI)
@ -44,6 +39,8 @@ void setup_exti0_in (void) {
// This one is for EXTI0 ~~ GPIOx0 pins // This one is for EXTI0 ~~ GPIOx0 pins
nvic_enable_irq(NVIC_EXTI0_IRQ); nvic_enable_irq(NVIC_EXTI0_IRQ);
// GPIO C8 amd C9 are the two LEDs
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO8 | GPIO9);
// GPIO A0 is the push button // GPIO A0 is the push button
// And we set it as a regular button and enable its interrupts in the next block // And we set it as a regular button and enable its interrupts in the next block
@ -58,32 +55,6 @@ void setup_exti0_in (void) {
exti_enable_request(EXTI0); exti_enable_request(EXTI0);
} }
void setup_tim6_periodic_irq (void) {
// Enable clock
rcc_periph_clock_enable(RCC_TIM6);
// Config:
// Set prescaler
timer_set_prescaler(TIM6, 65535);
// Set counter value
timer_set_period(TIM6, 183);
// Enable interrupts in NVIC
nvic_enable_irq(NVIC_TIM6_IRQ);
// Enable sending interrupts from the timer
timer_enable_irq(TIM6, TIM_DIER_UIE);
// Finally, enable the counter
timer_enable_counter(TIM6);
}
void setup (void) {
setup_system();
setup_gpio_out();
setup_exti0_in();
setup_tim6_periodic_irq();
}
// libopencm3 has a pre-declared interrupt handlers, so it needs to have this name // libopencm3 has a pre-declared interrupt handlers, so it needs to have this name
void exti0_isr (void) { void exti0_isr (void) {
// Clear the interrupt // Clear the interrupt
@ -91,27 +62,36 @@ void exti0_isr (void) {
// NB: For some reason it is at the begining in the examples // NB: For some reason it is at the begining in the examples
// It needs to be here (possibly because of reordering, when this was at the end, I usually got the interrupt twice). // It needs to be here (possibly because of reordering, when this was at the end, I usually got the interrupt twice).
// Toggle TIM6 in order to disable blinking if (!running) {
// Code inspired by libopencm3 source, since we cannot read the status otherwise… direction = FORWARD;
TIM_CR1(TIM6) ^= TIM_CR1_CEN;
}
void tim6_isr (void) {
timer_clear_flag(TIM6, TIM_SR_UIF);
// Just change value of GPIO C9 (green LED)
uint16_t cur = gpio_get(GPIOC, GPIO9);
if (cur) {
gpio_clear(GPIOC, GPIO9);
} else { } else {
gpio_set(GPIOC, GPIO9); direction = direction == FORWARD ? BACKWARD : FORWARD;
} }
running = true;
} }
int main (void) { int main (void) {
setup(); setup();
while (true) __asm ("wfi"); // Array of what leds should be on
uint16_t states[4] = {0, GPIO9, GPIO8, GPIO9 | GPIO8};
char state = 0;
int i;
// Initial wait
while (!running) ;
while (true) {
for (i=0 ; i<DELAY ; i++) {
__asm ("nop");
}
state = (direction == FORWARD ? (state + 1)%4 : (/*state+4-1*/ state+3)%4 ); // New state
gpio_set(GPIOC, states[state]);
gpio_clear(GPIOC, (GPIO8 | GPIO9) ^ states[state]);
}
return 0; return 0;
} }

Loading…
Cancel
Save