Advertisement
SolarisFalls

Untitled

Jan 26th, 2025
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.27 KB | None | 0 0
  1. #include <SPI.h>
  2. #include <SoftwareSerial.h>
  3. #include <Adafruit_MCP2515.h>
  4. #include <CANTS_CANTSProtocol.h>
  5.  
  6. #include "hardware/watchdog.h"
  7.  
  8. #include "Config.h"
  9. #include "TMTC.h"
  10.  
  11. #define COLOR_RED (0xFF0000)
  12. #define COLOR_GREEN (0x00FF00)
  13. #define COLOR_BLUE (0x0000FF)
  14.  
  15. #define ERROR_CODE_RF69_INIT_FAIL (2)
  16. #define ERROR_CODE_RF69_FREQ_FAIL (3)
  17. #define ERROR_CODE_MCP25625_BEGIN_FAIL (4)
  18. #define ERROR_CODE_CANTS_INIT_FAIL (5)
  19.  
  20. // The encryption key used for the RF communications
  21. uint8_t RFEncryptionKey[] = {
  22.   0x5A, 0x71, 0x15, 0xA7, 0x11, 0x5A, 0x71, 0x15,
  23.   0xA7, 0x11, 0x5A, 0x71, 0x15, 0xA7, 0x11, 0x5A
  24. };
  25.  
  26. uint8_t RFReceiveBuffer[CONFIG_RF_RECEIVE_BUFFER_SIZE];
  27. uint8_t UARTReceiveBuffer[CONFIG_UART_RECEIVE_BUFFER_SIZE];
  28.  
  29. // Used for thread to blink NeoPixel to indicate RF activity
  30. bool RFActivity = false;
  31.  
  32. // The controller object to interact with the MCP25625 CAN transceiver
  33. Adafruit_MCP2515 MCPController(CONFIG_MCP25625_PIN_CHIP_SELECT, CONFIG_MCP25625_PIN_MOSI, CONFIG_MCP25625_PIN_MISO, CONFIG_MCP25625_PIN_CLOCK);
  34.  
  35. void HardFault(uint8_t ErrorCode)
  36. {
  37.   // Turn off LED
  38.   NeoPixelHandle.setPixelColor(0, 0);
  39.   NeoPixelHandle.show();
  40.  
  41.   delay(500);
  42.  
  43.   for (uint8_t BlinkCount = 0; BlinkCount < ErrorCode; ++BlinkCount)
  44.   {
  45.     NeoPixelHandle.setPixelColor(0, COLOR_RED);
  46.     NeoPixelHandle.show();
  47.     delay(200);
  48.     NeoPixelHandle.setPixelColor(0, 0);
  49.     NeoPixelHandle.show();
  50.     delay(200);
  51.   }
  52.  
  53.   delay(2000);
  54.   watchdog_reboot(0, 0, 0);
  55. }
  56.  
  57. // Transmit bytes over RF and block until they're sent (no acknowledgmenet)
  58. void TransmitBytes(uint8_t* BytesToSend, uint8_t BufferSize)
  59. {
  60.   // The driver 'send' function disallows a buffer size of 0
  61.   if (BufferSize == 0) return;
  62.  
  63.   // Indicate RF activity with the LED (refer to loop1())
  64.   RFActivity = true;
  65.  
  66.   // Send the buffer of data
  67.   RF69Driver.send(BytesToSend, BufferSize);
  68.  
  69.   // Block until all bytes have been sent
  70.   RF69Driver.waitPacketSent();
  71. }
  72.  
  73. void OnCANPacketReceived(int PacketSize)
  74. {
  75.   tsCANTS_FRAME_GENERIC tsReceivedFrame = { 0U };
  76.  
  77.   // The CAN packet ID
  78.   long iPacketID = MCPController.packetId();
  79.  
  80.   /* Populate the fields within the CAN-TS frame */
  81.   /* This extracts the CAN-TS fields out of the identifier and assigns them to the frame */
  82.   /* CAN-TS identifier format:
  83.    * [ 8 bits: To Address ][ 3 bits: Type ][ 8 bits: From Address ][ 10 bits: Command ]
  84.    */
  85.   tsReceivedFrame.tsIdentifiers.iToAddress = ((iPacketID & 0x1FE00000) >> 21);
  86.   tsReceivedFrame.tsIdentifiers.iFrameType = ((iPacketID & 0x1C0000) >> 18);
  87.   tsReceivedFrame.tsIdentifiers.iFromAddress = ((iPacketID & 0x3FC00) >> 10);
  88.   tsReceivedFrame.tsIdentifiers.iCommand = ((iPacketID & 0x3FF) >> 0);
  89.  
  90.   tsReceivedFrame.iDataLength = PacketSize;
  91.  
  92.   /* Copy the data into the frame */
  93.   for (tUINT32 iByteIndex = 0U; iByteIndex < PacketSize; ++iByteIndex)
  94.   {
  95.     tsReceivedFrame.acData[iByteIndex] = (tUINT8)(MCPController.read());
  96.   }
  97.  
  98.   CANTS_HandleFrame(&tsReceivedFrame);
  99. }
  100.  
  101. teFUNC_STATUS CallbackSendCANFrame(const tsCANTS_FRAME_GENERIC* tsFrame)
  102. {
  103.   // Contains the frame identifiers as an integer
  104.   tUINT32 iIdentifiers = 0U;
  105.  
  106.   // Shift the identifiers in
  107.   iIdentifiers |= ((tsFrame->tsIdentifiers.iToAddress) << 21);
  108.   iIdentifiers |= ((tsFrame->tsIdentifiers.iFrameType) << 18);
  109.   iIdentifiers |= ((tsFrame->tsIdentifiers.iFromAddress) << 10);
  110.   iIdentifiers |= ((tsFrame->tsIdentifiers.iCommand) << 0);
  111.  
  112.   // Begin the extended CAN packet with the 29-bit identifiers
  113.   MCPController.beginExtendedPacket(iIdentifiers);
  114.  
  115.   // Write the data bytes into the packet
  116.   MCPController.write(tsFrame->acData, tsFrame->iDataLength);
  117.  
  118.   // Send the CAN frame
  119.   MCPController.endPacket();
  120.  
  121.   return BT_SUCCESS;
  122. }
  123.  
  124. void InitialiseCAN()
  125. {
  126.   // Start the MCP controller
  127.   uint32_t MCPBeginStatus = MCPController.begin(CONFIG_CAN_BAUDRATE);
  128.  
  129.   // Ensure that the MCP25625 controller successfully started
  130.   if (MCPBeginStatus != 1)
  131.   {
  132.     HardFault(ERROR_CODE_MCP25625_BEGIN_FAIL);
  133.   }
  134.  
  135.   // Assign the interrupt callback for the MCP controller
  136.   MCPController.onReceive(CONFIG_MCP25625_PIN_INTERRUPT, OnCANPacketReceived);
  137.  
  138.   /* Setup the CAN-TS node address and callbacks */
  139.   tsCANTS_CONFIGURATION tsCANTSConfig = { 0 };
  140.   tsCANTSConfig.iNodeAddress = CONFIG_CANTS_NODE_ADDRESS;
  141.   tsCANTSConfig.funcSendFrame = CallbackSendCANFrame;
  142.  
  143.   tsCANTSConfig.funcCallbackOnTelemetryRequest = OnTelemetryRequest;
  144.   tsCANTSConfig.funcCallbackOnTelecommandRequest = OnTelecommandRequest;
  145.  
  146.   teFUNC_STATUS CANTSInitialiseStatus = CANTS_Initialise(&tsCANTSConfig);
  147.  
  148.   if (CANTSInitialiseStatus != BT_SUCCESS)
  149.   {
  150.     HardFault(ERROR_CODE_CANTS_INIT_FAIL);
  151.   }
  152.  
  153.   MCPController.filter(0x05, 0x7F8);
  154. }
  155.  
  156. void setup()
  157. {
  158.   // Begin the UART serial output driver
  159.   Serial1.begin(CONFIG_UART_BAUDRATE);
  160.   Serial.begin(CONFIG_UART_BAUDRATE);
  161.  
  162.   // Initialise the NeoPixel LED
  163.   NeoPixelHandle.begin();
  164.   NeoPixelHandle.show();
  165.   NeoPixelHandle.setBrightness(20);
  166.  
  167.   // Configure the RF69 Reset Pin as an GPIO output
  168.   pinMode(CONFIG_RF69_RESET_PIN, OUTPUT);
  169.  
  170.   // Set the jumpers as input pins
  171.   pinMode(CONFIG_JUMPER_REGION_PIN, INPUT);
  172.   pinMode(CONFIG_JUMPER_ADDRESS_0_PIN, INPUT);
  173.   pinMode(CONFIG_JUMPER_ADDRESS_1_PIN, INPUT);
  174.   pinMode(CONFIG_JUMPER_ADDRESS_2_PIN, INPUT);
  175.  
  176.   // Read the jumper values
  177.   uint8_t RegionSelection = digitalRead(CONFIG_JUMPER_REGION_PIN);
  178.   uint8_t Address0 = digitalRead(CONFIG_JUMPER_ADDRESS_0_PIN);
  179.   uint8_t Address1 = digitalRead(CONFIG_JUMPER_ADDRESS_1_PIN);
  180.   uint8_t Address2 = digitalRead(CONFIG_JUMPER_ADDRESS_2_PIN);
  181.  
  182.   // Get the Comms address from the jumper values
  183.   RFAddress |= (RegionSelection << 3);
  184.   RFAddress |= (Address0 << 2);
  185.   RFAddress |= (Address1 << 1);
  186.   RFAddress |= (Address2 << 0);
  187.  
  188.   // Start the RF69 Reset Pin at low
  189.   digitalWrite(CONFIG_RF69_RESET_PIN, LOW);
  190.  
  191.   // Perform a board reset for the RF69
  192.   digitalWrite(CONFIG_RF69_RESET_PIN, HIGH);
  193.   delay(10);
  194.   digitalWrite(CONFIG_RF69_RESET_PIN, LOW);
  195.  
  196.   if (!RF69Driver.init())
  197.   {
  198.     HardFault(ERROR_CODE_RF69_INIT_FAIL);
  199.   }
  200.  
  201.   // If low then use Eruope frequencies
  202.   if (RegionSelection == LOW)
  203.   {
  204.     RFFrequency = EuropeFrequencies[RFAddress & 0x07];
  205.   }
  206.   // Else high uses US frequencies
  207.   else
  208.   {
  209.     RFFrequency = USFrequencies[RFAddress & 0x07];
  210.    
  211.     // US frequencies not implemented
  212.     HardFault(ERROR_CODE_RF69_FREQ_FAIL);
  213.   }
  214.  
  215.   // Set the frequency being used
  216.   if (!RF69Driver.setFrequency(RFFrequency))
  217.   {
  218.     HardFault(ERROR_CODE_RF69_FREQ_FAIL);
  219.   }
  220.  
  221.   // Enable high power mode and set the dBm
  222.   RF69Driver.setTxPower(RFTransmitPower, true);
  223.  
  224.   // Set the RF encryption key
  225.   RF69Driver.setEncryptionKey(RFEncryptionKey);
  226.  
  227.   // Setup the MCP controller and CAN-TS object
  228.   InitialiseCAN();
  229.  
  230.   // Default color to green
  231.   NeoPixelHandle.setPixelColor(0, COLOR_GREEN);
  232.   NeoPixelHandle.show();
  233. }
  234.  
  235. void loop()
  236. {
  237.   // If there are RF bytes pending to be received
  238.   if (RF69Driver.available() == true)
  239.   {
  240.     RFActivity = true;
  241.  
  242.     // Receive the pending RF buffer
  243.     uint8_t RFBufferSize = CONFIG_RF_RECEIVE_BUFFER_SIZE;
  244.     RF69Driver.recv(RFReceiveBuffer, &RFBufferSize);
  245.  
  246.     // Send the received RF bytes over the UART
  247.     Serial1.write(RFReceiveBuffer, RFBufferSize);
  248.   }
  249.  
  250.   // Get the number of bytes pending on UART
  251.   size_t UARTBytesToRead = Serial1.available();
  252.  
  253.   // If there are UART bytes waiting to be reada
  254.   if (UARTBytesToRead > 0)
  255.   {
  256.     // Set the number of bytes to read, not exceeding the buffer size
  257.     // This is done so the Serial object doesn't timeout waiting for more bytes to be received
  258.     if (UARTBytesToRead > CONFIG_UART_RECEIVE_BUFFER_SIZE)
  259.     {
  260.       UARTBytesToRead = CONFIG_UART_RECEIVE_BUFFER_SIZE;
  261.     }
  262.  
  263.     // Receive the pending UART bytes
  264.     uint8_t UARTBytesWritten = Serial1.readBytes(UARTReceiveBuffer, UARTBytesToRead);
  265.  
  266.     // Transmit the bytes over UART
  267.     TransmitBytes(UARTReceiveBuffer, UARTBytesWritten);
  268.   }
  269.  
  270.   // Invoke the telemetry and telecommand file loop
  271.   TMTCLoop();
  272. }
  273.  
  274. void loop1()
  275. {
  276.   if (RFActivity == true)
  277.   {
  278.     RFActivity = false;
  279.  
  280.     NeoPixelHandle.setPixelColor(0, COLOR_BLUE);
  281.     NeoPixelHandle.show();
  282.     delay(50);
  283.     NeoPixelHandle.setPixelColor(0, COLOR_GREEN);
  284.     NeoPixelHandle.show();
  285.   }
  286. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement