Skip to content

Commit

Permalink
Restructured repo
Browse files Browse the repository at this point in the history
  • Loading branch information
jomaway committed Jan 26, 2024
1 parent 35ac27f commit b126c7d
Show file tree
Hide file tree
Showing 126 changed files with 956 additions and 1,676 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
Nucleo-F401RE Blinky (CMSIS version)
Nucleo-F401RE exti push button blink version (CMSIS version)
This Program should start/stop blinking the USER LED (PA5) on the nucleo f401re Board, if the USER BUTTON (PC13) is pressed.
But instead of polling the state of the butten this version uses an interrupt to trigger a butten press.
Therefore we need to do a bit of a setup.
SETUP for the interrupt:
1. Enable the clock for the system configuration controller (SYSCFG)
2. Set port c as exti in SYSCFG_EXTICR4 for pin 13.
Expand All @@ -18,17 +18,14 @@
c. reset pending bit for pin 13
*/

// Define the microcontroller variant we use
#define STM32F401xE

// include generic header files
#include <stm32f4xx.h>

#define BLINK_OFF 0
#define BLINK_ON 1

/* create a global blink_state variable */
uint32_t blink_state = BLINK_OFF;
volatile uint32_t blink_state = BLINK_OFF; // use volatile because of shared with ISR

/* a very bad delay method */
static void delay_ms(uint32_t ms)
Expand All @@ -37,48 +34,60 @@ static void delay_ms(uint32_t ms)
Because each loop takes around 4 cycles we need to devide by 4.
*/
ms = ms * 16000 / 4;
for(;ms > 0;ms--)
for (; ms > 0; ms--)
{
__NOP(); // No operation
__NOP(); // No operation
}
}

int main(void)
void gpio_setup()
{
/* SETUP */
/* turn on clock on GPIOA */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;

/* set LED (PA5) to output mode */
GPIOA->MODER |= GPIO_MODER_MODE5_0;
GPIOA->MODER |= GPIO_MODER_MODER5_0;

/* turn on clock on GPIOC */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;

/* set USER Button (PC13) as Input */
GPIOC->MODER &= ~GPIO_MODER_MODER13_Msk;
}

void exti_setup()
{
/* Turn interrupt on */
/* Enable the clock for SYSCFG */
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
/* Select gpio port c pin13 as external interrupt */
SYSCFG->EXTICR[3] &= ~SYSCFG_EXTICR4_EXTI13; // Clear EXTI13 bits
SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI13_PC; // Set EXTI13 bits to PC
SYSCFG->EXTICR[3] &= ~SYSCFG_EXTICR4_EXTI13; // Clear EXTI13 bits
SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI13_PC; // Set EXTI13 bits to PC

/* Enable EXTI for line 13 (PC13) */
EXTI->IMR |= EXTI_IMR_MR13; // Enable EXTI interrupt
EXTI->FTSR |= EXTI_FTSR_TR13; // Enable falling edge trigger
EXTI->IMR |= EXTI_IMR_MR13; // Enable EXTI interrupt
EXTI->FTSR |= EXTI_FTSR_TR13; // Enable falling edge trigger

/* Enable and set the EXTI interrupt in NVIC */
NVIC_EnableIRQ(EXTI15_10_IRQn);
NVIC_SetPriority(EXTI15_10_IRQn, 0);
}

