Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "user_code.h"
- #include "bm_network.h"
- #include "bm_printf.h"
- #include "bm_pubsub.h"
- #include "bristlefin.h"
- #include "bsp.h"
- #include "debug.h"
- #include "lwip/inet.h"
- #include "payload_uart.h"
- #include "sensors.h"
- #include "stm32_rtc.h"
- #include "task_priorities.h"
- #include "uptime.h"
- #include "usart.h"
- #include "util.h"
- #define LED_ON_TIME_MS 20
- #define LED_PERIOD_MS 1000
- #define DEFAULT_BAUD_RATE 9600
- #define DEFAULT_LINE_TERM 10 // FL / '\n', 0x0A
- #define BYTES_CLUSTER_MS 50
- // app_main passes a handle to the user config partition in NVM.
- extern cfg::Configuration *userConfigurationPartition;
- // A timer variable we can set to trigger a pulse on LED2 when we get payload serial data
- static int32_t ledLinePulse = -1;
- static u_int32_t baud_rate_config = DEFAULT_BAUD_RATE;
- static u_int32_t line_term_config = DEFAULT_LINE_TERM;
- // A buffer for our data from the payload uart
- char payload_buffer[2048];
- // Global buffer and counter
- #define RPI_BUFFER_SIZE 48
- static uint8_t current_rpi_buffer[RPI_BUFFER_SIZE];
- static size_t current_rpi_buffer_count = 0;
- void setup(void) {
- /* USER ONE-TIME SETUP CODE GOES HERE */
- // Retrieve user-set config values out of NVM.
- userConfigurationPartition->getConfig("plUartBaudRate", strlen("plUartBaudRate"),
- baud_rate_config);
- userConfigurationPartition->getConfig("plUartLineTerm", strlen("plUartLineTerm"),
- line_term_config);
- // Setup the UART – the on-board serial driver that talks to the RS232 transceiver.
- PLUART::init(USER_TASK_PRIORITY);
- // Baud set per expected baud rate of the sensor.
- PLUART::setBaud(baud_rate_config);
- // Enable passing raw bytes to user app.
- PLUART::setUseByteStreamBuffer(true);
- // Enable parsing lines and passing to user app.
- /// Warning: PLUART only stores a single line at a time. If your attached payload sends lines
- /// faster than the app reads them, they will be overwritten and data will be lost.
- PLUART::setUseLineBuffer(true);
- // Set a line termination character per protocol of the sensor.
- PLUART::setTerminationCharacter((char)line_term_config);
- // Turn on the UART.
- PLUART::enable();
- // Enable the input to the Vout power supply.
- bristlefin.enableVbus();
- // ensure Vbus stable before enable Vout with a 5ms delay.
- vTaskDelay(pdMS_TO_TICKS(5));
- // enable Vout, 12V by default.
- bristlefin.enableVout();
- }
- void loop(void) {
- /* USER LOOP CODE GOES HERE */
- static bool led2State = false;
- /// This checks for a trigger set by ledLinePulse when data is received from the payload UART.
- /// Each time this happens, we pulse LED2 Green.
- // If LED2 is off and the ledLinePulse flag is set (done in our payload UART process line function), turn it on Green.
- if (!led2State && ledLinePulse > -1) {
- bristlefin.setLed(2, Bristlefin::LED_GREEN);
- led2State = true;
- }
- // If LED2 has been on for LED_ON_TIME_MS, turn it off.
- else if (led2State &&
- ((u_int32_t)uptimeGetMs() - ledLinePulse >= LED_ON_TIME_MS)) {
- bristlefin.setLed(2, Bristlefin::LED_OFF);
- ledLinePulse = -1;
- led2State = false;
- }
- /// This section demonstrates a simple non-blocking bare metal method for rollover-safe timed tasks,
- /// like blinking an LED.
- /// More canonical (but more arcane) modern methods of implementing this kind functionality
- /// would bee to use FreeRTOS tasks or hardware timer ISRs.
- static u_int32_t ledPulseTimer = uptimeGetMs();
- static u_int32_t ledOnTimer = 0;
- static bool led1State = false;
- // Turn LED1 on green every LED_PERIOD_MS milliseconds.
- if (!led1State &&
- ((u_int32_t)uptimeGetMs() - ledPulseTimer >= LED_PERIOD_MS)) {
- bristlefin.setLed(1, Bristlefin::LED_GREEN);
- ledOnTimer = uptimeGetMs();
- ledPulseTimer += LED_PERIOD_MS;
- led1State = true;
- }
- // If LED1 has been on for LED_ON_TIME_MS milliseconds, turn it off.
- else if (led1State &&
- ((u_int32_t)uptimeGetMs() - ledOnTimer >= LED_ON_TIME_MS)) {
- bristlefin.setLed(1, Bristlefin::LED_OFF);
- led1State = false;
- }
- // Read a cluster of bytes if available
- // -- A timer is used to try to keep clusters of bytes (say from lines) in the same output.
- static int64_t readingBytesTimer = -1;
- // Note - PLUART::setUseByteStreamBuffer must be set true in setup to enable bytes.
- if (readingBytesTimer == -1 && PLUART::byteAvailable()) {
- // Get the RTC if available
- RTCTimeAndDate_t time_and_date = {};
- rtcGet(&time_and_date);
- char rtcTimeBuffer[32];
- rtcPrint(rtcTimeBuffer, &time_and_date);
- printf("[payload-bytes] | tick: %llu, rtc: %s, bytes:", uptimeGetMs(),
- rtcTimeBuffer);
- // not very readable, but it's a compact trick to overload our timer variable with a -1 flag
- readingBytesTimer = (int64_t)((u_int32_t)uptimeGetMs());
- }
- // while (PLUART::byteAvailable()) {
- // readingBytesTimer = (int64_t)((u_int32_t)uptimeGetMs());
- // uint8_t byte_read = PLUART::readByte();
- // printf("%02X ", byte_read); //<--------
- // bm_fprintf(0, "rpi_bytes.log", "%02X\n", byte_read);
- // }
- // if (readingBytesTimer > -1 &&
- // (u_int32_t)uptimeGetMs() - (u_int32_t)readingBytesTimer >= BYTES_CLUSTER_MS) {
- // printf("\n");
- // readingBytesTimer = -1;
- // }
- // Check for available bytes and read them into the buffer
- while (PLUART::byteAvailable()) {
- if (current_rpi_buffer_count < RPI_BUFFER_SIZE) {
- uint8_t byte_read = PLUART::readByte();
- current_rpi_buffer[current_rpi_buffer_count++] = byte_read;
- } else {
- // Buffer full, handle overflow or flush here
- // TODO empty it so that the last (incomplete) buffer doesnt have old values
- }
- // Reset the timer since we've just read a byte
- readingBytesTimer = (int64_t)((u_int32_t)uptimeGetMs());
- }
- // No more bytes available and we have data in the buffer
- if (!PLUART::byteAvailable() && current_rpi_buffer_count > 0 &&
- (u_int32_t)uptimeGetMs() - (u_int32_t)readingBytesTimer >= BYTES_CLUSTER_MS) {
- // Print the buffered bytes all at once
- for (size_t i = 0; i < current_rpi_buffer_count; i++) {
- printf("%02X ", current_rpi_buffer[i]);
- bm_fprintf(0, "rpi_bytes.log", "%02X\n", current_rpi_buffer[i]);
- }
- printf("\n");
- // Reset the buffer count after printing
- current_rpi_buffer_count = 0;
- // Reset the timer
- readingBytesTimer = -1;
- }
- // Read a line if it is available
- // Note - PLUART::setUseLineBuffer must be set true in setup to enable lines.
- if (PLUART::lineAvailable()) {
- // Shortcut the raw bytes cluster completion so the parsed line will be on a new console line
- if (readingBytesTimer > -1) {
- printf("\n");
- readingBytesTimer = -1;
- }
- uint16_t read_len =
- PLUART::readLine(payload_buffer, sizeof(payload_buffer));
- // Get the RTC if available
- RTCTimeAndDate_t time_and_date = {};
- rtcGet(&time_and_date);
- char rtcTimeBuffer[32];
- rtcPrint(rtcTimeBuffer, &time_and_date);
- // Print the payload data to a file, to the bm_printf console, and to the printf console.
- bm_fprintf(0, "payload_data.log", "tick: %llu, rtc: %s, line: %.*s\n",
- uptimeGetMs(), rtcTimeBuffer, read_len, payload_buffer);
- bm_printf(0, "[payload] | tick: %llu, rtc: %s, line: %.*s", uptimeGetMs(),
- rtcTimeBuffer, read_len, payload_buffer);
- printf("[payload-line] | tick: %llu, rtc: %s, line: %.*s\n", uptimeGetMs(),
- rtcTimeBuffer, read_len, payload_buffer);
- //uint16_t payload_buffer[] = {0x01, 0x02, 0x03, 0x04, 0x69}; // Example data bytes
- // ELLIE ADDITION HERE: try to tx data via cellular
- // Copy uart data into a raw bytes buffer and send
- uint8_t tx_data[read_len] = {};
- memcpy(tx_data, reinterpret_cast<uint8_t *>(&payload_buffer), read_len);
- if(spotter_tx_data(tx_data, sizeof(tx_data), BM_NETWORK_TYPE_CELLULAR_IRI_FALLBACK)){
- printf("%llut - %s | Successfully sent Spotter transmit data request\n", uptimeGetMs(), rtcTimeBuffer);
- }
- else {
- printf("%llut - %s | ERR Failed to send Spotter transmit data request!\n", uptimeGetMs(), rtcTimeBuffer);
- }
- ledLinePulse = uptimeGetMs(); // trigger a pulse on LED2
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment