Compare commits
6 Commits
74a0780219
...
a9f342b45b
| Author | SHA256 | Date | |
|---|---|---|---|
| a9f342b45b | |||
| 042d38b0f5 | |||
| 7e8165e7a2 | |||
| e0781257a6 | |||
| 35c66787de | |||
| c9d30ef44e |
@ -76,7 +76,7 @@ Hardware: FT232 USB-UART adapter connected to UPDI with a 4.7 kΩ resistor.
|
||||
```
|
||||
4. Flash using pymcuprog:
|
||||
```bash
|
||||
pymcuprog -t uart -u /dev/ttyUSB0 -d attiny202 write -f build/main.hex
|
||||
pymcuprog -t uart -u /dev/ttyUSB0 -d attiny202 erase && pymcuprog -t uart -u /dev/ttyUSB0 -d attiny202 write -f build/main.hex
|
||||
```
|
||||
## Hardware Setup (FT232 → ATtiny202 UPDI)
|
||||
```bash
|
||||
|
||||
77
main.c
77
main.c
@ -10,27 +10,33 @@
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#define BUTTON_PIN_MASK 0x01 // PA0
|
||||
#define PA1_SET_MASK 0x02 // LED 1–2
|
||||
#define PA2_SET_MASK 0x04 // LED 3–6
|
||||
#define PA3_SET_MASK 0x08 // LED 7–8
|
||||
#define PA6_SET_MASK 0x40 // Green LED
|
||||
#define PA7_SET_MASK 0x80 // Red LED
|
||||
#define BUTTON_PIN_MASK 0x01 // PA0 used as RESET/UPDI pin
|
||||
#define PA1_SET_MASK 0x02 ///< LED 1–2
|
||||
#define PA2_SET_MASK 0x04 ///< LED 3–6
|
||||
#define PA3_SET_MASK 0x08 ///< LED 7–8
|
||||
#define PA6_SET_MASK 0x40 ///< Green LED pin
|
||||
#define PA7_SET_MASK 0x80 ///< Red LED
|
||||
|
||||
#define MAIN_LOOP_SLEEP 50U // Loop period in ms
|
||||
#define BUTTON_LONG_PRESS_DURATION_MS 1000U // Long press threshold
|
||||
#define BUTTON_IGNORE_DURATION_MS 1000U // Ignore after long press
|
||||
#define BUTTON_IGNORE_DURATION_MS 2000U // Time button ignored after long press
|
||||
#define BUTTON_CONFIRMATION_BLINK_LOOPS 10U // Blink animation for confirmation
|
||||
#define BUTTON_CONFIRMATION_BLINK_DURATION_MS 50U
|
||||
|
||||
#define MS_TO_TICKS(ms) ((ms) / MAIN_LOOP_SLEEP)
|
||||
|
||||
volatile bool bLedEnabled = false;
|
||||
/** Global flags */
|
||||
volatile bool bLedEnabled = true;
|
||||
volatile bool bBtnPressed = false;
|
||||
|
||||
// Forward declarations
|
||||
void blinkLed(bool resetCounters);
|
||||
static inline void leds_off(void);
|
||||
static inline void leds_on(void);
|
||||
static void battery_level_indicator(void);
|
||||
static void handleSwitch(void);
|
||||
void blinkLed(bool resetCounters);
|
||||
static void software_reset(void);
|
||||
ISR(PORTA_PORT_vect);
|
||||
|
||||
/* --- Timer init: Use RTC PIT for periodic wake-up --- */
|
||||
void init_timer(void)
|
||||
@ -86,19 +92,32 @@ int main(void)
|
||||
leds_off();
|
||||
}
|
||||
|
||||
// Long press detected → show confirmation blink
|
||||
// Long press detected --> show confirmation blink
|
||||
if (bLedEnabledOld != bLedEnabled)
|
||||
{
|
||||
bLedEnabledOld = bLedEnabled;
|
||||
|
||||
leds_off();
|
||||
_delay_ms(BUTTON_IGNORE_DURATION_MS / 10);
|
||||
leds_on();
|
||||
_delay_ms(BUTTON_IGNORE_DURATION_MS / 10);
|
||||
leds_off();
|
||||
for (uint8_t i = 0U; i < BUTTON_CONFIRMATION_BLINK_LOOPS; i++)
|
||||
{
|
||||
leds_off();
|
||||
_delay_ms(BUTTON_CONFIRMATION_BLINK_DURATION_MS);
|
||||
leds_on();
|
||||
_delay_ms(BUTTON_CONFIRMATION_BLINK_DURATION_MS);
|
||||
leds_off();
|
||||
}
|
||||
|
||||
// Give time until button is released
|
||||
_delay_ms(BUTTON_IGNORE_DURATION_MS);
|
||||
|
||||
blinkLed(true); // reset blink state machine
|
||||
// Activate the interrupt for PA0
|
||||
PORTA.PIN0CTRL = PORT_PULLUPEN_bm | PORT_ISC_FALLING_gc;
|
||||
|
||||
set_sleep_mode(SLEEP_MODE_STANDBY); // Deepest sleep mode (standby)
|
||||
sleep_enable(); // Enable sleep
|
||||
|
||||
cli(); // Disable global interrupts
|
||||
sei(); // Re-enable interrupts
|
||||
sleep_cpu(); // MCU sleeps here
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -171,6 +190,32 @@ static void handleSwitch(void)
|
||||
prevPressed = pressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform software reset
|
||||
*/
|
||||
static void software_reset(void)
|
||||
{
|
||||
CCP = CCP_IOREG_gc; // unlock protected registers
|
||||
RSTCTRL.SWRR = 1; // trigger software reset
|
||||
while (1)
|
||||
; // wait for reset
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Interrupt service routine
|
||||
*/
|
||||
ISR(PORTA_PORT_vect)
|
||||
{
|
||||
// Clear interrupt flags for PA0
|
||||
PORTA.INTFLAGS = BUTTON_PIN_MASK;
|
||||
|
||||
if (!(VPORTA.IN & BUTTON_PIN_MASK)) // check PA0 low
|
||||
{
|
||||
// Turn off all LEDs
|
||||
software_reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LED blink state machine (bike rear light style)
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user