int main(void)
{
/* SETUP */
// Disable all interrupts globally
__disable_irq();

gpio_setup();
exti_setup();

// Enable global interrupts
__enable_irq();

/* LOOP */
while(1) {

while (1)
{

if (BLINK_ON == blink_state)
{
Expand All @@ -89,11 +98,12 @@ int main(void)
/* set LOW value on pin PA5 */
GPIOA->BSRR |= GPIO_BSRR_BR_5;
delay_ms(500);
} else {
}
else
{
/* set LOW value on pin PA5 */
GPIOA->BSRR |= GPIO_BSRR_BR_5;
}

}
}

Expand All @@ -102,10 +112,10 @@ void EXTI15_10_IRQHandler(void)
/* check if the EXTI pin 13 interrupt flag is set (user button) */
if (EXTI->PR & EXTI_PR_PR13)
{
//Handle button press
// Handle button press
blink_state = !blink_state;

//Clear the interrupt flag
// Clear the interrupt flag
EXTI->PR |= EXTI_PR_PR13;
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
platform = ststm32
board = nucleo_f401re
framework = cmsis

111 changes: 111 additions & 0 deletions CMSIS/nucleo-f401re_exti_rotary-encoder_CMSIS/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
nucleo-f401re exti rotary encoder example (CMSIS version).
GPIO SETUP:
Part of the GPIO port mode register (GPIOx_MODER) taken from the STM32F401RE reference manual.
+---------------------+---------------------+---------------------+
... | PIN 7 | PIN 6 | PIN 5 | ...
+----------+----------+----------+----------+----------+----------+
BIT | 15 | 14 | 13 | 12 | 11 | 10 |
+----------+----------+----------+----------+----------+----------+
NAME | MODER7_1 | MODER7_0 | MODER6_1 | MODER6_0 | MODER5_1 | MODER5_0 |
+----------+----------+----------+----------+----------+----------+
VALUE | 0 | 0 | 0 | 0 | 0 | 1 |
+----------+----------+----------+----------+----------+----------+
MODE | INPUT | INPUT | OUTPUT |
+---------------------+---------------------+---------------------+
USE FOR | RE_PIN B | RE PIN B | BOARD LED |
+---------------------+---------------------+---------------------+
*/
#include <stm32f4xx.h>

#define LED_OFF 0 // Pin is LOW
#define LED_ON 1 // Pin is HIGH

volatile uint32_t led_state = LED_OFF;

void gpio_setup()
{
// LED SETUP
/* turn on clock on GPIOA */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;

/* set PA5 to output mode */
GPIOA->MODER &= ~GPIO_MODER_MODER5_Msk; // (3 << 10)
GPIOA->MODER |= GPIO_MODER_MODER5_0; // (1 << 10)

// ROTARY ENCODER SETUP
/* set PA6 (RE_PIN_A) as INPUT */
GPIOA->MODER &= ~GPIO_MODER_MODER6_Msk; // (3 << 12)
/* set PA8 (RE_PIN_B) as INPUT */
GPIOA->MODER &= ~GPIO_MODER_MODER7_Msk; // (3 << 14)
/* set PA9 (RE_PUSH_BUTTON) as INPUT */
GPIOA->MODER &= ~GPIO_MODER_MODER9_Msk; // (3 << 18)
}

void exti_setup()
{
/* Turn interrupt on */
/* Enable the clock for SYSCFG */
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;

/* connect exti lines to ports */
SYSCFG->EXTICR[1] |= SYSCFG_EXTICR2_EXTI6_PA; // Set EXTI6 line to Port A
SYSCFG->EXTICR[2] |= SYSCFG_EXTICR3_EXTI9_PA; // Set EXTI6 line to Port B

/* Enable EXTI line 6 (PA6) - rotary A */
EXTI->IMR |= EXTI_IMR_MR6; // Enable EXTI interrupt
EXTI->FTSR |= EXTI_FTSR_TR6; // Enable falling edge trigger

/* Enable EXTI line 9 (PA9) - rotary push button */
EXTI->IMR |= EXTI_IMR_MR9; // Enable EXTI interrupt
EXTI->RTSR |= EXTI_RTSR_TR9; // Enable rising edge trigger

/* Enable and set the EXTI interrupt in NVIC */
NVIC_EnableIRQ(EXTI9_5_IRQn);
NVIC_SetPriority(EXTI9_5_IRQn, 0);
}

int main()
{
gpio_setup();
exti_setup();

while (1)
{
if (LED_OFF == led_state)
{
GPIOA->BSRR |= GPIO_BSRR_BR_5;
}
else // LED_ON
{
GPIOA->BSRR |= GPIO_BSRR_BS_5;
}
}
}

void EXTI9_5_IRQHandler(void)
{
/* check if the EXTI Line 6 interrupt flag is set (RE_PIN_A rising edge) */
if (EXTI->PR & EXTI_PR_PR6) // RE_PIN_A triggered
{
__disable_irq();
if (GPIOA->IDR & GPIO_IDR_ID7) // RE_PIN_B state is HIGH -> clockwise rotation
{
led_state = LED_ON;
}
else // RE_PIN_B state is LOW -> counter clockwise rotation
{
led_state = LED_OFF;
}

// Clear the interrupt flag
EXTI->PR |= EXTI_PR_PR6;
__enable_irq();
}
else if (EXTI->PR & EXTI_PR_PR9) // ROTARY PUSH BUTTON trigger
{
led_state = !led_state;
EXTI->PR |= EXTI_PR_PR9;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ board = nucleo_f401re
framework = cmsis

lib_deps =
MCAL=symlink://../stm32f401-mcal
MCAL=https://codeberg.org/jomaway/stm32f401-mcal.git
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ board = nucleo_f401re
framework = cmsis

lib_deps =
MCAL=symlink://../stm32f401-mcal
MCAL=https://codeberg.org/jomaway/stm32f401-mcal.git
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
/*
Nucleo-F401RE Blinky (CMSIS version)
Nucleo-F401RE gpio button blink led (CMSIS version)
This Program should start/stop blinking the USER LED (PA5) on the nucleo f401re Board, if the USER BUTTON (PC13) is pressed.
*/

// Define the microcontroller variant we use
#define STM32F401xE

// include generic header files
#include <stm32f4xx.h>

Expand All @@ -16,53 +13,61 @@

#define BTN_PRESSED 0 /* USER BUTTON was pressed */


/* a very bad delay method */
static void delay_ms(uint32_t ms)
{
/* Running at 16MHz it needs around 16000 cycles to reach 1ms.
Because each loop takes around 4 cycles we need to devide by 4.
*/
ms = ms * 16000 / 4;
for(;ms > 0;ms--)
for (; ms > 0; ms--)
{
__NOP(); // No operation
__NOP(); // No operation
}
}

int main(void)
void gpio_setup()
{
/* SETUP */
/* turn on clock on GPIOA */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;

/* set LED (PA5) to output mode */
GPIOA->MODER |= GPIO_MODER_MODE5_0;
GPIOA->MODER |= GPIO_MODER_MODER5_0;

/* turn on clock on GPIOC */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;

/* set USER Button (PC13) as Input */
GPIOC->MODER &= ~GPIO_MODER_MODER13_Msk;
}

int main(void)
{
/* SETUP */
gpio_setup();

/* create some state variables */
uint32_t btn_state = !BTN_PRESSED;
uint32_t blink_state = BLINK_OFF;

/* LOOP */
while(1) {
while (1)
{

/* Check if the button is pressed. ! Button is low active */
if (!(GPIOC->IDR & GPIO_IDR_ID13))
if (!(GPIOC->IDR & GPIO_IDR_ID13))
{
btn_state = BTN_PRESSED;
delay_ms(50); // debounce button
} else {
if (BTN_PRESSED == btn_state) {
delay_ms(50); // debounce button
}
else
{
if (BTN_PRESSED == btn_state)
{
blink_state = !blink_state;
}
btn_state = !BTN_PRESSED;
delay_ms(50); // debounce button
delay_ms(50); // debounce button
}

if (BLINK_ON == blink_state)
Expand All @@ -74,10 +79,11 @@ int main(void)
/* set LOW value on pin PA5 */
GPIOA->BSRR |= GPIO_BSRR_BR_5;
delay_ms(500);
} else {
}
else
{
/* set LOW value on pin PA5 */
GPIOA->BSRR |= GPIO_BSRR_BR_5;
}

}
}
File renamed without changes.
Loading

0 comments on commit b126c7d

Please sign in to comment.