elliepeauroi

user_code.cpp

May 6th, 2024
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.30 KB | None | 0 0
  1. #include "user_code.h"
  2. #include "bm_network.h"
  3. #include "bm_printf.h"
  4. #include "bm_pubsub.h"
  5. #include "bristlefin.h"
  6. #include "bsp.h"
  7. #include "debug.h"
  8. #include "lwip/inet.h"
  9. #include "payload_uart.h"
  10. #include "sensors.h"
  11. #include "stm32_rtc.h"
  12. #include "task_priorities.h"
  13. #include "uptime.h"
  14. #include "usart.h"
  15. #include "util.h"
  16.  
  17. #define LED_ON_TIME_MS 20
  18. #define LED_PERIOD_MS 1000
  19. #define DEFAULT_BAUD_RATE 9600
  20. #define DEFAULT_LINE_TERM 10 // FL / '\n', 0x0A
  21. #define BYTES_CLUSTER_MS 50
  22.  
  23. // app_main passes a handle to the user config partition in NVM.
  24. extern cfg::Configuration *userConfigurationPartition;
  25.  
  26. // A timer variable we can set to trigger a pulse on LED2 when we get payload serial data
  27. static int32_t ledLinePulse = -1;
  28. static u_int32_t baud_rate_config = DEFAULT_BAUD_RATE;
  29. static u_int32_t line_term_config = DEFAULT_LINE_TERM;
  30.  
  31. // A buffer for our data from the payload uart
  32. char payload_buffer[2048];
  33. // Global buffer and counter
  34. #define RPI_BUFFER_SIZE 48
  35. static uint8_t current_rpi_buffer[RPI_BUFFER_SIZE];
  36. static size_t current_rpi_buffer_count = 0;
  37.  
  38. void setup(void) {
  39.   /* USER ONE-TIME SETUP CODE GOES HERE */
  40.   // Retrieve user-set config values out of NVM.
  41.   userConfigurationPartition->getConfig("plUartBaudRate", strlen("plUartBaudRate"),
  42.                                         baud_rate_config);
  43.   userConfigurationPartition->getConfig("plUartLineTerm", strlen("plUartLineTerm"),
  44.                                         line_term_config);
  45.   // Setup the UART – the on-board serial driver that talks to the RS232 transceiver.
  46.   PLUART::init(USER_TASK_PRIORITY);
  47.   // Baud set per expected baud rate of the sensor.
  48.   PLUART::setBaud(baud_rate_config);
  49.   // Enable passing raw bytes to user app.
  50.   PLUART::setUseByteStreamBuffer(true);
  51.   // Enable parsing lines and passing to user app.
  52.   /// Warning: PLUART only stores a single line at a time. If your attached payload sends lines
  53.   /// faster than the app reads them, they will be overwritten and data will be lost.
  54.   PLUART::setUseLineBuffer(true);
  55.   // Set a line termination character per protocol of the sensor.
  56.   PLUART::setTerminationCharacter((char)line_term_config);
  57.   // Turn on the UART.
  58.   PLUART::enable();
  59.   // Enable the input to the Vout power supply.
  60.   bristlefin.enableVbus();
  61.   // ensure Vbus stable before enable Vout with a 5ms delay.
  62.   vTaskDelay(pdMS_TO_TICKS(5));
  63.   // enable Vout, 12V by default.
  64.   bristlefin.enableVout();
  65. }
  66.  
  67. void loop(void) {
  68.   /* USER LOOP CODE GOES HERE */
  69.   static bool led2State = false;
  70.   /// This checks for a trigger set by ledLinePulse when data is received from the payload UART.
  71.   ///   Each time this happens, we pulse LED2 Green.
  72.   // If LED2 is off and the ledLinePulse flag is set (done in our payload UART process line function), turn it on Green.
  73.   if (!led2State && ledLinePulse > -1) {
  74.     bristlefin.setLed(2, Bristlefin::LED_GREEN);
  75.     led2State = true;
  76.   }
  77.   // If LED2 has been on for LED_ON_TIME_MS, turn it off.
  78.   else if (led2State &&
  79.            ((u_int32_t)uptimeGetMs() - ledLinePulse >= LED_ON_TIME_MS)) {
  80.     bristlefin.setLed(2, Bristlefin::LED_OFF);
  81.     ledLinePulse = -1;
  82.     led2State = false;
  83.   }
  84.  
  85.   /// This section demonstrates a simple non-blocking bare metal method for rollover-safe timed tasks,
  86.   ///   like blinking an LED.
  87.   /// More canonical (but more arcane) modern methods of implementing this kind functionality
  88.   ///   would bee to use FreeRTOS tasks or hardware timer ISRs.
  89.   static u_int32_t ledPulseTimer = uptimeGetMs();
  90.   static u_int32_t ledOnTimer = 0;
  91.   static bool led1State = false;
  92.   // Turn LED1 on green every LED_PERIOD_MS milliseconds.
  93.   if (!led1State &&
  94.       ((u_int32_t)uptimeGetMs() - ledPulseTimer >= LED_PERIOD_MS)) {
  95.     bristlefin.setLed(1, Bristlefin::LED_GREEN);
  96.     ledOnTimer = uptimeGetMs();
  97.     ledPulseTimer += LED_PERIOD_MS;
  98.     led1State = true;
  99.   }
  100.   // If LED1 has been on for LED_ON_TIME_MS milliseconds, turn it off.
  101.   else if (led1State &&
  102.            ((u_int32_t)uptimeGetMs() - ledOnTimer >= LED_ON_TIME_MS)) {
  103.     bristlefin.setLed(1, Bristlefin::LED_OFF);
  104.     led1State = false;
  105.   }
  106.  
  107.   // Read a cluster of bytes if available
  108.   // -- A timer is used to try to keep clusters of bytes (say from lines) in the same output.
  109.   static int64_t readingBytesTimer = -1;
  110.   // Note - PLUART::setUseByteStreamBuffer must be set true in setup to enable bytes.
  111.   if (readingBytesTimer == -1 && PLUART::byteAvailable()) {
  112.     // Get the RTC if available
  113.     RTCTimeAndDate_t time_and_date = {};
  114.     rtcGet(&time_and_date);
  115.     char rtcTimeBuffer[32];
  116.     rtcPrint(rtcTimeBuffer, &time_and_date);
  117.     printf("[payload-bytes] | tick: %llu, rtc: %s, bytes:", uptimeGetMs(),
  118.            rtcTimeBuffer);
  119.     // not very readable, but it's a compact trick to overload our timer variable with a -1 flag
  120.     readingBytesTimer = (int64_t)((u_int32_t)uptimeGetMs());
  121.   }
  122.   // while (PLUART::byteAvailable()) {
  123.   //   readingBytesTimer = (int64_t)((u_int32_t)uptimeGetMs());
  124.   //   uint8_t byte_read = PLUART::readByte();
  125.   //   printf("%02X ", byte_read);                             //<--------
  126.   //   bm_fprintf(0, "rpi_bytes.log", "%02X\n", byte_read);
  127.   // }
  128.   // if (readingBytesTimer > -1 &&
  129.   //     (u_int32_t)uptimeGetMs() - (u_int32_t)readingBytesTimer >= BYTES_CLUSTER_MS) {
  130.   //   printf("\n");
  131.   //   readingBytesTimer = -1;
  132.   // }
  133.  
  134.     // Check for available bytes and read them into the buffer
  135.   while (PLUART::byteAvailable()) {
  136.     if (current_rpi_buffer_count < RPI_BUFFER_SIZE) {
  137.       uint8_t byte_read = PLUART::readByte();
  138.       current_rpi_buffer[current_rpi_buffer_count++] = byte_read;
  139.     } else {
  140.       // Buffer full, handle overflow or flush here
  141.       // TODO empty it so that the last (incomplete) buffer doesnt have old values
  142.     }
  143.     // Reset the timer since we've just read a byte
  144.     readingBytesTimer = (int64_t)((u_int32_t)uptimeGetMs());
  145.   }
  146.   // No more bytes available and we have data in the buffer
  147.   if (!PLUART::byteAvailable() && current_rpi_buffer_count > 0 &&
  148.       (u_int32_t)uptimeGetMs() - (u_int32_t)readingBytesTimer >= BYTES_CLUSTER_MS) {
  149.     // Print the buffered bytes all at once
  150.     for (size_t i = 0; i < current_rpi_buffer_count; i++) {
  151.       printf("%02X ", current_rpi_buffer[i]);
  152.       bm_fprintf(0, "rpi_bytes.log", "%02X\n", current_rpi_buffer[i]);
  153.     }
  154.     printf("\n");
  155.     // Reset the buffer count after printing
  156.     current_rpi_buffer_count = 0;
  157.     // Reset the timer
  158.     readingBytesTimer = -1;
  159.   }
  160.  
  161.  
  162.   // Read a line if it is available
  163.   // Note - PLUART::setUseLineBuffer must be set true in setup to enable lines.
  164.   if (PLUART::lineAvailable()) {
  165.     // Shortcut the raw bytes cluster completion so the parsed line will be on a new console line
  166.     if (readingBytesTimer > -1) {
  167.       printf("\n");
  168.       readingBytesTimer = -1;
  169.     }
  170.     uint16_t read_len =
  171.         PLUART::readLine(payload_buffer, sizeof(payload_buffer));
  172.  
  173.     // Get the RTC if available
  174.     RTCTimeAndDate_t time_and_date = {};
  175.     rtcGet(&time_and_date);
  176.     char rtcTimeBuffer[32];
  177.     rtcPrint(rtcTimeBuffer, &time_and_date);
  178.  
  179.     // Print the payload data to a file, to the bm_printf console, and to the printf console.
  180.     bm_fprintf(0, "payload_data.log", "tick: %llu, rtc: %s, line: %.*s\n",
  181.                uptimeGetMs(), rtcTimeBuffer, read_len, payload_buffer);
  182.     bm_printf(0, "[payload] | tick: %llu, rtc: %s, line: %.*s", uptimeGetMs(),
  183.               rtcTimeBuffer, read_len, payload_buffer);
  184.     printf("[payload-line] | tick: %llu, rtc: %s, line: %.*s\n", uptimeGetMs(),
  185.            rtcTimeBuffer, read_len, payload_buffer);
  186.  
  187.     //uint16_t payload_buffer[] = {0x01, 0x02, 0x03, 0x04, 0x69}; // Example data bytes
  188.  
  189.     // ELLIE ADDITION HERE: try to tx data via cellular
  190.     // Copy uart data into a raw bytes buffer and send
  191.     uint8_t tx_data[read_len] = {};
  192.     memcpy(tx_data, reinterpret_cast<uint8_t *>(&payload_buffer), read_len);
  193.     if(spotter_tx_data(tx_data, sizeof(tx_data), BM_NETWORK_TYPE_CELLULAR_IRI_FALLBACK)){
  194.       printf("%llut - %s | Successfully sent Spotter transmit data request\n", uptimeGetMs(), rtcTimeBuffer);
  195.     }
  196.     else {
  197.       printf("%llut - %s | ERR Failed to send Spotter transmit data request!\n", uptimeGetMs(), rtcTimeBuffer);
  198.     }
  199.  
  200.     ledLinePulse = uptimeGetMs(); // trigger a pulse on LED2
  201.   }
  202.  
  203. }
  204.  
Advertisement
Add Comment
Please, Sign In to add comment