Platform: STM32F103 (Cortex‑M3)
This project implements a Keeloq (HCS301) remote control decoder and EEPROM programmer.
It provides signal decoding from a typical 433 MHz RF remote, decrypting the transmitted data and extracting synchronization, discrimination, and serial information.
This project utilizes EXTI (External Interrupts) and Timer/Counters as hardware peripherals available on almost all microcontrollers.
When configuring the timer, pay close attention to its frequency — it must be high enough to capture the remote signal’s level transitions accurately and ensure precise decoding timing.
Additionally, make sure to match the receiver module to the transmitter’s carrier frequency (typically 433 MHz for most Keeloq‑based remote systems).
Purpose: Memory layout and code format definitions
🧮 EEPROM Memory Map (12 × 16 bit = 192 bit)
Each HCS301 device contains a 192‑bit EEPROM array divided into 12 words.
This memory stores encryption keys, synchronization data, serial identity, and device configuration.
| Address / Word | Field | Size (bit) | Description |
|---|---|---|---|
KEY_0 → KEY_3 |
Encryption Key | 64 | Unique 64‑bit Keeloq key used for encryption & decryption. |
SYNC |
Synchronization Value | 16 | Rolling counter incremented per transmission; used by the receiver to authenticate sequence. |
RESERVED |
Reserved | 16 | Must be 0x0000; unused. |
SER_0, SER_1 |
Serial Number | 32 (28 lsb used) | Unique transmitter ID. Bit 31 is used for the auto‑shutoff timer. |
SEED_0, SEED_1 |
Seed Value | 32 | Used during secure learning (when all four buttons are pressed simultaneously). |
EN_KEY |
Envelope Key (optional) | 16 | Secondary encryption key for serial number & button data. Requires enabling via configuration bit 15. |
CONFIG |
🧩Configuration Register | 16 | Device behavioral setup bits (see below). |
| Bit(s) | Field | Description |
|---|---|---|
| 0 – 9 | Discrimination Bits (10 bit) | Uniquely identifies transmitters sharing the same main key. |
| 10 – 11 | Overflow Bits | Handle sequence counter overflow. |
| 12 | Low‑Voltage Flag | Indicates low supply at transmission. |
| 13 – 14 | Baud‑Rate Select | Defines pulse‑width encoding speed. |
| 15 | Envelope Encryption Select | Enables/disables use of the envelope key (EN_KEY). |
typedef struct
{
uint64_t encryption_key;
uint16_t syncronzation_value;
uint16_t reserved;
uint32_t serial_number;
uint32_t seed_value;
uint16_t envelope_key;
uint16_t configuration;
}hcs301_eeprom_t;Every HCS301 transmission consists of a 66‑bit code word sent via ASK/OOK modulation.
| Segment | Length | Description |
|---|---|---|
| Encrypted Code Data | 32 bits | Rolling portion containing dynamic encryption. |
| Fixed Code Data | 34 bits | Static portion containing permanent identity information and status flags. |
| Field | Size (bit) | Description |
|---|---|---|
| Sync Value | 16 | Rolling counter that increments on each valid button press. Used by the receiver to validate transmission sequence. |
| Discrimination Bits | 12 | Derived from the transmitter’s configuration word (bits 0–9). Ensures unique identification among devices sharing the same key. |
| Button Status | 4 | Encodes which button(s) are pressed; included in encryption for message integrity. |
| Field | Size (bit) | Description |
|---|---|---|
| Serial Number | 28 | Unique transmitter ID stored in EEPROM (matches SER_0/SER_1). |
| Button Status | 4 | Duplicated (redundant) button code for error detection. |
| Vlow | 1 | Indicates that the transmitter’s battery is below the low‑voltage threshold. |
| Repeat | 1 | Differentiates between a new button press and a repeated frame while the button remains pressed. |
The following C structure represents a decoded HCS301 data frame after successful Keeloq decryption:
typedef struct
{
// Encrypted section
uint32_t seed; // Used only during secure learning mode [IGNORE in normal decoding]
uint32_t Decrypted; // 32-bit plaintext result after Keeloq decryption
uint16_t Sync; // 16-bit synchronization value
uint16_t Discrimination; // 12-bit discriminator extracted from decrypted block
// Fixed section
uint32_t Serial_Number; // 28-bit serial unique identifier
bool btn0; // Button 0 status
bool btn1; // Button 1 status
bool btn2; // Button 2 status
bool btn3; // Button 3 status
bool Vlow; // Low-battery indicator bit
bool Repeat; // Repeat frame indicator bit
} HCS301_Packet_t;After each word is written to the HCS301 EEPROM,
the data pin must be released (set to high impedance)
and you must wait for the ACK pulse from the HCS301
before continuing with the next word.
To clarify this behavior, a logic analyzer capture has been attached.
You can view or export it in Saleae Logic for better visualization.