Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef __COM_H_
- #define __COM_H_
- #include "ModuleBase.h"
- #include "UART.h"
- #define BOARD_BUILD BUILD_NUMBER_STR
- #define NUMBER_BUFFER_SIZE 15
- enum COMStates {
- COM_TROUBLESHOOT,
- COM_INIT,
- COM_BUILD_MODULE_CAPACITY_MATRIX,
- COM_MANAGE_SENSORS,
- COM_MANAGE_GPSS,
- COM_MANAGE_KALMAN,
- COM_MANAGE_GUIDANCE,
- COM_MANAGE_NAVIGATION,
- COM_MANAGE_CONTROL,
- COM_MANAGE_SERVOS,
- COM_MANAGE_POWER,
- COM_ANSWER_UART,
- COM_VERIFY_FLAGS,
- COM_EVALUATE_STATUS,
- COM_BROADCAST_TELEMETRY,
- COM_MANAGE_HEARTBEAT
- };
- ///
- /// Communications module (COM) main class.
- ///
- /// The COM module is responsible for interrogating and/or delivering information
- /// to all the other modules of the system via the main SPI bus. COM is the SPI master.
- /// It needs physical access to the other modules' SS lines. The code calls all the slots
- /// in sequence, asking them to send an identification byte. If a module is present
- /// in the slot, it is identified and placed in the correct part of the operation
- /// sequence. After identification, the main sequence is started. First the data source
- /// modules are called, like sensor and GPS modules.
- /// Then the data is sent to and from decision taking modules, such as the flight control one.
- /// Finally the servo control module is called to send the new positions of the servos.
- /// Power supply modules are also interrogated to inform power status to the system.
- ///
- class COM : public ModuleBase {
- public:
- COM();
- ~COM();
- void Run();
- void CustomSetup();
- void CustomLoop();
- bool Init(); ///< Inits SPI, UART and other stuff.
- bool BuildModuleCapacityMatrix(); ///< Identifies the connected modules and saves the information in the m_aeModuleIdentities array.
- bool ManagePower();
- bool ManageSensors();
- bool ManageGPSs();
- bool ManageKalman();
- bool ManageGuidance();
- bool ManageNavigation();
- bool ManageControl();
- bool ManageServos();
- bool AnswerUART(); ///< Answers any UART request, sending back information or executing commands.
- bool VerifyFlags(); ///< Verifies if an flags were set as requested by UART commands.
- bool EvaluateStatus(); ///< Evaluates system status based on all modules status' information.
- bool BroadcastTelemetry(); ///< Broadcasts telemetry via UART.
- bool ManageHeartbeat(); ///< Sends heart beat to redundant COM module
- void TroubleShoot(); ///< Handle errors
- void ReadAndFuse(uint8_t, uint8_t, uint8_t, uint8_t);
- float FuseValues(float, float, float, float, float &);
- void SetupSlotsSS(); ///< Sets all the GPIOs that controls the SS lines of each slot to OUTPUT and HIGH.
- char * FormatFreeRAM(char *); ///< Formats a char array with some text and free RAM size.
- void ConvertAndConcatenate(DataType, char *);
- char * FormatSlotOccupation(char *); ///< Formats a string with slot occupation information.
- void FormatLongAndSend(int32_t);
- void SendNextByteWrapper(); ///< Wraps the UART SendNextByte method so it can be accessed by COMModule.cpp.
- void ReceiveNextByteWrapper(); ///< Wraps the UART ReceiveNextByte method so it can be accessed by COMModule.cpp. Also verifies if the reception was complete and, if so, sets a flag.
- void Echo(char *); ///< Echoes wrong commands back to UART.
- //char * FloatToCharPtr(float, int, char *, uint8_t);
- private:
- UART m_cUART;
- uint8_t m_nError;
- volatile bool m_bUARTMessageReady;
- char m_achReceivedUARTMessage[UART_TRANSFER_BUFFER_SIZE];
- float m_afDataArray[MODULE_SELECT_TOTAL_OPTIONS];
- uint32_t m_nCycleCount;
- volatile uint8_t m_anSlotsStatuses[NUM_SLOTS+1];
- volatile uint32_t m_anCapacitiesPerSlot[NUM_SLOTS+1];
- volatile uint32_t m_anSlotListPerCapacity[TOTAL_CAPACITIES];
- volatile SystemStatus m_eSystemStatus;
- volatile bool m_bSendSPIData;
- volatile COMStates m_eCOMState;
- volatile bool m_bRestart;
- volatile bool m_bIdentifyModulesAgain;
- volatile bool m_bUARTMessageBeingProcessed;
- };
- #endif
- #include "COM.h"
- ///
- /// YAUVeC
- /// Brief description. Detailed stuff.
- ///
- COM::COM() {
- m_nError = 0;
- m_nCycleCount = 0;
- m_eSystemStatus = STATUS_NORMAL;
- m_bUARTMessageReady = false;
- m_bSendSPIData = false;
- m_cBlink.SetLEDGPIO(7);
- m_eCOMState = COM_INIT;
- m_bRestart = false;
- m_bIdentifyModulesAgain = false;
- m_bUARTMessageBeingProcessed = true;
- }
- COM::~COM() {
- }
- void COM::Run() {
- CustomSetup();
- while(1) {
- m_cBlink.ManageLED();
- CustomLoop();
- }
- }
- void COM::CustomSetup() {
- SetAsMasterSPI();
- m_cUART.Init();
- m_cBlink.SetLEDGPIO(7);
- m_cBlink.SetLEDOnCount(10);
- m_cBlink.SetLEDOffCount(100);
- m_cBlink.SetAttentionLEDOnCount(100);
- m_cBlink.SetAttentionLEDOffCount(100);
- m_cBlink.BlinkLED();
- SetupSlotsSS();
- }
- void COM::CustomLoop() {
- m_nCycleCount++;
- switch (m_eCOMState) {
- case COM_INIT:
- m_eCOMState = Init() ? COM_BUILD_MODULE_CAPACITY_MATRIX : COM_TROUBLESHOOT;
- break;
- case COM_BUILD_MODULE_CAPACITY_MATRIX:
- m_eCOMState = BuildModuleCapacityMatrix() ? COM_MANAGE_SENSORS : COM_TROUBLESHOOT;
- break;
- case COM_MANAGE_POWER:
- m_eCOMState = ManagePower() ? COM_MANAGE_SENSORS : COM_ANSWER_UART;
- break;
- case COM_MANAGE_SENSORS:
- m_eCOMState = ManageSensors() ? COM_MANAGE_GPSS : COM_TROUBLESHOOT;
- break;
- case COM_MANAGE_GPSS:
- m_eCOMState = ManageGPSs() ? COM_MANAGE_KALMAN : COM_TROUBLESHOOT;
- break;
- case COM_MANAGE_KALMAN:
- m_eCOMState = ManageKalman() ? COM_MANAGE_GUIDANCE : COM_TROUBLESHOOT;
- break;
- case COM_MANAGE_GUIDANCE:
- m_eCOMState = ManageGuidance() ? COM_MANAGE_NAVIGATION : COM_TROUBLESHOOT;
- break;
- case COM_MANAGE_NAVIGATION:
- m_eCOMState = ManageNavigation() ? COM_MANAGE_CONTROL : COM_TROUBLESHOOT;
- break;
- case COM_MANAGE_CONTROL:
- m_eCOMState = ManageControl() ? COM_MANAGE_SERVOS : COM_TROUBLESHOOT;
- break;
- case COM_MANAGE_SERVOS:
- m_eCOMState = ManageServos() ? COM_ANSWER_UART : COM_TROUBLESHOOT;
- break;
- case COM_ANSWER_UART:
- m_eCOMState = AnswerUART() ? COM_VERIFY_FLAGS : COM_TROUBLESHOOT;
- break;
- case COM_VERIFY_FLAGS:
- m_eCOMState = COM_EVALUATE_STATUS;
- VerifyFlags();
- break;
- case COM_EVALUATE_STATUS:
- m_eCOMState = EvaluateStatus() ? COM_BROADCAST_TELEMETRY : COM_TROUBLESHOOT;
- break;
- case COM_BROADCAST_TELEMETRY:
- m_eCOMState = BroadcastTelemetry() ? COM_MANAGE_HEARTBEAT : COM_TROUBLESHOOT;
- break;
- case COM_MANAGE_HEARTBEAT:
- m_eCOMState = ManageHeartbeat() ? COM_INIT : COM_TROUBLESHOOT;
- break;
- default: m_eCOMState = COM_INIT;
- }
- }
- bool COM::Init() {
- m_bRestart = false;
- return true;
- }
- bool COM::BuildModuleCapacityMatrix() {
- for (volatile uint8_t nSlot = 1; nSlot <= NUM_SLOTS; nSlot++) {
- m_anCapacitiesPerSlot[nSlot] = ReadLongViaSPI(B00_MODULE_CAPACITIES, nSlot);
- for (uint8_t nCapacityBit = 0; nCapacityBit < TOTAL_CAPACITIES; nCapacityBit++) {
- if (bit_is_set(m_anCapacitiesPerSlot, nCapacityBit)) {
- sbi(m_anSlotListPerCapacity[nCapacityBit], nSlot);
- }
- }
- }
- m_bIdentifyModulesAgain = false;
- return true;
- }
- bool COM::ManageSensors() {
- for (uint8_t nSlot = 1; nSlot < NUM_SLOTS; nSlot++) {
- ReadAndFuse(BIT09_ACCELEROMETER, B09_ACCEL_X_AVG, B09_ACCEL_X_STD_DEV, nSlot);
- ReadAndFuse(BIT09_ACCELEROMETER, B09_ACCEL_Y_AVG, B09_ACCEL_Y_STD_DEV, nSlot);
- ReadAndFuse(BIT09_ACCELEROMETER, B09_ACCEL_Z_AVG, B09_ACCEL_Z_STD_DEV, nSlot);
- ReadAndFuse(BIT10_GYROSCOPE, B10_GYRO_X_AVG, B10_GYRO_X_STD_DEV, nSlot);
- ReadAndFuse(BIT10_GYROSCOPE, B10_GYRO_Y_AVG, B10_GYRO_Y_STD_DEV, nSlot);
- ReadAndFuse(BIT10_GYROSCOPE, B10_GYRO_Z_AVG, B10_GYRO_Z_STD_DEV, nSlot);
- ReadAndFuse(BIT11_MAGNETOMETER, B11_MAG_X_AVG, B11_MAG_X_STD_DEV, nSlot);
- ReadAndFuse(BIT11_MAGNETOMETER, B11_MAG_X_AVG, B11_MAG_X_STD_DEV, nSlot);
- ReadAndFuse(BIT11_MAGNETOMETER, B11_MAG_X_AVG, B11_MAG_X_STD_DEV, nSlot);
- ReadAndFuse(BIT12_BAROMETER, B12_BARO_P_AVG, B12_BARO_P_STD_DEV, nSlot);
- ReadAndFuse(BIT12_BAROMETER, B12_BARO_T_AVG, B12_BARO_T_STD_DEV, nSlot);
- ReadAndFuse(BIT12_BAROMETER, B12_BARO_ALT_AVG, B12_BARO_ALT_STD_DEV, nSlot);
- }
- return true;
- }
- bool COM::ManageGPSs() {
- // m_anDataArray[COM_GPS_LATITUDE] = ReadViaSPI(GPSM_GET_GPS_LATITUDE, nSlot);
- // m_anDataArray[COM_GPS_LONGITUDE] = ReadViaSPI(GPSM_GET_GPS_LONGITUDE, nSlot);
- // m_anDataArray[COM_GPS_ALTITUDE] = ReadViaSPI(GPSM_GET_GPS_ALTITUDE, nSlot);
- return true;
- }
- bool COM::ManageKalman() {
- return true;
- }
- bool COM::ManageGuidance() {
- return true;
- }
- bool COM::ManageNavigation() {
- return true;
- }
- bool COM::ManageControl() {
- return true;
- }
- bool COM::ManageServos() {
- return true;
- }
- bool COM::ManagePower() {
- return true;
- }
- bool COM::AnswerUART() {
- if (m_bUARTMessageReady) {
- m_bUARTMessageBeingProcessed = true;
- char achAnswer[UART_TRANSFER_BUFFER_SIZE];
- switch (m_achReceivedUARTMessage[0]) {
- case 's': m_cUART.SendCharArray(FormatSlotOccupation(achAnswer)); break;
- case 'r': m_bRestart = true; break;
- case 'i': m_bIdentifyModulesAgain = true; break;
- case 'f': m_cUART.SendCharArray(FormatFreeRAM(achAnswer)); break;
- case 'C': if (m_achReceivedUARTMessage[1] == '0') {
- switch (m_achReceivedUARTMessage[2]) {
- case '0': ; break; // C00 Ask pilot to warm up engines.
- }
- }
- default: Echo(m_achReceivedUARTMessage);
- }
- m_bUARTMessageReady = false;
- m_bUARTMessageBeingProcessed = false;
- }
- return true;
- }
- bool COM::VerifyFlags() {
- if (m_bRestart) {
- m_eCOMState = COM_INIT;
- }
- if (m_bIdentifyModulesAgain) {
- m_eCOMState = COM_BUILD_MODULE_CAPACITY_MATRIX;
- }
- return true;
- }
- bool COM::EvaluateStatus() {
- return true;
- }
- bool COM::BroadcastTelemetry() {
- if (m_nCycleCount > 30000) {
- char achNumber[NUMBER_BUFFER_SIZE];
- m_nCycleCount = 0;
- uint8_t nIndex;
- uConvertArrayToFloat uUnpacker;
- for (nIndex = 0; nIndex < MODULE_SELECT_TOTAL_OPTIONS; nIndex++) {
- memset(achNumber, 0, NUMBER_BUFFER_SIZE);
- itoa(nIndex, achNumber, 10);
- m_cUART.SendCharArrayNoEOL(achNumber);
- uUnpacker.f = m_afDataArray[nIndex];
- m_cUART.Write(uUnpacker.b[0]);
- m_cUART.Write(uUnpacker.b[1]);
- m_cUART.Write(uUnpacker.b[2]);
- m_cUART.Write(uUnpacker.b[3]);
- //m_cUART.Write('.');
- }
- m_cUART.Write('\n');
- }
- return true;
- }
- bool COM::ManageHeartbeat() {
- return true;
- }
- void COM::TroubleShoot() {
- }
- void COM::ReadAndFuse(uint8_t nCapacityBit, uint8_t nValueSelectOption, uint8_t nSDSelectOption, uint8_t nSlot) {
- float fValue, fStdDev; // FIXME!! Convert all fusing to float!
- bool bFirst = true;
- if (bit_is_set(m_anSlotListPerCapacity[nCapacityBit], nSlot)) {
- fValue = ReadFloatViaSPI(nValueSelectOption, nSlot);
- fStdDev = ReadFloatViaSPI(nSDSelectOption, nSlot);
- if (bFirst) {
- bFirst = false;
- m_afDataArray[nValueSelectOption] = fValue;
- m_afDataArray[nSDSelectOption] = fStdDev;
- }
- else {
- float fFusedSigma;
- m_afDataArray[nValueSelectOption] = FuseValues(m_afDataArray[nValueSelectOption],
- m_afDataArray[nSDSelectOption],
- fValue,
- fStdDev,
- fFusedSigma);
- m_afDataArray[nSDSelectOption] = fFusedSigma;
- }
- }
- }
- float COM::FuseValues(float fZ1, float fSigma1, float fZ2, float fSigma2, float &fFusedSigma) {
- float fVariance1 = pow(fSigma1, 2);
- float fVariance2 = pow(fSigma2, 2);
- float fSumVariances = fVariance1 + fVariance2;
- float fFusedVariance = (fVariance1 * fVariance2) / (fVariance1 + fVariance2);
- fFusedSigma = sqrt(fFusedVariance);
- return ((fVariance2 / fSumVariances) * fZ1 + (fVariance1 / fSumVariances) * fZ2);
- }
- void COM::SetupSlotsSS() {
- // Disable Slave Selects from all slots
- GPIO1_IS_OUTPUT; GPIO1_HIGH; // SS1
- GPIO2_IS_OUTPUT; GPIO2_HIGH; // SS2
- GPIO3_IS_OUTPUT; GPIO3_HIGH; // SS3
- GPIO4_IS_OUTPUT; GPIO4_HIGH; // SS4
- GPIO5_IS_OUTPUT; GPIO5_HIGH; // SS5
- GPIO6_IS_OUTPUT; GPIO6_HIGH; // SS6
- GPIO7_IS_OUTPUT; //GPIO7_HIGH; // SS8 // FIXME! GPIO7 is also SS7 the LED pin.
- GPIO8_IS_OUTPUT; GPIO8_HIGH; // SS7
- }
- char * COM::FormatFreeRAM(char * achBuffer) {
- char achNumber[NUMBER_BUFFER_SIZE];
- memset(achBuffer, 0, UART_TRANSFER_BUFFER_SIZE);
- memset(achNumber, 0, NUMBER_BUFFER_SIZE);
- itoa(FreeRAM(), achNumber, 10);
- strncat(achBuffer, achNumber, UART_TRANSFER_BUFFER_SIZE);
- return achBuffer;
- }
- void COM::ConvertAndConcatenate(DataType Value, char * achBuffer) {
- char achNumber[NUMBER_BUFFER_SIZE];
- ltoa(Value, achNumber, 10);
- strncat(achBuffer, achNumber, UART_TRANSFER_BUFFER_SIZE);
- }
- char * COM::FormatSlotOccupation(char * achBuffer) {
- char achNumber[NUMBER_BUFFER_SIZE];
- char chSeparator[3] = {':', ' ', 0};
- char chSpace[2] = {' ', 0};
- memset(achBuffer, 0, UART_TRANSFER_BUFFER_SIZE);
- for (uint8_t nSlot = 1; nSlot <= NUM_SLOTS; nSlot ++) {
- memset(achNumber, 0, NUMBER_BUFFER_SIZE);
- itoa(nSlot, achNumber, 10);
- strncat(achBuffer, achNumber, UART_TRANSFER_BUFFER_SIZE);
- strncat(achBuffer, chSeparator, UART_TRANSFER_BUFFER_SIZE);
- memset(achNumber, 0, NUMBER_BUFFER_SIZE);
- ltoa(m_anCapacitiesPerSlot[nSlot], achNumber, 10);
- strncat(achBuffer, achNumber, UART_TRANSFER_BUFFER_SIZE);
- strncat(achBuffer, chSpace, UART_TRANSFER_BUFFER_SIZE);
- }
- return achBuffer;
- }
- void COM::FormatLongAndSend(int32_t nNumber) {
- char achNumber[15];
- char chComma[2] = {',', 0};
- ltoa(nNumber, achNumber, 10);
- strncat( achNumber, chComma, sizeof(achNumber));
- m_cUART.SendCharArrayNoEOL(achNumber);
- }
- void COM::SendNextByteWrapper() {
- m_cUART.SendNextByte();
- }
- void COM::ReceiveNextByteWrapper() {
- m_cUART.ReceiveNextByte();
- if (m_cUART.ReceptionIsComplete()) {
- m_bUARTMessageReady = true;
- memset(m_achReceivedUARTMessage, 0, UART_TRANSFER_BUFFER_SIZE);
- m_cUART.GetIncommingMessage(m_achReceivedUARTMessage);
- }
- }
- void COM::Echo(char * achReceived) {
- m_cUART.Write(achReceived[0]);
- m_cUART.Write(achReceived[1]);
- m_cUART.Write(achReceived[2]);
- m_cUART.Write(achReceived[3]);
- m_cUART.Write(achReceived[4]);
- m_cUART.Write(achReceived[5]);
- m_cUART.Write(achReceived[6]);
- m_cUART.Write(achReceived[7]);
- m_cUART.Write(achReceived[8]);
- m_cUART.Write(achReceived[9]);
- m_cUART.Write('\n');
- m_cUART.SendCharArray(achReceived);
- }
Advertisement
Add Comment
Please, Sign In to add comment