Firmware Features
Relevant source files
The following files were used as context for generating this wiki page:
- README.md
- Firmware/App/Version.h
- Firmware/App/Config/Config.h
- Firmware/App/Service/DataProc/DP_Version.cpp
- Firmware/App/Service/DataProc/Def/Version.h
- Firmware/App/Service/HAL/HAL_Config.h
- Firmware/App/Service/HAL/HAL_Def.h
- Firmware/Vendor/Artery/Platform/AT32F421/Config/mcu_config.h
- Firmware/Vendor/Artery/Platform/AT32F421/MDK-ARM/RTE/_AT32F421/RTE_Components.h
- Firmware/Vendor/Artery/Platform/AT32F421/MDK-ARM/RTE/Device/-AT32F421K8U7/at32f421_conf.h
- Firmware/Vendor/Artery/Application/flashdb_port/fal_cfg.h
- Firmware/Vendor/Artery/Application/flashdb_port/fdb_cfg.h
- Firmware/Vendor/Artery/ArduinoAPI/Arduino.h
- Firmware/Vendor/Artery/ArduinoAPI/Wire.cpp
- Firmware/Vendor/Artery/ArduinoAPI/WireBase.h
The DutyCycle firmware is designed for the AT32F421 microcontroller, providing the core logic for the "Work-Life Duty Cycle Clock". It manages all hardware components, including the motor-driven indicator, buzzer, and user input button. The firmware is built upon a layered architecture that includes a Hardware Abstraction Layer (HAL), an Arduino-compatible API for core functionalities, and application-level services for data processing and device control.
Key responsibilities of the firmware include initializing the system, handling real-time operations, processing user commands via a serial interface, managing power states, and providing feedback through the physical indicator and audible alerts. It also features a persistent storage system using the onboard flash memory to store configuration data.
Core Architecture
The firmware is structured in layers, from the low-level MCU drivers to the high-level application logic. This design promotes modularity and separates hardware-specific code from the main application.
This diagram shows the layered architecture of the firmware, from the AT32F421 MCU at the bottom to the application-specific services at the top.
Sources: Firmware/App/Service/HAL/HAL.h, Firmware/Vendor/Artery/ArduinoAPI/Arduino.h, Firmware/Vendor/Artery/Platform/AT32F421/MDK-ARM/RTE/Device/-AT32F421K8U7/at32f421_conf.h
Microcontroller and Peripherals
The firmware is built for the ArteryTek AT32F421 series microcontroller. The build configuration enables a specific set of standard peripheral libraries required for the clock's operation.
| Enabled Module | Purpose |
|---|---|
ADC | Analog-to-Digital Converter (e.g., for battery level detection). |
CRM | Clock, Reset, and MUX management. |
DMA | Direct Memory Access. |
ERTC | Enhanced Real-Time Clock. |
EXINT | External Interrupts (for buttons). |
FLASH | Flash memory interface. |
GPIO | General Purpose Input/Output. |
I2C | Inter-Integrated Circuit communication. |
MISC | Miscellaneous functions, including NVIC configuration. |
PWC | Power Control. |
SPI | Serial Peripheral Interface. |
TMR | Timers (for PWM, tone generation). |
USART | Universal Synchronous/Asynchronous Receiver/Transmitter. |
WDT | Watchdog Timer. |
Sources: Firmware/Vendor/Artery/Platform/AT32F421/MDK-ARM/RTE/_AT32F421/RTE_Components.h:15-42, Firmware/Vendor/Artery/Platform/AT32F421/MDK-ARM/RTE/Device/-AT32F421K8U7/at32f421_conf.h:58-77
Hardware Abstraction Layer (HAL)
The HAL provides a standardized interface to the underlying hardware, abstracting pin numbers and low-level driver calls. It defines interfaces for key components of the device.
Sources: Firmware/App/Service/HAL/HAL_Def.h, Firmware/App/Service/HAL/HAL_Config.h
HAL Components
The HAL manages the following hardware components:
- Motor: Controls the indicator needle.
- Buzzer: Provides audible feedback.
- Battery: Monitors the battery level.
- Power: Manages the device's power state.
- Button: Handles user input.
- Flash: Interacts with the onboard flash memory.
- Clock: Manages system time.
- WatchDog: Prevents firmware lock-ups.
Pin Configuration
Hardware pin assignments are defined in HAL_Config.h. The configuration supports different hardware versions (v1.1 and v1.2) by remapping pins.
| Feature | Pin (v1.2) | Pin (v1.1) | Active Pin Macro |
|---|---|---|---|
| Motor Out 1 | PA2 | PA2 | CONFIG_MOTOR_OUT1_PIN |
| Motor Out 2 | PA3 | PA3 | CONFIG_MOTOR_OUT2_PIN |
| Buzzer | PB1 | PB2 | CONFIG_BUZZ_PIN |
| Battery Detect | PB0 | PB1 | CONFIG_BATT_DET_PIN |
| Power Enable | PA6 | PA7 | CONFIG_PWR_EN_PIN |
| Button Select | PA7 | PB0 | CONFIG_BUTTON_SEL_PIN |
Sources: Firmware/App/Service/HAL/HAL_Config.h:21-41
Arduino API Compatibility
To simplify development, the firmware incorporates an Arduino-compatible API layer. This provides familiar functions for interacting with GPIO, timers, and communication interfaces.
Key supported functions include:
pinMode(pin, mode)digitalWrite(pin, value)digitalRead(pin)analogWrite(pin, value)(PWM)analogRead(pin)delay(ms)I2Ccommunication via theWirelibrary.
Sources: Firmware/Vendor/Artery/ArduinoAPI/Arduino.h, Firmware/Vendor/Artery/ArduinoAPI/Arduino.c
I2C (Wire) Implementation
The firmware includes a software-based I2C implementation (TwoWire) that inherits from a WireBase class. This allows for communication with I2C peripherals.
This diagram shows the class structure for the I2C Wire library. TwoWire implements the abstract process() method from WireBase to handle software-based I2C communication.
Sources: Firmware/Vendor/Artery/ArduinoAPI/Wire.cpp, Firmware/Vendor/Artery/ArduinoAPI/WireBase.h
The I2C pins and behavior are configurable:
| Configuration | Default Value | Description |
|---|---|---|
WIRE_SDA_PIN | PB7 | I2C data pin. |
WIRE_SCL_PIN | PB6 | I2C clock pin. |
WIRE_DELAY | 1 | Microseconds delay for bit-banging. |
WIRE_BUFF_SIZE | 32 | Size of the I2C transmit and receive buffers. |
Sources: Firmware/Vendor/Artery/Platform/AT32F421/Config/mcu_config.h:42-46
System Configuration
Several key system parameters are defined at compile-time through various configuration headers.
General MCU Configuration
| Parameter | Value | Description |
|---|---|---|
SYSTICK_TICK_FREQ | 1000 Hz | Frequency of the system tick interrupt. |
SERIAL_RX_BUFFER_SIZE | 64 bytes | Buffer size for the hardware serial port. |
SERIAL_1_ENABLE | 1 (Enabled) | Enables USART1 for serial communication. |
PWM_RESOLUTION_DEFAULT | 1000 | Default resolution for PWM signals. |
PWM_FREQUENCY_DEFAULT | 10000 Hz | Default frequency for PWM signals. |
TONE_TIMER_DEFAULT | TIM1 | Default timer used for tone() function. |
Sources: Firmware/Vendor/Artery/Platform/AT32F421/Config/mcu_config.h
Application Configuration
| Parameter | Value | Description |
|---|---|---|
CONFIG_WATCHDOG_TIMEOUT | 10 seconds | Timeout for the independent watchdog timer (WDT). |
Sources: Firmware/App/Config/Config.h:19-22, Firmware/App/Service/HAL/HAL_Config.h:47-48
Data Processing and Versioning
The firmware includes a data processing service (DataProc) that handles various data-related tasks. A key part of this is the versioning system, which collects and provides detailed information about the firmware build.
Version Information
At startup, the DP_Version module gathers version details and logs them to the serial console. This information is encapsulated in the Version_Info_t structure.
// Firmware/App/Service/DataProc/Def/Version.h
typedef struct Version_Info {
const char* name;
const char* software;
const char* hardware;
const char* author;
const char* website;
const char* compiler;
const char* buildDate;
const char* buildTime;
} Version_Info_t;
Sources: Firmware/App/Service/DataProc/Def/Version.h:21-36
The values are populated from pre-processor macros defined in Version.h and compiler-specific macros.
This diagram illustrates the process of initializing the version service, which then collects and logs the firmware's build and version information.
Sources: Firmware/App/Service/DataProc/DP_Version.cpp:60-98
On-Chip Storage
The firmware utilizes the microcontroller's internal flash for persistent storage using the FlashDB library. It relies on a Flash Abstraction Layer (FAL) to interact with the flash memory.
Sources: Firmware/Vendor/Artery/Application/flashdb_port/fdb_cfg.h, Firmware/Vendor/Artery/Application/flashdb_port/fal_cfg.h
Flash Partitioning
A single partition named fdb_kvdb is defined for a key-value database. This partition is located on the onchip flash device.
This diagram shows the conceptual layout of the on-chip flash, with space allocated for the firmware and a dedicated partition for the key-value database.
The partition table is defined as follows:
// Firmware/Vendor/Artery/Application/flashdb_port/fal_cfg.h:43-46
#define FAL_PART_TABLE \
{ \
{ FAL_PART_MAGIC_WORD, FDB_KVDB_PART_NAME, "onchip", (64 - 2) * 1024, 2 * 1024, 0 }, \
}
| Parameter | Value | Description |
|---|---|---|
| Name | FDB_KVDB_PART_NAME ("fdb_kvdb") | Partition name for the Key-Value DB. |
| Flash Device | "onchip" | The partition resides on the internal flash. |
| Offset | (64 - 2) * 1024 | Starts at 62KB from the beginning of flash. |
| Size | 2 * 1024 | The partition is 2KB in size. |
Sources: Firmware/Vendor/Artery/Application/flashdb_port/fal_cfg.h:35-46
This setup allows the application to store settings or state that persists across power cycles. The FlashDB is configured with a 32-bit write granularity, suitable for the AT32F421 MCU.
Sources: Firmware/Vendor/Artery/Application/flashdb_port/fdb_cfg.h:35-36
User Interaction
The firmware interprets button presses to perform various actions, providing a simple user interface.
- Single Click (from off): Powers on the device.
- Long Press (10s+): Powers off the device.
- Single Click (from on): Displays the current battery level.
- Double Click: Toggles mute mode for all sounds (button clicks, alarms).
Sources: README.md:31-38
Summary
The DutyCycle firmware is a well-structured embedded application tailored for the AT32F421 microcontroller. It leverages a layered architecture with a HAL and an Arduino-compatible API to create a modular and maintainable codebase. Key features include robust hardware control, a serial command interface for configuration, user interaction via a single button, and persistent storage on the internal flash memory. The comprehensive versioning and logging system aids in debugging and deployment.