#include "stm32c031xx.h"
#include <stdint.h>
#define DEBUG_MODE
volatile uint32_t button_pressed = 0;
// ============================================================
// EXTI0_1 IRQ Handler
// STM32C031: EXTI Line 0 và Line 1 dùng chung IRQ
// ============================================================
void EXTI01_IRQHandler(void)
{
//Set led pin high
//GPIOA->ODR ^= (1U << 5);
//Signal to turn on led
button_pressed = 1U;
}
// ============================================================
// Setup
// ============================================================
void setup()
{
// --------------------------------------------------------
// 1. Enable clock GPIOA
// --------------------------------------------------------
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
// Enable clock SYSCFG
RCC->APBENR2 |= RCC_APBENR2_SYSCFGEN;
// --------------------------------------------------------
// 2. PA5 = Output
// --------------------------------------------------------
// Clear MODER5[1:0]
GPIOA->MODER &= ~(3U << (5U * 2U));
// 01 = General purpose output
GPIOA->MODER |= (1U << (5U * 2U));
// --------------------------------------------------------
// 3. PA0 = Input
// --------------------------------------------------------
// 00 = Input
GPIOA->MODER &= ~(3U << (0U * 2U));
// --------------------------------------------------------
// 4. PA0 Pull-down
// --------------------------------------------------------
// Clear PUPDR0[1:0]
GPIOA->PUPDR &= ~(3U << (0U * 2U));
// 10 = Pull-down
GPIOA->PUPDR |= (2U << (0U * 2U));
// --------------------------------------------------------
// 5. Configure EXTI0 source = PA0
// --------------------------------------------------------
// EXTICR[0] controls EXTI0..EXTI3
//
// EXTICR1:
// bits [3:0] = EXTI0 source
//
// 0000 = Port A
EXTI->EXTICR[0] &= ~(0x0FU << 0U);
EXTI->EXTICR[0] |= (0x00U << 0U);
// --------------------------------------------------------
// 6. Configure Rising Edge
// --------------------------------------------------------
// Disable Falling Edge
EXTI->FTSR1 &= ~EXTI_FTSR1_FT0;
// Enable Rising Edge
EXTI->RTSR1 |= EXTI_RTSR1_RT0;
// --------------------------------------------------------
// 7. Unmask EXTI Line 0
// --------------------------------------------------------
EXTI->IMR1 |= EXTI_IMR1_IM0;
// --------------------------------------------------------
// 8. Clear any pending flag before enabling NVIC
// --------------------------------------------------------
EXTI->RPR1 = EXTI_RPR1_RPIF0;
EXTI->FPR1 = EXTI_FPR1_FPIF0;
// --------------------------------------------------------
// 9. Configure NVIC
// --------------------------------------------------------
__disable_irq();
__enable_irq();
//NVIC->ISER[0] = (1U << 7);
//NVIC_SetPriority(EXTI0_1_IRQn, 2);
//NVIC_EnableIRQ(EXTI0_1_IRQn);
attachInterrupt(digitalPinToInterrupt(A0), EXTI01_IRQHandler, RISING);
// LED initially OFF
GPIOA->ODR &= ~GPIO_ODR_OD5;
Serial.begin(115200);
}
// ============================================================
// Loop
// ============================================================
static uint32_t last_pressed = 0;
void loop()
{
// CPU sleep until interrupt occurs
//__WFI();
//Debounce button logic
if (button_pressed){
button_pressed = 0U;
uint32_t timeNow = millis();
if (timeNow - last_pressed >= 140U){
#ifdef DEBUG_MODE
if (last_pressed == 0){
Serial.println("First pressed time: ");
Serial.println(timeNow);
} else {
Serial.println("time between 2 presses: ");
Serial.println(timeNow - last_pressed);
}
#endif
GPIOA->ODR ^= (1U << 5);
last_pressed = timeNow;
}
}
}
//Bare metal EXTI_Handler
/*
void EXTI0_1_IRQHandler(void)
{
// Kiểm tra cờ Rising Edge của EXTI Line 0
if (EXTI->RPR1 & EXTI_RPR1_RPIF0)
{
// Đảo trạng thái LED PA5
GPIOA->ODR ^= GPIO_ODR_OD5;
// Xóa cờ Rising Pending Flag
// W1C: Write 1 to Clear
EXTI->RPR1 = EXTI_RPR1_RPIF0;
}
// Nếu vô tình có cờ Falling Edge
if (EXTI->FPR1 & EXTI_FPR1_FPIF0)
{
// Xóa cờ Falling Pending Flag
EXTI->FPR1 = EXTI_FPR1_FPIF0;
}
}
*/