/* * @file sbc_fw.ino * @brief Main firmware for sensor board controller, YKSA PL/EDU16 RSENSE * * Created: 21.09.2025 * Author: ThePetrovich * * Copyright YKSA - Sakha Aerospace Systems, LLC. * See the LICENSE file for details. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #include #include "config.h" #include "eeprom.h" #include "iodefs.h" #include "lsense.h" #include "rsense.h" static uint32_t status_led_last_blink = 0; void setup() { pinMode(STATUS_LED, OUTPUT); Serial.pins(0, 1); Serial.begin(SERIAL_BAUD_RATE); initialize_spi(); eeprom_init(); rsense_init(); } /** * @brief Initialize SPI interface for potentiometer control */ void initialize_spi(void) { SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV128); // 125 kHz @ 16 MHz SPI.setDataMode(SPI_MODE0); // AD5160 (Rev C.) SPI.setBitOrder(MSBFIRST); // AD5160 (Rev C.), p. 13, fig. 37 } /** * @brief Handle incoming serial commands * @param command Command character received */ void handle_serial_command(char command) { switch (command) { case 'v': // Firmware version handle_version_command(); break; case 'd': // Detect/ping handle_detect_command(); break; case 'l': // Light sensor presence lsense_cmd_presence(); break; case 'r': // Read sensors lsense_cmd_read(); rsense_cmd_get_cpm(); break; case 'c': // Dump 128 bytes of channel data rsense_cmd_dump_channels(); break; case 'f': // Flush counters rsense_cmd_flush(); break; case 'e': // Enable radiation detection rsense_cmd_enable(); break; case 's': // Disable radiation detection rsense_cmd_disable(); break; case 'p': // Set potentiometers rsense_cmd_set_potentiometers(); break; case 't': // Telemetry rsense_cmd_telemetry(); break; case 'm': // Set spectrum mode (16-bit or 32-bit) rsense_cmd_set_mode(); break; default: // Unknown command - ignore break; } } /** * @brief Handle firmware version command */ void handle_version_command(void) { Serial.write(FIRMWARE_VERSION_MAJOR); Serial.write(FIRMWARE_VERSION_MINOR); Serial.flush(); SERIAL_BUFFER_CLEAR(); } /** * @brief Handle detect/ping command */ void handle_detect_command(void) { SERIAL_SEND_OK(); } /** * @brief Update status LED (blink) */ inline void update_status_led(void) { if (millis() - status_led_last_blink > STATUS_LED_BLINK_PERIOD) { digitalWrite(STATUS_LED, !digitalRead(STATUS_LED)); status_led_last_blink = millis(); } } /** * @brief Main program loop */ void loop() { // Process incoming serial commands while (Serial.available()) { char command = Serial.read(); handle_serial_command(command); } update_status_led(); rsense_periodic(); }