From 84ff3b91b45ae2e78f9933b216daa7145b085274 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sun, 29 Sep 2024 20:51:26 -0400 Subject: [PATCH 01/47] Added new git branch --- include/HIB.hpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index 68eca95..dcd3f00 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -1,13 +1,25 @@ #pragma once +#include + namespace HIB { /** * HIB header file */ class HIB { -public: private: + uint16_t throttlePosition; + uint16_t brakePosition; + uint8_t offByOneErrors; + uint8_t marginErrors; + uint8_t comparisonErrors; + uint8_t thresholdInformation; +public: + /// Creates a payload for the CAN bus to transmit. + uint8_t* makePayload(); + uint16_t getThrottlePosition(); + uint16_t getBrakePosition(); }; }// namespace HIB \ No newline at end of file From 213a367f75deded1f8b8b98efc7b135611f800b3 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sun, 29 Sep 2024 20:57:24 -0400 Subject: [PATCH 02/47] Checking if commits work --- include/HIB.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index dcd3f00..7d3f271 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -5,7 +5,7 @@ namespace HIB { /** - * HIB header file + * HIB header file in Branch */ class HIB { private: From 363a9c8faa9138b4081fffe93284f0d43b958252 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Wed, 9 Oct 2024 23:29:04 -0400 Subject: [PATCH 03/47] Ready for testing --- include/HIB.hpp | 32 +++++++++----- src/HIB.cpp | 42 ++++++++++++++++++ targets/REV3-HIB/main.cpp | 90 +++++++++++++++++++++++++++++++++++---- 3 files changed, 146 insertions(+), 18 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index 7d3f271..da7f16d 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace HIB { @@ -9,17 +10,28 @@ namespace HIB { */ class HIB { private: - uint16_t throttlePosition; - uint16_t brakePosition; - uint8_t offByOneErrors; - uint8_t marginErrors; - uint8_t comparisonErrors; - uint8_t thresholdInformation; + uint16_t throttlePosition; + uint16_t brakePosition; + uint8_t noErrors, precisionErrors, marginErrors, comparisonErrors; + DEV::RedundantADC throttle, brake; public: - /// Creates a payload for the CAN bus to transmit. - uint8_t* makePayload(); - uint16_t getThrottlePosition(); - uint16_t getBrakePosition(); + /// Payload for the CAN transmission + uint8_t payload[8]; + + /// Gets the RedundantADCs for the throttle and break voltages + HIB(const DEV::RedundantADC& throttle, const DEV::RedundantADC& brake); + + /// Runs through all the necessary function to update the payload + void process(); + + /// Creates a payload for the CAN bus to transmit. + void makePayload(); + + /// Reads the throttles position and returns it in millivolts + uint16_t getVoltage(DEV::RedundantADC& adc); + + /// Set the positions of the throttle and brake + void getPositions(); }; }// namespace HIB \ No newline at end of file diff --git a/src/HIB.cpp b/src/HIB.cpp index bd5129d..df0e00a 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -1,5 +1,47 @@ #include + namespace HIB { + HIB::HIB(const DEV::RedundantADC& throttle, const DEV::RedundantADC& brake) + : throttlePosition(0), brakePosition(0), noErrors(0), precisionErrors(0), marginErrors(0), + comparisonErrors(0), throttle(throttle), brake(brake) {} + + // "Run" the HIB and update the payload + void HIB::process() { + getPositions(); + makePayload(); + } + + uint16_t HIB::getVoltage(DEV::RedundantADC& red_adc) { + uint32_t voltage = 0; // Voltage to be recieved in millivolts + DEV::RedundantADC::Status status = red_adc.readVoltage(voltage); // gets the errors and voltage from the ADC cluster + if (status == DEV::RedundantADC::Status::OK) { + noErrors++; + } else if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + precisionErrors++; + } else if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + marginErrors++; + } else if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { + comparisonErrors++; + } return voltage; + } + + // Get the position voltage from throttle and break + void HIB::getPositions() { + throttlePosition = getVoltage(throttle); + brakePosition = getVoltage(brake); + } + + // Form payload + void HIB::makePayload() { + payload[0] = throttlePosition >> 8; // Bitshift to get the most sig + payload[1] = throttlePosition & 0xFF; // Erases the most significant bits to ensure data is only collectd from the first 8 bits + payload[2] = brakePosition >> 8; // Same as above + payload[3] = brakePosition & 0xFF; // Same as above + payload[4] = noErrors; + payload[5] = precisionErrors; + payload[6] = marginErrors; + payload[7] = comparisonErrors; + } }// namespace HIB \ No newline at end of file diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index b30c56b..10e9be9 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include namespace IO = EVT::core::IO; @@ -14,16 +16,88 @@ int main() { // Initialize system EVT::core::platform::init(); - // Setup UART + // Get CAN instance with loopback enabled + IO::CAN& can = IO::getCAN(true); IO::UART& uart = IO::getUART(9600); - // String to store user input - char buf[100]; + // TODO: Change these to be the correct pins for the throttle and brake ADCs + IO::ADC& adc0 = IO::getADC(); + IO::ADC& adc1 = IO::getADC(); + IO::ADC& adc2 = IO::getADC(); - while (1) { - // Read user input - uart.printf("Enter message: "); - uart.gets(buf, 100); - uart.printf("\n\recho: %s\n\r", buf); + // Create RedundantADC object + const HIB::DEV::RedundantADC throttleADC(adc0, adc1, adc2); + + IO::ADC& adc3 = IO::getADC(); + IO::ADC& adc4 = IO::getADC(); + IO::ADC& adc5 = IO::getADC(); + + // Create RedundantADC object + const HIB::DEV::RedundantADC brakeADC(adc3, adc4, adc5); + // TODO: End of necessary ADC changes + + HIB::HIB hib = HIB::HIB(throttleADC, brakeADC); + + // ID is 0x0D0 + IO::CANMessage transmit_message(0x0D0, 8, &hib.payload[0], false); + IO::CANMessage received_message; + + // Try to join the network + IO::CAN::CANStatus result = can.connect(); + + // can.addCANFilter(0, 0, 13); //This would create a filter that allows all messages through + can.addCANFilter(0x0D0, 0b0000111111110000, 0); + can.enableEmergencyFilter(ENABLE); + + uart.printf("Starting CAN testing\r\n"); + + if (result != IO::CAN::CANStatus::OK) { + uart.printf("Failed to connect to CAN network\r\n"); + return 1; } + + // MAIN loop + while (true) { + hib.process(); + + result = can.transmit(transmit_message); + if (result != IO::CAN::CANStatus::OK) { + uart.printf("Failed to transmit message\r\n"); + return 1; + } + + result = can.receive(&received_message, false); + if (result != IO::CAN::CANStatus::OK) { + uart.printf("Failed to receive message\r\n"); + continue; + } + + if (received_message.getDataLength() == 0) { + uart.printf("Message filtered out!"); + } else { + uart.printf("Message received\r\n"); + uart.printf("Message id: %d \r\n", received_message.getId()); + uart.printf("Message length: %d\r\n", received_message.getDataLength()); + uart.printf("Message contents: "); + + uint8_t* message_payload = received_message.getPayload(); + for (int i = 0; i < received_message.getDataLength(); i++) { + uart.printf("0x%02X ", message_payload[i]); + } + + // CAN most likely make variables to store total errors over the entire runtime to get a better picture + uart.printf("\r\n"); + uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); + uart.printf("Brake Voltage: %i mV\r\n", message_payload[2] << 8 | message_payload[3]); + uart.printf("No Errors: %i\r\n", message_payload[4]); + uart.printf("Precision Errors: %i\r\n", message_payload[5]); + uart.printf("Margin Errors: %i\r\n", message_payload[6]); + uart.printf("Comparison Errors: %i\r\n", message_payload[7]); + } + uart.printf("\r\n\r\n"); + + EVT::core::time::wait(2999); + } + + return 0; } From e2d66d2d7dd614d24d6eb37d0f3635df49a3109a Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 19 Oct 2024 11:45:36 -0400 Subject: [PATCH 04/47] Ready for CAN, just need it to be implemented on f4 --- CMakeLists.txt | 7 +++++-- targets/REV3-HIB/main.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c9e9602..7d3b07c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,9 +11,9 @@ if(EVT_CORE_LOG_ENABLE) endif() # Handle selection of the target device -option(TARGET_DEV "Target device" "STM32F334x8") +option(TARGET_DEV "Target device" "STM32F446xx") if(NOT TARGET_DEV) - set(TARGET_DEV "STM32F334x8") + set(TARGET_DEV "STM32F446xx") endif() if(TARGET_DEV STREQUAL "STM32F302x8") @@ -22,6 +22,9 @@ if(TARGET_DEV STREQUAL "STM32F302x8") elseif(TARGET_DEV STREQUAL "STM32F334x8") add_compile_definitions(STM32F334x8) add_compile_definitions(STM32F3xx) +elseif(TARGET_DEV STREQUAL "STM32F446xx") + add_compile_definitions(STM32F446xx) + add_compile_definitions(STM32F4xx) else() message(FATAL_ERROR "The target device is not supported") endif() diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 10e9be9..9d83986 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -21,9 +21,9 @@ int main() { IO::UART& uart = IO::getUART(9600); // TODO: Change these to be the correct pins for the throttle and brake ADCs - IO::ADC& adc0 = IO::getADC(); - IO::ADC& adc1 = IO::getADC(); - IO::ADC& adc2 = IO::getADC(); + IO::ADC& adc0 = IO::getADC(); + IO::ADC& adc1 = IO::getADC(); + IO::ADC& adc2 = IO::getADC(); // Create RedundantADC object const HIB::DEV::RedundantADC throttleADC(adc0, adc1, adc2); @@ -39,7 +39,7 @@ int main() { HIB::HIB hib = HIB::HIB(throttleADC, brakeADC); // ID is 0x0D0 - IO::CANMessage transmit_message(0x0D0, 8, &hib.payload[0], false); + IO::CANMessage transmit_message(0x0D0, 8, hib.payload, false); IO::CANMessage received_message; // Try to join the network From d115e6beedf9b54512bf7d104669c1fb06eb071b Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Mon, 4 Nov 2024 19:14:23 -0500 Subject: [PATCH 05/47] Ready for CAN, just need it to be implemented on f4 --- include/HIB.hpp | 2 ++ include/dev/RedundantADC.hpp | 1 - src/HIB.cpp | 9 ++++- src/dev/RedundantADC.cpp | 2 +- targets/REV3-HIB/main.cpp | 64 ++++++++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 3 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index da7f16d..e4e2c3f 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -32,6 +32,8 @@ class HIB { /// Set the positions of the throttle and brake void getPositions(); + + uint16_t readV(uint16_t& adc1, uint16_t& adc2, uint16_t& adc3); }; }// namespace HIB \ No newline at end of file diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index 72e42db..d88147a 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -47,7 +47,6 @@ class RedundantADC { */ RedundantADC::Status readVoltage(uint32_t& return_val); -private: /** Reference to the first ADC. */ IO::ADC& adc0; /** Reference to the second ADC. */ diff --git a/src/HIB.cpp b/src/HIB.cpp index df0e00a..5f81f60 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -28,7 +28,7 @@ namespace HIB { // Get the position voltage from throttle and break void HIB::getPositions() { - throttlePosition = getVoltage(throttle); + // throttlePosition = getVoltage(throttle); brakePosition = getVoltage(brake); } @@ -44,4 +44,11 @@ namespace HIB { payload[7] = comparisonErrors; } + uint16_t HIB::readV(uint16_t& adc1, uint16_t& adc2, uint16_t& adc3) { + adc1 = brake.adc0.read() * 1000; + adc2 = brake.adc1.read() * 1000; + adc3 = brake.adc2.read() * 1000; + return (adc1 + adc2 + adc3) / 3; + } + }// namespace HIB \ No newline at end of file diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 797d5e5..b0610a4 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -62,7 +62,7 @@ RedundantADC::Status RedundantADC::readVoltage(uint32_t& return_val) { return RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED; } - return_val = 0; + return_val = 1; return RedundantADC::Status::COMPARISON_ERROR; } diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 9d83986..0ee5023 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -4,6 +4,69 @@ * enters. */ +#include +#include +#include +#include +#include +#include + +namespace IO = EVT::core::IO; + +int main() { + // Initialize system + EVT::core::platform::init(); + IO::UART& uart = IO::getUART(9600); + + // TODO: Change these to be the correct pins for the throttle and brake ADCs + IO::ADC& adc0 = IO::getADC(); + IO::ADC& adc1 = IO::getADC(); + IO::ADC& adc2 = IO::getADC(); + + // Create RedundantADC object + const HIB::DEV::RedundantADC throttleADC(adc0, adc1, adc2); + + IO::ADC& adc3 = IO::getADC(); + IO::ADC& adc4 = IO::getADC(); + IO::ADC& adc5 = IO::getADC(); + + // Create RedundantADC object + const HIB::DEV::RedundantADC brakeADC(adc3, adc4, adc5); + // TODO: End of necessary ADC changes + + HIB::HIB hib = HIB::HIB(throttleADC, brakeADC); + + // MAIN loop + while (true) { + hib.process(); + uint16_t adc7 = 0; + uint16_t adc8 = 0; + uint16_t adc9 = 0; + uint16_t adcAvg = hib.readV(adc7, adc8, adc9); + // Should most likely make variables to store total errors over the entire runtime to get a better picture + uart.printf("\r\n"); + uart.printf("Throttle Voltage: %i mV\r\n", hib.payload[0] << 8 | hib.payload[1]); + uart.printf("Brake Voltage: %i mV\r\n", hib.payload[2] << 8 | hib.payload[3]); + uart.printf("No Errors: %i\r\n", hib.payload[4]); + uart.printf("Precision Errors: %i\r\n", hib.payload[5]); + uart.printf("Margin Errors: %i\r\n", hib.payload[6]); + uart.printf("Comparison Errors: %i\r\n", hib.payload[7]); + uart.printf("adc0 voltage: %i\r\n", adc7); + uart.printf("adc1 voltage: %i\r\n", adc8); + uart.printf("adc2 voltage: %i\r\n", adc9); + uart.printf("\r\n"); + EVT::core::time::wait(1500); + } + + return 0; +} +/** + * This is a basic sample of using the UART module. The program provides a + * basic echo functionality where the uart will write back whatever the user + * enters. + */ + +/* #include #include #include @@ -101,3 +164,4 @@ int main() { return 0; } +*/ \ No newline at end of file From a85fdce301dfea21c9822a5d87f27472fc39fb67 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Thu, 7 Nov 2024 20:18:33 -0500 Subject: [PATCH 06/47] added vs folder --- .vs/HIB/v17/.wsuo | Bin 0 -> 14848 bytes .vs/HIB/v17/DocumentLayout.json | 12 ++++++++++++ .vs/VSWorkspaceState.json | 6 ++++++ 3 files changed, 18 insertions(+) create mode 100644 .vs/HIB/v17/.wsuo create mode 100644 .vs/HIB/v17/DocumentLayout.json create mode 100644 .vs/VSWorkspaceState.json diff --git a/.vs/HIB/v17/.wsuo b/.vs/HIB/v17/.wsuo new file mode 100644 index 0000000000000000000000000000000000000000..edba235f2f81cad8cf397c34be34c11317d3792f GIT binary patch literal 14848 zcmeI3-*Zz%6vsCpBL2o7D40eN=48&jyL)%{?4CX6?Aagr z_3rLJzWQe0pC$lj%yx5cb(eYAm!9y2&C|v_r#NZ%R##W~L|DN##E1h|OkTf|=`dqv zN$-NW%}_>$J!VH`%y(>1>aV?b7WN3BK6IB&PAw>yjBrxCm=LHv<>!s=^KQe|xjHDRalb>Si58^XiFH-&Er-xeMb zb_u(MM}u@yj&{;=ARQ5zQIjpxM?M&i8E@@nI9jTZHZ|L`7L!`oK6!Q+&^W7B{r^uzdY zSoHCM-8^S2-QY2(@7O3HNS}2`N*q`Y)jF>%&qGb{AE{=328PAiytut6o)`3vy6*8x zW7D@K5{lq6MCJde@?zV8t5*6K%teiLQGK42;I%`PnBuW=d^80_d2`Wtr5abl_W7(<}@#cTV+1m*@D@(Mj`H}e_Pk>ZEoG9C0e7>mtXIhO02bDK=Q|04nH$0eZTzs{hbLb*VE;huv=Qe z{Iev=Y3U_WkC#+!k<@=n*Nwqi%j$>dJ3a#tMt{ooyku?UOr`IXNQ*P`wk6WP1b%fR z^s$$2{$=i(5RY@JF_Y~ejIgmrU#GrWCnT$yQX_)(p~*C z{e4}7Gtd31L(^pQQv zuhp?Uq-bQ=Z2Kb<3d!i!0{$$UN%PkeHOzkQx55!~$|TF0&zcCE*WvR@lClec_<~4cm1CD*{e!*u6>W z%|15kgrphQ4WD7FG1XPGZ~T$@xH_?c81y#-+-Iq*K{;5YLhwni#oaoQDXJGWlCG6= zj>U$Ax zfAzoiZlC}Czt8`|&L6JpjDb^_OPc?9a}E*&oxfMk9?*^8_gZoGHkosQF#03%CA^cU zMc*BO_p8of&glGu`$gP0ib|ikJj(ftpT0XI#`pK%L(uta0$a)brl|ClwL-s<^Vht3 zp0>NF?4XvYMt7MS=l?mCBn&V?SBy-;P~77XWVOz%KxoA{_XpJ>+c`d u(>+vZ3*7%}`2R=#`+v-X*iS46_YWFf{|DEv?fV}{MRW-AFM7$= Date: Mon, 2 Dec 2024 19:09:18 -0500 Subject: [PATCH 07/47] Saving work with the brake until we are ready to implement it --- CMakeLists.txt | 5 +- include/HIB.hpp | 39 -------- include/HIB_Soon.h | 40 ++++++++ libs/EVT-core | 2 +- src/HIB.cpp | 54 ----------- src/HIB_Soon.cpp | 54 +++++++++++ targets/REV3-HIB/main.cpp | 167 --------------------------------- targets/REV3-HIB/main_Soon.cpp | 146 ++++++++++++++++++++++++++++ 8 files changed, 245 insertions(+), 262 deletions(-) create mode 100644 include/HIB_Soon.h create mode 100644 src/HIB_Soon.cpp create mode 100644 targets/REV3-HIB/main_Soon.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d3b07c..3a795ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,10 @@ project(${BOARD_LIB_NAME} LANGUAGES CXX C ) -add_library(${PROJECT_NAME} STATIC) +add_library(${PROJECT_NAME} STATIC + src/HIB_Soon.cpp + targets/REV3-HIB/main_Soon.cpp + include/HIB_Soon.h) # Add sources target_sources(${PROJECT_NAME} PRIVATE diff --git a/include/HIB.hpp b/include/HIB.hpp index e4e2c3f..e69de29 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -1,39 +0,0 @@ -#pragma once - -#include -#include - -namespace HIB { - -/** - * HIB header file in Branch - */ -class HIB { -private: - uint16_t throttlePosition; - uint16_t brakePosition; - uint8_t noErrors, precisionErrors, marginErrors, comparisonErrors; - DEV::RedundantADC throttle, brake; -public: - /// Payload for the CAN transmission - uint8_t payload[8]; - - /// Gets the RedundantADCs for the throttle and break voltages - HIB(const DEV::RedundantADC& throttle, const DEV::RedundantADC& brake); - - /// Runs through all the necessary function to update the payload - void process(); - - /// Creates a payload for the CAN bus to transmit. - void makePayload(); - - /// Reads the throttles position and returns it in millivolts - uint16_t getVoltage(DEV::RedundantADC& adc); - - /// Set the positions of the throttle and brake - void getPositions(); - - uint16_t readV(uint16_t& adc1, uint16_t& adc2, uint16_t& adc3); -}; - -}// namespace HIB \ No newline at end of file diff --git a/include/HIB_Soon.h b/include/HIB_Soon.h new file mode 100644 index 0000000..404e56d --- /dev/null +++ b/include/HIB_Soon.h @@ -0,0 +1,40 @@ +#pragma once +#include +#include + +namespace HIB { +/** + * HIB header file in Branch + */ +class HIB { +private: + uint16_t throttlePosition; + uint16_t brakePosition; + uint8_t noErrors; + uint8_t precisionErrors; + uint8_t marginErrors; + uint8_t comparisonErrors; + DEV::RedundantADC throttle; + DEV::RedundantADC brake; + uint8_t payload[8]; +public: + /// Gets the RedundantADCs for the throttle and break voltages + HIB(const DEV::RedundantADC& throttle, const DEV::RedundantADC& brake); + + /// Runs through all the necessary function to update the payload + void process(); + + /// Creates a payload for the CAN bus to transmit. + void makePayload(); + + /// Reads the throttles position and returns it in millivolts + uint16_t getVoltage(DEV::RedundantADC& adc); + + /// Set the positions of the throttle and brake + void getPositions(); + + /// Read the voltage from the triple ADC setup + uint16_t readV(uint16_t& adc1, uint16_t& adc2, uint16_t& adc3); +}; + +}// namespace HIB \ No newline at end of file diff --git a/libs/EVT-core b/libs/EVT-core index b3321e9..b67f79b 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit b3321e978e7a7dd057f932aa252653b7002bcb7a +Subproject commit b67f79b915d7d153503475990ce1ce41f1bcc304 diff --git a/src/HIB.cpp b/src/HIB.cpp index 5f81f60..e69de29 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -1,54 +0,0 @@ -#include - - -namespace HIB { - HIB::HIB(const DEV::RedundantADC& throttle, const DEV::RedundantADC& brake) - : throttlePosition(0), brakePosition(0), noErrors(0), precisionErrors(0), marginErrors(0), - comparisonErrors(0), throttle(throttle), brake(brake) {} - - // "Run" the HIB and update the payload - void HIB::process() { - getPositions(); - makePayload(); - } - - uint16_t HIB::getVoltage(DEV::RedundantADC& red_adc) { - uint32_t voltage = 0; // Voltage to be recieved in millivolts - DEV::RedundantADC::Status status = red_adc.readVoltage(voltage); // gets the errors and voltage from the ADC cluster - if (status == DEV::RedundantADC::Status::OK) { - noErrors++; - } else if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { - precisionErrors++; - } else if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { - marginErrors++; - } else if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { - comparisonErrors++; - } return voltage; - } - - // Get the position voltage from throttle and break - void HIB::getPositions() { - // throttlePosition = getVoltage(throttle); - brakePosition = getVoltage(brake); - } - - // Form payload - void HIB::makePayload() { - payload[0] = throttlePosition >> 8; // Bitshift to get the most sig - payload[1] = throttlePosition & 0xFF; // Erases the most significant bits to ensure data is only collectd from the first 8 bits - payload[2] = brakePosition >> 8; // Same as above - payload[3] = brakePosition & 0xFF; // Same as above - payload[4] = noErrors; - payload[5] = precisionErrors; - payload[6] = marginErrors; - payload[7] = comparisonErrors; - } - - uint16_t HIB::readV(uint16_t& adc1, uint16_t& adc2, uint16_t& adc3) { - adc1 = brake.adc0.read() * 1000; - adc2 = brake.adc1.read() * 1000; - adc3 = brake.adc2.read() * 1000; - return (adc1 + adc2 + adc3) / 3; - } - -}// namespace HIB \ No newline at end of file diff --git a/src/HIB_Soon.cpp b/src/HIB_Soon.cpp new file mode 100644 index 0000000..5f81f60 --- /dev/null +++ b/src/HIB_Soon.cpp @@ -0,0 +1,54 @@ +#include + + +namespace HIB { + HIB::HIB(const DEV::RedundantADC& throttle, const DEV::RedundantADC& brake) + : throttlePosition(0), brakePosition(0), noErrors(0), precisionErrors(0), marginErrors(0), + comparisonErrors(0), throttle(throttle), brake(brake) {} + + // "Run" the HIB and update the payload + void HIB::process() { + getPositions(); + makePayload(); + } + + uint16_t HIB::getVoltage(DEV::RedundantADC& red_adc) { + uint32_t voltage = 0; // Voltage to be recieved in millivolts + DEV::RedundantADC::Status status = red_adc.readVoltage(voltage); // gets the errors and voltage from the ADC cluster + if (status == DEV::RedundantADC::Status::OK) { + noErrors++; + } else if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + precisionErrors++; + } else if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + marginErrors++; + } else if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { + comparisonErrors++; + } return voltage; + } + + // Get the position voltage from throttle and break + void HIB::getPositions() { + // throttlePosition = getVoltage(throttle); + brakePosition = getVoltage(brake); + } + + // Form payload + void HIB::makePayload() { + payload[0] = throttlePosition >> 8; // Bitshift to get the most sig + payload[1] = throttlePosition & 0xFF; // Erases the most significant bits to ensure data is only collectd from the first 8 bits + payload[2] = brakePosition >> 8; // Same as above + payload[3] = brakePosition & 0xFF; // Same as above + payload[4] = noErrors; + payload[5] = precisionErrors; + payload[6] = marginErrors; + payload[7] = comparisonErrors; + } + + uint16_t HIB::readV(uint16_t& adc1, uint16_t& adc2, uint16_t& adc3) { + adc1 = brake.adc0.read() * 1000; + adc2 = brake.adc1.read() * 1000; + adc3 = brake.adc2.read() * 1000; + return (adc1 + adc2 + adc3) / 3; + } + +}// namespace HIB \ No newline at end of file diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 0ee5023..e69de29 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -1,167 +0,0 @@ -/** - * This is a basic sample of using the UART module. The program provides a - * basic echo functionality where the uart will write back whatever the user - * enters. - */ - -#include -#include -#include -#include -#include -#include - -namespace IO = EVT::core::IO; - -int main() { - // Initialize system - EVT::core::platform::init(); - IO::UART& uart = IO::getUART(9600); - - // TODO: Change these to be the correct pins for the throttle and brake ADCs - IO::ADC& adc0 = IO::getADC(); - IO::ADC& adc1 = IO::getADC(); - IO::ADC& adc2 = IO::getADC(); - - // Create RedundantADC object - const HIB::DEV::RedundantADC throttleADC(adc0, adc1, adc2); - - IO::ADC& adc3 = IO::getADC(); - IO::ADC& adc4 = IO::getADC(); - IO::ADC& adc5 = IO::getADC(); - - // Create RedundantADC object - const HIB::DEV::RedundantADC brakeADC(adc3, adc4, adc5); - // TODO: End of necessary ADC changes - - HIB::HIB hib = HIB::HIB(throttleADC, brakeADC); - - // MAIN loop - while (true) { - hib.process(); - uint16_t adc7 = 0; - uint16_t adc8 = 0; - uint16_t adc9 = 0; - uint16_t adcAvg = hib.readV(adc7, adc8, adc9); - // Should most likely make variables to store total errors over the entire runtime to get a better picture - uart.printf("\r\n"); - uart.printf("Throttle Voltage: %i mV\r\n", hib.payload[0] << 8 | hib.payload[1]); - uart.printf("Brake Voltage: %i mV\r\n", hib.payload[2] << 8 | hib.payload[3]); - uart.printf("No Errors: %i\r\n", hib.payload[4]); - uart.printf("Precision Errors: %i\r\n", hib.payload[5]); - uart.printf("Margin Errors: %i\r\n", hib.payload[6]); - uart.printf("Comparison Errors: %i\r\n", hib.payload[7]); - uart.printf("adc0 voltage: %i\r\n", adc7); - uart.printf("adc1 voltage: %i\r\n", adc8); - uart.printf("adc2 voltage: %i\r\n", adc9); - uart.printf("\r\n"); - EVT::core::time::wait(1500); - } - - return 0; -} -/** - * This is a basic sample of using the UART module. The program provides a - * basic echo functionality where the uart will write back whatever the user - * enters. - */ - -/* -#include -#include -#include -#include -#include - -namespace IO = EVT::core::IO; - -int main() { - // Initialize system - EVT::core::platform::init(); - - // Get CAN instance with loopback enabled - IO::CAN& can = IO::getCAN(true); - IO::UART& uart = IO::getUART(9600); - - // TODO: Change these to be the correct pins for the throttle and brake ADCs - IO::ADC& adc0 = IO::getADC(); - IO::ADC& adc1 = IO::getADC(); - IO::ADC& adc2 = IO::getADC(); - - // Create RedundantADC object - const HIB::DEV::RedundantADC throttleADC(adc0, adc1, adc2); - - IO::ADC& adc3 = IO::getADC(); - IO::ADC& adc4 = IO::getADC(); - IO::ADC& adc5 = IO::getADC(); - - // Create RedundantADC object - const HIB::DEV::RedundantADC brakeADC(adc3, adc4, adc5); - // TODO: End of necessary ADC changes - - HIB::HIB hib = HIB::HIB(throttleADC, brakeADC); - - // ID is 0x0D0 - IO::CANMessage transmit_message(0x0D0, 8, hib.payload, false); - IO::CANMessage received_message; - - // Try to join the network - IO::CAN::CANStatus result = can.connect(); - - // can.addCANFilter(0, 0, 13); //This would create a filter that allows all messages through - can.addCANFilter(0x0D0, 0b0000111111110000, 0); - can.enableEmergencyFilter(ENABLE); - - uart.printf("Starting CAN testing\r\n"); - - if (result != IO::CAN::CANStatus::OK) { - uart.printf("Failed to connect to CAN network\r\n"); - return 1; - } - - // MAIN loop - while (true) { - hib.process(); - - result = can.transmit(transmit_message); - if (result != IO::CAN::CANStatus::OK) { - uart.printf("Failed to transmit message\r\n"); - return 1; - } - - result = can.receive(&received_message, false); - if (result != IO::CAN::CANStatus::OK) { - uart.printf("Failed to receive message\r\n"); - continue; - } - - if (received_message.getDataLength() == 0) { - uart.printf("Message filtered out!"); - } else { - uart.printf("Message received\r\n"); - uart.printf("Message id: %d \r\n", received_message.getId()); - uart.printf("Message length: %d\r\n", received_message.getDataLength()); - uart.printf("Message contents: "); - - uint8_t* message_payload = received_message.getPayload(); - for (int i = 0; i < received_message.getDataLength(); i++) { - uart.printf("0x%02X ", message_payload[i]); - } - - // CAN most likely make variables to store total errors over the entire runtime to get a better picture - uart.printf("\r\n"); - uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); - uart.printf("Brake Voltage: %i mV\r\n", message_payload[2] << 8 | message_payload[3]); - uart.printf("No Errors: %i\r\n", message_payload[4]); - uart.printf("Precision Errors: %i\r\n", message_payload[5]); - uart.printf("Margin Errors: %i\r\n", message_payload[6]); - uart.printf("Comparison Errors: %i\r\n", message_payload[7]); - } - uart.printf("\r\n\r\n"); - - EVT::core::time::wait(2999); - } - - return 0; -} -*/ \ No newline at end of file diff --git a/targets/REV3-HIB/main_Soon.cpp b/targets/REV3-HIB/main_Soon.cpp new file mode 100644 index 0000000..7541d45 --- /dev/null +++ b/targets/REV3-HIB/main_Soon.cpp @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include + +namespace IO = core::io; + +int main() { + core::platform::init(); + + IO::CAN& can = IO::getCAN(true); + IO::UART& uart = IO::getUART(9600); + IO::ADC& adc0 = IO::getADC(); + IO::ADC& adc1 = IO::getADC(); + IO::ADC& adc2 = IO::getADC(); + + const HIB::DEV::RedundantADC throttleADC(adc0, adc1, adc2); + + HIB::HIB hib = HIB::HIB(throttleADC, brakeADC); + + // ID for HIB is 0x0D0 + IO::CANMessage transmit_message(0x0D0, 8, hib.payload, false); + IO::CANMessage received_message; + + // Try to join the network + IO::CAN::CANStatus result = can.connect(); + + // can.addCANFilter(0, 0, 13); //This would create a filter that allows all messages through + can.addCANFilter(0xD0, 0xFF0, 0); + can.enableEmergencyFilter(ENABLE); + + uart.printf("Starting CAN testing\r\n"); + + if (result != IO::CAN::CANStatus::OK) { + uart.printf("Failed to connect to CAN network\r\n"); + return 1; + } + + // MAIN loop + while (true) { + hib.process(); + + result = can.transmit(transmit_message); + if (result != IO::CAN::CANStatus::OK) { + uart.printf("Failed to transmit message\r\n"); + return 1; + } + + result = can.receive(&received_message, false); + if (result != IO::CAN::CANStatus::OK) { + uart.printf("Failed to receive message\r\n"); + continue; + } + + if (received_message.getDataLength() == 0) { + uart.printf("Message filtered out!"); + } else { + uart.printf("Message received\r\n"); + uart.printf("Message id: %d \r\n", received_message.getId()); + uart.printf("Message length: %d\r\n", received_message.getDataLength()); + uart.printf("Message contents: "); + + uint8_t* message_payload = received_message.getPayload(); + for (int i = 0; i < received_message.getDataLength(); i++) { + uart.printf("0x%02X ", message_payload[i]); + } + + // CAN most likely make variables to store total errors over the entire runtime to get a better picture + uart.printf("\r\n"); + uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); + uart.printf("Brake Voltage: %i mV\r\n", message_payload[2] << 8 | message_payload[3]); + uart.printf("No Errors: %i\r\n", message_payload[4]); + uart.printf("Precision Errors: %i\r\n", message_payload[5]); + uart.printf("Margin Errors: %i\r\n", message_payload[6]); + uart.printf("Comparison Errors: %i\r\n", message_payload[7]); + } + uart.printf("\r\n\r\n"); + + EVT::core::time::wait(2999); + } + + return 0; +} + + +/* + +#include +#include +#include +#include +#include +#include + +namespace IO = EVT::core::IO; + +int main() { + // Initialize system + EVT::core::platform::init(); + IO::UART& uart = IO::getUART(9600); + + // TODO: Change these to be the correct pins for the throttle and brake ADCs + IO::ADC& adc0 = IO::getADC(); + IO::ADC& adc1 = IO::getADC(); + IO::ADC& adc2 = IO::getADC(); + + // Create RedundantADC object + const HIB::DEV::RedundantADC throttleADC(adc0, adc1, adc2); + + IO::ADC& adc3 = IO::getADC(); + IO::ADC& adc4 = IO::getADC(); + IO::ADC& adc5 = IO::getADC(); + + // Create RedundantADC object + const HIB::DEV::RedundantADC brakeADC(adc3, adc4, adc5); + // TODO: End of necessary ADC changes + + HIB::HIB hib = HIB::HIB(throttleADC, brakeADC); + + // MAIN loop + while (true) { + hib.process(); + uint16_t adc7 = 0; + uint16_t adc8 = 0; + uint16_t adc9 = 0; + uint16_t adcAvg = hib.readV(adc7, adc8, adc9); + // Should most likely make variables to store total errors over the entire runtime to get a better picture + uart.printf("\r\n"); + uart.printf("Throttle Voltage: %i mV\r\n", hib.payload[0] << 8 | hib.payload[1]); + uart.printf("Brake Voltage: %i mV\r\n", hib.payload[2] << 8 | hib.payload[3]); + uart.printf("No Errors: %i\r\n", hib.payload[4]); + uart.printf("Precision Errors: %i\r\n", hib.payload[5]); + uart.printf("Margin Errors: %i\r\n", hib.payload[6]); + uart.printf("Comparison Errors: %i\r\n", hib.payload[7]); + uart.printf("adc0 voltage: %i\r\n", adc7); + uart.printf("adc1 voltage: %i\r\n", adc8); + uart.printf("adc2 voltage: %i\r\n", adc9); + uart.printf("\r\n"); + EVT::core::time::wait(1500); + } + + return 0; +} +*/ \ No newline at end of file From 545394ca28ea85d2453e6d3e2652d904f4fcd2a5 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Mon, 2 Dec 2024 21:06:22 -0500 Subject: [PATCH 08/47] Should probably work now :) --- CMakeLists.txt | 1 - include/HIB.hpp | 57 +++++++++++++ include/HIB_Soon.h | 8 +- include/dev/RedundantADC.hpp | 5 +- src/HIB.cpp | 42 ++++++++++ src/HIB_Soon.cpp | 6 +- src/dev/RedundantADC.cpp | 9 +- targets/REV3-HIB/main.cpp | 91 ++++++++++++++++++++ targets/REV3-HIB/main_Soon.cpp | 146 --------------------------------- 9 files changed, 204 insertions(+), 161 deletions(-) delete mode 100644 targets/REV3-HIB/main_Soon.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a795ae..dca1f81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,6 @@ project(${BOARD_LIB_NAME} add_library(${PROJECT_NAME} STATIC src/HIB_Soon.cpp - targets/REV3-HIB/main_Soon.cpp include/HIB_Soon.h) # Add sources diff --git a/include/HIB.hpp b/include/HIB.hpp index e69de29..35a4a0d 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -0,0 +1,57 @@ +#pragma once +#include +#include +#include + +namespace IO = core::io; + +namespace HIB { + +class HIB { +public: + /** + * Constructor for the HIB + * Takes a redundant ADC reference + * @param throttle: const RedundantADC reference + */ + HIB(const DEV::RedundantADC& throttle); + + /** + * Main function for the HIB. Runs all subroutines for things like reading voltage + */ + void process(); + + /** + * Takes an adc to read from and the payload index of the most significant byte for the voltage + * from the redundant adc + * @param adc: The redundant adc that the voltage should be read from + * @param volts: The payload index that the most significant + * byte of voltage should be stored at + */ + void setVoltage(DEV::RedundantADC adc, uint8_t* volts); + + /** + * Gets the payload for reading from + * @return: The address of the first index of the payload + */ + uint8_t* getPayload(); + +private: + /** 8 byte payload stores data in this order: + * [0] - Most Significant Throttle Byte + * [1] - Least Significant Throttle Byte + * [2] - Most Significant Blank Byte for Brake + * [3] - Least Significant Blank Byte for Brake + * [4] - # of OK's + * [5] - # of PRECISION_MARGIN_EXCEEDED errors + * [6] - # of ACCEPTABLE_MARGIN_EXCEEDED errors + * [7] - # of COMPARISON_ERROR errors + */ + uint8_t payload[8]; + size_t payloadLength = 8; + + /// The triple adc setup attached to the throttle + DEV::RedundantADC throttle; +}; + +} diff --git a/include/HIB_Soon.h b/include/HIB_Soon.h index 404e56d..2098f6b 100644 --- a/include/HIB_Soon.h +++ b/include/HIB_Soon.h @@ -1,12 +1,12 @@ -#pragma once +/* #pragma once #include #include -namespace HIB { +namespace HIB_Soon { /** * HIB header file in Branch */ -class HIB { +class HIB_Nah { private: uint16_t throttlePosition; uint16_t brakePosition; @@ -37,4 +37,4 @@ class HIB { uint16_t readV(uint16_t& adc1, uint16_t& adc2, uint16_t& adc3); }; -}// namespace HIB \ No newline at end of file +}// namespace HIB */ \ No newline at end of file diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index d88147a..c61fec2 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -1,8 +1,7 @@ #pragma once +#include -#include - -namespace IO = EVT::core::IO; +namespace IO = core::io; namespace HIB::DEV { diff --git a/src/HIB.cpp b/src/HIB.cpp index e69de29..297df24 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -0,0 +1,42 @@ +#include +#include +#include + +namespace HIB { + +HIB::HIB(const DEV::RedundantADC& throttle) + : throttle(throttle) { + // Clear payload + for (int i = 0; i < payloadLength; i++) { + payload[i] = 0; + } +} + +void HIB::process() { + HIB::setVoltage(throttle, &payload[0]); +} + +void HIB::setVoltage(DEV::RedundantADC adc, uint8_t* volts) { + uint32_t voltage = 0; // Voltage to be recieved in millivolts + DEV::RedundantADC::Status status = adc.readVoltage(voltage); // gets the errors and voltage from the ADC cluster + if (status == DEV::RedundantADC::Status::OK) { + payload[4]++; + } else if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + payload[5]++; + } else if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + payload[6]++; + } else if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { + payload[7]++; + } + + // Set the given byte pointer and the index after to the voltage given + // Bit-masking just in case + volts[0] = (voltage >> 24) & 0xFF; + volts[1] = (voltage >> 16) & 0xFF; +} + +uint8_t* HIB::getPayload() { + return &payload[0]; +} + +} \ No newline at end of file diff --git a/src/HIB_Soon.cpp b/src/HIB_Soon.cpp index 5f81f60..7c68a54 100644 --- a/src/HIB_Soon.cpp +++ b/src/HIB_Soon.cpp @@ -1,7 +1,7 @@ -#include +/* #include -namespace HIB { +namespace HIB_Soon { HIB::HIB(const DEV::RedundantADC& throttle, const DEV::RedundantADC& brake) : throttlePosition(0), brakePosition(0), noErrors(0), precisionErrors(0), marginErrors(0), comparisonErrors(0), throttle(throttle), brake(brake) {} @@ -51,4 +51,4 @@ namespace HIB { return (adc1 + adc2 + adc3) / 3; } -}// namespace HIB \ No newline at end of file +}// namespace HIB */ \ No newline at end of file diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index b0610a4..80164c0 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -1,15 +1,16 @@ -#include -#include #include +#include +#include -namespace IO = EVT::core::IO; +namespace IO = core::io; constexpr uint32_t LOW_MARGIN = 1; constexpr uint32_t HIGH_MARGIN = 5; namespace HIB::DEV { -RedundantADC::RedundantADC(IO::ADC& adc0, IO::ADC& adc1, IO::ADC& adc2) : adc0(adc0), adc1(adc1), adc2(adc2) {} +RedundantADC::RedundantADC(IO::ADC& adc0, IO::ADC& adc1, IO::ADC& adc2) + : adc0(adc0), adc1(adc1), adc2(adc2) {} RedundantADC::Status RedundantADC::readVoltage(uint32_t& return_val) { // Read ADC values diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index e69de29..d4af224 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include + +namespace IO = core::io; + +int main() { + core::platform::init(); + + // Initialize devices + IO::CAN& can = IO::getCAN(true); + IO::UART& uart = IO::getUART(9600); + IO::ADC& adc0 = IO::getADC(); + IO::ADC& adc1 = IO::getADC(); + IO::ADC& adc2 = IO::getADC(); + + // Initialize HIB + const HIB::DEV::RedundantADC throttle(adc0, adc1, adc2); + HIB::HIB hib(throttle); + + // ID for HIB is 0x0D0 + IO::CANMessage transmit_message(0x0D0, 8, hib.getPayload(), false); + IO::CANMessage received_message; + + // Try to join the network + IO::CAN::CANStatus result = can.connect(); + + // can.addCANFilter(0, 0, 13); //This would create a filter that allows all messages through + can.addCANFilter(0xD0, 0xFF0, 0); + can.enableEmergencyFilter(ENABLE); + + // Begin CAN Tests + uart.printf("Starting CAN testing\r\n"); + + if (result != IO::CAN::CANStatus::OK) { + uart.printf("Failed to connect to CAN network\r\n"); + return 1; + } + + // MAIN loop + while (true) { + // Process the voltage + hib.process(); + + // Try to send the message + result = can.transmit(transmit_message); + if (result != IO::CAN::CANStatus::OK) { + uart.printf("Failed to transmit message\r\n"); + return 1; + } + + // Try to recieve the message + result = can.receive(&received_message, false); + if (result != IO::CAN::CANStatus::OK) { + uart.printf("Failed to receive message\r\n"); + continue; + } + + // Check if data was recieved + if (received_message.getDataLength() == 0) { + uart.printf("Message filtered out!"); + } else { + uart.printf("Message received\r\n"); + uart.printf("Message id: %d \r\n", received_message.getId()); + uart.printf("Message length: %d\r\n", received_message.getDataLength()); + uart.printf("Message contents: "); + + uint8_t* message_payload = received_message.getPayload(); + for (int i = 0; i < received_message.getDataLength(); i++) { + uart.printf("0x%02X ", message_payload[i]); + } + + // CAN most likely make variables to store total errors over the entire runtime to get a better picture + uart.printf("\r\n"); + uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); + uart.printf("Brake Voltage: %i mV\r\n", message_payload[2] << 8 | message_payload[3]); + uart.printf("No Errors: %i\r\n", message_payload[4]); + uart.printf("Precision Errors: %i\r\n", message_payload[5]); + uart.printf("Margin Errors: %i\r\n", message_payload[6]); + uart.printf("Comparison Errors: %i\r\n", message_payload[7]); + } + uart.printf("\r\n\r\n"); + + core::time::wait(2000); + } + + return 0; +} \ No newline at end of file diff --git a/targets/REV3-HIB/main_Soon.cpp b/targets/REV3-HIB/main_Soon.cpp deleted file mode 100644 index 7541d45..0000000 --- a/targets/REV3-HIB/main_Soon.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include -#include -#include -#include -#include -#include - -namespace IO = core::io; - -int main() { - core::platform::init(); - - IO::CAN& can = IO::getCAN(true); - IO::UART& uart = IO::getUART(9600); - IO::ADC& adc0 = IO::getADC(); - IO::ADC& adc1 = IO::getADC(); - IO::ADC& adc2 = IO::getADC(); - - const HIB::DEV::RedundantADC throttleADC(adc0, adc1, adc2); - - HIB::HIB hib = HIB::HIB(throttleADC, brakeADC); - - // ID for HIB is 0x0D0 - IO::CANMessage transmit_message(0x0D0, 8, hib.payload, false); - IO::CANMessage received_message; - - // Try to join the network - IO::CAN::CANStatus result = can.connect(); - - // can.addCANFilter(0, 0, 13); //This would create a filter that allows all messages through - can.addCANFilter(0xD0, 0xFF0, 0); - can.enableEmergencyFilter(ENABLE); - - uart.printf("Starting CAN testing\r\n"); - - if (result != IO::CAN::CANStatus::OK) { - uart.printf("Failed to connect to CAN network\r\n"); - return 1; - } - - // MAIN loop - while (true) { - hib.process(); - - result = can.transmit(transmit_message); - if (result != IO::CAN::CANStatus::OK) { - uart.printf("Failed to transmit message\r\n"); - return 1; - } - - result = can.receive(&received_message, false); - if (result != IO::CAN::CANStatus::OK) { - uart.printf("Failed to receive message\r\n"); - continue; - } - - if (received_message.getDataLength() == 0) { - uart.printf("Message filtered out!"); - } else { - uart.printf("Message received\r\n"); - uart.printf("Message id: %d \r\n", received_message.getId()); - uart.printf("Message length: %d\r\n", received_message.getDataLength()); - uart.printf("Message contents: "); - - uint8_t* message_payload = received_message.getPayload(); - for (int i = 0; i < received_message.getDataLength(); i++) { - uart.printf("0x%02X ", message_payload[i]); - } - - // CAN most likely make variables to store total errors over the entire runtime to get a better picture - uart.printf("\r\n"); - uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); - uart.printf("Brake Voltage: %i mV\r\n", message_payload[2] << 8 | message_payload[3]); - uart.printf("No Errors: %i\r\n", message_payload[4]); - uart.printf("Precision Errors: %i\r\n", message_payload[5]); - uart.printf("Margin Errors: %i\r\n", message_payload[6]); - uart.printf("Comparison Errors: %i\r\n", message_payload[7]); - } - uart.printf("\r\n\r\n"); - - EVT::core::time::wait(2999); - } - - return 0; -} - - -/* - -#include -#include -#include -#include -#include -#include - -namespace IO = EVT::core::IO; - -int main() { - // Initialize system - EVT::core::platform::init(); - IO::UART& uart = IO::getUART(9600); - - // TODO: Change these to be the correct pins for the throttle and brake ADCs - IO::ADC& adc0 = IO::getADC(); - IO::ADC& adc1 = IO::getADC(); - IO::ADC& adc2 = IO::getADC(); - - // Create RedundantADC object - const HIB::DEV::RedundantADC throttleADC(adc0, adc1, adc2); - - IO::ADC& adc3 = IO::getADC(); - IO::ADC& adc4 = IO::getADC(); - IO::ADC& adc5 = IO::getADC(); - - // Create RedundantADC object - const HIB::DEV::RedundantADC brakeADC(adc3, adc4, adc5); - // TODO: End of necessary ADC changes - - HIB::HIB hib = HIB::HIB(throttleADC, brakeADC); - - // MAIN loop - while (true) { - hib.process(); - uint16_t adc7 = 0; - uint16_t adc8 = 0; - uint16_t adc9 = 0; - uint16_t adcAvg = hib.readV(adc7, adc8, adc9); - // Should most likely make variables to store total errors over the entire runtime to get a better picture - uart.printf("\r\n"); - uart.printf("Throttle Voltage: %i mV\r\n", hib.payload[0] << 8 | hib.payload[1]); - uart.printf("Brake Voltage: %i mV\r\n", hib.payload[2] << 8 | hib.payload[3]); - uart.printf("No Errors: %i\r\n", hib.payload[4]); - uart.printf("Precision Errors: %i\r\n", hib.payload[5]); - uart.printf("Margin Errors: %i\r\n", hib.payload[6]); - uart.printf("Comparison Errors: %i\r\n", hib.payload[7]); - uart.printf("adc0 voltage: %i\r\n", adc7); - uart.printf("adc1 voltage: %i\r\n", adc8); - uart.printf("adc2 voltage: %i\r\n", adc9); - uart.printf("\r\n"); - EVT::core::time::wait(1500); - } - - return 0; -} -*/ \ No newline at end of file From f070a6f41c427a37891e78d8e458f5ee6ae90dfb Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Mon, 27 Jan 2025 23:28:27 -0500 Subject: [PATCH 09/47] Working on fixes for the payload transference --- CMakeLists.txt | 2 +- include/HIB.hpp | 82 ++++++++++++++++++--------------------- include/HIB_Soon.h | 40 ------------------- libs/EVT-core | 2 +- src/HIB.cpp | 29 ++++++++------ targets/REV3-HIB/main.cpp | 19 ++++++++- 6 files changed, 74 insertions(+), 100 deletions(-) delete mode 100644 include/HIB_Soon.h diff --git a/CMakeLists.txt b/CMakeLists.txt index dca1f81..f98835c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,7 @@ project(${BOARD_LIB_NAME} add_library(${PROJECT_NAME} STATIC src/HIB_Soon.cpp - include/HIB_Soon.h) +) # Add sources target_sources(${PROJECT_NAME} PRIVATE diff --git a/include/HIB.hpp b/include/HIB.hpp index 35a4a0d..c0bfd77 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -1,57 +1,51 @@ #pragma once #include -#include #include namespace IO = core::io; namespace HIB { - class HIB { public: - /** - * Constructor for the HIB - * Takes a redundant ADC reference - * @param throttle: const RedundantADC reference - */ - HIB(const DEV::RedundantADC& throttle); - - /** - * Main function for the HIB. Runs all subroutines for things like reading voltage - */ - void process(); - - /** - * Takes an adc to read from and the payload index of the most significant byte for the voltage - * from the redundant adc - * @param adc: The redundant adc that the voltage should be read from - * @param volts: The payload index that the most significant - * byte of voltage should be stored at - */ - void setVoltage(DEV::RedundantADC adc, uint8_t* volts); - - /** - * Gets the payload for reading from - * @return: The address of the first index of the payload - */ - uint8_t* getPayload(); +/** 8 byte payload stores data in this order: + * [0] - Most Significant Throttle Byte + * [1] - Least Significant Throttle Byte + * [2] - Most Significant Blank Byte for Brake + * [3] - Least Significant Blank Byte for Brake + * [4] - # of OK's + * [5] - # of PRECISION_MARGIN_EXCEEDED errors + * [6] - # of ACCEPTABLE_MARGIN_EXCEEDED errors + * [7] - # of COMPARISON_ERROR errors + */ +uint8_t payload[8]; +const uint8_t payloadLength = 8; + +/** + * Constructor for the HIB + * Takes a redundant ADC reference + * @param throttle: RedundantADC reference + */ +HIB(DEV::RedundantADC& throttle); + +/** + * Main function for the HIB. Runs all subroutines for things like reading voltage + */ +void process(); + +/** + * Reads in the voltage from the throttle redundant adc and increments the errors acquired + */ +void readThrottleVoltage(); + +/** + * Reads in the voltage from the brake redundant adc and increments the errors acquired + */ +void readBrakeVoltage(); private: - /** 8 byte payload stores data in this order: - * [0] - Most Significant Throttle Byte - * [1] - Least Significant Throttle Byte - * [2] - Most Significant Blank Byte for Brake - * [3] - Least Significant Blank Byte for Brake - * [4] - # of OK's - * [5] - # of PRECISION_MARGIN_EXCEEDED errors - * [6] - # of ACCEPTABLE_MARGIN_EXCEEDED errors - * [7] - # of COMPARISON_ERROR errors - */ - uint8_t payload[8]; - size_t payloadLength = 8; - - /// The triple adc setup attached to the throttle - DEV::RedundantADC throttle; +/** + * The triple adc setup attached to the throttle + */ +DEV::RedundantADC throttle; }; - } diff --git a/include/HIB_Soon.h b/include/HIB_Soon.h deleted file mode 100644 index 2098f6b..0000000 --- a/include/HIB_Soon.h +++ /dev/null @@ -1,40 +0,0 @@ -/* #pragma once -#include -#include - -namespace HIB_Soon { -/** - * HIB header file in Branch - */ -class HIB_Nah { -private: - uint16_t throttlePosition; - uint16_t brakePosition; - uint8_t noErrors; - uint8_t precisionErrors; - uint8_t marginErrors; - uint8_t comparisonErrors; - DEV::RedundantADC throttle; - DEV::RedundantADC brake; - uint8_t payload[8]; -public: - /// Gets the RedundantADCs for the throttle and break voltages - HIB(const DEV::RedundantADC& throttle, const DEV::RedundantADC& brake); - - /// Runs through all the necessary function to update the payload - void process(); - - /// Creates a payload for the CAN bus to transmit. - void makePayload(); - - /// Reads the throttles position and returns it in millivolts - uint16_t getVoltage(DEV::RedundantADC& adc); - - /// Set the positions of the throttle and brake - void getPositions(); - - /// Read the voltage from the triple ADC setup - uint16_t readV(uint16_t& adc1, uint16_t& adc2, uint16_t& adc3); -}; - -}// namespace HIB */ \ No newline at end of file diff --git a/libs/EVT-core b/libs/EVT-core index b67f79b..d5b7812 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit b67f79b915d7d153503475990ce1ce41f1bcc304 +Subproject commit d5b7812a234ee5d7403657b37a4eb03b26d9de2a diff --git a/src/HIB.cpp b/src/HIB.cpp index 297df24..16a6d65 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -4,21 +4,27 @@ namespace HIB { -HIB::HIB(const DEV::RedundantADC& throttle) +HIB::HIB(DEV::RedundantADC& throttle) : throttle(throttle) { - // Clear payload + // Initialize payload to 0's for (int i = 0; i < payloadLength; i++) { payload[i] = 0; } } void HIB::process() { - HIB::setVoltage(throttle, &payload[0]); + HIB::readThrottleVoltage(); + HIB::readBrakeVoltage(); } -void HIB::setVoltage(DEV::RedundantADC adc, uint8_t* volts) { +void HIB::readThrottleVoltage() { uint32_t voltage = 0; // Voltage to be recieved in millivolts - DEV::RedundantADC::Status status = adc.readVoltage(voltage); // gets the errors and voltage from the ADC cluster + DEV::RedundantADC::Status status = throttle.readVoltage(voltage); // gets the errors and voltage from the ADC cluster + + payload[0] += voltage; + payload[1] += voltage >> 8; + + // Increment the status of each if (status == DEV::RedundantADC::Status::OK) { payload[4]++; } else if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { @@ -28,15 +34,14 @@ void HIB::setVoltage(DEV::RedundantADC adc, uint8_t* volts) { } else if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { payload[7]++; } - - // Set the given byte pointer and the index after to the voltage given - // Bit-masking just in case - volts[0] = (voltage >> 24) & 0xFF; - volts[1] = (voltage >> 16) & 0xFF; } -uint8_t* HIB::getPayload() { - return &payload[0]; +void HIB::readBrakeVoltage() { + uint32_t voltage = 0; // Voltage to be recieved in millivolts + DEV::RedundantADC::Status status = throttle.readVoltage(voltage); // gets the errors and voltage from the ADC cluster + + payload[2] += voltage; + payload[3] += voltage >> 8; } } \ No newline at end of file diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index d4af224..8e82feb 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -18,11 +18,11 @@ int main() { IO::ADC& adc2 = IO::getADC(); // Initialize HIB - const HIB::DEV::RedundantADC throttle(adc0, adc1, adc2); + HIB::DEV::RedundantADC throttle(adc0, adc1, adc2); HIB::HIB hib(throttle); // ID for HIB is 0x0D0 - IO::CANMessage transmit_message(0x0D0, 8, hib.getPayload(), false); + IO::CANMessage transmit_message(0x0D0, 8, hib.payload, false); IO::CANMessage received_message; // Try to join the network @@ -81,6 +81,21 @@ int main() { uart.printf("Precision Errors: %i\r\n", message_payload[5]); uart.printf("Margin Errors: %i\r\n", message_payload[6]); uart.printf("Comparison Errors: %i\r\n", message_payload[7]); + + uart.printf("\r\nADC0 : %d mV\r\n", static_cast(adc0.read() * 1000)); + uart.printf("ADC0: %d%%\r\n", static_cast(adc0.readPercentage() * 100)); + uart.printf("ADC0 raw: %d\r\n", adc0.readRaw()); + uart.printf("--------------------\r\n\r\n"); + + uart.printf("ADC1 : %d mV\r\n", static_cast(adc1.read() * 1000)); + uart.printf("ADC1: %d%%\r\n", static_cast(adc1.readPercentage() * 100)); + uart.printf("ADC1 raw: %d\r\n", adc1.readRaw()); + uart.printf("--------------------\r\n\r\n"); + + uart.printf("ADC2 : %d mV\r\n", static_cast(adc2.read() * 1000)); + uart.printf("ADC2: %d%%\r\n", static_cast(adc2.readPercentage() * 100)); + uart.printf("ADC2 raw: %d\r\n", adc2.readRaw()); + uart.printf("--------------------\r\n\r\n"); } uart.printf("\r\n\r\n"); From a9c79325c61f6512470e2b12f17151edadf994e1 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Thu, 6 Feb 2025 19:59:49 -0500 Subject: [PATCH 10/47] Need to change HIB for new ADCs --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index d5b7812..5e94372 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit d5b7812a234ee5d7403657b37a4eb03b26d9de2a +Subproject commit 5e943729415298676a1bc7b0bf3772f263172875 From f05b0e16d83794e7630436ffbec29c4ebfc834b7 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Wed, 12 Mar 2025 00:10:11 -0400 Subject: [PATCH 11/47] Getting things up to date --- CMakeLists.txt | 4 ++- include/dev/ADS8689IPWR.h | 16 +++++++++ include/dev/RedundantADC.hpp | 2 -- src/HIB_Soon.cpp | 54 ------------------------------ src/dev/ADS8689IPWR.cpp | 2 ++ targets/ADS8689IPWR/CMakeLists.txt | 7 ++++ targets/ADS8689IPWR/main.cpp | 6 ++++ 7 files changed, 34 insertions(+), 57 deletions(-) create mode 100644 include/dev/ADS8689IPWR.h delete mode 100644 src/HIB_Soon.cpp create mode 100644 src/dev/ADS8689IPWR.cpp create mode 100644 targets/ADS8689IPWR/CMakeLists.txt create mode 100644 targets/ADS8689IPWR/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f98835c..68a76f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,9 @@ project(${BOARD_LIB_NAME} ) add_library(${PROJECT_NAME} STATIC - src/HIB_Soon.cpp + include/dev/ADS8689IPWR.h + src/dev/ADS8689IPWR.cpp + targets/ADS8689IPWR/main.cpp ) # Add sources diff --git a/include/dev/ADS8689IPWR.h b/include/dev/ADS8689IPWR.h new file mode 100644 index 0000000..35c197d --- /dev/null +++ b/include/dev/ADS8689IPWR.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace io = core::io; + +namespace HIB::DEV { +class ADS8689IPWR { +public: + ADS8689IPWR(io::SPI& spi); +private: +}; +} diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index c61fec2..4cee8f7 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -4,11 +4,9 @@ namespace IO = core::io; namespace HIB::DEV { - /** * This class allows processing readings from redundant ADCs and checking for errors */ - class RedundantADC { public: /** diff --git a/src/HIB_Soon.cpp b/src/HIB_Soon.cpp deleted file mode 100644 index 7c68a54..0000000 --- a/src/HIB_Soon.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* #include - - -namespace HIB_Soon { - HIB::HIB(const DEV::RedundantADC& throttle, const DEV::RedundantADC& brake) - : throttlePosition(0), brakePosition(0), noErrors(0), precisionErrors(0), marginErrors(0), - comparisonErrors(0), throttle(throttle), brake(brake) {} - - // "Run" the HIB and update the payload - void HIB::process() { - getPositions(); - makePayload(); - } - - uint16_t HIB::getVoltage(DEV::RedundantADC& red_adc) { - uint32_t voltage = 0; // Voltage to be recieved in millivolts - DEV::RedundantADC::Status status = red_adc.readVoltage(voltage); // gets the errors and voltage from the ADC cluster - if (status == DEV::RedundantADC::Status::OK) { - noErrors++; - } else if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { - precisionErrors++; - } else if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { - marginErrors++; - } else if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { - comparisonErrors++; - } return voltage; - } - - // Get the position voltage from throttle and break - void HIB::getPositions() { - // throttlePosition = getVoltage(throttle); - brakePosition = getVoltage(brake); - } - - // Form payload - void HIB::makePayload() { - payload[0] = throttlePosition >> 8; // Bitshift to get the most sig - payload[1] = throttlePosition & 0xFF; // Erases the most significant bits to ensure data is only collectd from the first 8 bits - payload[2] = brakePosition >> 8; // Same as above - payload[3] = brakePosition & 0xFF; // Same as above - payload[4] = noErrors; - payload[5] = precisionErrors; - payload[6] = marginErrors; - payload[7] = comparisonErrors; - } - - uint16_t HIB::readV(uint16_t& adc1, uint16_t& adc2, uint16_t& adc3) { - adc1 = brake.adc0.read() * 1000; - adc2 = brake.adc1.read() * 1000; - adc3 = brake.adc2.read() * 1000; - return (adc1 + adc2 + adc3) / 3; - } - -}// namespace HIB */ \ No newline at end of file diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp new file mode 100644 index 0000000..92d685a --- /dev/null +++ b/src/dev/ADS8689IPWR.cpp @@ -0,0 +1,2 @@ +#include + diff --git a/targets/ADS8689IPWR/CMakeLists.txt b/targets/ADS8689IPWR/CMakeLists.txt new file mode 100644 index 0000000..3e1de00 --- /dev/null +++ b/targets/ADS8689IPWR/CMakeLists.txt @@ -0,0 +1,7 @@ +include(${EVT_CORE_DIR}/cmake/evt-core_build.cmake) + +project(RedundantADC) +cmake_minimum_required(VERSION 3.15) + +make_exe(${PROJECT_NAME} main.cpp) +target_link_libraries(${PROJECT_NAME} PUBLIC ${BOARD_LIB_NAME}) diff --git a/targets/ADS8689IPWR/main.cpp b/targets/ADS8689IPWR/main.cpp new file mode 100644 index 0000000..7149c05 --- /dev/null +++ b/targets/ADS8689IPWR/main.cpp @@ -0,0 +1,6 @@ +// +// Created by Anonymous on 3/3/2025. +// +int main() { + +} \ No newline at end of file From 1cd87cb2184ec7ea2b6940b6687028532e5ef99d Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Mon, 31 Mar 2025 18:46:53 -0400 Subject: [PATCH 12/47] Hopefully this works --- CMakeLists.txt | 1 - include/dev/ADS8689IPWR.h | 16 +++++++++-- src/dev/ADS8689IPWR.cpp | 5 ++++ targets/ADS8689IPWR/CMakeLists.txt | 2 +- targets/ADS8689IPWR/main.cpp | 45 ++++++++++++++++++++++++++++-- targets/CMakeLists.txt | 1 + 6 files changed, 62 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68a76f7..c1574ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,6 @@ project(${BOARD_LIB_NAME} add_library(${PROJECT_NAME} STATIC include/dev/ADS8689IPWR.h src/dev/ADS8689IPWR.cpp - targets/ADS8689IPWR/main.cpp ) # Add sources diff --git a/include/dev/ADS8689IPWR.h b/include/dev/ADS8689IPWR.h index 35c197d..b425252 100644 --- a/include/dev/ADS8689IPWR.h +++ b/include/dev/ADS8689IPWR.h @@ -5,12 +5,22 @@ #include #include -namespace io = core::io; +namespace IO = core::io; -namespace HIB::DEV { +namespace ADS8689IPWR { class ADS8689IPWR { public: - ADS8689IPWR(io::SPI& spi); + // Initiates the setup process and prepares the component for voltage readings + ADS8689IPWR(IO::SPI& spi); + + // Reads the voltage signal from the ADC + uint32_t read(); + + // Writes to a register on the chip + // Meant to be used during the setup process + uint32_t write(uint32_t data); private: + // Reference to the SPI object that is communicating with the chip + IO::SPI& spi; }; } diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index 92d685a..107c804 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -1,2 +1,7 @@ #include +namespace ADS8689IPWR { + +ADS8689IPWR::ADS8689IPWR(IO::SPI& spi) : spi(spi) {} + +} \ No newline at end of file diff --git a/targets/ADS8689IPWR/CMakeLists.txt b/targets/ADS8689IPWR/CMakeLists.txt index 3e1de00..4ee2133 100644 --- a/targets/ADS8689IPWR/CMakeLists.txt +++ b/targets/ADS8689IPWR/CMakeLists.txt @@ -1,6 +1,6 @@ include(${EVT_CORE_DIR}/cmake/evt-core_build.cmake) -project(RedundantADC) +project(ADS8689IPWR) cmake_minimum_required(VERSION 3.15) make_exe(${PROJECT_NAME} main.cpp) diff --git a/targets/ADS8689IPWR/main.cpp b/targets/ADS8689IPWR/main.cpp index 7149c05..7c56bb5 100644 --- a/targets/ADS8689IPWR/main.cpp +++ b/targets/ADS8689IPWR/main.cpp @@ -1,6 +1,45 @@ -// -// Created by Anonymous on 3/3/2025. -// +#include +#include +#include +#include +#include + +namespace io = core::io; +namespace time = core::time; + +constexpr uint32_t SPI_SPEED = SPI_SPEED_2MHZ; // 2MHz +constexpr uint8_t deviceCount = 6; + +io::GPIO* devices[deviceCount]; + int main() { + // Initialize system + core::platform::init(); + + // ------ Begin DAC and Self-Test pulldowns ------ + // DAC1 pulldown + io::GPIO& dac1 = io::getGPIO(); + dac1.writePin(io::GPIO::State::LOW); + + // DAC2 pulldown + io::GPIO& dac2 = io::getGPIO(); + dac2.writePin(io::GPIO::State::LOW); + + // Self-test1 pulldown + io::GPIO& self_test1 = io::getGPIO(); + self_test1.writePin(io::GPIO::State::LOW); + + // Self-test2 pulldown + io::GPIO& self_test2 = io::getGPIO(); + self_test2.writePin(io::GPIO::State::LOW); + // ------ End DAC and Self-Test pulldowns ------ + + devices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + devices[0]->writePin(io::GPIO::State::HIGH); + + io::SPI& spi = io::getSPI(devices, deviceCount); + + spi.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE3, SPI_MSB_FIRST); + io::UART& uart = io::getUART(9600); } \ No newline at end of file diff --git a/targets/CMakeLists.txt b/targets/CMakeLists.txt index b84c011..c3dd7cd 100644 --- a/targets/CMakeLists.txt +++ b/targets/CMakeLists.txt @@ -1,3 +1,4 @@ # Add all targets add_subdirectory(REV3-HIB) add_subdirectory(RedundantADC) +add_subdirectory(ADS8689IPWR) From e7d3808088bf54f47342bfd2e30c9ad1722acb96 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Mon, 14 Apr 2025 15:28:44 -0400 Subject: [PATCH 13/47] ADS8689IPWR driver created, needs to be tested and verified --- .vs/HIB/v17/.wsuo | Bin 14848 -> 0 bytes .vs/HIB/v17/DocumentLayout.json | 12 --- .vs/VSWorkspaceState.json | 6 -- CMakeLists.txt | 7 +- Changelog.md | 6 ++ include/HIB.hpp | 56 +++++-------- include/dev/ADS8689IPWR.h | 16 ---- include/dev/ADS8689IPWR.hpp | 35 ++++++++ include/dev/RedundantADC.hpp | 18 +++-- src/HIB.cpp | 10 +-- src/dev/ADS8689IPWR.cpp | 44 +++++++++- src/dev/RedundantADC.cpp | 11 ++- targets/ADS8689IPWR/CMakeLists.txt | 2 +- targets/ADS8689IPWR/main.cpp | 75 ++++++++++++++++- targets/CMakeLists.txt | 3 +- targets/REV3-HIB/main.cpp | 124 ++++++++++++++++++++--------- 16 files changed, 288 insertions(+), 137 deletions(-) delete mode 100644 .vs/HIB/v17/.wsuo delete mode 100644 .vs/HIB/v17/DocumentLayout.json delete mode 100644 .vs/VSWorkspaceState.json delete mode 100644 include/dev/ADS8689IPWR.h create mode 100644 include/dev/ADS8689IPWR.hpp diff --git a/.vs/HIB/v17/.wsuo b/.vs/HIB/v17/.wsuo deleted file mode 100644 index edba235f2f81cad8cf397c34be34c11317d3792f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14848 zcmeI3-*Zz%6vsCpBL2o7D40eN=48&jyL)%{?4CX6?Aagr z_3rLJzWQe0pC$lj%yx5cb(eYAm!9y2&C|v_r#NZ%R##W~L|DN##E1h|OkTf|=`dqv zN$-NW%}_>$J!VH`%y(>1>aV?b7WN3BK6IB&PAw>yjBrxCm=LHv<>!s=^KQe|xjHDRalb>Si58^XiFH-&Er-xeMb zb_u(MM}u@yj&{;=ARQ5zQIjpxM?M&i8E@@nI9jTZHZ|L`7L!`oK6!Q+&^W7B{r^uzdY zSoHCM-8^S2-QY2(@7O3HNS}2`N*q`Y)jF>%&qGb{AE{=328PAiytut6o)`3vy6*8x zW7D@K5{lq6MCJde@?zV8t5*6K%teiLQGK42;I%`PnBuW=d^80_d2`Wtr5abl_W7(<}@#cTV+1m*@D@(Mj`H}e_Pk>ZEoG9C0e7>mtXIhO02bDK=Q|04nH$0eZTzs{hbLb*VE;huv=Qe z{Iev=Y3U_WkC#+!k<@=n*Nwqi%j$>dJ3a#tMt{ooyku?UOr`IXNQ*P`wk6WP1b%fR z^s$$2{$=i(5RY@JF_Y~ejIgmrU#GrWCnT$yQX_)(p~*C z{e4}7Gtd31L(^pQQv zuhp?Uq-bQ=Z2Kb<3d!i!0{$$UN%PkeHOzkQx55!~$|TF0&zcCE*WvR@lClec_<~4cm1CD*{e!*u6>W z%|15kgrphQ4WD7FG1XPGZ~T$@xH_?c81y#-+-Iq*K{;5YLhwni#oaoQDXJGWlCG6= zj>U$Ax zfAzoiZlC}Czt8`|&L6JpjDb^_OPc?9a}E*&oxfMk9?*^8_gZoGHkosQF#03%CA^cU zMc*BO_p8of&glGu`$gP0ib|ikJj(ftpT0XI#`pK%L(uta0$a)brl|ClwL-s<^Vht3 zp0>NF?4XvYMt7MS=l?mCBn&V?SBy-;P~77XWVOz%KxoA{_XpJ>+c`d u(>+vZ3*7%}`2R=#`+v-X*iS46_YWFf{|DEv?fV}{MRW-AFM7$= #include -#include - -namespace IO = core::io; +#include namespace HIB { -class HIB { -public: -/** 8 byte payload stores data in this order: - * [0] - Most Significant Throttle Byte - * [1] - Least Significant Throttle Byte - * [2] - Most Significant Blank Byte for Brake - * [3] - Least Significant Blank Byte for Brake - * [4] - # of OK's - * [5] - # of PRECISION_MARGIN_EXCEEDED errors - * [6] - # of ACCEPTABLE_MARGIN_EXCEEDED errors - * [7] - # of COMPARISON_ERROR errors - */ -uint8_t payload[8]; -const uint8_t payloadLength = 8; -/** - * Constructor for the HIB - * Takes a redundant ADC reference - * @param throttle: RedundantADC reference - */ -HIB(DEV::RedundantADC& throttle); +constexpr size_t payloadLength = 8; /** - * Main function for the HIB. Runs all subroutines for things like reading voltage + * HIB header file */ -void process(); +class HIB { +public: + HIB(DEV::RedundantADC& throttle, DEV::RedundantADC& brake); -/** - * Reads in the voltage from the throttle redundant adc and increments the errors acquired - */ -void readThrottleVoltage(); + void process(); -/** - * Reads in the voltage from the brake redundant adc and increments the errors acquired - */ -void readBrakeVoltage(); + void readThrottleVoltage(); + + void readBrakeVoltage(); + + uint8_t payload[payloadLength]; private: -/** - * The triple adc setup attached to the throttle - */ -DEV::RedundantADC throttle; + DEV::RedundantADC& throttle; + DEV::RedundantADC& brake; + }; -} + +}// namespace HIB \ No newline at end of file diff --git a/include/dev/ADS8689IPWR.h b/include/dev/ADS8689IPWR.h deleted file mode 100644 index 35c197d..0000000 --- a/include/dev/ADS8689IPWR.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace io = core::io; - -namespace HIB::DEV { -class ADS8689IPWR { -public: - ADS8689IPWR(io::SPI& spi); -private: -}; -} diff --git a/include/dev/ADS8689IPWR.hpp b/include/dev/ADS8689IPWR.hpp new file mode 100644 index 0000000..48c9749 --- /dev/null +++ b/include/dev/ADS8689IPWR.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#define RANGE_SEL_REG 0x14 // R/W Range selection register ---- +#define TWELVE_VOLT_SCALER 0b1000 + +namespace io = core::io; + +namespace HIB::DEV { + +class ADS8689IPWR { +public: + /** + * Creates a ADS8689IPWR object while configuring the range selector. + * + * @param spi SPI reference to interface with the ADC + * @param deviceNumber The number of the cs pin that the device is + */ + ADS8689IPWR(io::SPI& spi, uint8_t deviceNumber); + + /** + * Reads out the voltage from the ADC + * + * @param voltage reference to variable that is storing voltage + * @return the status of whether the transaction was successful + */ + uint16_t read(); +private: + io::SPI& spi; + const uint8_t deviceNumber; +}; + +}// namespace HIB::DEV diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index 4cee8f7..2514092 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -1,12 +1,15 @@ #pragma once -#include -namespace IO = core::io; +#include + +namespace io = core::io; namespace HIB::DEV { + /** * This class allows processing readings from redundant ADCs and checking for errors */ + class RedundantADC { public: /** @@ -30,7 +33,7 @@ class RedundantADC { * @param[in] adc1 The second ADC instance. * @param[in] adc2 The third ADC instance. */ - RedundantADC(IO::ADC& adc0, IO::ADC& adc1, IO::ADC& adc2); + RedundantADC(ADS8689IPWR& adc0, ADS8689IPWR& adc1, ADS8689IPWR& adc2); /** * Read voltage readings from the ADCs and check for redundancy. @@ -42,14 +45,15 @@ class RedundantADC { * @param[in] val3 Reference to the variable to store the value read from the third ADC. * @return RedundantADC::Status The status of the processing. */ - RedundantADC::Status readVoltage(uint32_t& return_val); + RedundantADC::Status read(uint32_t& return_val); +private: /** Reference to the first ADC. */ - IO::ADC& adc0; + ADS8689IPWR& adc0; /** Reference to the second ADC. */ - IO::ADC& adc1; + ADS8689IPWR& adc1; /** Reference to the third ADC. */ - IO::ADC& adc2; + ADS8689IPWR& adc2; }; }// namespace HIB::DEV diff --git a/src/HIB.cpp b/src/HIB.cpp index 16a6d65..832f6ce 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -1,11 +1,11 @@ #include #include -#include +#include namespace HIB { -HIB::HIB(DEV::RedundantADC& throttle) - : throttle(throttle) { +HIB::HIB(DEV::RedundantADC& throttle, DEV::RedundantADC& brake) + : throttle(throttle), brake(brake) { // Initialize payload to 0's for (int i = 0; i < payloadLength; i++) { payload[i] = 0; @@ -19,7 +19,7 @@ void HIB::process() { void HIB::readThrottleVoltage() { uint32_t voltage = 0; // Voltage to be recieved in millivolts - DEV::RedundantADC::Status status = throttle.readVoltage(voltage); // gets the errors and voltage from the ADC cluster + DEV::RedundantADC::Status status = throttle.read(voltage); // gets the errors and voltage from the ADC cluster payload[0] += voltage; payload[1] += voltage >> 8; @@ -38,7 +38,7 @@ void HIB::readThrottleVoltage() { void HIB::readBrakeVoltage() { uint32_t voltage = 0; // Voltage to be recieved in millivolts - DEV::RedundantADC::Status status = throttle.readVoltage(voltage); // gets the errors and voltage from the ADC cluster + DEV::RedundantADC::Status status = brake.read(voltage); // gets the errors and voltage from the ADC cluster payload[2] += voltage; payload[3] += voltage >> 8; diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index 92d685a..faef6c7 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -1,2 +1,44 @@ -#include +#include +namespace HIB::DEV { + + +ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), deviceNumber(deviceNumber) { + // Pull CS low + spi.startTransmission(deviceNumber); + spi.write(0b11010000); + spi.write(RANGE_SEL_REG); + spi.write(0b00000000); + spi.write(TWELVE_VOLT_SCALER); + // Pull CS high + spi.endTransmission(deviceNumber); + + // begin the conversion + spi.startTransmission(deviceNumber); + // NOP command + spi.write(0b0); + spi.write(0b0); + spi.write(0b0); + spi.write(0b0); + spi.endTransmission(deviceNumber); +} + +uint16_t ADS8689IPWR::read() { + uint8_t bytes[4]; + uint16_t voltage; + + spi.startTransmission(deviceNumber); + // NOP command + spi.write(0b0); + spi.write(0b0); + spi.write(0b0); + spi.write(0b0); + spi.read(bytes, 4); + spi.endTransmission(deviceNumber); + + voltage = bytes[2] << 8 | bytes[3]; + voltage *= voltage * 12288 / 65536; + return voltage; +} + +} diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 80164c0..60f8762 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -1,18 +1,17 @@ -#include #include #include +#include -namespace IO = core::io; +namespace io = core::io; constexpr uint32_t LOW_MARGIN = 1; constexpr uint32_t HIGH_MARGIN = 5; namespace HIB::DEV { -RedundantADC::RedundantADC(IO::ADC& adc0, IO::ADC& adc1, IO::ADC& adc2) - : adc0(adc0), adc1(adc1), adc2(adc2) {} +RedundantADC::RedundantADC(ADS8689IPWR& adc0, ADS8689IPWR& adc1, ADS8689IPWR& adc2) : adc0(adc0), adc1(adc1), adc2(adc2) {} -RedundantADC::Status RedundantADC::readVoltage(uint32_t& return_val) { +RedundantADC::Status RedundantADC::read(uint32_t& return_val) { // Read ADC values int32_t adcValues[3]; adcValues[0] = static_cast(adc0.read() * 1000); @@ -63,7 +62,7 @@ RedundantADC::Status RedundantADC::readVoltage(uint32_t& return_val) { return RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED; } - return_val = 1; + return_val = 0; return RedundantADC::Status::COMPARISON_ERROR; } diff --git a/targets/ADS8689IPWR/CMakeLists.txt b/targets/ADS8689IPWR/CMakeLists.txt index 3e1de00..4ee2133 100644 --- a/targets/ADS8689IPWR/CMakeLists.txt +++ b/targets/ADS8689IPWR/CMakeLists.txt @@ -1,6 +1,6 @@ include(${EVT_CORE_DIR}/cmake/evt-core_build.cmake) -project(RedundantADC) +project(ADS8689IPWR) cmake_minimum_required(VERSION 3.15) make_exe(${PROJECT_NAME} main.cpp) diff --git a/targets/ADS8689IPWR/main.cpp b/targets/ADS8689IPWR/main.cpp index 7149c05..2b0f7f4 100644 --- a/targets/ADS8689IPWR/main.cpp +++ b/targets/ADS8689IPWR/main.cpp @@ -1,6 +1,75 @@ -// -// Created by Anonymous on 3/3/2025. -// +#include +#include +#include +#include +#include +#include +#include +#include + +namespace io = core::io; +namespace time = core::time; + +constexpr uint32_t SPI_SPEED = SPI_SPEED_4MHZ; // 500KHz +constexpr uint8_t deviceCount = 3; + +io::GPIO* throttleDevices[deviceCount]; +io::GPIO* brakeDevices[deviceCount]; + int main() { + // Initialize system + core::platform::init(); + + // Initialize UART + io::UART& uart = io::getUART(9600); + + // Set up each device + brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[0]->writePin(io::GPIO::State::HIGH); + brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[1]->writePin(io::GPIO::State::HIGH); + brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[2]->writePin(io::GPIO::State::HIGH); + + throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[0]->writePin(io::GPIO::State::HIGH); + throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[1]->writePin(io::GPIO::State::HIGH); + throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[2]->writePin(io::GPIO::State::HIGH); + + // Create the two SPI clusters + io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); + io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); + + // Configure the systems + spiThrottle.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); + spiBrake.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); + + // Create each ADS8689IPWR object + auto throttleADC1 = HIB::DEV::ADS8689IPWR(spiThrottle, 0); + auto throttleADC2 = HIB::DEV::ADS8689IPWR(spiThrottle, 1); + auto throttleADC3 = HIB::DEV::ADS8689IPWR(spiThrottle, 2); + auto brakeADC1 = HIB::DEV::ADS8689IPWR(spiBrake, 0); + auto brakeADC2 = HIB::DEV::ADS8689IPWR(spiBrake, 1); + auto brakeADC3 = HIB::DEV::ADS8689IPWR(spiBrake, 2); + + // Create the Redundant ADC's + auto throttle = HIB::DEV::RedundantADC(throttleADC1, throttleADC2, throttleADC3); + auto brake = HIB::DEV::RedundantADC(brakeADC1, brakeADC2, brakeADC3); + + // Finally create the HIB object to begin processing data + auto hib = HIB::HIB(throttle, brake); + // main loop + while (true) { + hib.process(); + uart.printf("Throttle Voltage: %i mV\r\n", hib.payload[0] << 8 | hib.payload[1]); + uart.printf("Brake Voltage: %i mV\r\n", hib.payload[2] << 8 | hib.payload[3]); + uart.printf("OK: %i\r\n", hib.payload[4]); + uart.printf("PRECISION_MARGIN_EXCEEDED: %i\r\n", hib.payload[5]); + uart.printf("ACCEPTABLE_MARGIN_EXCEEDED: %i\r\n", hib.payload[6]); + uart.printf("COMPARISON_ERROR: %i\r\n", hib.payload[7]); + time::wait(1000); + } } \ No newline at end of file diff --git a/targets/CMakeLists.txt b/targets/CMakeLists.txt index b84c011..70fd474 100644 --- a/targets/CMakeLists.txt +++ b/targets/CMakeLists.txt @@ -1,3 +1,4 @@ # Add all targets add_subdirectory(REV3-HIB) -add_subdirectory(RedundantADC) +add_subdirectory(ADS8689IPWR) +add_subdirectory(RedundantADC) \ No newline at end of file diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 8e82feb..c60779e 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -1,32 +1,95 @@ +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include +#include + +namespace io = core::io; +namespace time = core::time; + +constexpr uint32_t SPI_SPEED = SPI_SPEED_500KHZ; // 500KHz +constexpr uint8_t deviceCount = 3; + +#define ADS8689IPWR_RANGE_SEL_REG 0x14 // R/W Range selection register ---- + +io::GPIO* throttleDevices[deviceCount]; +io::GPIO* brakeDevices[deviceCount]; -namespace IO = core::io; +void canIRQHandler(io::CANMessage& message, void* priv) { + io::UART* uart = (io::UART*) priv; + uart->printf("Message received\r\n"); + uart->printf("Message id: 0x%X \r\n", message.getId()); + uart->printf("Message length: %d\r\n", message.getDataLength()); + uart->printf("Message contents: "); + + uint8_t* message_payload = message.getPayload(); + for (int i = 0; i < message.getDataLength(); i++) { + uart->printf("0x%02X ", message_payload[i]); + } + uart->printf("\r\n\r\n"); +} int main() { + // Initialize system core::platform::init(); - // Initialize devices - IO::CAN& can = IO::getCAN(true); - IO::UART& uart = IO::getUART(9600); - IO::ADC& adc0 = IO::getADC(); - IO::ADC& adc1 = IO::getADC(); - IO::ADC& adc2 = IO::getADC(); + // Initialize UART + io::UART& uart = io::getUART(9600); + + // Initialize CAN + io::CAN& can = io::getCAN(true); + + // Set up each device + brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[0]->writePin(io::GPIO::State::HIGH); + + brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[1]->writePin(io::GPIO::State::HIGH); - // Initialize HIB - HIB::DEV::RedundantADC throttle(adc0, adc1, adc2); - HIB::HIB hib(throttle); + brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[2]->writePin(io::GPIO::State::HIGH); + + throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[0]->writePin(io::GPIO::State::HIGH); + + throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[1]->writePin(io::GPIO::State::HIGH); + + throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[2]->writePin(io::GPIO::State::HIGH); + + // Create the two SPI clusters + io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); + io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); + + // Configure the systems + spiThrottle.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); + spiBrake.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); + + // Create each ADS8689IPWR object + auto throttleADC1 = HIB::DEV::ADS8689IPWR(spiThrottle, 0); + auto throttleADC2 = HIB::DEV::ADS8689IPWR(spiThrottle, 1); + auto throttleADC3 = HIB::DEV::ADS8689IPWR(spiThrottle, 2); + auto brakeADC1 = HIB::DEV::ADS8689IPWR(spiBrake, 0); + auto brakeADC2 = HIB::DEV::ADS8689IPWR(spiBrake, 1); + auto brakeADC3 = HIB::DEV::ADS8689IPWR(spiBrake, 2); + + // Create the Redundant ADC's + auto throttle = HIB::DEV::RedundantADC(throttleADC1, throttleADC2, throttleADC3); + auto brake = HIB::DEV::RedundantADC(brakeADC1, brakeADC2, brakeADC3); + + // Finally create the HIB object to begin processing data + auto hib = HIB::HIB(throttle, brake); // ID for HIB is 0x0D0 - IO::CANMessage transmit_message(0x0D0, 8, hib.payload, false); - IO::CANMessage received_message; + io::CANMessage transmit_message(0x0D0, 8, hib.payload, false); + io::CANMessage received_message; // Try to join the network - IO::CAN::CANStatus result = can.connect(); + io::CAN::CANStatus result = can.connect(); // can.addCANFilter(0, 0, 13); //This would create a filter that allows all messages through can.addCANFilter(0xD0, 0xFF0, 0); @@ -35,7 +98,7 @@ int main() { // Begin CAN Tests uart.printf("Starting CAN testing\r\n"); - if (result != IO::CAN::CANStatus::OK) { + if (result !=io::CAN::CANStatus::OK) { uart.printf("Failed to connect to CAN network\r\n"); return 1; } @@ -47,19 +110,19 @@ int main() { // Try to send the message result = can.transmit(transmit_message); - if (result != IO::CAN::CANStatus::OK) { + if (result !=io::CAN::CANStatus::OK) { uart.printf("Failed to transmit message\r\n"); return 1; } - // Try to recieve the message + // Try to receive the message result = can.receive(&received_message, false); - if (result != IO::CAN::CANStatus::OK) { + if (result != io::CAN::CANStatus::OK) { uart.printf("Failed to receive message\r\n"); continue; } - // Check if data was recieved + // Check if data was received if (received_message.getDataLength() == 0) { uart.printf("Message filtered out!"); } else { @@ -68,7 +131,7 @@ int main() { uart.printf("Message length: %d\r\n", received_message.getDataLength()); uart.printf("Message contents: "); - uint8_t* message_payload = received_message.getPayload(); + const uint8_t* message_payload = received_message.getPayload(); for (int i = 0; i < received_message.getDataLength(); i++) { uart.printf("0x%02X ", message_payload[i]); } @@ -81,21 +144,6 @@ int main() { uart.printf("Precision Errors: %i\r\n", message_payload[5]); uart.printf("Margin Errors: %i\r\n", message_payload[6]); uart.printf("Comparison Errors: %i\r\n", message_payload[7]); - - uart.printf("\r\nADC0 : %d mV\r\n", static_cast(adc0.read() * 1000)); - uart.printf("ADC0: %d%%\r\n", static_cast(adc0.readPercentage() * 100)); - uart.printf("ADC0 raw: %d\r\n", adc0.readRaw()); - uart.printf("--------------------\r\n\r\n"); - - uart.printf("ADC1 : %d mV\r\n", static_cast(adc1.read() * 1000)); - uart.printf("ADC1: %d%%\r\n", static_cast(adc1.readPercentage() * 100)); - uart.printf("ADC1 raw: %d\r\n", adc1.readRaw()); - uart.printf("--------------------\r\n\r\n"); - - uart.printf("ADC2 : %d mV\r\n", static_cast(adc2.read() * 1000)); - uart.printf("ADC2: %d%%\r\n", static_cast(adc2.readPercentage() * 100)); - uart.printf("ADC2 raw: %d\r\n", adc2.readRaw()); - uart.printf("--------------------\r\n\r\n"); } uart.printf("\r\n\r\n"); From 9782656cb780e5d2116d2d2a5f57e03307805d7f Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Tue, 22 Apr 2025 17:02:06 -0400 Subject: [PATCH 14/47] This is broken but I need to move the code --- include/HIB.hpp | 19 ++++++++++++++++++- include/dev/RedundantADC.hpp | 2 -- src/HIB.cpp | 10 +--------- src/dev/ADS8689IPWR.cpp | 15 ++++++++------- src/dev/RedundantADC.cpp | 24 ++++++++++++------------ targets/ADS8689IPWR/main.cpp | 10 +++++++--- 6 files changed, 46 insertions(+), 34 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index 509e68b..5a4ffb9 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -1,11 +1,19 @@ #pragma once +#include #include #include #include +/** + * Counts that when exceeded throw an error to the VC + */ +#define COMPARISON_ERROR_COUNT = 1; +#define PRECISION_MARGIN_ERROR_COUNT = 3; +#define ACCEPTABLE_MARGIN_ERROR_COUNT = 5; + namespace HIB { -constexpr size_t payloadLength = 8; +constexpr size_t payloadLength = 5; /** * HIB header file @@ -26,6 +34,15 @@ class HIB { DEV::RedundantADC& throttle; DEV::RedundantADC& brake; + /** + * Payload for CAN transmission. + * Byte 0: MSB for Throttle Voltage + * Byte 1: LSB for Throttle Voltage + * Byte 2: MSB for Brake Voltage + * Byte 3: LSB for Brake Voltage + * Byte 4: Error Byte for triggering a shutdown + */ + uint8_t data[payloadLength]; }; }// namespace HIB \ No newline at end of file diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index 2514092..9ac6c25 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -41,8 +41,6 @@ class RedundantADC { * This function reads values from three ADCs and checks for redundancy. * * @param[out] return_val Reference to the variable to store the value read from the ADCs - * @param[in] val2 Reference to the variable to store the value read from the second ADC. - * @param[in] val3 Reference to the variable to store the value read from the third ADC. * @return RedundantADC::Status The status of the processing. */ RedundantADC::Status read(uint32_t& return_val); diff --git a/src/HIB.cpp b/src/HIB.cpp index 832f6ce..1aaceb0 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -1,6 +1,5 @@ #include #include -#include namespace HIB { @@ -18,7 +17,7 @@ void HIB::process() { } void HIB::readThrottleVoltage() { - uint32_t voltage = 0; // Voltage to be recieved in millivolts + uint32_t voltage = 0; // Voltage to be received in millivolts DEV::RedundantADC::Status status = throttle.read(voltage); // gets the errors and voltage from the ADC cluster payload[0] += voltage; @@ -27,13 +26,6 @@ void HIB::readThrottleVoltage() { // Increment the status of each if (status == DEV::RedundantADC::Status::OK) { payload[4]++; - } else if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { - payload[5]++; - } else if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { - payload[6]++; - } else if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { - payload[7]++; - } } void HIB::readBrakeVoltage() { diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index faef6c7..e840000 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -1,4 +1,5 @@ #include +#include namespace HIB::DEV { @@ -24,20 +25,20 @@ ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), d } uint16_t ADS8689IPWR::read() { + uint8_t NOP[4] = {0x0, 0x0, 0x0, 0x0}; uint8_t bytes[4]; - uint16_t voltage; + uint32_t voltage; spi.startTransmission(deviceNumber); // NOP command - spi.write(0b0); - spi.write(0b0); - spi.write(0b0); - spi.write(0b0); spi.read(bytes, 4); spi.endTransmission(deviceNumber); - voltage = bytes[2] << 8 | bytes[3]; - voltage *= voltage * 12288 / 65536; + voltage = bytes[0] << 8 | bytes[1]; + voltage = voltage * 12288 / 65536; + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "byte0 = %x", bytes[0]); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "byte1 = %x", bytes[1]);; + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "voltage = %u", voltage); return voltage; } diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 60f8762..c9c835d 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -12,26 +12,26 @@ namespace HIB::DEV { RedundantADC::RedundantADC(ADS8689IPWR& adc0, ADS8689IPWR& adc1, ADS8689IPWR& adc2) : adc0(adc0), adc1(adc1), adc2(adc2) {} RedundantADC::Status RedundantADC::read(uint32_t& return_val) { - // Read ADC values + // Read in ADC values in millivoltage int32_t adcValues[3]; - adcValues[0] = static_cast(adc0.read() * 1000); - adcValues[1] = static_cast(adc1.read() * 1000); - adcValues[2] = static_cast(adc2.read() * 1000); + adcValues[0] = static_cast(adc0.read()); + adcValues[1] = static_cast(adc1.read()); + adcValues[2] = static_cast(adc2.read()); // Calculate average of all ADC values - int32_t average = (adcValues[0] + adcValues[1] + adcValues[2]) / 3; + const int32_t average = (adcValues[0] + adcValues[1] + adcValues[2]) / 3; // Check for margin error - bool adc0underLow = (std::abs(adcValues[0] - average) * 100 / average) < LOW_MARGIN; - bool adc1underLow = (std::abs(adcValues[1] - average) * 100 / average) < LOW_MARGIN; - bool adc2underLow = (std::abs(adcValues[2] - average) * 100 / average) < LOW_MARGIN; + const bool adc0underLow = (std::abs(adcValues[0] - average) * 100 / average) < LOW_MARGIN; + const bool adc1underLow = (std::abs(adcValues[1] - average) * 100 / average) < LOW_MARGIN; + const bool adc2underLow = (std::abs(adcValues[2] - average) * 100 / average) < LOW_MARGIN; - bool adc0underHigh = (std::abs(adcValues[0] - average) * 100 / average) < HIGH_MARGIN; - bool adc1underHigh = (std::abs(adcValues[1] - average) * 100 / average) < HIGH_MARGIN; - bool adc2underHigh = (std::abs(adcValues[2] - average) * 100 / average) < HIGH_MARGIN; + const bool adc0underHigh = (std::abs(adcValues[0] - average) * 100 / average) < HIGH_MARGIN; + const bool adc1underHigh = (std::abs(adcValues[1] - average) * 100 / average) < HIGH_MARGIN; + const bool adc2underHigh = (std::abs(adcValues[2] - average) * 100 / average) < HIGH_MARGIN; // Check for redundancy - bool allUnderLow = adc0underLow && adc1underLow && adc2underLow; + const bool allUnderLow = adc0underLow && adc1underLow && adc2underLow; if (allUnderLow) { return_val = average; diff --git a/targets/ADS8689IPWR/main.cpp b/targets/ADS8689IPWR/main.cpp index 2b0f7f4..ec73841 100644 --- a/targets/ADS8689IPWR/main.cpp +++ b/targets/ADS8689IPWR/main.cpp @@ -1,16 +1,18 @@ +#include +#include #include #include #include #include +#include #include -#include -#include #include +#include namespace io = core::io; namespace time = core::time; -constexpr uint32_t SPI_SPEED = SPI_SPEED_4MHZ; // 500KHz +constexpr uint32_t SPI_SPEED = SPI_SPEED_500KHZ; // 500KHz constexpr uint8_t deviceCount = 3; io::GPIO* throttleDevices[deviceCount]; @@ -22,6 +24,8 @@ int main() { // Initialize UART io::UART& uart = io::getUART(9600); + core::log::LOGGER.setUART(&uart); + core::log::LOGGER.setLogLevel(core::log::Logger::LogLevel::INFO); // Set up each device brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); From e6f7b4540efa2f31032f8ec7f0b86b519bc725b4 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Tue, 22 Apr 2025 18:14:54 -0400 Subject: [PATCH 15/47] Almost done changing margin errors to a static voltage difference --- include/dev/ADS8689IPWR.hpp | 7 ++++++- src/HIB.cpp | 1 + src/dev/ADS8689IPWR.cpp | 32 ++++++++++++-------------------- src/dev/RedundantADC.cpp | 12 +++++++----- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/include/dev/ADS8689IPWR.hpp b/include/dev/ADS8689IPWR.hpp index 48c9749..dc3b801 100644 --- a/include/dev/ADS8689IPWR.hpp +++ b/include/dev/ADS8689IPWR.hpp @@ -5,6 +5,11 @@ #define RANGE_SEL_REG 0x14 // R/W Range selection register ---- #define TWELVE_VOLT_SCALER 0b1000 +#define HALF_WORD_WRITE 0b11010000 +#define EMPTY_BYTE 0b00000000 +#define NOP {EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE} +#define UINT16_MAX 65535 +#define VOLTAGE_MAX 12288 namespace io = core::io; @@ -21,7 +26,7 @@ class ADS8689IPWR { ADS8689IPWR(io::SPI& spi, uint8_t deviceNumber); /** - * Reads out the voltage from the ADC + * Reads out the voltage from the ADC with a blank command through SPI * * @param voltage reference to variable that is storing voltage * @return the status of whether the transaction was successful diff --git a/src/HIB.cpp b/src/HIB.cpp index 1aaceb0..ab7fa43 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -26,6 +26,7 @@ void HIB::readThrottleVoltage() { // Increment the status of each if (status == DEV::RedundantADC::Status::OK) { payload[4]++; + } } void HIB::readBrakeVoltage() { diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index e840000..be7beb1 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -1,41 +1,33 @@ -#include +#include "../../libs/EVT-core/samples/canopen/canopen_sample/TestCanNode.hpp" + #include +#include namespace HIB::DEV { - ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), deviceNumber(deviceNumber) { - // Pull CS low + uint8_t message[4] = {HALF_WORD_WRITE, RANGE_SEL_REG, EMPTY_BYTE, TWELVE_VOLT_SCALER}; spi.startTransmission(deviceNumber); - spi.write(0b11010000); - spi.write(RANGE_SEL_REG); - spi.write(0b00000000); - spi.write(TWELVE_VOLT_SCALER); - // Pull CS high + spi.write(message, 4); spi.endTransmission(deviceNumber); - // begin the conversion + // Begin the conversion with a NOP command + uint8_t nop[4] = NOP; spi.startTransmission(deviceNumber); - // NOP command - spi.write(0b0); - spi.write(0b0); - spi.write(0b0); - spi.write(0b0); + spi.write(nop, 4); spi.endTransmission(deviceNumber); } uint16_t ADS8689IPWR::read() { - uint8_t NOP[4] = {0x0, 0x0, 0x0, 0x0}; uint8_t bytes[4]; - uint32_t voltage; - spi.startTransmission(deviceNumber); - // NOP command spi.read(bytes, 4); spi.endTransmission(deviceNumber); - voltage = bytes[0] << 8 | bytes[1]; - voltage = voltage * 12288 / 65536; + // First byte is MSB + uint32_t voltage = bytes[0] << 8 | bytes[1]; + // Normalize the received info (divide by uint16_t(MAX)) and scale accordingly + voltage = voltage / UINT16_MAX * VOLTAGE_MAX; core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "byte0 = %x", bytes[0]); core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "byte1 = %x", bytes[1]);; core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "voltage = %u", voltage); diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index c9c835d..28a4725 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -1,9 +1,10 @@ -#include -#include #include +#include +#include namespace io = core::io; +// Percantage differences constexpr uint32_t LOW_MARGIN = 1; constexpr uint32_t HIGH_MARGIN = 5; @@ -12,16 +13,17 @@ namespace HIB::DEV { RedundantADC::RedundantADC(ADS8689IPWR& adc0, ADS8689IPWR& adc1, ADS8689IPWR& adc2) : adc0(adc0), adc1(adc1), adc2(adc2) {} RedundantADC::Status RedundantADC::read(uint32_t& return_val) { - // Read in ADC values in millivoltage + // Read in the millivoltage of each ADC int32_t adcValues[3]; adcValues[0] = static_cast(adc0.read()); adcValues[1] = static_cast(adc1.read()); adcValues[2] = static_cast(adc2.read()); - // Calculate average of all ADC values + // Calculate average of all ADC millivoltages const int32_t average = (adcValues[0] + adcValues[1] + adcValues[2]) / 3; - // Check for margin error + // Check for deviation errors. + // Formula: |DEVIATION_FROM_AVERAGE| / AVERAGE (NORMALIZED) * 100 TO SCALE UP PERCENTAGE FROM 0.01 TO 1 const bool adc0underLow = (std::abs(adcValues[0] - average) * 100 / average) < LOW_MARGIN; const bool adc1underLow = (std::abs(adcValues[1] - average) * 100 / average) < LOW_MARGIN; const bool adc2underLow = (std::abs(adcValues[2] - average) * 100 / average) < LOW_MARGIN; From 40714d9acc2164d1f353c30d95790996b40ff681 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Tue, 22 Apr 2025 22:14:38 -0400 Subject: [PATCH 16/47] Hopefully a fully function driver with a few interface pins missing --- include/HIB.hpp | 27 ++++++++++++--- include/dev/ADS8689IPWR.hpp | 1 - src/HIB.cpp | 65 +++++++++++++++++++++++++++++++------ src/dev/RedundantADC.cpp | 17 +++++----- targets/REV3-HIB/main.cpp | 7 ++-- 5 files changed, 88 insertions(+), 29 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index 5a4ffb9..0aa3c9a 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -4,14 +4,14 @@ #include #include +namespace HIB { + /** * Counts that when exceeded throw an error to the VC */ -#define COMPARISON_ERROR_COUNT = 1; -#define PRECISION_MARGIN_ERROR_COUNT = 3; -#define ACCEPTABLE_MARGIN_ERROR_COUNT = 5; - -namespace HIB { +#define COMPARISON_ERROR_COUNT 1 +#define PRECISION_MARGIN_ERROR_COUNT 3 +#define ACCEPTABLE_MARGIN_ERROR_COUNT 5 constexpr size_t payloadLength = 5; @@ -34,6 +34,17 @@ class HIB { DEV::RedundantADC& throttle; DEV::RedundantADC& brake; + // Counters for throttle errors + uint8_t acceptableThrottleMarginErrors; + uint8_t precisionThrottleMarginErrors; + uint8_t comparisonThrottleErrors; + + // Counters for brake errors + uint8_t acceptableBrakeMarginErrors; + uint8_t precisionBrakeMarginErrors; + uint8_t comparisonBrakeErrors; + + /** * Payload for CAN transmission. * Byte 0: MSB for Throttle Voltage @@ -41,6 +52,12 @@ class HIB { * Byte 2: MSB for Brake Voltage * Byte 3: LSB for Brake Voltage * Byte 4: Error Byte for triggering a shutdown + * Byte 4 layout: X X X X X X X X + * 7 6 5 4 3 2 1 0 + * ^ ^ + * | \ + * ________________/ \__________________ + * Brake Error Bit Throttle Error Bit */ uint8_t data[payloadLength]; }; diff --git a/include/dev/ADS8689IPWR.hpp b/include/dev/ADS8689IPWR.hpp index dc3b801..575dad5 100644 --- a/include/dev/ADS8689IPWR.hpp +++ b/include/dev/ADS8689IPWR.hpp @@ -8,7 +8,6 @@ #define HALF_WORD_WRITE 0b11010000 #define EMPTY_BYTE 0b00000000 #define NOP {EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE} -#define UINT16_MAX 65535 #define VOLTAGE_MAX 12288 namespace io = core::io; diff --git a/src/HIB.cpp b/src/HIB.cpp index ab7fa43..b79489c 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -6,35 +6,80 @@ namespace HIB { HIB::HIB(DEV::RedundantADC& throttle, DEV::RedundantADC& brake) : throttle(throttle), brake(brake) { // Initialize payload to 0's - for (int i = 0; i < payloadLength; i++) { + for (uint8_t i = 0; i < payloadLength; i++) { payload[i] = 0; } } +// Reads the 2 sets of 3 ADC's and processes their errors while packaging them for CAN void HIB::process() { HIB::readThrottleVoltage(); HIB::readBrakeVoltage(); + + if (acceptableThrottleMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) { + payload[4] = payload[4] | 0b00000001; + } + + if (acceptableBrakeMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) { + payload[4] = payload[4] | 0b00000010; + } + + if (precisionThrottleMarginErrors < PRECISION_MARGIN_ERROR_COUNT) { + payload[4] = payload[4] | 0b00000001; + } + + if (precisionBrakeMarginErrors > PRECISION_MARGIN_ERROR_COUNT) { + payload[4] = payload[4] | 0b00000010; + } + + if (comparisonThrottleErrors < COMPARISON_ERROR_COUNT) { + payload[4] = payload[4] | 0b00000001; + } + + if (comparisonBrakeErrors < COMPARISON_ERROR_COUNT) { + payload[4] = payload[4] | 0b00000010; + } } void HIB::readThrottleVoltage() { uint32_t voltage = 0; // Voltage to be received in millivolts - DEV::RedundantADC::Status status = throttle.read(voltage); // gets the errors and voltage from the ADC cluster + const DEV::RedundantADC::Status status = throttle.read(voltage); // gets the errors and voltage from the ADC cluster + payload[0] += voltage >> 8; + payload[1] += voltage & 0xff; + + // Increment the status of each error if it is received + if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + acceptableThrottleMarginErrors++; + } - payload[0] += voltage; - payload[1] += voltage >> 8; + if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + precisionThrottleMarginErrors++; + } - // Increment the status of each - if (status == DEV::RedundantADC::Status::OK) { - payload[4]++; + if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { + comparisonThrottleErrors++; } } void HIB::readBrakeVoltage() { - uint32_t voltage = 0; // Voltage to be recieved in millivolts + uint32_t voltage = 0; // Voltage to be received in millivolts DEV::RedundantADC::Status status = brake.read(voltage); // gets the errors and voltage from the ADC cluster - payload[2] += voltage; - payload[3] += voltage >> 8; + payload[2] += voltage >> 8; + payload[3] += voltage & 0xff; + + // Increment the status of each error if it is received + if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + acceptableBrakeMarginErrors++; + } + + if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + precisionBrakeMarginErrors++; + } + + if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { + comparisonBrakeErrors++; + } } } \ No newline at end of file diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 28a4725..0076c10 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -5,8 +5,9 @@ namespace io = core::io; // Percantage differences -constexpr uint32_t LOW_MARGIN = 1; -constexpr uint32_t HIGH_MARGIN = 5; +// Values are 1% and 5% of 12288 Mv respectively +constexpr uint32_t LOW_MARGIN = 123; +constexpr uint32_t HIGH_MARGIN = 614; namespace HIB::DEV { @@ -24,13 +25,13 @@ RedundantADC::Status RedundantADC::read(uint32_t& return_val) { // Check for deviation errors. // Formula: |DEVIATION_FROM_AVERAGE| / AVERAGE (NORMALIZED) * 100 TO SCALE UP PERCENTAGE FROM 0.01 TO 1 - const bool adc0underLow = (std::abs(adcValues[0] - average) * 100 / average) < LOW_MARGIN; - const bool adc1underLow = (std::abs(adcValues[1] - average) * 100 / average) < LOW_MARGIN; - const bool adc2underLow = (std::abs(adcValues[2] - average) * 100 / average) < LOW_MARGIN; + const bool adc0underLow = static_cast(::abs(adcValues[0] - average)) < LOW_MARGIN; + const bool adc1underLow = static_cast(std::abs(adcValues[1] - average)) < LOW_MARGIN; + const bool adc2underLow = static_cast(std::abs(adcValues[2] - average)) < LOW_MARGIN; - const bool adc0underHigh = (std::abs(adcValues[0] - average) * 100 / average) < HIGH_MARGIN; - const bool adc1underHigh = (std::abs(adcValues[1] - average) * 100 / average) < HIGH_MARGIN; - const bool adc2underHigh = (std::abs(adcValues[2] - average) * 100 / average) < HIGH_MARGIN; + const bool adc0underHigh = static_cast(std::abs(adcValues[0] - average)) < HIGH_MARGIN; + const bool adc1underHigh = static_cast(std::abs(adcValues[1] - average)) < HIGH_MARGIN; + const bool adc2underHigh = static_cast(std::abs(adcValues[2] - average)) < HIGH_MARGIN; // Check for redundancy const bool allUnderLow = adc0underLow && adc1underLow && adc2underLow; diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index c60779e..a165824 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -85,7 +85,7 @@ int main() { auto hib = HIB::HIB(throttle, brake); // ID for HIB is 0x0D0 - io::CANMessage transmit_message(0x0D0, 8, hib.payload, false); + io::CANMessage transmit_message(0x0D0, 5, hib.payload, false); io::CANMessage received_message; // Try to join the network @@ -140,10 +140,7 @@ int main() { uart.printf("\r\n"); uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); uart.printf("Brake Voltage: %i mV\r\n", message_payload[2] << 8 | message_payload[3]); - uart.printf("No Errors: %i\r\n", message_payload[4]); - uart.printf("Precision Errors: %i\r\n", message_payload[5]); - uart.printf("Margin Errors: %i\r\n", message_payload[6]); - uart.printf("Comparison Errors: %i\r\n", message_payload[7]); + uart.printf("Error Code (1 = Throttle, 2 = Brake, 3 = Both): %i\r\n", message_payload[4]); } uart.printf("\r\n\r\n"); From 464b4ea0861b5471ed2e25b210fa6d62d5ca3763 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Wed, 23 Apr 2025 14:54:07 -0400 Subject: [PATCH 17/47] CAN it do it? Yes it CAN! --- include/HIB.hpp | 29 +++++++++++----------- src/HIB.cpp | 34 +++++++++++++++----------- src/dev/ADS8689IPWR.cpp | 8 ++---- src/dev/RedundantADC.cpp | 12 ++++++--- targets/ADS8689IPWR/main.cpp | 12 ++++----- targets/REV3-HIB/main.cpp | 47 +++++++++++++++++++++++++++--------- 6 files changed, 85 insertions(+), 57 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index 0aa3c9a..49026cd 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -24,26 +24,27 @@ class HIB { void process(); - void readThrottleVoltage(); - - void readBrakeVoltage(); - uint8_t payload[payloadLength]; - -private: - DEV::RedundantADC& throttle; - DEV::RedundantADC& brake; + uint32_t throttleVoltage = 0; + uint32_t brakeVoltage = 0; // Counters for throttle errors - uint8_t acceptableThrottleMarginErrors; - uint8_t precisionThrottleMarginErrors; - uint8_t comparisonThrottleErrors; + uint8_t acceptableThrottleMarginErrors = 0; + uint8_t precisionThrottleMarginErrors = 0; + uint8_t comparisonThrottleErrors = 0; // Counters for brake errors - uint8_t acceptableBrakeMarginErrors; - uint8_t precisionBrakeMarginErrors; - uint8_t comparisonBrakeErrors; + uint8_t acceptableBrakeMarginErrors = 0; + uint8_t precisionBrakeMarginErrors = 0; + uint8_t comparisonBrakeErrors = 0; +private: + void readThrottleVoltage(); + + void readBrakeVoltage(); + + DEV::RedundantADC& throttle; + DEV::RedundantADC& brake; /** * Payload for CAN transmission. diff --git a/src/HIB.cpp b/src/HIB.cpp index b79489c..bafecf0 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -13,8 +13,21 @@ HIB::HIB(DEV::RedundantADC& throttle, DEV::RedundantADC& brake) // Reads the 2 sets of 3 ADC's and processes their errors while packaging them for CAN void HIB::process() { - HIB::readThrottleVoltage(); - HIB::readBrakeVoltage(); + readThrottleVoltage(); + readBrakeVoltage(); + + if (throttleVoltage < 300) { + throttleVoltage = 0; + } + + if (brakeVoltage < 300) { + brakeVoltage = 0; + } + + payload[0] = throttleVoltage >> 8; + payload[1] = throttleVoltage & 0xFF; + payload[2] = brakeVoltage >> 8; + payload[3] = brakeVoltage & 0xFF; if (acceptableThrottleMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) { payload[4] = payload[4] | 0b00000001; @@ -24,7 +37,7 @@ void HIB::process() { payload[4] = payload[4] | 0b00000010; } - if (precisionThrottleMarginErrors < PRECISION_MARGIN_ERROR_COUNT) { + if (precisionThrottleMarginErrors > PRECISION_MARGIN_ERROR_COUNT) { payload[4] = payload[4] | 0b00000001; } @@ -32,20 +45,17 @@ void HIB::process() { payload[4] = payload[4] | 0b00000010; } - if (comparisonThrottleErrors < COMPARISON_ERROR_COUNT) { + if (comparisonThrottleErrors > COMPARISON_ERROR_COUNT) { payload[4] = payload[4] | 0b00000001; } - if (comparisonBrakeErrors < COMPARISON_ERROR_COUNT) { + if (comparisonBrakeErrors > COMPARISON_ERROR_COUNT) { payload[4] = payload[4] | 0b00000010; } } void HIB::readThrottleVoltage() { - uint32_t voltage = 0; // Voltage to be received in millivolts - const DEV::RedundantADC::Status status = throttle.read(voltage); // gets the errors and voltage from the ADC cluster - payload[0] += voltage >> 8; - payload[1] += voltage & 0xff; + const DEV::RedundantADC::Status status = throttle.read(throttleVoltage); // gets the errors and voltage from the ADC cluster // Increment the status of each error if it is received if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { @@ -62,11 +72,7 @@ void HIB::readThrottleVoltage() { } void HIB::readBrakeVoltage() { - uint32_t voltage = 0; // Voltage to be received in millivolts - DEV::RedundantADC::Status status = brake.read(voltage); // gets the errors and voltage from the ADC cluster - - payload[2] += voltage >> 8; - payload[3] += voltage & 0xff; + DEV::RedundantADC::Status status = brake.read(brakeVoltage); // gets the errors and voltage from the ADC cluster // Increment the status of each error if it is received if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index be7beb1..9ffbcb9 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -1,5 +1,3 @@ -#include "../../libs/EVT-core/samples/canopen/canopen_sample/TestCanNode.hpp" - #include #include @@ -25,11 +23,9 @@ uint16_t ADS8689IPWR::read() { spi.endTransmission(deviceNumber); // First byte is MSB - uint32_t voltage = bytes[0] << 8 | bytes[1]; + uint32_t voltage = (bytes[0] << 8) + bytes[1]; // Normalize the received info (divide by uint16_t(MAX)) and scale accordingly - voltage = voltage / UINT16_MAX * VOLTAGE_MAX; - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "byte0 = %x", bytes[0]); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "byte1 = %x", bytes[1]);; + voltage = voltage * VOLTAGE_MAX / UINT16_MAX; core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "voltage = %u", voltage); return voltage; } diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 0076c10..c676624 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -5,9 +5,9 @@ namespace io = core::io; // Percantage differences -// Values are 1% and 5% of 12288 Mv respectively -constexpr uint32_t LOW_MARGIN = 123; -constexpr uint32_t HIGH_MARGIN = 614; +// Values are 1% and 5% of 12288 Mv respectively not really though +constexpr uint32_t LOW_MARGIN = 400; +constexpr uint32_t HIGH_MARGIN = 800; namespace HIB::DEV { @@ -25,7 +25,7 @@ RedundantADC::Status RedundantADC::read(uint32_t& return_val) { // Check for deviation errors. // Formula: |DEVIATION_FROM_AVERAGE| / AVERAGE (NORMALIZED) * 100 TO SCALE UP PERCENTAGE FROM 0.01 TO 1 - const bool adc0underLow = static_cast(::abs(adcValues[0] - average)) < LOW_MARGIN; + const bool adc0underLow = static_cast(std::abs(adcValues[0] - average)) < LOW_MARGIN; const bool adc1underLow = static_cast(std::abs(adcValues[1] - average)) < LOW_MARGIN; const bool adc2underLow = static_cast(std::abs(adcValues[2] - average)) < LOW_MARGIN; @@ -36,6 +36,10 @@ RedundantADC::Status RedundantADC::read(uint32_t& return_val) { // Check for redundancy const bool allUnderLow = adc0underLow && adc1underLow && adc2underLow; + if (average == 0) { + return RedundantADC::Status::OK; + } + if (allUnderLow) { return_val = average; return RedundantADC::Status::OK; diff --git a/targets/ADS8689IPWR/main.cpp b/targets/ADS8689IPWR/main.cpp index ec73841..5b9cc45 100644 --- a/targets/ADS8689IPWR/main.cpp +++ b/targets/ADS8689IPWR/main.cpp @@ -68,12 +68,10 @@ int main() { // main loop while (true) { hib.process(); - uart.printf("Throttle Voltage: %i mV\r\n", hib.payload[0] << 8 | hib.payload[1]); - uart.printf("Brake Voltage: %i mV\r\n", hib.payload[2] << 8 | hib.payload[3]); - uart.printf("OK: %i\r\n", hib.payload[4]); - uart.printf("PRECISION_MARGIN_EXCEEDED: %i\r\n", hib.payload[5]); - uart.printf("ACCEPTABLE_MARGIN_EXCEEDED: %i\r\n", hib.payload[6]); - uart.printf("COMPARISON_ERROR: %i\r\n", hib.payload[7]); - time::wait(1000); + uart.printf("Throttle Voltage: %i mV\r\n", hib.throttleVoltage); + uart.printf("Brake Voltage: %i mV\r\n", hib.brakeVoltage); + uart.printf("Acceptable Errors: %i\r\n", hib.acceptableThrottleMarginErrors); + uart.printf("Precision Errors: %i\r\n", hib.precisionThrottleMarginErrors); + uart.printf("Comparison Errors: %i\r\n", hib.comparisonThrottleErrors); } } \ No newline at end of file diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index a165824..a392b30 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -1,14 +1,14 @@ +#include +#include #include #include #include #include #include -#include -#include #include +#include namespace io = core::io; -namespace time = core::time; constexpr uint32_t SPI_SPEED = SPI_SPEED_500KHZ; // 500KHz constexpr uint8_t deviceCount = 3; @@ -85,16 +85,12 @@ int main() { auto hib = HIB::HIB(throttle, brake); // ID for HIB is 0x0D0 - io::CANMessage transmit_message(0x0D0, 5, hib.payload, false); + io::CANMessage transmit_message(0x0D0, 5, &hib.payload[0], false); io::CANMessage received_message; // Try to join the network io::CAN::CANStatus result = can.connect(); - - // can.addCANFilter(0, 0, 13); //This would create a filter that allows all messages through - can.addCANFilter(0xD0, 0xFF0, 0); can.enableEmergencyFilter(ENABLE); - // Begin CAN Tests uart.printf("Starting CAN testing\r\n"); @@ -103,11 +99,24 @@ int main() { return 1; } - // MAIN loop + // main + int count = 0; + + // Speed Loop (Comment out to get display + /* while (true) { + hib.process(); + io::CANMessage transmit_message(0x0D0, 5, &hib.payload[0], false); + can.receive(&received_message, false); + } */ + + // Display Loop while (true) { // Process the voltage hib.process(); + // ID for HIB is 0x0D0 + io::CANMessage transmit_message(0x0D0, 5, &hib.payload[0], false); + // Try to send the message result = can.transmit(transmit_message); if (result !=io::CAN::CANStatus::OK) { @@ -125,7 +134,7 @@ int main() { // Check if data was received if (received_message.getDataLength() == 0) { uart.printf("Message filtered out!"); - } else { + } else { uart.printf("Message received\r\n"); uart.printf("Message id: %d \r\n", received_message.getId()); uart.printf("Message length: %d\r\n", received_message.getDataLength()); @@ -136,15 +145,29 @@ int main() { uart.printf("0x%02X ", message_payload[i]); } + uart.printf("\r\n"); + + for (int i = 0; i < received_message.getDataLength(); i++) { + uart.printf("0x%02X ", hib.payload[i]); + } + // CAN most likely make variables to store total errors over the entire runtime to get a better picture uart.printf("\r\n"); uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); uart.printf("Brake Voltage: %i mV\r\n", message_payload[2] << 8 | message_payload[3]); uart.printf("Error Code (1 = Throttle, 2 = Brake, 3 = Both): %i\r\n", message_payload[4]); + uart.printf("Throttle Voltage: %i mV\r\n", hib.throttleVoltage); + uart.printf("Brake Voltage: %i mV\r\n", hib.brakeVoltage); + uart.printf("Throttle Acceptable Errors: %i\r\n", hib.acceptableThrottleMarginErrors); + uart.printf("Throttle Precision Errors: %i\r\n", hib.precisionThrottleMarginErrors); + uart.printf("Throttle Comparison Errors: %i\r\n", hib.comparisonThrottleErrors); + uart.printf("Brake Acceptable Errors: %i\r\n", hib.acceptableBrakeMarginErrors); + uart.printf("Brake Precision Errors: %i\r\n", hib.precisionBrakeMarginErrors); + uart.printf("Brake Comparison Errors: %i\r\n", hib.comparisonBrakeErrors); + count++; + core::time::wait(1000); } uart.printf("\r\n\r\n"); - - core::time::wait(2000); } return 0; From f4d830bbfbc5a3fa5776d6086f630b7ea17e3ced Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Wed, 23 Apr 2025 14:55:05 -0400 Subject: [PATCH 18/47] It CAN now go even faster --- targets/REV3-HIB/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index a392b30..7b7bdc8 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -103,11 +103,11 @@ int main() { int count = 0; // Speed Loop (Comment out to get display - /* while (true) { + while (true) { hib.process(); io::CANMessage transmit_message(0x0D0, 5, &hib.payload[0], false); can.receive(&received_message, false); - } */ + } // Display Loop while (true) { From d03b6fe166abf29c60bf896821d0999ec2eeac09 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Thu, 1 May 2025 23:53:49 -0400 Subject: [PATCH 19/47] Attempted to fix the read issue on the ADCs --- src/HIB.cpp | 43 +++++++-------- targets/REV3-HIB/main.cpp | 113 +++++++++++++++----------------------- 2 files changed, 64 insertions(+), 92 deletions(-) diff --git a/src/HIB.cpp b/src/HIB.cpp index bafecf0..ed3cd91 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -11,8 +11,9 @@ HIB::HIB(DEV::RedundantADC& throttle, DEV::RedundantADC& brake) } } -// Reads the 2 sets of 3 ADC's and processes their errors while packaging them for CAN +// Reads the 2 sets of 3 ADCs and processes their errors while packaging them for CAN void HIB::process() { + // Read in the voltages from the throttle readThrottleVoltage(); readBrakeVoltage(); @@ -24,34 +25,28 @@ void HIB::process() { brakeVoltage = 0; } - payload[0] = throttleVoltage >> 8; - payload[1] = throttleVoltage & 0xFF; - payload[2] = brakeVoltage >> 8; - payload[3] = brakeVoltage & 0xFF; + payload[0] = static_cast(throttleVoltage >> 8 & 0xFF); + payload[1] = static_cast(throttleVoltage & 0xFF); + payload[2] = static_cast(brakeVoltage >> 8 & 0xFF); + payload[3] = static_cast(brakeVoltage & 0xFF); - if (acceptableThrottleMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) { - payload[4] = payload[4] | 0b00000001; - } + if (acceptableThrottleMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) + payload[4] |= 0b01; - if (acceptableBrakeMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) { - payload[4] = payload[4] | 0b00000010; - } + if (acceptableBrakeMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) + payload[4] |= 0b10; - if (precisionThrottleMarginErrors > PRECISION_MARGIN_ERROR_COUNT) { - payload[4] = payload[4] | 0b00000001; - } + if (precisionThrottleMarginErrors > PRECISION_MARGIN_ERROR_COUNT) + payload[4] |= 0b01; - if (precisionBrakeMarginErrors > PRECISION_MARGIN_ERROR_COUNT) { - payload[4] = payload[4] | 0b00000010; - } + if (precisionBrakeMarginErrors > PRECISION_MARGIN_ERROR_COUNT) + payload[4] |= 0b10; - if (comparisonThrottleErrors > COMPARISON_ERROR_COUNT) { - payload[4] = payload[4] | 0b00000001; - } + if (comparisonThrottleErrors > COMPARISON_ERROR_COUNT) + payload[4] |= 0b01; - if (comparisonBrakeErrors > COMPARISON_ERROR_COUNT) { - payload[4] = payload[4] | 0b00000010; - } + if (comparisonBrakeErrors > COMPARISON_ERROR_COUNT) + payload[4] |= 0b10; } void HIB::readThrottleVoltage() { @@ -72,7 +67,7 @@ void HIB::readThrottleVoltage() { } void HIB::readBrakeVoltage() { - DEV::RedundantADC::Status status = brake.read(brakeVoltage); // gets the errors and voltage from the ADC cluster + const DEV::RedundantADC::Status status = brake.read(brakeVoltage); // gets the errors and voltage from the ADC cluster // Increment the status of each error if it is received if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 7b7bdc8..148bf0d 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -8,7 +8,9 @@ #include #include -namespace io = core::io; +namespace io = core::io; +namespace dev = HIB::DEV; +namespace hib = HIB; constexpr uint32_t SPI_SPEED = SPI_SPEED_500KHZ; // 500KHz constexpr uint8_t deviceCount = 3; @@ -33,6 +35,9 @@ void canIRQHandler(io::CANMessage& message, void* priv) { } int main() { + // Count for the number of iterations of the process + uint64_t count = 0; + // Initialize system core::platform::init(); @@ -42,51 +47,40 @@ int main() { // Initialize CAN io::CAN& can = io::getCAN(true); - // Set up each device + // Brake ADC setup brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[0]->writePin(io::GPIO::State::HIGH); - brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[1]->writePin(io::GPIO::State::HIGH); - brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[2]->writePin(io::GPIO::State::HIGH); + io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); + spiBrake.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); + + dev::ADS8689IPWR brakeADC1 = dev::ADS8689IPWR(spiBrake, 0); + dev::ADS8689IPWR brakeADC2 = dev::ADS8689IPWR(spiBrake, 1); + dev::ADS8689IPWR brakeADC3 = dev::ADS8689IPWR(spiBrake, 2); + dev::RedundantADC brake = dev::RedundantADC(brakeADC1, brakeADC2, brakeADC3); + + // Throttle ADC setup throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[0]->writePin(io::GPIO::State::HIGH); - throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[1]->writePin(io::GPIO::State::HIGH); - throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[2]->writePin(io::GPIO::State::HIGH); - // Create the two SPI clusters io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); - io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); - - // Configure the systems spiThrottle.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); - spiBrake.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); - // Create each ADS8689IPWR object - auto throttleADC1 = HIB::DEV::ADS8689IPWR(spiThrottle, 0); - auto throttleADC2 = HIB::DEV::ADS8689IPWR(spiThrottle, 1); - auto throttleADC3 = HIB::DEV::ADS8689IPWR(spiThrottle, 2); - auto brakeADC1 = HIB::DEV::ADS8689IPWR(spiBrake, 0); - auto brakeADC2 = HIB::DEV::ADS8689IPWR(spiBrake, 1); - auto brakeADC3 = HIB::DEV::ADS8689IPWR(spiBrake, 2); - - // Create the Redundant ADC's - auto throttle = HIB::DEV::RedundantADC(throttleADC1, throttleADC2, throttleADC3); - auto brake = HIB::DEV::RedundantADC(brakeADC1, brakeADC2, brakeADC3); + dev::ADS8689IPWR throttleADC1 = dev::ADS8689IPWR(spiThrottle, 0); + dev::ADS8689IPWR throttleADC2 = dev::ADS8689IPWR(spiThrottle, 1); + dev::ADS8689IPWR throttleADC3 = dev::ADS8689IPWR(spiThrottle, 2); + dev::RedundantADC throttle = dev::RedundantADC(throttleADC1, throttleADC2, throttleADC3); // Finally create the HIB object to begin processing data - auto hib = HIB::HIB(throttle, brake); - - // ID for HIB is 0x0D0 - io::CANMessage transmit_message(0x0D0, 5, &hib.payload[0], false); - io::CANMessage received_message; + hib::HIB hib = hib::HIB(throttle, brake); // Try to join the network io::CAN::CANStatus result = can.connect(); @@ -99,16 +93,6 @@ int main() { return 1; } - // main - int count = 0; - - // Speed Loop (Comment out to get display - while (true) { - hib.process(); - io::CANMessage transmit_message(0x0D0, 5, &hib.payload[0], false); - can.receive(&received_message, false); - } - // Display Loop while (true) { // Process the voltage @@ -116,6 +100,7 @@ int main() { // ID for HIB is 0x0D0 io::CANMessage transmit_message(0x0D0, 5, &hib.payload[0], false); + io::CANMessage received_message; // Try to send the message result = can.transmit(transmit_message); @@ -131,43 +116,35 @@ int main() { continue; } - // Check if data was received - if (received_message.getDataLength() == 0) { - uart.printf("Message filtered out!"); - } else { - uart.printf("Message received\r\n"); - uart.printf("Message id: %d \r\n", received_message.getId()); - uart.printf("Message length: %d\r\n", received_message.getDataLength()); - uart.printf("Message contents: "); - - const uint8_t* message_payload = received_message.getPayload(); - for (int i = 0; i < received_message.getDataLength(); i++) { - uart.printf("0x%02X ", message_payload[i]); + if (count >= 2000) { + uart.printf("\033[2J\033[H"); + // Check if data was received + if (received_message.getDataLength() == 0) { + uart.printf("Message filtered out!"); } + else { + const uint8_t* message_payload = received_message.getPayload(); + uart.printf("CAN payload: \033[32m"); + + for (int i = 0; i < received_message.getDataLength(); i++) { + uart.printf("0x%02X ", message_payload[i]); + } - uart.printf("\r\n"); + uart.printf("\r\n\033[37mHIB payload: \033[34m"); - for (int i = 0; i < received_message.getDataLength(); i++) { - uart.printf("0x%02X ", hib.payload[i]); + for (int i = 0; i < received_message.getDataLength(); i++) { + uart.printf("0x%02X ", hib.payload[i]); + } + + uart.printf("\r\n\033[37m"); + uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); + uart.printf("Error Code: %i\r\n", message_payload[4]); } - // CAN most likely make variables to store total errors over the entire runtime to get a better picture - uart.printf("\r\n"); - uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); - uart.printf("Brake Voltage: %i mV\r\n", message_payload[2] << 8 | message_payload[3]); - uart.printf("Error Code (1 = Throttle, 2 = Brake, 3 = Both): %i\r\n", message_payload[4]); - uart.printf("Throttle Voltage: %i mV\r\n", hib.throttleVoltage); - uart.printf("Brake Voltage: %i mV\r\n", hib.brakeVoltage); - uart.printf("Throttle Acceptable Errors: %i\r\n", hib.acceptableThrottleMarginErrors); - uart.printf("Throttle Precision Errors: %i\r\n", hib.precisionThrottleMarginErrors); - uart.printf("Throttle Comparison Errors: %i\r\n", hib.comparisonThrottleErrors); - uart.printf("Brake Acceptable Errors: %i\r\n", hib.acceptableBrakeMarginErrors); - uart.printf("Brake Precision Errors: %i\r\n", hib.precisionBrakeMarginErrors); - uart.printf("Brake Comparison Errors: %i\r\n", hib.comparisonBrakeErrors); - count++; - core::time::wait(1000); + count = 0; } - uart.printf("\r\n\r\n"); + + count++; } return 0; From 404a142e941e801991097f3d41c11a867d7bfeef Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Fri, 2 May 2025 00:09:44 -0400 Subject: [PATCH 20/47] Really not sure how to fix this issue --- include/dev/ADS8689IPWR.hpp | 2 +- src/dev/ADS8689IPWR.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dev/ADS8689IPWR.hpp b/include/dev/ADS8689IPWR.hpp index 575dad5..2f1f20d 100644 --- a/include/dev/ADS8689IPWR.hpp +++ b/include/dev/ADS8689IPWR.hpp @@ -30,7 +30,7 @@ class ADS8689IPWR { * @param voltage reference to variable that is storing voltage * @return the status of whether the transaction was successful */ - uint16_t read(); + uint16_t read() const; private: io::SPI& spi; const uint8_t deviceNumber; diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index 9ffbcb9..926305f 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -16,7 +16,7 @@ ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), d spi.endTransmission(deviceNumber); } -uint16_t ADS8689IPWR::read() { +uint16_t ADS8689IPWR::read() const { uint8_t bytes[4]; spi.startTransmission(deviceNumber); spi.read(bytes, 4); @@ -24,9 +24,9 @@ uint16_t ADS8689IPWR::read() { // First byte is MSB uint32_t voltage = (bytes[0] << 8) + bytes[1]; + // Normalize the received info (divide by uint16_t(MAX)) and scale accordingly voltage = voltage * VOLTAGE_MAX / UINT16_MAX; - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "voltage = %u", voltage); return voltage; } From 122c1402c0041fa07a4e4c6487484d61988adf54 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Fri, 2 May 2025 00:18:50 -0400 Subject: [PATCH 21/47] I tried to prevent int overflow but that did not solve the problem --- include/HIB.hpp | 12 ++++++------ src/HIB.cpp | 24 ++++++++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index 49026cd..e423234 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -29,14 +29,14 @@ class HIB { uint32_t brakeVoltage = 0; // Counters for throttle errors - uint8_t acceptableThrottleMarginErrors = 0; - uint8_t precisionThrottleMarginErrors = 0; - uint8_t comparisonThrottleErrors = 0; + uint64_t acceptableThrottleMarginErrors = 0; + uint64_t precisionThrottleMarginErrors = 0; + uint64_t comparisonThrottleErrors = 0; // Counters for brake errors - uint8_t acceptableBrakeMarginErrors = 0; - uint8_t precisionBrakeMarginErrors = 0; - uint8_t comparisonBrakeErrors = 0; + uint64_t acceptableBrakeMarginErrors = 0; + uint64_t precisionBrakeMarginErrors = 0; + uint64_t comparisonBrakeErrors = 0; private: void readThrottleVoltage(); diff --git a/src/HIB.cpp b/src/HIB.cpp index ed3cd91..911257f 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -30,23 +30,35 @@ void HIB::process() { payload[2] = static_cast(brakeVoltage >> 8 & 0xFF); payload[3] = static_cast(brakeVoltage & 0xFF); - if (acceptableThrottleMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) + if (acceptableThrottleMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) { + acceptableThrottleMarginErrors = ACCEPTABLE_MARGIN_ERROR_COUNT + 1; payload[4] |= 0b01; + } - if (acceptableBrakeMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) + if (acceptableBrakeMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) { + acceptableBrakeMarginErrors = ACCEPTABLE_MARGIN_ERROR_COUNT + 1; payload[4] |= 0b10; + } - if (precisionThrottleMarginErrors > PRECISION_MARGIN_ERROR_COUNT) + if (precisionThrottleMarginErrors > PRECISION_MARGIN_ERROR_COUNT) { + precisionThrottleMarginErrors = PRECISION_MARGIN_ERROR_COUNT + 1; payload[4] |= 0b01; + } - if (precisionBrakeMarginErrors > PRECISION_MARGIN_ERROR_COUNT) + if (precisionBrakeMarginErrors > PRECISION_MARGIN_ERROR_COUNT) { + precisionBrakeMarginErrors = PRECISION_MARGIN_ERROR_COUNT + 1; payload[4] |= 0b10; + } - if (comparisonThrottleErrors > COMPARISON_ERROR_COUNT) + if (comparisonThrottleErrors > COMPARISON_ERROR_COUNT) { + comparisonThrottleErrors = COMPARISON_ERROR_COUNT + 1; payload[4] |= 0b01; + } - if (comparisonBrakeErrors > COMPARISON_ERROR_COUNT) + if (comparisonBrakeErrors > COMPARISON_ERROR_COUNT) { + comparisonBrakeErrors = COMPARISON_ERROR_COUNT + 1; payload[4] |= 0b10; + } } void HIB::readThrottleVoltage() { From 4ab2d0774c731a24d3f1e8603af8cb95ea16284a Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Tue, 19 Aug 2025 21:06:47 -0400 Subject: [PATCH 22/47] Beginning to change statements to logger --- targets/REV3-HIB/main.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 148bf0d..4eeb743 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace io = core::io; namespace dev = HIB::DEV; @@ -41,8 +42,13 @@ int main() { // Initialize system core::platform::init(); - // Initialize UART + // Initialize UART and logger io::UART& uart = io::getUART(9600); + core::log::LOGGER.setUART(&uart); + core::log::LOGGER.setLogLevel(core::log::Logger::LogLevel::INFO); + + // TEMPLATE + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, ""); // Initialize CAN io::CAN& can = io::getCAN(true); From 00411da7565b9e11f3eebcab7385057b9f6b866b Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Mon, 15 Sep 2025 19:35:25 -0400 Subject: [PATCH 23/47] Update for Oleg --- include/dev/RedundantADC.hpp | 2 +- src/HIB.cpp | 3 +- src/dev/ADS8689IPWR.cpp | 7 ++++ src/dev/RedundantADC.cpp | 13 +++++++- targets/REV3-HIB/main.cpp | 65 ++++++++++++++++++++---------------- 5 files changed, 58 insertions(+), 32 deletions(-) diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index 9ac6c25..f54ecfc 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -43,7 +43,7 @@ class RedundantADC { * @param[out] return_val Reference to the variable to store the value read from the ADCs * @return RedundantADC::Status The status of the processing. */ - RedundantADC::Status read(uint32_t& return_val); + RedundantADC::Status read(uint32_t& return_val) const; private: /** Reference to the first ADC. */ diff --git a/src/HIB.cpp b/src/HIB.cpp index 911257f..041afa4 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace HIB { @@ -15,7 +16,7 @@ HIB::HIB(DEV::RedundantADC& throttle, DEV::RedundantADC& brake) void HIB::process() { // Read in the voltages from the throttle readThrottleVoltage(); - readBrakeVoltage(); + // readBrakeVoltage(); if (throttleVoltage < 300) { throttleVoltage = 0; diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index 926305f..1af2898 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace HIB::DEV { @@ -27,6 +28,12 @@ uint16_t ADS8689IPWR::read() const { // Normalize the received info (divide by uint16_t(MAX)) and scale accordingly voltage = voltage * VOLTAGE_MAX / UINT16_MAX; + static int count = 0; + if (count > 2000) { + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage at the ADS8689IPWR: %i\r\n", voltage); + count = 0; + } + count += 1; return voltage; } diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index c676624..5d0b866 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace io = core::io; @@ -13,7 +14,7 @@ namespace HIB::DEV { RedundantADC::RedundantADC(ADS8689IPWR& adc0, ADS8689IPWR& adc1, ADS8689IPWR& adc2) : adc0(adc0), adc1(adc1), adc2(adc2) {} -RedundantADC::Status RedundantADC::read(uint32_t& return_val) { +RedundantADC::Status RedundantADC::read(uint32_t& return_val) const { // Read in the millivoltage of each ADC int32_t adcValues[3]; adcValues[0] = static_cast(adc0.read()); @@ -23,6 +24,16 @@ RedundantADC::Status RedundantADC::read(uint32_t& return_val) { // Calculate average of all ADC millivoltages const int32_t average = (adcValues[0] + adcValues[1] + adcValues[2]) / 3; + static int count = 0; + if (count > 2000) { + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage average at the RedundantADC: %i\r\n", average); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage average at the RedundantADC: %i\r\n", average); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage average at the RedundantADC: %i\r\n", average); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage average at the RedundantADC: %i\r\n", average); + count = 0; + } + count += 1; + // Check for deviation errors. // Formula: |DEVIATION_FROM_AVERAGE| / AVERAGE (NORMALIZED) * 100 TO SCALE UP PERCENTAGE FROM 0.01 TO 1 const bool adc0underLow = static_cast(std::abs(adcValues[0] - average)) < LOW_MARGIN; diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 148bf0d..3638c8b 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -7,9 +7,10 @@ #include #include #include +#include namespace io = core::io; -namespace dev = HIB::DEV; +namespace devh = HIB::DEV; namespace hib = HIB; constexpr uint32_t SPI_SPEED = SPI_SPEED_500KHZ; // 500KHz @@ -22,16 +23,16 @@ io::GPIO* brakeDevices[deviceCount]; void canIRQHandler(io::CANMessage& message, void* priv) { io::UART* uart = (io::UART*) priv; - uart->printf("Message received\r\n"); - uart->printf("Message id: 0x%X \r\n", message.getId()); - uart->printf("Message length: %d\r\n", message.getDataLength()); - uart->printf("Message contents: "); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message received\r\n"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message id: 0x%X \r\n", message.getId()); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message length: %d\r\n", message.getDataLength()); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message contents: "); uint8_t* message_payload = message.getPayload(); for (int i = 0; i < message.getDataLength(); i++) { - uart->printf("0x%02X ", message_payload[i]); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"0x%02X ", message_payload[i]); } - uart->printf("\r\n\r\n"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"\r\n\r\n"); } int main() { @@ -44,6 +45,9 @@ int main() { // Initialize UART io::UART& uart = io::getUART(9600); + core::log::LOGGER.setUART(&uart); + core::log::LOGGER.setLogLevel(core::log::Logger::LogLevel::INFO); + // Initialize CAN io::CAN& can = io::getCAN(true); @@ -58,10 +62,10 @@ int main() { io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); spiBrake.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); - dev::ADS8689IPWR brakeADC1 = dev::ADS8689IPWR(spiBrake, 0); - dev::ADS8689IPWR brakeADC2 = dev::ADS8689IPWR(spiBrake, 1); - dev::ADS8689IPWR brakeADC3 = dev::ADS8689IPWR(spiBrake, 2); - dev::RedundantADC brake = dev::RedundantADC(brakeADC1, brakeADC2, brakeADC3); + devh::ADS8689IPWR brakeADC1 = devh::ADS8689IPWR(spiBrake, 0); + devh::ADS8689IPWR brakeADC2 = devh::ADS8689IPWR(spiBrake, 1); + devh::ADS8689IPWR brakeADC3 = devh::ADS8689IPWR(spiBrake, 2); + devh::RedundantADC brake = devh::RedundantADC(brakeADC1, brakeADC2, brakeADC3); // Throttle ADC setup throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); @@ -74,10 +78,10 @@ int main() { io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); spiThrottle.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); - dev::ADS8689IPWR throttleADC1 = dev::ADS8689IPWR(spiThrottle, 0); - dev::ADS8689IPWR throttleADC2 = dev::ADS8689IPWR(spiThrottle, 1); - dev::ADS8689IPWR throttleADC3 = dev::ADS8689IPWR(spiThrottle, 2); - dev::RedundantADC throttle = dev::RedundantADC(throttleADC1, throttleADC2, throttleADC3); + devh::ADS8689IPWR throttleADC1 = devh::ADS8689IPWR(spiThrottle, 0); + devh::ADS8689IPWR throttleADC2 = devh::ADS8689IPWR(spiThrottle, 1); + devh::ADS8689IPWR throttleADC3 = devh::ADS8689IPWR(spiThrottle, 2); + devh::RedundantADC throttle = devh::RedundantADC(throttleADC1, throttleADC2, throttleADC3); // Finally create the HIB object to begin processing data hib::HIB hib = hib::HIB(throttle, brake); @@ -85,15 +89,16 @@ int main() { // Try to join the network io::CAN::CANStatus result = can.connect(); can.enableEmergencyFilter(ENABLE); + // Begin CAN Tests - uart.printf("Starting CAN testing\r\n"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Starting CAN testing\r\n"); if (result !=io::CAN::CANStatus::OK) { - uart.printf("Failed to connect to CAN network\r\n"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Failed to connect to CAN network\r\n"); return 1; } - // Display Loop + // Main loop while (true) { // Process the voltage hib.process(); @@ -105,40 +110,42 @@ int main() { // Try to send the message result = can.transmit(transmit_message); if (result !=io::CAN::CANStatus::OK) { - uart.printf("Failed to transmit message\r\n"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Failed to transmit message\r\n"); return 1; } // Try to receive the message result = can.receive(&received_message, false); if (result != io::CAN::CANStatus::OK) { - uart.printf("Failed to receive message\r\n"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Failed to receive message\r\n"); continue; } + // Give the state of the payload + // Count is counting the number of loops if (count >= 2000) { - uart.printf("\033[2J\033[H"); + // uart.printf("\033[2J\033[H"); // Check if data was received if (received_message.getDataLength() == 0) { - uart.printf("Message filtered out!"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Message filtered out!"); } else { const uint8_t* message_payload = received_message.getPayload(); - uart.printf("CAN payload: \033[32m"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "CAN payload: \033[32m"); for (int i = 0; i < received_message.getDataLength(); i++) { - uart.printf("0x%02X ", message_payload[i]); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"0x%02X ", message_payload[i]); } - uart.printf("\r\n\033[37mHIB payload: \033[34m"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"\r\n\033[37mHIB payload: \033[34m"); for (int i = 0; i < received_message.getDataLength(); i++) { - uart.printf("0x%02X ", hib.payload[i]); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"0x%02X ", hib.payload[i]); } - uart.printf("\r\n\033[37m"); - uart.printf("Throttle Voltage: %i mV\r\n", message_payload[0] << 8 | message_payload[1]); - uart.printf("Error Code: %i\r\n", message_payload[4]); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"\r\n\033[37m"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Throttle Voltage: %i mV\r\n", (message_payload[0] << 8 | message_payload[1])); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Error Code: %i\r\n", message_payload[4]); } count = 0; From b0cdaa72d301afa33e11b5d0f407f03bf7c3c6e6 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 1 Nov 2025 13:37:09 -0400 Subject: [PATCH 24/47] Altered Clang-Format path in the cmake file --- include/HIB.hpp | 6 ++-- include/dev/RedundantADC.hpp | 2 +- libs/EVT-core | 2 +- src/HIB.cpp | 5 ++- src/dev/ADS8689IPWR.cpp | 24 +++++-------- src/dev/RedundantADC.cpp | 44 +++++++++++------------- targets/REV3-HIB/main.cpp | 66 +++++++++++++++--------------------- 7 files changed, 63 insertions(+), 86 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index e423234..22d1fae 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -1,6 +1,4 @@ #pragma once -#include -#include #include #include @@ -25,8 +23,8 @@ class HIB { void process(); uint8_t payload[payloadLength]; - uint32_t throttleVoltage = 0; - uint32_t brakeVoltage = 0; + uint16_t throttleVoltage = 0; + uint16_t brakeVoltage = 0; // Counters for throttle errors uint64_t acceptableThrottleMarginErrors = 0; diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index f54ecfc..ca01d87 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -43,7 +43,7 @@ class RedundantADC { * @param[out] return_val Reference to the variable to store the value read from the ADCs * @return RedundantADC::Status The status of the processing. */ - RedundantADC::Status read(uint32_t& return_val) const; + RedundantADC::Status read(uint16_t& return_val) const; private: /** Reference to the first ADC. */ diff --git a/libs/EVT-core b/libs/EVT-core index 5e94372..2a4abc3 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit 5e943729415298676a1bc7b0bf3772f263172875 +Subproject commit 2a4abc3798b77d251106675a35d07c3a75575fb9 diff --git a/src/HIB.cpp b/src/HIB.cpp index 041afa4..29f17de 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -1,6 +1,5 @@ #include #include -#include namespace HIB { @@ -18,11 +17,11 @@ void HIB::process() { readThrottleVoltage(); // readBrakeVoltage(); - if (throttleVoltage < 300) { + if (throttleVoltage < 475) { throttleVoltage = 0; } - if (brakeVoltage < 300) { + if (brakeVoltage < 450) { brakeVoltage = 0; } diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index 1af2898..88bfbc6 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -1,6 +1,5 @@ #include #include -#include namespace HIB::DEV { @@ -17,24 +16,19 @@ ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), d spi.endTransmission(deviceNumber); } -uint16_t ADS8689IPWR::read() const { - uint8_t bytes[4]; +// Oleg function (old read was narrowing uint32 -> uint8 or uint16) +uint16_t ADS8689IPWR::read() const{ + uint8_t bytes[4] = {0}; spi.startTransmission(deviceNumber); spi.read(bytes, 4); spi.endTransmission(deviceNumber); - // First byte is MSB - uint32_t voltage = (bytes[0] << 8) + bytes[1]; - - // Normalize the received info (divide by uint16_t(MAX)) and scale accordingly - voltage = voltage * VOLTAGE_MAX / UINT16_MAX; - static int count = 0; - if (count > 2000) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage at the ADS8689IPWR: %i\r\n", voltage); - count = 0; - } - count += 1; - return voltage; + uint16_t raw = (static_cast(bytes[0]) << 8) | static_cast(bytes[1]); + + uint32_t scaled = static_cast(raw) * VOLTAGE_MAX / UINT16_MAX; + + return static_cast(scaled); } + } diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 5d0b866..ae7763d 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -7,42 +7,32 @@ namespace io = core::io; // Percantage differences // Values are 1% and 5% of 12288 Mv respectively not really though -constexpr uint32_t LOW_MARGIN = 400; -constexpr uint32_t HIGH_MARGIN = 800; +constexpr uint16_t LOW_MARGIN = 400; +constexpr uint16_t HIGH_MARGIN = 800; namespace HIB::DEV { RedundantADC::RedundantADC(ADS8689IPWR& adc0, ADS8689IPWR& adc1, ADS8689IPWR& adc2) : adc0(adc0), adc1(adc1), adc2(adc2) {} -RedundantADC::Status RedundantADC::read(uint32_t& return_val) const { +RedundantADC::Status RedundantADC::read(uint16_t& return_val) const { // Read in the millivoltage of each ADC - int32_t adcValues[3]; - adcValues[0] = static_cast(adc0.read()); - adcValues[1] = static_cast(adc1.read()); - adcValues[2] = static_cast(adc2.read()); + int16_t adcValues[3] = {0}; + adcValues[0] = static_cast(adc0.read()); + adcValues[1] = static_cast(adc1.read()); + adcValues[2] = static_cast(adc2.read()); // Calculate average of all ADC millivoltages - const int32_t average = (adcValues[0] + adcValues[1] + adcValues[2]) / 3; - - static int count = 0; - if (count > 2000) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage average at the RedundantADC: %i\r\n", average); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage average at the RedundantADC: %i\r\n", average); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage average at the RedundantADC: %i\r\n", average); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Voltage average at the RedundantADC: %i\r\n", average); - count = 0; - } - count += 1; + const int16_t average = (adcValues[0] + adcValues[1] + adcValues[2]) / 3; // Check for deviation errors. // Formula: |DEVIATION_FROM_AVERAGE| / AVERAGE (NORMALIZED) * 100 TO SCALE UP PERCENTAGE FROM 0.01 TO 1 - const bool adc0underLow = static_cast(std::abs(adcValues[0] - average)) < LOW_MARGIN; - const bool adc1underLow = static_cast(std::abs(adcValues[1] - average)) < LOW_MARGIN; - const bool adc2underLow = static_cast(std::abs(adcValues[2] - average)) < LOW_MARGIN; + const bool adc0underLow = static_cast(std::abs(adcValues[0] - average)) < LOW_MARGIN; + const bool adc1underLow = static_cast(std::abs(adcValues[1] - average)) < LOW_MARGIN; + const bool adc2underLow = static_cast(std::abs(adcValues[2] - average)) < LOW_MARGIN; - const bool adc0underHigh = static_cast(std::abs(adcValues[0] - average)) < HIGH_MARGIN; - const bool adc1underHigh = static_cast(std::abs(adcValues[1] - average)) < HIGH_MARGIN; - const bool adc2underHigh = static_cast(std::abs(adcValues[2] - average)) < HIGH_MARGIN; + const bool adc0underHigh = static_cast(std::abs(adcValues[0] - average)) < HIGH_MARGIN; + const bool adc1underHigh = static_cast(std::abs(adcValues[1] - average)) < HIGH_MARGIN; + const bool adc2underHigh = static_cast(std::abs(adcValues[2] - average)) < HIGH_MARGIN; // Check for redundancy const bool allUnderLow = adc0underLow && adc1underLow && adc2underLow; @@ -81,6 +71,12 @@ RedundantADC::Status RedundantADC::read(uint32_t& return_val) const { } return_val = 0; + + // Zero out adc's + adcValues[0] = 0; + adcValues[1] = 0; + adcValues[2] = 0; + return RedundantADC::Status::COMPARISON_ERROR; } diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 3638c8b..6bad268 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -22,11 +21,15 @@ io::GPIO* throttleDevices[deviceCount]; io::GPIO* brakeDevices[deviceCount]; void canIRQHandler(io::CANMessage& message, void* priv) { - io::UART* uart = (io::UART*) priv; - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message received\r\n"); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message id: 0x%X \r\n", message.getId()); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message length: %d\r\n", message.getDataLength()); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message contents: "); + core::log::LOGGER.log( + core::log::Logger::LogLevel::INFO, + "Message received\r\n" + "Message id: 0x%X \r\n" + "Message length: %d\r\n" + "Message contents: ", + message.getId(), + message.getDataLength() + ); uint8_t* message_payload = message.getPayload(); for (int i = 0; i < message.getDataLength(); i++) { @@ -36,9 +39,6 @@ void canIRQHandler(io::CANMessage& message, void* priv) { } int main() { - // Count for the number of iterations of the process - uint64_t count = 0; - // Initialize system core::platform::init(); @@ -88,7 +88,6 @@ int main() { // Try to join the network io::CAN::CANStatus result = can.connect(); - can.enableEmergencyFilter(ENABLE); // Begin CAN Tests core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Starting CAN testing\r\n"); @@ -121,37 +120,28 @@ int main() { continue; } - // Give the state of the payload - // Count is counting the number of loops - if (count >= 2000) { - // uart.printf("\033[2J\033[H"); - // Check if data was received - if (received_message.getDataLength() == 0) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Message filtered out!"); + // uart.printf("\033[2J\033[H"); + // Check if data was received + if (received_message.getDataLength() == 0) { + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message filtered out!\r\n"); + } else { + // + const uint8_t* message_payload = received_message.getPayload(); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "CAN payload: \033[32m"); + + for (int i = 0; i < received_message.getDataLength(); i++) { + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "0x%02X ", message_payload[i]); } - else { - const uint8_t* message_payload = received_message.getPayload(); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "CAN payload: \033[32m"); - - for (int i = 0; i < received_message.getDataLength(); i++) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"0x%02X ", message_payload[i]); - } - - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"\r\n\033[37mHIB payload: \033[34m"); - - for (int i = 0; i < received_message.getDataLength(); i++) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"0x%02X ", hib.payload[i]); - } - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"\r\n\033[37m"); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Throttle Voltage: %i mV\r\n", (message_payload[0] << 8 | message_payload[1])); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Error Code: %i\r\n", message_payload[4]); - } - - count = 0; + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, + "\r\n" + "\033[37m" + "Throttle Voltage: %i mV\r\n" + "Throttle Voltage: %i mV\r\n" + "\033[2J\033[H", + message_payload[0] << 8 | message_payload[1], + message_payload[4]); } - - count++; } return 0; From 61d82a6ee34d608a8f2976661045436a79f0439e Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Mon, 3 Nov 2025 18:54:28 -0500 Subject: [PATCH 25/47] Altered Clang-Format path in the cmake file --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index 2a4abc3..f70fe94 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit 2a4abc3798b77d251106675a35d07c3a75575fb9 +Subproject commit f70fe949622032fd0c6a3821136bbef90c264247 From 9b0b1100932316d4351ca43bf52daa4bf539a787 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia <112414791+Ethan-Caracoglia@users.noreply.github.com> Date: Thu, 6 Nov 2025 19:46:57 -0500 Subject: [PATCH 26/47] Apply suggestions from code review Co-authored-by: Diego <119289719+DiegoLHendrix@users.noreply.github.com> Co-authored-by: Rue <61093955+aclowmclaughlin@users.noreply.github.com> Co-authored-by: Matthew Heller <69865851+mjh9585@users.noreply.github.com> --- include/HIB.hpp | 6 ++++-- src/dev/RedundantADC.cpp | 2 +- targets/ADS8689IPWR/main.cpp | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index 22d1fae..e4c9b15 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -1,4 +1,5 @@ -#pragma once +#ifndef _HIB_ +#define _HIB_ #include #include @@ -61,4 +62,5 @@ class HIB { uint8_t data[payloadLength]; }; -}// namespace HIB \ No newline at end of file +}// namespace HIB +#endif \ No newline at end of file diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index ae7763d..39df30d 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -5,7 +5,7 @@ namespace io = core::io; -// Percantage differences +// Percentage differences // Values are 1% and 5% of 12288 Mv respectively not really though constexpr uint16_t LOW_MARGIN = 400; constexpr uint16_t HIGH_MARGIN = 800; diff --git a/targets/ADS8689IPWR/main.cpp b/targets/ADS8689IPWR/main.cpp index 5b9cc45..193a636 100644 --- a/targets/ADS8689IPWR/main.cpp +++ b/targets/ADS8689IPWR/main.cpp @@ -42,11 +42,11 @@ int main() { throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[2]->writePin(io::GPIO::State::HIGH); - // Create the two SPI clusters + // Create the two SPI buses io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); - // Configure the systems + // Configure the buses spiThrottle.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); spiBrake.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); From 127cef7f793682b938da1afd352331d745c87b35 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 17 Jan 2026 14:44:12 -0500 Subject: [PATCH 27/47] Saving progress on dependecy refactor --- include/HIB.hpp | 33 +++++----- include/dev/ADS8689IPWR.hpp | 80 ++++++++++++++++++++--- include/dev/RedundantADC.hpp | 27 +++++--- src/HIB.cpp | 21 ++++--- src/dev/ADS8689IPWR.cpp | 12 ++-- src/dev/RedundantADC.cpp | 27 ++++---- targets/ADS8689IPWR/main.cpp | 60 +++++++----------- targets/REV3-HIB/main.cpp | 115 +++++++++++++--------------------- targets/RedundantADC/main.cpp | 81 ++++++++++++++++++------ 9 files changed, 271 insertions(+), 185 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index e4c9b15..d1240de 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -1,25 +1,30 @@ -#ifndef _HIB_ -#define _HIB_ +#ifndef HIB_ +#define HIB_ + #include -#include -namespace HIB { +using namespace std; -/** - * Counts that when exceeded throw an error to the VC - */ -#define COMPARISON_ERROR_COUNT 1 -#define PRECISION_MARGIN_ERROR_COUNT 3 -#define ACCEPTABLE_MARGIN_ERROR_COUNT 5 +namespace HIB { constexpr size_t payloadLength = 5; /** - * HIB header file + * The Handlebar Interface Board Takes in a 0.0 to 12.0 volt signal from the throttle and brake + * which it then converts to a 16 bit value through its "double-triple" ADC setup. It then sends + * this voltage value along with any error codes that were generated to the Vehicle Control Unit + * (VCU). + * + * It reads in the voltage from either the throttle or the brake through one set of three ADCs + * that communicate with the microcontroller using SPI. After the controller sets up the devices + * they are read in and then averaged and contrasted with the average to find any margin errors. + * + * The data after being correctly parsed and checked for errors is then sent through CAN to the + * VCU for decision-making. */ class HIB { public: - HIB(DEV::RedundantADC& throttle, DEV::RedundantADC& brake); + HIB(RedundantADC& throttle, RedundantADC& brake); void process(); @@ -42,8 +47,8 @@ class HIB { void readBrakeVoltage(); - DEV::RedundantADC& throttle; - DEV::RedundantADC& brake; + RedundantADC& throttle; + RedundantADC& brake; /** * Payload for CAN transmission. diff --git a/include/dev/ADS8689IPWR.hpp b/include/dev/ADS8689IPWR.hpp index 2f1f20d..827f600 100644 --- a/include/dev/ADS8689IPWR.hpp +++ b/include/dev/ADS8689IPWR.hpp @@ -1,19 +1,85 @@ -#pragma once +#ifndef ADS8689IPWR_ +#define ADS8689IPWR_ -#include #include -#define RANGE_SEL_REG 0x14 // R/W Range selection register ---- +/** + * R/W Range selection register for changing the range of the ADC from + */ +#define RANGE_SEL_REG 0x14 + +/** + * The 2 byte value used to change the range selection register from 3V3 to 12V0 when writing to it + */ #define TWELVE_VOLT_SCALER 0b1000 + +/** + * Used for writing to the range selection register to alter the range read in by the ADC + */ #define HALF_WORD_WRITE 0b11010000 + +/** + * Empty byte defined for use in the No-Operation command + */ #define EMPTY_BYTE 0b00000000 + +/** + * Defined No-Operation command + */ #define NOP {EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE} + +/** + * The maximum voltage that can be read in by the ADC | Used for transforming the given 2 bytes + * from the ADC into a usable value that will be sent to the Vehicle Control Unit + */ #define VOLTAGE_MAX 12288 -namespace io = core::io; +/** + * EVT info logger macro + * @param text The formatted text that should be logged out + */ +#define LOG_INFO(text, ...) core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, text, __VA_ARGS__) + +/** + * Brake Chip Select Pins + */ +#define BRAKE_0 io::Pin::PB_9 +#define BRAKE_1 io::Pin::PB_8 +#define BRAKE_2 io::Pin::PB_7 -namespace HIB::DEV { +/** + * Throttle Chip Select Pins + * */ +#define THROTTLE_0 io::Pin::PC_9 +#define THROTTLE_1 io::Pin::PC_8 +#define THROTTLE_2 io::Pin::PC_7 +/** + * The exact speed that the ADCs need to run at + */ +#define SPI_SPEED SPI_SPEED_500KHZ + +/** + * The mode that spi should run in + */ +#define SPI_MODE io::SPI::SPIMode::SPI_MODE0 + +#define BRAKE_SPI_SCK io::Pin::PC_10 +#define BRAKE_SPI_MOSI io::Pin::PC_12 +#define BRAKE_SPI_MISO io::Pin::PC_11 + +#define THROTTLE_SPI_SCK io::Pin::PB_10 +#define THROTTLE_SPI_MOSI io::Pin::PB_15 +#define THROTTLE_SPI_MISO io::Pin::PB_14 + +namespace io = core::io; + +namespace HIB { +/** + * Device driver for the ADS8689IPWR 16-bit ADC. Contains a constructor that runs the necessary + * setup for the device and a read function that reads in the voltage from the ADC and transforms + * it into a useful number (the actual numerical millivoltage) + */ class ADS8689IPWR { public: /** @@ -30,10 +96,10 @@ class ADS8689IPWR { * @param voltage reference to variable that is storing voltage * @return the status of whether the transaction was successful */ - uint16_t read() const; + uint16_t readVoltage() const; private: io::SPI& spi; const uint8_t deviceNumber; }; - }// namespace HIB::DEV +#endif diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index ca01d87..06f9d1a 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -1,15 +1,24 @@ -#pragma once +#ifndef REDUNDANT_ADC_ +#define REDUNDANT_ADC_ #include -namespace io = core::io; +/** + * Defined limits for the amount of times an error can occur before it is a larger issue + */ +#define COMPARISON_ERROR_COUNT 1 +#define PRECISION_MARGIN_ERROR_COUNT 3 +#define ACCEPTABLE_MARGIN_ERROR_COUNT 5 -namespace HIB::DEV { +namespace io = core::io; +namespace HIB { /** - * This class allows processing readings from redundant ADCs and checking for errors + * An object that takes in 3 different ADS8689IPWR objects to read out and compare their output + * voltages. It compares and contrasts these voltages against their average to find the marginal + * error for each of them. If the margin error is a little high, too high, or completely off in + * one or more of the devices then it will return a corresponding error the HIB object. */ - class RedundantADC { public: /** @@ -43,15 +52,13 @@ class RedundantADC { * @param[out] return_val Reference to the variable to store the value read from the ADCs * @return RedundantADC::Status The status of the processing. */ - RedundantADC::Status read(uint16_t& return_val) const; + Status read(uint16_t& return_val) const; private: - /** Reference to the first ADC. */ ADS8689IPWR& adc0; - /** Reference to the second ADC. */ ADS8689IPWR& adc1; - /** Reference to the third ADC. */ ADS8689IPWR& adc2; }; -}// namespace HIB::DEV +} +#endif \ No newline at end of file diff --git a/src/HIB.cpp b/src/HIB.cpp index 29f17de..85abdb5 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -1,9 +1,12 @@ +#include "core/io/CAN.hpp" +#include "core/io/types/CANMessage.hpp" +#include "core/utils/log.hpp" #include #include namespace HIB { -HIB::HIB(DEV::RedundantADC& throttle, DEV::RedundantADC& brake) +HIB::HIB(RedundantADC& throttle, RedundantADC& brake) : throttle(throttle), brake(brake) { // Initialize payload to 0's for (uint8_t i = 0; i < payloadLength; i++) { @@ -62,35 +65,35 @@ void HIB::process() { } void HIB::readThrottleVoltage() { - const DEV::RedundantADC::Status status = throttle.read(throttleVoltage); // gets the errors and voltage from the ADC cluster + const RedundantADC::Status status = throttle.read(throttleVoltage); // gets the errors and voltage from the ADC cluster // Increment the status of each error if it is received - if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + if (status == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { acceptableThrottleMarginErrors++; } - if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + if (status == RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { precisionThrottleMarginErrors++; } - if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { + if (status == RedundantADC::Status::COMPARISON_ERROR) { comparisonThrottleErrors++; } } void HIB::readBrakeVoltage() { - const DEV::RedundantADC::Status status = brake.read(brakeVoltage); // gets the errors and voltage from the ADC cluster + const RedundantADC::Status status = brake.read(brakeVoltage); // gets the errors and voltage from the ADC cluster // Increment the status of each error if it is received - if (status == DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + if (status == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { acceptableBrakeMarginErrors++; } - if (status == DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + if (status == RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { precisionBrakeMarginErrors++; } - if (status == DEV::RedundantADC::Status::COMPARISON_ERROR) { + if (status == RedundantADC::Status::COMPARISON_ERROR) { comparisonBrakeErrors++; } } diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index 88bfbc6..c370f4d 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -1,8 +1,12 @@ #include #include -namespace HIB::DEV { - +namespace HIB { +/** + * + * @param spi + * @param deviceNumber + */ ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), deviceNumber(deviceNumber) { uint8_t message[4] = {HALF_WORD_WRITE, RANGE_SEL_REG, EMPTY_BYTE, TWELVE_VOLT_SCALER}; spi.startTransmission(deviceNumber); @@ -17,7 +21,7 @@ ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), d } // Oleg function (old read was narrowing uint32 -> uint8 or uint16) -uint16_t ADS8689IPWR::read() const{ +uint16_t ADS8689IPWR::readVoltage() const{ uint8_t bytes[4] = {0}; spi.startTransmission(deviceNumber); spi.read(bytes, 4); @@ -29,6 +33,4 @@ uint16_t ADS8689IPWR::read() const{ return static_cast(scaled); } - - } diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 39df30d..92ff5a1 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -1,31 +1,31 @@ -#include -#include #include #include +#include +#include + namespace io = core::io; +using namespace HIB; // Percentage differences -// Values are 1% and 5% of 12288 Mv respectively not really though +// Values are approximately 1% and 5% of 12288 Mv, but "approximately" is a stretch constexpr uint16_t LOW_MARGIN = 400; constexpr uint16_t HIGH_MARGIN = 800; -namespace HIB::DEV { - -RedundantADC::RedundantADC(ADS8689IPWR& adc0, ADS8689IPWR& adc1, ADS8689IPWR& adc2) : adc0(adc0), adc1(adc1), adc2(adc2) {} +RedundantADC::RedundantADC(ADS8689IPWR& adc0, ADS8689IPWR& adc1, ADS8689IPWR& adc2) +: adc0(adc0), adc1(adc1), adc2(adc2) {} RedundantADC::Status RedundantADC::read(uint16_t& return_val) const { // Read in the millivoltage of each ADC int16_t adcValues[3] = {0}; - adcValues[0] = static_cast(adc0.read()); - adcValues[1] = static_cast(adc1.read()); - adcValues[2] = static_cast(adc2.read()); + adcValues[0] = static_cast(adc0.readVoltage()); + adcValues[1] = static_cast(adc1.readVoltage()); + adcValues[2] = static_cast(adc2.readVoltage()); // Calculate average of all ADC millivoltages - const int16_t average = (adcValues[0] + adcValues[1] + adcValues[2]) / 3; + const auto average = static_cast((adcValues[0] + adcValues[1] + adcValues[2]) / 3); - // Check for deviation errors. - // Formula: |DEVIATION_FROM_AVERAGE| / AVERAGE (NORMALIZED) * 100 TO SCALE UP PERCENTAGE FROM 0.01 TO 1 + // Check for deviation errors const bool adc0underLow = static_cast(std::abs(adcValues[0] - average)) < LOW_MARGIN; const bool adc1underLow = static_cast(std::abs(adcValues[1] - average)) < LOW_MARGIN; const bool adc2underLow = static_cast(std::abs(adcValues[2] - average)) < LOW_MARGIN; @@ -38,6 +38,7 @@ RedundantADC::Status RedundantADC::read(uint16_t& return_val) const { const bool allUnderLow = adc0underLow && adc1underLow && adc2underLow; if (average == 0) { + return_val = average; return RedundantADC::Status::OK; } @@ -79,5 +80,3 @@ RedundantADC::Status RedundantADC::read(uint16_t& return_val) const { return RedundantADC::Status::COMPARISON_ERROR; } - -}// namespace HIB::DEV diff --git a/targets/ADS8689IPWR/main.cpp b/targets/ADS8689IPWR/main.cpp index 193a636..e4c0a70 100644 --- a/targets/ADS8689IPWR/main.cpp +++ b/targets/ADS8689IPWR/main.cpp @@ -1,5 +1,7 @@ -#include -#include +/** + * Test target for the ASD8689IPWR Analog to Digital converter. Use this if you just need to + * verify that they are properly taking in and reading out an expected voltage + */ #include #include #include @@ -7,17 +9,16 @@ #include #include #include -#include -namespace io = core::io; +namespace io = core::io; namespace time = core::time; -constexpr uint32_t SPI_SPEED = SPI_SPEED_500KHZ; // 500KHz constexpr uint8_t deviceCount = 3; io::GPIO* throttleDevices[deviceCount]; io::GPIO* brakeDevices[deviceCount]; +namespace HIB { int main() { // Initialize system core::platform::init(); @@ -28,50 +29,37 @@ int main() { core::log::LOGGER.setLogLevel(core::log::Logger::LogLevel::INFO); // Set up each device - brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[0]->writePin(io::GPIO::State::HIGH); - brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[1]->writePin(io::GPIO::State::HIGH); - brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[2]->writePin(io::GPIO::State::HIGH); - throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[0]->writePin(io::GPIO::State::HIGH); - throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[1]->writePin(io::GPIO::State::HIGH); - throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[2]->writePin(io::GPIO::State::HIGH); // Create the two SPI buses - io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); - io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); - - // Configure the buses - spiThrottle.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); - spiBrake.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); + io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); + spiThrottle.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); + io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); + spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); // Create each ADS8689IPWR object - auto throttleADC1 = HIB::DEV::ADS8689IPWR(spiThrottle, 0); - auto throttleADC2 = HIB::DEV::ADS8689IPWR(spiThrottle, 1); - auto throttleADC3 = HIB::DEV::ADS8689IPWR(spiThrottle, 2); - auto brakeADC1 = HIB::DEV::ADS8689IPWR(spiBrake, 0); - auto brakeADC2 = HIB::DEV::ADS8689IPWR(spiBrake, 1); - auto brakeADC3 = HIB::DEV::ADS8689IPWR(spiBrake, 2); - - // Create the Redundant ADC's - auto throttle = HIB::DEV::RedundantADC(throttleADC1, throttleADC2, throttleADC3); - auto brake = HIB::DEV::RedundantADC(brakeADC1, brakeADC2, brakeADC3); - - // Finally create the HIB object to begin processing data - auto hib = HIB::HIB(throttle, brake); + auto throttleAdc1 = ADS8689IPWR(spiThrottle, 0); + auto throttleAdc2 = ADS8689IPWR(spiThrottle, 1); + auto throttleAdc3 = ADS8689IPWR(spiThrottle, 2); + auto brakeAdc1 = ADS8689IPWR(spiBrake, 0); + auto brakeAdc2 = ADS8689IPWR(spiBrake, 1); + auto brakeAdc3 = ADS8689IPWR(spiBrake, 2); // main loop while (true) { - hib.process(); - uart.printf("Throttle Voltage: %i mV\r\n", hib.throttleVoltage); - uart.printf("Brake Voltage: %i mV\r\n", hib.brakeVoltage); - uart.printf("Acceptable Errors: %i\r\n", hib.acceptableThrottleMarginErrors); - uart.printf("Precision Errors: %i\r\n", hib.precisionThrottleMarginErrors); - uart.printf("Comparison Errors: %i\r\n", hib.comparisonThrottleErrors); + return 0; } +} } \ No newline at end of file diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 6bad268..09aa54a 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -1,25 +1,24 @@ +/** + * REV3-HIB main target. + */ + #include -#include +#include +#include +#include +#include #include #include #include -#include -#include -#include -#include namespace io = core::io; -namespace devh = HIB::DEV; -namespace hib = HIB; -constexpr uint32_t SPI_SPEED = SPI_SPEED_500KHZ; // 500KHz constexpr uint8_t deviceCount = 3; -#define ADS8689IPWR_RANGE_SEL_REG 0x14 // R/W Range selection register ---- - io::GPIO* throttleDevices[deviceCount]; io::GPIO* brakeDevices[deviceCount]; +namespace HIB { void canIRQHandler(io::CANMessage& message, void* priv) { core::log::LOGGER.log( core::log::Logger::LogLevel::INFO, @@ -52,97 +51,71 @@ int main() { io::CAN& can = io::getCAN(true); // Brake ADC setup - brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[0]->writePin(io::GPIO::State::HIGH); - brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[1]->writePin(io::GPIO::State::HIGH); - brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[2]->writePin(io::GPIO::State::HIGH); - io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); - spiBrake.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); + // Initialize the brake SPI array + io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); + spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); - devh::ADS8689IPWR brakeADC1 = devh::ADS8689IPWR(spiBrake, 0); - devh::ADS8689IPWR brakeADC2 = devh::ADS8689IPWR(spiBrake, 1); - devh::ADS8689IPWR brakeADC3 = devh::ADS8689IPWR(spiBrake, 2); - devh::RedundantADC brake = devh::RedundantADC(brakeADC1, brakeADC2, brakeADC3); + // Initialize each brake ADC and then initialize the redundant ADC + ADS8689IPWR brakeADC1 = ADS8689IPWR(spiBrake, 0); + ADS8689IPWR brakeADC2 = ADS8689IPWR(spiBrake, 1); + ADS8689IPWR brakeADC3 = ADS8689IPWR(spiBrake, 2); + RedundantADC brake = RedundantADC(brakeADC1, brakeADC2, brakeADC3); - // Throttle ADC setup - throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[0]->writePin(io::GPIO::State::HIGH); - throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[1]->writePin(io::GPIO::State::HIGH); - throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[2]->writePin(io::GPIO::State::HIGH); - io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); - spiThrottle.configureSPI(SPI_SPEED, io::SPI::SPIMode::SPI_MODE0, SPI_MSB_FIRST); + // Initialize the throttle SPI array + io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); + spiThrottle.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); - devh::ADS8689IPWR throttleADC1 = devh::ADS8689IPWR(spiThrottle, 0); - devh::ADS8689IPWR throttleADC2 = devh::ADS8689IPWR(spiThrottle, 1); - devh::ADS8689IPWR throttleADC3 = devh::ADS8689IPWR(spiThrottle, 2); - devh::RedundantADC throttle = devh::RedundantADC(throttleADC1, throttleADC2, throttleADC3); + // Initialize each throttle ADC and then initialize the redundant ADC + ADS8689IPWR throttleADC1 = ADS8689IPWR(spiThrottle, 0); + ADS8689IPWR throttleADC2 = ADS8689IPWR(spiThrottle, 1); + ADS8689IPWR throttleADC3 = ADS8689IPWR(spiThrottle, 2); + RedundantADC throttle = RedundantADC(throttleADC1, throttleADC2, throttleADC3); // Finally create the HIB object to begin processing data - hib::HIB hib = hib::HIB(throttle, brake); + HIB hib = HIB(throttle, brake); // Try to join the network io::CAN::CANStatus result = can.connect(); - // Begin CAN Tests - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Starting CAN testing\r\n"); + // ID for HIB is 0x0D0 + io::CANMessage transmit_message(0x0D0, 5, hib.payload, false); - if (result !=io::CAN::CANStatus::OK) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Failed to connect to CAN network\r\n"); - return 1; + // Try to send the message + result = can.transmit(transmit_message); + if (result != io::CAN::CANStatus::OK) { + LOG_INFO("Failed to transmit message\r\n"); } + // Begin CAN Test + LOG_INFO("Starting CAN testing\r\n"); + // Main loop while (true) { // Process the voltage hib.process(); - - // ID for HIB is 0x0D0 - io::CANMessage transmit_message(0x0D0, 5, &hib.payload[0], false); - io::CANMessage received_message; + transmit_message = io::CANMessage(0x0D0, 5, hib.payload, false); // Try to send the message result = can.transmit(transmit_message); - if (result !=io::CAN::CANStatus::OK) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Failed to transmit message\r\n"); - return 1; - } - - // Try to receive the message - result = can.receive(&received_message, false); if (result != io::CAN::CANStatus::OK) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"Failed to receive message\r\n"); - continue; - } - - // uart.printf("\033[2J\033[H"); - // Check if data was received - if (received_message.getDataLength() == 0) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "Message filtered out!\r\n"); - } else { - // - const uint8_t* message_payload = received_message.getPayload(); - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "CAN payload: \033[32m"); - - for (int i = 0; i < received_message.getDataLength(); i++) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "0x%02X ", message_payload[i]); - } - - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, - "\r\n" - "\033[37m" - "Throttle Voltage: %i mV\r\n" - "Throttle Voltage: %i mV\r\n" - "\033[2J\033[H", - message_payload[0] << 8 | message_payload[1], - message_payload[4]); + LOG_INFO("Failed to transmit message\r\n"); } } return 0; +} } \ No newline at end of file diff --git a/targets/RedundantADC/main.cpp b/targets/RedundantADC/main.cpp index 7d04d04..7a76cbe 100644 --- a/targets/RedundantADC/main.cpp +++ b/targets/RedundantADC/main.cpp @@ -1,43 +1,86 @@ -#include -#include -#include -#include +/** + * RedundantADC test target. Run this on the board to test the functionality of the RedundantADC + * class and the physical setup of the two redundant adc setups on thd board + */ +#include +#include +#include +#include #include +#include -namespace IO = EVT::core::IO; -namespace DEV = EVT::core::DEV; +namespace io = core::io; +constexpr uint8_t deviceCount = 3; + +io::GPIO* throttleDevices[deviceCount]; +io::GPIO* brakeDevices[deviceCount]; + +namespace HIB { int main() { // Initialize system - EVT::core::platform::init(); + core::platform::init(); // Setup UART - IO::UART& uart = IO::getUART(9600); - uart.printf("UART initialized\r\n"); + io::UART& uart = io::getUART(9600); + core::log::LOGGER.setUART(&uart); + core::log::LOGGER.setLogLevel(core::log::Logger::LogLevel::INFO); + + // Brake ADC setup + brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[0]->writePin(io::GPIO::State::HIGH); + brakeDevices[1] = &io::getGPIO<:BRAKE_1>(io::GPIO::Direction::OUTPUT); + brakeDevices[1]->writePin(io::GPIO::State::HIGH); + brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + brakeDevices[2]->writePin(io::GPIO::State::HIGH); + + // Initialize the brake SPI array + io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); + spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); - IO::ADC& adc0 = IO::getADC(); - IO::ADC& adc1 = IO::getADC(); - IO::ADC& adc2 = IO::getADC(); + // Initialize each brake ADC and then initialize the redundant ADC + ADS8689IPWR brakeADC1 = ADS8689IPWR(spiBrake, 0); + ADS8689IPWR brakeADC2 = ADS8689IPWR(spiBrake, 1); + ADS8689IPWR brakeADC3 = ADS8689IPWR(spiBrake, 2); + RedundantADC brake = RedundantADC(brakeADC1, brakeADC2, brakeADC3); - // Create RedundantADC object - HIB::DEV::RedundantADC redundantADC(adc0, adc1, adc2); + throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[0]->writePin(io::GPIO::State::HIGH); + throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[1]->writePin(io::GPIO::State::HIGH); + throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); + throttleDevices[2]->writePin(io::GPIO::State::HIGH); + + // Initialize the throttle SPI array + io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); + spiThrottle.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); + + // Initialize each throttle ADC and then initialize the redundant ADC + ADS8689IPWR throttleADC1 = ADS8689IPWR(spiThrottle, 0); + ADS8689IPWR throttleADC2 = ADS8689IPWR(spiThrottle, 1); + ADS8689IPWR throttleADC3 = ADS8689IPWR(spiThrottle, 2); + RedundantADC throttle = RedundantADC(throttleADC1, throttleADC2, throttleADC3); + + // Finally create the HIB object to begin processing data + HIB hib = HIB(throttle, brake); // Variables to store ADC values uint32_t return_val; while (1) { // Process ADC values - HIB::DEV::RedundantADC::Status status = redundantADC.readVoltage(return_val); + RedundantADC::Status status = redundantADC.readVoltage(return_val); //check ADC Statuses0 - if (status == HIB::DEV::RedundantADC::Status::OK) { + if (status == RedundantADC::Status::OK) { uart.printf("Average Voltage Reading %d\r\n", return_val); - } else if (status == HIB::DEV::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + } else if (status == RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { uart.printf("One error detected\r\n"); - } else if (status == HIB::DEV::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + } else if (status == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { uart.printf("Margin error detected\r\n"); - } else if (status == HIB::DEV::RedundantADC::Status::COMPARISON_ERROR) { + } else if (status == RedundantADC::Status::COMPARISON_ERROR) { uart.printf("Comparison error detected\r\n"); } } } +} From 436f26ca2468aa34cbecacd3b2e26232451aa383 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 15:43:01 -0500 Subject: [PATCH 28/47] Refactored a good deal of the code and altered the dependencies so now there should be a straight line of dependence from the HIB to the ADC (HIB inherits RedundantADC inherits ADS8689IPWR) --- .github/workflows/cmake.yml | 2 +- include/HIB.hpp | 74 ++++++++++++++++---------------- include/dev/ADS8689IPWR.hpp | 5 +-- include/dev/RedundantADC.hpp | 8 +++- src/HIB.cpp | 40 ++++++++++-------- src/dev/RedundantADC.cpp | 7 +++- targets/ADS8689IPWR/main.cpp | 21 +++++++--- targets/REV3-HIB/main.cpp | 72 +++++++++++++++++-------------- targets/RedundantADC/main.cpp | 79 ++++++++++++++++++++--------------- 9 files changed, 176 insertions(+), 132 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index fbd8e81..cf21b3d 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -16,7 +16,7 @@ env: jobs: build: # Select the server's operating system - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: # Checkout the repository, including all submodules diff --git a/include/HIB.hpp b/include/HIB.hpp index d1240de..0b2c5d3 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -3,11 +3,10 @@ #include -using namespace std; - namespace HIB { +#define VCU_CAN_ID 0xD0 -constexpr size_t payloadLength = 5; +constexpr size_t payloadLength = 6; /** * The Handlebar Interface Board Takes in a 0.0 to 12.0 volt signal from the throttle and brake @@ -26,22 +25,31 @@ class HIB { public: HIB(RedundantADC& throttle, RedundantADC& brake); - void process(); - - uint8_t payload[payloadLength]; - uint16_t throttleVoltage = 0; - uint16_t brakeVoltage = 0; - - // Counters for throttle errors - uint64_t acceptableThrottleMarginErrors = 0; - uint64_t precisionThrottleMarginErrors = 0; - uint64_t comparisonThrottleErrors = 0; - - // Counters for brake errors - uint64_t acceptableBrakeMarginErrors = 0; - uint64_t precisionBrakeMarginErrors = 0; - uint64_t comparisonBrakeErrors = 0; + /** + * Reads the voltages and errors from the redundant ADCs and returns a can message containing + * the data from each read + * @return The can message that should be transmitted + */ + io::CANMessage process(); + /** + * Payload for CAN transmission. + * Byte 0: MSB for Throttle Voltage + * Byte 1: LSB for Throttle Voltage + * Byte 2: MSB for Brake Voltage + * Byte 3: LSB for Brake Voltage + * Byte 4: Error Byte for Throttle + * Byte 5: Error Byte for Brake + * Error Byte Layout: 0: No Error, 1: Precision Error, 2: Margin Error, 3: Comparison Error + */ + struct { + uint8_t throttleVoltageMSB = 0; + uint8_t throttleVoltageLSB = 0; + uint8_t brakeVoltageMSB = 0; + uint8_t brakeVoltageLSB = 0; + uint8_t throttleError = 0; + uint8_t brakeError = 0; + } hibPayload; private: void readThrottleVoltage(); @@ -50,22 +58,18 @@ class HIB { RedundantADC& throttle; RedundantADC& brake; - /** - * Payload for CAN transmission. - * Byte 0: MSB for Throttle Voltage - * Byte 1: LSB for Throttle Voltage - * Byte 2: MSB for Brake Voltage - * Byte 3: LSB for Brake Voltage - * Byte 4: Error Byte for triggering a shutdown - * Byte 4 layout: X X X X X X X X - * 7 6 5 4 3 2 1 0 - * ^ ^ - * | \ - * ________________/ \__________________ - * Brake Error Bit Throttle Error Bit - */ - uint8_t data[payloadLength]; -}; + uint16_t throttleVoltage = 0; + uint16_t brakeVoltage = 0; -}// namespace HIB + // Counters for throttle errors + uint32_t acceptableThrottleMarginErrors = 0; + uint32_t precisionThrottleMarginErrors = 0; + uint32_t comparisonThrottleErrors = 0; + + // Counters for brake errors + uint32_t acceptableBrakeMarginErrors = 0; + uint32_t precisionBrakeMarginErrors = 0; + uint32_t comparisonBrakeErrors = 0; +}; +} #endif \ No newline at end of file diff --git a/include/dev/ADS8689IPWR.hpp b/include/dev/ADS8689IPWR.hpp index 827f600..93145cf 100644 --- a/include/dev/ADS8689IPWR.hpp +++ b/include/dev/ADS8689IPWR.hpp @@ -4,7 +4,7 @@ #include /** - * R/W Range selection register for changing the range of the ADC from + * Read/Write Range selection register for changing the range of the ADC to 0V-12V */ #define RANGE_SEL_REG 0x14 @@ -93,7 +93,6 @@ class ADS8689IPWR { /** * Reads out the voltage from the ADC with a blank command through SPI * - * @param voltage reference to variable that is storing voltage * @return the status of whether the transaction was successful */ uint16_t readVoltage() const; @@ -101,5 +100,5 @@ class ADS8689IPWR { io::SPI& spi; const uint8_t deviceNumber; }; -}// namespace HIB::DEV +} #endif diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index 06f9d1a..e8a27fd 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -4,12 +4,18 @@ #include /** - * Defined limits for the amount of times an error can occur before it is a larger issue + * Defined limits for the amount of times an error can occur before a restart is required */ #define COMPARISON_ERROR_COUNT 1 #define PRECISION_MARGIN_ERROR_COUNT 3 #define ACCEPTABLE_MARGIN_ERROR_COUNT 5 +/** + * CAN TX and RX pins + */ +#define CAN_TX io::Pin::PA_12 +#define CAN_RX io::Pin::PA_11 + namespace io = core::io; namespace HIB { diff --git a/src/HIB.cpp b/src/HIB.cpp index 85abdb5..335e399 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -1,4 +1,3 @@ -#include "core/io/CAN.hpp" #include "core/io/types/CANMessage.hpp" #include "core/utils/log.hpp" #include @@ -7,15 +6,10 @@ namespace HIB { HIB::HIB(RedundantADC& throttle, RedundantADC& brake) - : throttle(throttle), brake(brake) { - // Initialize payload to 0's - for (uint8_t i = 0; i < payloadLength; i++) { - payload[i] = 0; - } -} + : throttle(throttle), brake(brake) {} // Reads the 2 sets of 3 ADCs and processes their errors while packaging them for CAN -void HIB::process() { +io::CANMessage HIB::process() { // Read in the voltages from the throttle readThrottleVoltage(); // readBrakeVoltage(); @@ -28,40 +22,50 @@ void HIB::process() { brakeVoltage = 0; } - payload[0] = static_cast(throttleVoltage >> 8 & 0xFF); - payload[1] = static_cast(throttleVoltage & 0xFF); - payload[2] = static_cast(brakeVoltage >> 8 & 0xFF); - payload[3] = static_cast(brakeVoltage & 0xFF); + hibPayload.throttleVoltageMSB = static_cast(throttleVoltage >> 8 & 0xFF); + hibPayload.throttleVoltageLSB = static_cast(throttleVoltage & 0xFF); + hibPayload.brakeVoltageMSB = static_cast(brakeVoltage >> 8 & 0xFF); + hibPayload.brakeVoltageLSB = static_cast(brakeVoltage & 0xFF); if (acceptableThrottleMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) { acceptableThrottleMarginErrors = ACCEPTABLE_MARGIN_ERROR_COUNT + 1; - payload[4] |= 0b01; + hibPayload.throttleError = 1; } if (acceptableBrakeMarginErrors > ACCEPTABLE_MARGIN_ERROR_COUNT) { acceptableBrakeMarginErrors = ACCEPTABLE_MARGIN_ERROR_COUNT + 1; - payload[4] |= 0b10; + hibPayload.brakeError = 1; } if (precisionThrottleMarginErrors > PRECISION_MARGIN_ERROR_COUNT) { precisionThrottleMarginErrors = PRECISION_MARGIN_ERROR_COUNT + 1; - payload[4] |= 0b01; + hibPayload.throttleError = 2; } if (precisionBrakeMarginErrors > PRECISION_MARGIN_ERROR_COUNT) { precisionBrakeMarginErrors = PRECISION_MARGIN_ERROR_COUNT + 1; - payload[4] |= 0b10; + hibPayload.brakeError = 2; } if (comparisonThrottleErrors > COMPARISON_ERROR_COUNT) { comparisonThrottleErrors = COMPARISON_ERROR_COUNT + 1; - payload[4] |= 0b01; + hibPayload.throttleError = 3; } if (comparisonBrakeErrors > COMPARISON_ERROR_COUNT) { comparisonBrakeErrors = COMPARISON_ERROR_COUNT + 1; - payload[4] |= 0b10; + hibPayload.throttleError = 3; } + + uint8_t payload[payloadLength]; + payload[0] = hibPayload.throttleVoltageMSB; + payload[1] = hibPayload.throttleVoltageLSB; + payload[2] = hibPayload.brakeVoltageMSB; + payload[3] = hibPayload.brakeVoltageLSB; + payload[4] = hibPayload.throttleError; + payload[5] = hibPayload.brakeError; + + return {VCU_CAN_ID, payloadLength, payload, false}; } void HIB::readThrottleVoltage() { diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 92ff5a1..3de39ea 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -7,8 +7,11 @@ namespace io = core::io; using namespace HIB; -// Percentage differences -// Values are approximately 1% and 5% of 12288 Mv, but "approximately" is a stretch +/* Percentage differences + * Values are approximately 1% and 5% of 12288 Mv, but "approximately" is a stretch. + * These can be altered as needed in the future after stress testing the ADCs and finding out + * how they perform while running on the bike + */ constexpr uint16_t LOW_MARGIN = 400; constexpr uint16_t HIGH_MARGIN = 800; diff --git a/targets/ADS8689IPWR/main.cpp b/targets/ADS8689IPWR/main.cpp index e4c0a70..8fe0f28 100644 --- a/targets/ADS8689IPWR/main.cpp +++ b/targets/ADS8689IPWR/main.cpp @@ -23,12 +23,12 @@ int main() { // Initialize system core::platform::init(); - // Initialize UART + // Initialize UART and logger io::UART& uart = io::getUART(9600); core::log::LOGGER.setUART(&uart); core::log::LOGGER.setLogLevel(core::log::Logger::LogLevel::INFO); - // Set up each device + // Set up each chip select pin brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[0]->writePin(io::GPIO::State::HIGH); brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); @@ -43,13 +43,13 @@ int main() { throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[2]->writePin(io::GPIO::State::HIGH); - // Create the two SPI buses + // Create the two SPI buses and configure them io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); spiThrottle.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); - // Create each ADS8689IPWR object + // Create all 6 ADS8689IPWR objects auto throttleAdc1 = ADS8689IPWR(spiThrottle, 0); auto throttleAdc2 = ADS8689IPWR(spiThrottle, 1); auto throttleAdc3 = ADS8689IPWR(spiThrottle, 2); @@ -57,9 +57,18 @@ int main() { auto brakeAdc2 = ADS8689IPWR(spiBrake, 1); auto brakeAdc3 = ADS8689IPWR(spiBrake, 2); - // main loop + // Test each adc one by one on loop while (true) { - return 0; + LOG_INFO("Throttle ADC1: %dV\r\n", throttleAdc1.readVoltage()); + LOG_INFO("Throttle ADC2: %dV\r\n", throttleAdc2.readVoltage()); + LOG_INFO("Throttle ADC3: %dV\r\n", throttleAdc3.readVoltage()); + LOG_INFO("Brake ADC1: %dV\r\n", brakeAdc1.readVoltage()); + LOG_INFO("Brake ADC2: %dV\r\n", brakeAdc2.readVoltage()); + LOG_INFO("Brake ADC3: %dV\r\n\r\n", brakeAdc3.readVoltage()); + + time::wait(1000); } + + return 0; } } \ No newline at end of file diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 09aa54a..fdc5a66 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -1,7 +1,14 @@ /** - * REV3-HIB main target. + * REV3-HIB main target. Runs the setup for the SPI, UART, and CAN buses. Creates the ADS8689IPWR, + * RedundantADC, and HIB objects and then runs the hib.process(). Optionally logs out the data stream + * from the HIB if the logger is enabled. + * + * The goal of this device is to read in voltage data from the throttle and the brake through a pair + * of three redundant 16 bit ADCs. These readings are then compared to each other to find the + * average voltage and any substantial errors or offset in the readings of each device. If the + * errors are too great, then the HIB will send an error signal to the VCU, otherwise it just + * data pertaining to the voltage of the break and the throttle */ - #include #include #include @@ -12,16 +19,16 @@ #include namespace io = core::io; +namespace time = core::time; +namespace HIB { constexpr uint8_t deviceCount = 3; io::GPIO* throttleDevices[deviceCount]; io::GPIO* brakeDevices[deviceCount]; -namespace HIB { void canIRQHandler(io::CANMessage& message, void* priv) { - core::log::LOGGER.log( - core::log::Logger::LogLevel::INFO, + LOG_INFO( "Message received\r\n" "Message id: 0x%X \r\n" "Message length: %d\r\n" @@ -41,16 +48,12 @@ int main() { // Initialize system core::platform::init(); - // Initialize UART + // Setup UART io::UART& uart = io::getUART(9600); - core::log::LOGGER.setUART(&uart); core::log::LOGGER.setLogLevel(core::log::Logger::LogLevel::INFO); - // Initialize CAN - io::CAN& can = io::getCAN(true); - - // Brake ADC setup + // Set up each chip select pin brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[0]->writePin(io::GPIO::State::HIGH); brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); @@ -58,16 +61,6 @@ int main() { brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[2]->writePin(io::GPIO::State::HIGH); - // Initialize the brake SPI array - io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); - spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); - - // Initialize each brake ADC and then initialize the redundant ADC - ADS8689IPWR brakeADC1 = ADS8689IPWR(spiBrake, 0); - ADS8689IPWR brakeADC2 = ADS8689IPWR(spiBrake, 1); - ADS8689IPWR brakeADC3 = ADS8689IPWR(spiBrake, 2); - RedundantADC brake = RedundantADC(brakeADC1, brakeADC2, brakeADC3); - throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[0]->writePin(io::GPIO::State::HIGH); throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); @@ -75,24 +68,35 @@ int main() { throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[2]->writePin(io::GPIO::State::HIGH); - // Initialize the throttle SPI array + // Create the two SPI buses io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); spiThrottle.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); + io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); + spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); + + // Create all 6 ADS8689IPWR objects + auto throttleAdc1 = ADS8689IPWR(spiThrottle, 0); + auto throttleAdc2 = ADS8689IPWR(spiThrottle, 1); + auto throttleAdc3 = ADS8689IPWR(spiThrottle, 2); + auto brakeAdc1 = ADS8689IPWR(spiBrake, 0); + auto brakeAdc2 = ADS8689IPWR(spiBrake, 1); + auto brakeAdc3 = ADS8689IPWR(spiBrake, 2); - // Initialize each throttle ADC and then initialize the redundant ADC - ADS8689IPWR throttleADC1 = ADS8689IPWR(spiThrottle, 0); - ADS8689IPWR throttleADC2 = ADS8689IPWR(spiThrottle, 1); - ADS8689IPWR throttleADC3 = ADS8689IPWR(spiThrottle, 2); - RedundantADC throttle = RedundantADC(throttleADC1, throttleADC2, throttleADC3); + // Initialize the 2 redundant ADCs + auto throttle = RedundantADC(throttleAdc1, throttleAdc2, throttleAdc3); + auto brake = RedundantADC(brakeAdc1, brakeAdc2, brakeAdc3); - // Finally create the HIB object to begin processing data + // Initialize the HIB object to begin processing data HIB hib = HIB(throttle, brake); + // Initialize CAN + io::CAN& can = io::getCAN(true); + // Try to join the network io::CAN::CANStatus result = can.connect(); // ID for HIB is 0x0D0 - io::CANMessage transmit_message(0x0D0, 5, hib.payload, false); + io::CANMessage transmit_message(0x0D0, 0, {}, false); // Try to send the message result = can.transmit(transmit_message); @@ -103,17 +107,21 @@ int main() { // Begin CAN Test LOG_INFO("Starting CAN testing\r\n"); - // Main loop + uint8_t payload[6] = {0}; + + // Read voltage and errors and send them through the CAN bus while (true) { // Process the voltage - hib.process(); - transmit_message = io::CANMessage(0x0D0, 5, hib.payload, false); + transmit_message = hib.process(); // Try to send the message result = can.transmit(transmit_message); if (result != io::CAN::CANStatus::OK) { LOG_INFO("Failed to transmit message\r\n"); } + + // Optional delay to make the logs easier to read + // time::wait(5000); } return 0; diff --git a/targets/RedundantADC/main.cpp b/targets/RedundantADC/main.cpp index 7a76cbe..6d0a838 100644 --- a/targets/RedundantADC/main.cpp +++ b/targets/RedundantADC/main.cpp @@ -10,6 +10,7 @@ #include namespace io = core::io; +namespace time = core::time; constexpr uint8_t deviceCount = 3; @@ -21,29 +22,19 @@ int main() { // Initialize system core::platform::init(); - // Setup UART + // Initialize UART and logger io::UART& uart = io::getUART(9600); core::log::LOGGER.setUART(&uart); core::log::LOGGER.setLogLevel(core::log::Logger::LogLevel::INFO); - // Brake ADC setup + // Set up each chip select pin brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[0]->writePin(io::GPIO::State::HIGH); - brakeDevices[1] = &io::getGPIO<:BRAKE_1>(io::GPIO::Direction::OUTPUT); + brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[1]->writePin(io::GPIO::State::HIGH); brakeDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[2]->writePin(io::GPIO::State::HIGH); - // Initialize the brake SPI array - io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); - spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); - - // Initialize each brake ADC and then initialize the redundant ADC - ADS8689IPWR brakeADC1 = ADS8689IPWR(spiBrake, 0); - ADS8689IPWR brakeADC2 = ADS8689IPWR(spiBrake, 1); - ADS8689IPWR brakeADC3 = ADS8689IPWR(spiBrake, 2); - RedundantADC brake = RedundantADC(brakeADC1, brakeADC2, brakeADC3); - throttleDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[0]->writePin(io::GPIO::State::HIGH); throttleDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); @@ -51,36 +42,56 @@ int main() { throttleDevices[2] = &io::getGPIO(io::GPIO::Direction::OUTPUT); throttleDevices[2]->writePin(io::GPIO::State::HIGH); - // Initialize the throttle SPI array + // Create the two SPI buses and configure them io::SPI& spiThrottle = io::getSPI(throttleDevices, deviceCount); spiThrottle.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); + io::SPI& spiBrake = io::getSPI(brakeDevices, deviceCount); + spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); - // Initialize each throttle ADC and then initialize the redundant ADC - ADS8689IPWR throttleADC1 = ADS8689IPWR(spiThrottle, 0); - ADS8689IPWR throttleADC2 = ADS8689IPWR(spiThrottle, 1); - ADS8689IPWR throttleADC3 = ADS8689IPWR(spiThrottle, 2); - RedundantADC throttle = RedundantADC(throttleADC1, throttleADC2, throttleADC3); + // Create all 6 ADS8689IPWR objects + auto throttleAdc1 = ADS8689IPWR(spiThrottle, 0); + auto throttleAdc2 = ADS8689IPWR(spiThrottle, 1); + auto throttleAdc3 = ADS8689IPWR(spiThrottle, 2); + auto brakeAdc1 = ADS8689IPWR(spiBrake, 0); + auto brakeAdc2 = ADS8689IPWR(spiBrake, 1); + auto brakeAdc3 = ADS8689IPWR(spiBrake, 2); - // Finally create the HIB object to begin processing data - HIB hib = HIB(throttle, brake); + // Initialize the two redundant ADCs + auto throttle = RedundantADC(throttleAdc1, throttleAdc2, throttleAdc3); + auto brake = RedundantADC(brakeAdc1, brakeAdc2, brakeAdc3); - // Variables to store ADC values - uint32_t return_val; + // Declare voltage variables + uint16_t throttleVoltage = 0; + uint16_t brakeVoltage = 0; - while (1) { + while (true) { // Process ADC values - RedundantADC::Status status = redundantADC.readVoltage(return_val); + RedundantADC::Status throttleStatus = throttle.read(throttleVoltage); + RedundantADC::Status brakeStatus = brake.read(brakeVoltage); + + //check ADC Statuses + if (throttleStatus == RedundantADC::Status::OK) { + LOG_INFO("Throttle Average Voltage Reading: %dV\r\n", throttleVoltage); + } else if (throttleStatus == RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + LOG_INFO("Throttle Precision error detected\r\n"); + } else if (throttleStatus == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + LOG_INFO("Throttle Margin error detected\r\n"); + } else if (throttleStatus == RedundantADC::Status::COMPARISON_ERROR) { + LOG_INFO("Throttle Comparison error detected\r\n"); + } - //check ADC Statuses0 - if (status == RedundantADC::Status::OK) { - uart.printf("Average Voltage Reading %d\r\n", return_val); - } else if (status == RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { - uart.printf("One error detected\r\n"); - } else if (status == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { - uart.printf("Margin error detected\r\n"); - } else if (status == RedundantADC::Status::COMPARISON_ERROR) { - uart.printf("Comparison error detected\r\n"); + //check ADC Statuses + if (brakeStatus == RedundantADC::Status::OK) { + LOG_INFO("Brake Average Voltage Reading: %dV\r\n", brakeVoltage); + } else if (brakeStatus == RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + LOG_INFO("Brake Precision error detected\r\n"); + } else if (brakeStatus == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + LOG_INFO("Brake Margin error detected\r\n"); + } else if (brakeStatus == RedundantADC::Status::COMPARISON_ERROR) { + LOG_INFO("Brake Comparison error detected\r\n\r\n"); } + + time::wait(1000); } } } From c9adcbe84158e5622906f09aeeb17cc179d5fc31 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 15:52:51 -0500 Subject: [PATCH 29/47] Fixed the macro and include errors for size_t --- include/HIB.hpp | 4 ++++ include/dev/ADS8689IPWR.hpp | 2 +- src/HIB.cpp | 3 ++- targets/REV3-HIB/main.cpp | 2 -- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index 0b2c5d3..38dc8e0 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -2,6 +2,10 @@ #define HIB_ #include +#include "core/io/types/CANMessage.hpp" +#include + +namespace io = core::io; namespace HIB { #define VCU_CAN_ID 0xD0 diff --git a/include/dev/ADS8689IPWR.hpp b/include/dev/ADS8689IPWR.hpp index 93145cf..870433b 100644 --- a/include/dev/ADS8689IPWR.hpp +++ b/include/dev/ADS8689IPWR.hpp @@ -38,7 +38,7 @@ * EVT info logger macro * @param text The formatted text that should be logged out */ -#define LOG_INFO(text, ...) core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, text, __VA_ARGS__) +#define LOG_INFO(text, ...) core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, text, ##__VA_ARGS__) /** * Brake Chip Select Pins diff --git a/src/HIB.cpp b/src/HIB.cpp index 335e399..7909b04 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -1,8 +1,9 @@ -#include "core/io/types/CANMessage.hpp" #include "core/utils/log.hpp" #include #include +namespace io = core::io; + namespace HIB { HIB::HIB(RedundantADC& throttle, RedundantADC& brake) diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index fdc5a66..4d7974b 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -107,8 +107,6 @@ int main() { // Begin CAN Test LOG_INFO("Starting CAN testing\r\n"); - uint8_t payload[6] = {0}; - // Read voltage and errors and send them through the CAN bus while (true) { // Process the voltage From eeecdf70306fa05b9a0e397535887e2ce985b4a2 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 21:40:06 -0500 Subject: [PATCH 30/47] Attempting to fix build error by only building f446 --- .github/workflows/cmake.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index cf21b3d..ce1e0eb 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -34,14 +34,9 @@ jobs: sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-12 10000 # Build the code for all supported chips - - name: F302 Build + - name: F446 Build run: | - cmake -DTARGET_DEV=STM32F302x8 -B ${{github.workspace}}/build - cmake --build ${{github.workspace}}/build - - - name: F334 Build - run: | - cmake -DTARGET_DEV=STM32F334x8 -B ${{github.workspace}}/build + cmake -DTARGET_DEV=STM32F446xx -B ${{github.workspace}}/build cmake --build ${{github.workspace}}/build # Apply clang-format formatting to the branch and create a new commit if any files are changed From 8233985c8e5e8fe94d69b7c8a65b31aa296494f8 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 21:47:31 -0500 Subject: [PATCH 31/47] Changed the EVT-core branch back to main --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index f70fe94..2a4abc3 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit f70fe949622032fd0c6a3821136bbef90c264247 +Subproject commit 2a4abc3798b77d251106675a35d07c3a75575fb9 From 6ca79d4f5730872fedb5b659698dc04521d1ae22 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 21:58:23 -0500 Subject: [PATCH 32/47] Took main() out of hib namespace to avoid missing main reference --- targets/REV3-HIB/main.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 4d7974b..9fdaa5b 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -21,7 +21,6 @@ namespace io = core::io; namespace time = core::time; -namespace HIB { constexpr uint8_t deviceCount = 3; io::GPIO* throttleDevices[deviceCount]; @@ -75,19 +74,19 @@ int main() { spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); // Create all 6 ADS8689IPWR objects - auto throttleAdc1 = ADS8689IPWR(spiThrottle, 0); - auto throttleAdc2 = ADS8689IPWR(spiThrottle, 1); - auto throttleAdc3 = ADS8689IPWR(spiThrottle, 2); - auto brakeAdc1 = ADS8689IPWR(spiBrake, 0); - auto brakeAdc2 = ADS8689IPWR(spiBrake, 1); - auto brakeAdc3 = ADS8689IPWR(spiBrake, 2); + auto throttleAdc1 = HIB::ADS8689IPWR(spiThrottle, 0); + auto throttleAdc2 = HIB::ADS8689IPWR(spiThrottle, 1); + auto throttleAdc3 = HIB::ADS8689IPWR(spiThrottle, 2); + auto brakeAdc1 = HIB::ADS8689IPWR(spiBrake, 0); + auto brakeAdc2 = HIB::ADS8689IPWR(spiBrake, 1); + auto brakeAdc3 = HIB::ADS8689IPWR(spiBrake, 2); // Initialize the 2 redundant ADCs - auto throttle = RedundantADC(throttleAdc1, throttleAdc2, throttleAdc3); - auto brake = RedundantADC(brakeAdc1, brakeAdc2, brakeAdc3); + auto throttle = HIB::RedundantADC(throttleAdc1, throttleAdc2, throttleAdc3); + auto brake = HIB::RedundantADC(brakeAdc1, brakeAdc2, brakeAdc3); // Initialize the HIB object to begin processing data - HIB hib = HIB(throttle, brake); + auto hib = HIB::HIB(throttle, brake); // Initialize CAN io::CAN& can = io::getCAN(true); @@ -123,5 +122,4 @@ int main() { } return 0; -} } \ No newline at end of file From 904e7ab1aab438e459fbae1db901c1c4b9ada188 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 22:03:19 -0500 Subject: [PATCH 33/47] Sorrowful attempt to fix IWDG compilation error --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index 2a4abc3..9a5a7d1 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit 2a4abc3798b77d251106675a35d07c3a75575fb9 +Subproject commit 9a5a7d137debcd92b96c77f9a97a16e1bd09583b From 12477c9b0f879f31fc6a52ad7f4cbfcb81492bc2 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 22:12:38 -0500 Subject: [PATCH 34/47] Sorrowful attempt to fix IWDG and timer compilation error --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index 9a5a7d1..456e4cb 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit 9a5a7d137debcd92b96c77f9a97a16e1bd09583b +Subproject commit 456e4cb48f05e5592897f7d4fb5831c052144eea From 80af2613a3b6c256e73b5a441303467a9f295d6a Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 22:16:15 -0500 Subject: [PATCH 35/47] Errasign timer sample --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index 456e4cb..68e281b 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit 456e4cb48f05e5592897f7d4fb5831c052144eea +Subproject commit 68e281ba8636541262adb97c1e464cb9d2b0fa5e From a8be3834d38fd28a0287b1b63f75cb724c85e40c Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 22:18:25 -0500 Subject: [PATCH 36/47] Fully erasing timer --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index 68e281b..42c3869 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit 68e281ba8636541262adb97c1e464cb9d2b0fa5e +Subproject commit 42c3869ecedc3b7103c028be472837b422674f8c From e793e3558e66cd340a214b9bb359e65fb121fefc Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 23:38:24 -0500 Subject: [PATCH 37/47] Trying to get the build to work by converting the build back to normal ubuntu --- .github/workflows/cmake.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index ce1e0eb..5873223 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -16,7 +16,7 @@ env: jobs: build: # Select the server's operating system - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: # Checkout the repository, including all submodules From 546606c89844522633a9349649fd2b9607cf964d Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 23:40:38 -0500 Subject: [PATCH 38/47] Reverting last change --- .github/workflows/cmake.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 5873223..ce1e0eb 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -16,7 +16,7 @@ env: jobs: build: # Select the server's operating system - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: # Checkout the repository, including all submodules From 346257a19fe794f84a576a8410ced8b945539fe2 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sat, 24 Jan 2026 23:44:28 -0500 Subject: [PATCH 39/47] Chained EVT-core target --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index 42c3869..2a4abc3 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit 42c3869ecedc3b7103c028be472837b422674f8c +Subproject commit 2a4abc3798b77d251106675a35d07c3a75575fb9 From 3121aa58c8c039bd7442b93b483e4d6b4715a77f Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sun, 25 Jan 2026 22:57:16 -0500 Subject: [PATCH 40/47] Updated github workflow and main to read out can connect result --- .github/workflows/cmake.yml | 12 ++++++------ targets/REV3-HIB/main.cpp | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index ce1e0eb..e43cf2a 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -16,7 +16,7 @@ env: jobs: build: # Select the server's operating system - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: # Checkout the repository, including all submodules @@ -26,17 +26,17 @@ jobs: ref: ${{ github.event.pull_request.head.ref }} submodules: recursive - # Install the gcc-arm tools and clang-format, and ensure clang-format 12 is being used + # Install the gcc-arm tools and clang-format, and ensure clang-format 15 is being used - name: Install Compiler and Linter run: | sudo apt-get install gcc-arm-none-eabi - sudo apt-get install clang-format-12 - sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-12 10000 + sudo apt-get install clang-format-15 + sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-15 10000 # Build the code for all supported chips - - name: F446 Build + - name: Project Build run: | - cmake -DTARGET_DEV=STM32F446xx -B ${{github.workspace}}/build + cmake -B ${{github.workspace}}/build cmake --build ${{github.workspace}}/build # Apply clang-format formatting to the branch and create a new commit if any files are changed diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 9fdaa5b..b521700 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -93,6 +93,9 @@ int main() { // Try to join the network io::CAN::CANStatus result = can.connect(); + if (result != io::CAN::CANStatus::OK) { + LOG_INFO("Failed to connect to the CAN network.\r\n"); + } // ID for HIB is 0x0D0 io::CANMessage transmit_message(0x0D0, 0, {}, false); From 67a4416466785755db8979e6cba06ac0f455d372 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sun, 25 Jan 2026 23:02:47 -0500 Subject: [PATCH 41/47] Removed all samples to fix compile errors --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index 2a4abc3..599d05f 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit 2a4abc3798b77d251106675a35d07c3a75575fb9 +Subproject commit 599d05f1d915f0a9d3b77269819c1c5572a1cc24 From c8d49dd07d4e2bf82d666738e3c1ce8e2aabdaaa Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sun, 25 Jan 2026 23:07:46 -0500 Subject: [PATCH 42/47] Fixed namespace errors faulting on main() --- targets/ADS8689IPWR/main.cpp | 14 ++++++------- targets/RedundantADC/main.cpp | 38 +++++++++++++++++------------------ 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/targets/ADS8689IPWR/main.cpp b/targets/ADS8689IPWR/main.cpp index 8fe0f28..6ba27d5 100644 --- a/targets/ADS8689IPWR/main.cpp +++ b/targets/ADS8689IPWR/main.cpp @@ -18,7 +18,6 @@ constexpr uint8_t deviceCount = 3; io::GPIO* throttleDevices[deviceCount]; io::GPIO* brakeDevices[deviceCount]; -namespace HIB { int main() { // Initialize system core::platform::init(); @@ -50,12 +49,12 @@ int main() { spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); // Create all 6 ADS8689IPWR objects - auto throttleAdc1 = ADS8689IPWR(spiThrottle, 0); - auto throttleAdc2 = ADS8689IPWR(spiThrottle, 1); - auto throttleAdc3 = ADS8689IPWR(spiThrottle, 2); - auto brakeAdc1 = ADS8689IPWR(spiBrake, 0); - auto brakeAdc2 = ADS8689IPWR(spiBrake, 1); - auto brakeAdc3 = ADS8689IPWR(spiBrake, 2); + auto throttleAdc1 = HIB::ADS8689IPWR(spiThrottle, 0); + auto throttleAdc2 = HIB::ADS8689IPWR(spiThrottle, 1); + auto throttleAdc3 = HIB::ADS8689IPWR(spiThrottle, 2); + auto brakeAdc1 = HIB::ADS8689IPWR(spiBrake, 0); + auto brakeAdc2 = HIB::ADS8689IPWR(spiBrake, 1); + auto brakeAdc3 = HIB::ADS8689IPWR(spiBrake, 2); // Test each adc one by one on loop while (true) { @@ -70,5 +69,4 @@ int main() { } return 0; -} } \ No newline at end of file diff --git a/targets/RedundantADC/main.cpp b/targets/RedundantADC/main.cpp index 6d0a838..66c983c 100644 --- a/targets/RedundantADC/main.cpp +++ b/targets/RedundantADC/main.cpp @@ -17,7 +17,6 @@ constexpr uint8_t deviceCount = 3; io::GPIO* throttleDevices[deviceCount]; io::GPIO* brakeDevices[deviceCount]; -namespace HIB { int main() { // Initialize system core::platform::init(); @@ -49,16 +48,16 @@ int main() { spiBrake.configureSPI(SPI_SPEED, SPI_MODE, SPI_MSB_FIRST); // Create all 6 ADS8689IPWR objects - auto throttleAdc1 = ADS8689IPWR(spiThrottle, 0); - auto throttleAdc2 = ADS8689IPWR(spiThrottle, 1); - auto throttleAdc3 = ADS8689IPWR(spiThrottle, 2); - auto brakeAdc1 = ADS8689IPWR(spiBrake, 0); - auto brakeAdc2 = ADS8689IPWR(spiBrake, 1); - auto brakeAdc3 = ADS8689IPWR(spiBrake, 2); + auto throttleAdc1 = HIB::ADS8689IPWR(spiThrottle, 0); + auto throttleAdc2 = HIB::ADS8689IPWR(spiThrottle, 1); + auto throttleAdc3 = HIB::ADS8689IPWR(spiThrottle, 2); + auto brakeAdc1 = HIB::ADS8689IPWR(spiBrake, 0); + auto brakeAdc2 = HIB::ADS8689IPWR(spiBrake, 1); + auto brakeAdc3 = HIB::ADS8689IPWR(spiBrake, 2); // Initialize the two redundant ADCs - auto throttle = RedundantADC(throttleAdc1, throttleAdc2, throttleAdc3); - auto brake = RedundantADC(brakeAdc1, brakeAdc2, brakeAdc3); + auto throttle = HIB::RedundantADC(throttleAdc1, throttleAdc2, throttleAdc3); + auto brake = HIB::RedundantADC(brakeAdc1, brakeAdc2, brakeAdc3); // Declare voltage variables uint16_t throttleVoltage = 0; @@ -66,32 +65,31 @@ int main() { while (true) { // Process ADC values - RedundantADC::Status throttleStatus = throttle.read(throttleVoltage); - RedundantADC::Status brakeStatus = brake.read(brakeVoltage); + HIB::RedundantADC::Status throttleStatus = throttle.read(throttleVoltage); + HIB::RedundantADC::Status brakeStatus = brake.read(brakeVoltage); //check ADC Statuses - if (throttleStatus == RedundantADC::Status::OK) { + if (throttleStatus == HIB::RedundantADC::Status::OK) { LOG_INFO("Throttle Average Voltage Reading: %dV\r\n", throttleVoltage); - } else if (throttleStatus == RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + } else if (throttleStatus == HIB::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { LOG_INFO("Throttle Precision error detected\r\n"); - } else if (throttleStatus == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + } else if (throttleStatus == HIB::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { LOG_INFO("Throttle Margin error detected\r\n"); - } else if (throttleStatus == RedundantADC::Status::COMPARISON_ERROR) { + } else if (throttleStatus == HIB::RedundantADC::Status::COMPARISON_ERROR) { LOG_INFO("Throttle Comparison error detected\r\n"); } //check ADC Statuses - if (brakeStatus == RedundantADC::Status::OK) { + if (brakeStatus == HIB::RedundantADC::Status::OK) { LOG_INFO("Brake Average Voltage Reading: %dV\r\n", brakeVoltage); - } else if (brakeStatus == RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { + } else if (brakeStatus == HIB::RedundantADC::Status::PRECISION_MARGIN_EXCEEDED) { LOG_INFO("Brake Precision error detected\r\n"); - } else if (brakeStatus == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { + } else if (brakeStatus == HIB::RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { LOG_INFO("Brake Margin error detected\r\n"); - } else if (brakeStatus == RedundantADC::Status::COMPARISON_ERROR) { + } else if (brakeStatus == HIB::RedundantADC::Status::COMPARISON_ERROR) { LOG_INFO("Brake Comparison error detected\r\n\r\n"); } time::wait(1000); } } -} From e3b4f32f3d067081b89557da023884c8eab4671b Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Sun, 25 Jan 2026 23:17:52 -0500 Subject: [PATCH 43/47] Messed around with clang-format issue --- libs/EVT-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/EVT-core b/libs/EVT-core index 599d05f..2b03616 160000 --- a/libs/EVT-core +++ b/libs/EVT-core @@ -1 +1 @@ -Subproject commit 599d05f1d915f0a9d3b77269819c1c5572a1cc24 +Subproject commit 2b036169c6ca442970b0e3965e74f44927d1b581 From f407ffb7ae672fbcb142ebd4e638223e22ed7a2f Mon Sep 17 00:00:00 2001 From: GitHub Build Date: Mon, 26 Jan 2026 04:19:06 +0000 Subject: [PATCH 44/47] Applied Formatting Changes During GitHub Build --- include/HIB.hpp | 5 +++-- include/dev/ADS8689IPWR.hpp | 6 ++++-- include/dev/RedundantADC.hpp | 2 +- src/HIB.cpp | 6 +++--- src/dev/ADS8689IPWR.cpp | 4 ++-- src/dev/RedundantADC.cpp | 4 ++-- targets/REV3-HIB/main.cpp | 15 +++++++-------- targets/RedundantADC/main.cpp | 4 ++-- 8 files changed, 24 insertions(+), 22 deletions(-) diff --git a/include/HIB.hpp b/include/HIB.hpp index 38dc8e0..685ebc8 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -1,9 +1,9 @@ #ifndef HIB_ #define HIB_ -#include #include "core/io/types/CANMessage.hpp" #include +#include namespace io = core::io; @@ -54,6 +54,7 @@ class HIB { uint8_t throttleError = 0; uint8_t brakeError = 0; } hibPayload; + private: void readThrottleVoltage(); @@ -75,5 +76,5 @@ class HIB { uint32_t precisionBrakeMarginErrors = 0; uint32_t comparisonBrakeErrors = 0; }; -} +}// namespace HIB #endif \ No newline at end of file diff --git a/include/dev/ADS8689IPWR.hpp b/include/dev/ADS8689IPWR.hpp index 870433b..1ad8648 100644 --- a/include/dev/ADS8689IPWR.hpp +++ b/include/dev/ADS8689IPWR.hpp @@ -26,7 +26,8 @@ /** * Defined No-Operation command */ -#define NOP {EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE} +#define NOP \ + { EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE, EMPTY_BYTE } /** * The maximum voltage that can be read in by the ADC | Used for transforming the given 2 bytes @@ -96,9 +97,10 @@ class ADS8689IPWR { * @return the status of whether the transaction was successful */ uint16_t readVoltage() const; + private: io::SPI& spi; const uint8_t deviceNumber; }; -} +}// namespace HIB #endif diff --git a/include/dev/RedundantADC.hpp b/include/dev/RedundantADC.hpp index e8a27fd..c8bb71e 100644 --- a/include/dev/RedundantADC.hpp +++ b/include/dev/RedundantADC.hpp @@ -66,5 +66,5 @@ class RedundantADC { ADS8689IPWR& adc2; }; -} +}// namespace HIB #endif \ No newline at end of file diff --git a/src/HIB.cpp b/src/HIB.cpp index 7909b04..2c30eb4 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -70,7 +70,7 @@ io::CANMessage HIB::process() { } void HIB::readThrottleVoltage() { - const RedundantADC::Status status = throttle.read(throttleVoltage); // gets the errors and voltage from the ADC cluster + const RedundantADC::Status status = throttle.read(throttleVoltage);// gets the errors and voltage from the ADC cluster // Increment the status of each error if it is received if (status == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { @@ -87,7 +87,7 @@ void HIB::readThrottleVoltage() { } void HIB::readBrakeVoltage() { - const RedundantADC::Status status = brake.read(brakeVoltage); // gets the errors and voltage from the ADC cluster + const RedundantADC::Status status = brake.read(brakeVoltage);// gets the errors and voltage from the ADC cluster // Increment the status of each error if it is received if (status == RedundantADC::Status::ACCEPTABLE_MARGIN_EXCEEDED) { @@ -103,4 +103,4 @@ void HIB::readBrakeVoltage() { } } -} \ No newline at end of file +}// namespace HIB \ No newline at end of file diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index c370f4d..2b4f92a 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -21,7 +21,7 @@ ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), d } // Oleg function (old read was narrowing uint32 -> uint8 or uint16) -uint16_t ADS8689IPWR::readVoltage() const{ +uint16_t ADS8689IPWR::readVoltage() const { uint8_t bytes[4] = {0}; spi.startTransmission(deviceNumber); spi.read(bytes, 4); @@ -33,4 +33,4 @@ uint16_t ADS8689IPWR::readVoltage() const{ return static_cast(scaled); } -} +}// namespace HIB diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 3de39ea..70434b9 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -1,8 +1,8 @@ #include #include -#include #include +#include namespace io = core::io; using namespace HIB; @@ -16,7 +16,7 @@ constexpr uint16_t LOW_MARGIN = 400; constexpr uint16_t HIGH_MARGIN = 800; RedundantADC::RedundantADC(ADS8689IPWR& adc0, ADS8689IPWR& adc1, ADS8689IPWR& adc2) -: adc0(adc0), adc1(adc1), adc2(adc2) {} + : adc0(adc0), adc1(adc1), adc2(adc2) {} RedundantADC::Status RedundantADC::read(uint16_t& return_val) const { // Read in the millivoltage of each ADC diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index b521700..d646ccd 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -10,13 +10,13 @@ * data pertaining to the voltage of the break and the throttle */ #include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include namespace io = core::io; namespace time = core::time; @@ -33,14 +33,13 @@ void canIRQHandler(io::CANMessage& message, void* priv) { "Message length: %d\r\n" "Message contents: ", message.getId(), - message.getDataLength() - ); + message.getDataLength()); uint8_t* message_payload = message.getPayload(); for (int i = 0; i < message.getDataLength(); i++) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"0x%02X ", message_payload[i]); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "0x%02X ", message_payload[i]); } - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO,"\r\n\r\n"); + core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "\r\n\r\n"); } int main() { diff --git a/targets/RedundantADC/main.cpp b/targets/RedundantADC/main.cpp index 66c983c..dc697c8 100644 --- a/targets/RedundantADC/main.cpp +++ b/targets/RedundantADC/main.cpp @@ -2,12 +2,12 @@ * RedundantADC test target. Run this on the board to test the functionality of the RedundantADC * class and the physical setup of the two redundant adc setups on thd board */ -#include #include +#include #include #include -#include #include +#include namespace io = core::io; namespace time = core::time; From cc5b0a5cc53430bcc9b6eb2cce7a8b387d42c9f2 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Mon, 23 Feb 2026 19:39:29 -0500 Subject: [PATCH 45/47] Ready to push (I am aware that the GPIO checking for the various Start and Forward Enable pins is commented, I will finish that in due time) --- Changelog.md | 11 +++++++++- include/HIB.hpp | 27 +++++++++++++++++++++++- src/HIB.cpp | 8 ++++---- src/dev/ADS8689IPWR.cpp | 12 +++-------- src/dev/RedundantADC.cpp | 5 ----- targets/REV3-HIB/main.cpp | 43 +++++++++++++++++++-------------------- 6 files changed, 64 insertions(+), 42 deletions(-) diff --git a/Changelog.md b/Changelog.md index 1084b7d..12d14f3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,4 +16,13 @@ Contains notable changes there were added, fixed, or removed in each release. ### Changes -* ADS8689IPWR driver +* ADS8689IPWR driver created and implemented +* RedundantADC driver created and implemented +* HIB driver created and implemented +* Updated README.md +* Created targets for HIB, RedundantADC testing, and ADS88689IPWR testing +* Improved dependency order +* Verified ADC results +* Added error checking for ADCs +* Added logger statements for easier debugging +* Documentation added for each class as well as each target diff --git a/include/HIB.hpp b/include/HIB.hpp index 685ebc8..dc49fbf 100644 --- a/include/HIB.hpp +++ b/include/HIB.hpp @@ -8,7 +8,32 @@ namespace io = core::io; namespace HIB { -#define VCU_CAN_ID 0xD0 +/** + * Id of the message being sent from the HIB + */ +#define HIB_MESSAGE_ID 0xD0 + +/** + * Deadzone for the ADCs so they do not send a signal before the throttle is twisted + */ +#define VOLTAGE_DEADZONE 475 + +/** + * Start Switch + */ +#define START io::Pin::PB_1 + +/** + * Throttle Switch + */ +#define THROTTLE_SWITCH io::Pin::PB_2 + +/** + * Forward Enable + */ +#define FORWARD_ENABLE_0 io::Pin::PB_4 +#define FORWARD_ENABLE_1 io::Pin::PB_5 +#define FORWARD_ENABLE_2 io::Pin::PB_6 constexpr size_t payloadLength = 6; diff --git a/src/HIB.cpp b/src/HIB.cpp index 2c30eb4..5a2b456 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -13,13 +13,13 @@ HIB::HIB(RedundantADC& throttle, RedundantADC& brake) io::CANMessage HIB::process() { // Read in the voltages from the throttle readThrottleVoltage(); - // readBrakeVoltage(); + readBrakeVoltage(); // Brake is currently not implemented, but read the ADCs anyways - if (throttleVoltage < 475) { + if (throttleVoltage < VOLTAGE_DEADZONE) { throttleVoltage = 0; } - if (brakeVoltage < 450) { + if (brakeVoltage < VOLTAGE_DEADZONE) { brakeVoltage = 0; } @@ -66,7 +66,7 @@ io::CANMessage HIB::process() { payload[4] = hibPayload.throttleError; payload[5] = hibPayload.brakeError; - return {VCU_CAN_ID, payloadLength, payload, false}; + return io::CANMessage{HIB_MESSAGE_ID, payloadLength, payload, false}; } void HIB::readThrottleVoltage() { diff --git a/src/dev/ADS8689IPWR.cpp b/src/dev/ADS8689IPWR.cpp index 2b4f92a..ce599bd 100644 --- a/src/dev/ADS8689IPWR.cpp +++ b/src/dev/ADS8689IPWR.cpp @@ -2,11 +2,6 @@ #include namespace HIB { -/** - * - * @param spi - * @param deviceNumber - */ ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), deviceNumber(deviceNumber) { uint8_t message[4] = {HALF_WORD_WRITE, RANGE_SEL_REG, EMPTY_BYTE, TWELVE_VOLT_SCALER}; spi.startTransmission(deviceNumber); @@ -20,16 +15,15 @@ ADS8689IPWR::ADS8689IPWR(io::SPI& spi, const uint8_t deviceNumber) : spi(spi), d spi.endTransmission(deviceNumber); } -// Oleg function (old read was narrowing uint32 -> uint8 or uint16) uint16_t ADS8689IPWR::readVoltage() const { uint8_t bytes[4] = {0}; spi.startTransmission(deviceNumber); - spi.read(bytes, 4); + spi.read(bytes, 2); spi.endTransmission(deviceNumber); - uint16_t raw = (static_cast(bytes[0]) << 8) | static_cast(bytes[1]); + const uint16_t raw = (static_cast(bytes[0]) << 8) | static_cast(bytes[1]); - uint32_t scaled = static_cast(raw) * VOLTAGE_MAX / UINT16_MAX; + const uint32_t scaled = static_cast(raw) * VOLTAGE_MAX / UINT16_MAX; return static_cast(scaled); } diff --git a/src/dev/RedundantADC.cpp b/src/dev/RedundantADC.cpp index 70434b9..03a18c6 100644 --- a/src/dev/RedundantADC.cpp +++ b/src/dev/RedundantADC.cpp @@ -76,10 +76,5 @@ RedundantADC::Status RedundantADC::read(uint16_t& return_val) const { return_val = 0; - // Zero out adc's - adcValues[0] = 0; - adcValues[1] = 0; - adcValues[2] = 0; - return RedundantADC::Status::COMPARISON_ERROR; } diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index d646ccd..6464170 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -26,22 +26,6 @@ constexpr uint8_t deviceCount = 3; io::GPIO* throttleDevices[deviceCount]; io::GPIO* brakeDevices[deviceCount]; -void canIRQHandler(io::CANMessage& message, void* priv) { - LOG_INFO( - "Message received\r\n" - "Message id: 0x%X \r\n" - "Message length: %d\r\n" - "Message contents: ", - message.getId(), - message.getDataLength()); - - uint8_t* message_payload = message.getPayload(); - for (int i = 0; i < message.getDataLength(); i++) { - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "0x%02X ", message_payload[i]); - } - core::log::LOGGER.log(core::log::Logger::LogLevel::INFO, "\r\n\r\n"); -} - int main() { // Initialize system core::platform::init(); @@ -51,7 +35,14 @@ int main() { core::log::LOGGER.setUART(&uart); core::log::LOGGER.setLogLevel(core::log::Logger::LogLevel::INFO); - // Set up each chip select pin + // // Setup GPIO pins for the throttle switch, start, and forward enable + // auto throttleSwitch = &io::getGPIO(io::GPIO::Direction::INPUT); + // auto start = &io::getGPIO(io::GPIO::Direction::INPUT); + // auto forwardEnable0 = &io::getGPIO(io::GPIO::Direction::INPUT); + // auto forwardEnable1 = &io::getGPIO(io::GPIO::Direction::INPUT); + // auto forwardEnable2 = &io::getGPIO(io::GPIO::Direction::INPUT); + + // Set up each chip select pink brakeDevices[0] = &io::getGPIO(io::GPIO::Direction::OUTPUT); brakeDevices[0]->writePin(io::GPIO::State::HIGH); brakeDevices[1] = &io::getGPIO(io::GPIO::Direction::OUTPUT); @@ -103,13 +94,12 @@ int main() { result = can.transmit(transmit_message); if (result != io::CAN::CANStatus::OK) { LOG_INFO("Failed to transmit message\r\n"); + } else { + LOG_INFO("Transmitted message.\r\n"); } - // Begin CAN Test - LOG_INFO("Starting CAN testing\r\n"); - // Read voltage and errors and send them through the CAN bus - while (true) { + while(true) { // Process the voltage transmit_message = hib.process(); @@ -119,7 +109,16 @@ int main() { LOG_INFO("Failed to transmit message\r\n"); } - // Optional delay to make the logs easier to read + // Uncomment to print results through UART when a P-CAN dongle is unavailable + // io::CANMessage message; + // auto status = can.receive(&message); + // uint8_t* payload = message.getPayload(); + // LOG_INFO("Throttle Voltage: %imV\r\n" + // "Brake Voltage: %imV\r\n" + // "Error Information: %x\r\n", + // (payload[0] << 8) + payload[1], + // (payload[2] << 8) + payload[3], + // payload[4]); // time::wait(5000); } From f4d4296ff4c941dee0715ecf02d3560082df660b Mon Sep 17 00:00:00 2001 From: GitHub Build Date: Tue, 24 Feb 2026 00:40:38 +0000 Subject: [PATCH 46/47] Applied Formatting Changes During GitHub Build --- src/HIB.cpp | 2 +- targets/REV3-HIB/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/HIB.cpp b/src/HIB.cpp index 5a2b456..5422620 100644 --- a/src/HIB.cpp +++ b/src/HIB.cpp @@ -13,7 +13,7 @@ HIB::HIB(RedundantADC& throttle, RedundantADC& brake) io::CANMessage HIB::process() { // Read in the voltages from the throttle readThrottleVoltage(); - readBrakeVoltage(); // Brake is currently not implemented, but read the ADCs anyways + readBrakeVoltage();// Brake is currently not implemented, but read the ADCs anyways if (throttleVoltage < VOLTAGE_DEADZONE) { throttleVoltage = 0; diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 6464170..3e9a385 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -99,7 +99,7 @@ int main() { } // Read voltage and errors and send them through the CAN bus - while(true) { + while (true) { // Process the voltage transmit_message = hib.process(); From 79d637510978141341f67870b3d2bda2fb5cb067 Mon Sep 17 00:00:00 2001 From: Ethan-Caracoglia Date: Mon, 23 Feb 2026 19:44:56 -0500 Subject: [PATCH 47/47] Added Brake error information to the UART logging section just in case the brake is ever implemented --- targets/REV3-HIB/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/targets/REV3-HIB/main.cpp b/targets/REV3-HIB/main.cpp index 6464170..612e5cf 100644 --- a/targets/REV3-HIB/main.cpp +++ b/targets/REV3-HIB/main.cpp @@ -115,10 +115,12 @@ int main() { // uint8_t* payload = message.getPayload(); // LOG_INFO("Throttle Voltage: %imV\r\n" // "Brake Voltage: %imV\r\n" - // "Error Information: %x\r\n", + // "Throttle Error Information: %x\r\n", + // "Brake Error Information: %x\r\n", // (payload[0] << 8) + payload[1], // (payload[2] << 8) + payload[3], - // payload[4]); + // payload[4], + // payload[5]); // time::wait(5000); }