# IEEE 802.15.4 Transceiver Component This ESP-IDF component provides a simple API for IEEE 802.15.4 communication using the ESP32's built-in IEEE 802.15.4 radio. It supports initializing the transceiver, transmitting and receiving frames, setting receive callbacks, and dynamically switching channels (11-26) in promiscuous mode. ## Features - Initialize the IEEE 802.15.4 radio in promiscuous mode for flexible frame capture. - Transmit and receive IEEE 802.15.4 frames with support for custom frame structures. - Register callbacks to process received frames with RSSI and LQI information. - Dynamically switch channels (11-26) without reinitializing the radio. - Built on top of ESP-IDF's `esp_ieee802154` component and `shoderico/ieee802154_frame` for frame handling. ## Requirements - ESP-IDF v5.0 or later (tested with v5.4.1). - ESP32 with IEEE 802.15.4 support (e.g., ESP32-C6, ESP32-H2). - Non-Volatile Storage (NVS) initialized before using the component. - FreeRTOS for task and message buffer management. ## Installation This component is available on the [ESP Component Registry](https://components.espressif.com/). To add it to your ESP-IDF project, run: ```bash idf.py add-dependency "shoderico/ieee802154_transceiver^1.0.0" ``` Alternatively, clone the component into your project's `components` directory and update your `CMakeLists.txt` to include it. ## Usage 1. **Initialize NVS**: Initialize NVS before using the component: ```c esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); ``` 2. **Initialize the Transceiver**: Set up the transceiver on a specific channel (11-26): ```c esp_err_t ret = ieee802154_transceiver_init(11); if (ret != ESP_OK) { // Handle error } ``` 3. **Set a Receive Callback**: Define a callback to process received frames: ```c void rx_callback(ieee802154_frame_t *frame, esp_ieee802154_frame_info_t *frame_info, void *user_data) { printf("Received frame: payloadLen=%d, RSSI=%d, LQI=%d\n", frame->payloadLen, frame_info->rssi, frame_info->lqi); } ieee802154_transceiver_set_rx_callback(rx_callback, NULL); ``` When a frame is received, the ESP-IDF's `esp_ieee802154_receive_done` interrupt function is triggered. By calling `ieee802154_transceiver_handle_receive_done` from this function, the registered callback (e.g., `rx_callback`) is invoked: ```c void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info) { ieee802154_transceiver_handle_receive_done(frame, frame_info); } ``` 4. **Transmit a Frame**: Create and send an IEEE 802.15.4 frame: ```c uint8_t payload[] = "Hello, IEEE 802.15.4!"; ieee802154_frame_t frame = { .fcf = { .frameType = IEEE802154_FRAME_TYPE_DATA, // 001 .securityEnabled = 0, // 0 .framePending = 0, // 0 .ackRequest = 1, // 1 .panIdCompression = 1, // 1 .reserved = 0, // 0 .sequenceNumberSuppression = 0, // 0 .informationElementsPresent = 0, // 0 .destAddrMode = IEEE802154_ADDR_MODE_SHORT, // 10 .frameVersion = IEEE802154_VERSION_2006, // 01 .srcAddrMode = IEEE802154_ADDR_MODE_SHORT // 10 }, .sequenceNumber = 0x02, .destPanId = 0x1234, .destAddress = {0xFF, 0xFF}, // Broadcast .srcPanId = 0x1234, .srcAddress = {0x9A, 0xBC}, .payloadLen = strlen((char *)payload), .payload = payload } ieee802154_transceiver_transmit(&frame); ``` 5. **Deinitialize**: Clean up resources when done: ```c ieee802154_transceiver_deinit(); ``` ## Examples 1. **simple_transceiver** The `examples/simple_transceiver` directory includes a sample project that demonstrates: - Initializing the transceiver on channel 11. - Logging received frames via a callback. - Periodically transmitting a test frame every 5 seconds. To build and run the example: ```bash cd examples/simple_transceiver idf.py set-target esp32c6 idf.py build flash monitor ``` 2. **ieee802154_sniffer** The `examples/ieee802154_sniffer` directory includes another project that demonstrates: - Initializing the rx transceiver on channel 11. - Tracing the binary dump of received frames To build and run the example: ```bash cd examples/ieee802154_sniffer idf.py set-target esp32c6 idf.py build flash monitor ``` 3. **ieee802154_bridge** The `examples/ieee802154_bridge` directory includes another project that demonstrates: - Initializing the rx transceiver on channel 11. - Once received a frame, transmitting the same frame to another channel 13. - Measuring performance and trace average time from receiving to transmitting. To build and run the example: ```bash cd examples/ieee802154_bridge idf.py set-target esp32c6 idf.py build flash monitor ``` ## Testing The `test` directory contains Unity-based unit tests to verify the component's functionality, including: - Transceiver initialization with valid and invalid channels. - Channel switching. - Receive callback registration. Each test case explicitly initializes and deinitializes the transceiver to ensure resource cleanup. To run the tests: ```bash cd test_runner idf.py set-target esp32c6 idf.py build flash monitor ``` ## Dependencies - `shoderico/ieee802154_frame`: Handles IEEE 802.15.4 frame parsing and building. - ESP-IDF's `esp_ieee802154`: Provides low-level radio control. - FreeRTOS: Manages tasks and message buffers. - NVS: Stores radio configuration. ## License Licensed under the [MIT](LICENSE). ## Contributing Contributions are welcome! Submit issues or pull requests to the repository at [your repository URL]. ## Troubleshooting - **Initialization Fails**: Ensure NVS is initialized and the channel is between 11 and 26. - **No Frames Received**: Verify the radio is in promiscuous mode and the channel matches the sender. - **Resource Errors**: Call `ieee802154_transceiver_deinit` after use to free resources.
idf.py add-dependency "shoderico/ieee802154_transceiver^1.0.0"