If it is really that necessary, I will just post it fully 
main.cpp:
// deps
#include "Adafruit_LSM6DSO32.h"
#include "Adafruit_NeoPixel.h"
#include "Adafruit_BMP3XX.h"
#include "main.h"
#include "peripherals.h"
#include "TinyGPSPlus.h"
#include "Arduino.h"
#include "Wire.h"
#include "FS.h"
#include "map"
Adafruit_NeoPixel WS2812B;
void initLed(){
WS2812B = Adafruit_NeoPixel(1, PIN_RGB, NEO_GRB + NEO_KHZ800);
WS2812B.begin();
WS2812B.setPixelColor(0, Adafruit_NeoPixel::Color(255, 255, 255));
WS2812B.setBrightness(100);
WS2812B.show();
}
void setup(){
delay(5000);
initLed();
delay(5000);
Serial.println("Computer starting");
initPeripherals();
}
void loop(){
delay(200);
}
peripherals.cpp:
#include "Adafruit_LSM6DSO32.h"
#include "Adafruit_NeoPixel.h"
#include "Adafruit_BMP3XX.h"
#include "main.h"
#include "TinyGPSPlus.h"
#include "W25N_origin.h"
#include "Arduino.h"
#include "Wire.h"
#include "SPI.h"
#include "FS.h"
#include "SD.h"
#include "map"
#include "peripherals.h"
#include "origin_errors.h"
// module definitions
SPIClass spi;
W25N flash;
Adafruit_LSM6DSO32 sensor_imu;
Adafruit_BMP3XX sensor_bar;
TinyGPSPlus gps;
// Adafruit_NeoPixel WS2812B;
// tests
std::map<std::string, std::function<void()>> test_registry;
#define REGISTER_TEST(name) \
void name(); \
struct name##_registrar { \
name##_registrar() { \
test_registry[#name] = name; \
} \
} name##_registrar_instance; \
void name()
void initSerial(){
#if SERIAL_INFO == true
Serial.begin(115200);
Serial.println("Computer starting");
#endif
}
// void initLed(){
// WS2812B = Adafruit_NeoPixel(1, PIN_RGB, NEO_GRB + NEO_KHZ800);
// WS2812B.begin();
// WS2812B.setPixelColor(0, Adafruit_NeoPixel::Color(255, 255, 255));
// WS2812B.setBrightness(100);
// WS2812B.show();
// }
void initBuzzer(){
pinMode(PIN_BUZZER, OUTPUT);
digitalWrite(PIN_BUZZER, HIGH);
delay(100);
digitalWrite(PIN_BUZZER, LOW);
delay(100);
digitalWrite(PIN_BUZZER, HIGH);
delay(100);
digitalWrite(PIN_BUZZER, LOW);
}
void initSPI(){
spi = SPIClass(HSPI);
spi.begin(SPI_SCK, SPI_MISO, SPI_MOSI, SD_CS); // setup SPI pins
}
void initSD(){
#if SERIAL_INFO == true
Serial.println("[SD] Mounting sd!");
#endif
if (!SD.begin(SD_CS, spi)) { // mount card
#if SERIAL_INFO == true
Serial.println("[SD] Error occurred!");
#endif
error("SD card mount failed.", ERROR_CODE_SD);
}
#if SERIAL_INFO == true
Serial.println("[SD] Mounted!");
#endif
uint8_t cardType = SD.cardType();
#if SERIAL_INFO == true
Serial.println("[SD] Checking sd type!");
#endif
if (cardType == CARD_NONE) {
#if SERIAL_INFO == true
Serial.println("[SD] Error occurred!");
#endif
error("No SD card attached.", ERROR_CODE_SD);
}
}
REGISTER_TEST(SD_TEST)
{
const unsigned int randomNumber = esp_random();
const String randomString = String(randomNumber);
if (SD.exists("/test.txt"))
{
SD.remove("/test.txt");
}
File testFile = SD.open("/test.txt", FILE_WRITE);
if (!testFile)
{
error("Testfile failed to open.", ERROR_CODE_SD_TEST);
}
testFile.println(randomString);
testFile.close();
File testFile2 = SD.open("/test.txt", FILE_READ);
if (!testFile2)
{
error("Testfile failed save.", ERROR_CODE_SD_TEST);
}
const String read_data = testFile2.readStringUntil(0x15);
if (!read_data.equals(randomString+"\r\n"))
{
#if SERIAL_INFO == true
Serial.print("Expected:");
for (const auto x : randomString)
{
Serial.print('"');
Serial.print(x);
Serial.print("\",");
}
Serial.println(" ");
Serial.print("Got:");
for (const auto x : read_data)
{
Serial.print('"');
Serial.print(x);
Serial.print("\",");
}
Serial.println(" ");
#endif
error("Read incorrect data from SD.", ERROR_CODE_SD_TEST);
}
testFile2.close();
if (SD.exists("/test.txt"))
{
SD.remove("/test.txt");
}
}
void initFlash(){
#if SERIAL_INFO == true
Serial.println("[FLASH] beginning flash");
#endif
flash = W25N();
if(flash.begin(FLASH_CS, &spi)){
#if SERIAL_INFO == true
Serial.println("[FLASH] flash error!");
#endif
error("Flash init failed.", ERROR_CODE_FLASH);
}
}
REGISTER_TEST(FLASH_TEST){
char buf[512] = {};
const unsigned int randomNumber = esp_random();
const String randomString = String(randomNumber);
memcpy(buf, randomString.c_str(), strlen(randomString.c_str()) + 1);
//erase pages 0-63 (block is 64 pages) (sets pages to all 1)
if (flash.blockErase(0)){
error("Block did not erase.", ERROR_CODE_FLASH_TEST);
}
flash.block_WIP();
// send max 2111 bytes to buffer
if (flash.loadProgData(0, buf, strlen(randomString.c_str())+1)){
error("Program did not load.", ERROR_CODE_FLASH_TEST);
}
flash.block_WIP();
// load data in page 0
if (flash.ProgramExecute(0)){
error("Program did not execute.", ERROR_CODE_FLASH_TEST);
}
flash.block_WIP();
if (flash.pageDataRead(0)){
error("Page did not read.", ERROR_CODE_FLASH_TEST);
}
flash.block_WIP();
// read out of buffer from index 0 to data len
if(flash.read(0, buf, sizeof(buf))){
error("Page did not read from buffer.", ERROR_CODE_FLASH_TEST);
}
if (strncmp(randomString.c_str(), buf, sizeof(buf)) != 0){
#if SERIAL_INFO == true
Serial.println("String is incorrect. (FLASH ERROR)");
Serial.println("Expecting:");
Serial.println(randomString);
Serial.println("Got:");
Serial.println(buf);
#endif
error("String is incorrect.", ERROR_CODE_FLASH_TEST);
}
}
void initI2C(){
if (!Wire.begin(PIN_SDA, PIN_SCL, 100000L)){
error("I2C could not be initialized.", ERROR_CODE_I2C);
}
}
void initIMU(){
if (!sensor_imu.begin_I2C()) {
error("IMU could not be initialized.", ERROR_CODE_IMU);
}
sensor_imu.setAccelRange(LSM6DSO32_ACCEL_RANGE_32_G);
sensor_imu.setAccelDataRate(LSM6DS_RATE_6_66K_HZ); // TODO test this
}
REGISTER_TEST(IMU_TEST)
{
}
void initBarometer(){
if (!sensor_bar.begin_I2C(118, &Wire)){
error("Barometer could not be initialized.", ERROR_CODE_BAROMETER);
}
bool res = true;
res = res & sensor_bar.setTemperatureOversampling(BMP3_NO_OVERSAMPLING);
res = res & sensor_bar.setPressureOversampling(BMP3_OVERSAMPLING_2X);
res = res & sensor_bar.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
res = res & sensor_bar.setOutputDataRate(BMP3_ODR_100_HZ);
if (!res)
{
error("Barometer settings could not be set.", ERROR_CODE_BAROMETER);
}
}
REGISTER_TEST(BAROMETER_TEST)
{
if (!sensor_bar.performReading()){
error("Failed to read from barometer.", ERROR_CODE_BAROMETER_TEST);
}
if (!(300 < (sensor_bar.pressure/100.0) && (sensor_bar.pressure/100.0) < 1250))
{
error("Barometer pressure measurement out of range.", ERROR_CODE_BAROMETER_TEST);
}
if (!(-40 < (sensor_bar.temperature) && (sensor_bar.temperature) < 85))
{
error("Barometer temperature measurement out of range.", ERROR_CODE_BAROMETER_TEST);
}
}
void initGPS(){
GPSSerial.begin(GPSBaud, SERIAL_8N1, GPS_RXPin, GPS_TXPin);
}
void initEverything(){
#if SERIAL_INFO == true
Serial.println("Starting init!");
#endif
initSerial();
#if SERIAL_INFO == true
Serial.println("Serial initialized!");
#endif
// initLed();
#if SERIAL_INFO == true
Serial.println("RGB Led initialized!");
#endif
initBuzzer();
#if SERIAL_INFO == true
Serial.println("Buzzer initialized!");
#endif
initI2C();
#if SERIAL_INFO == true
Serial.println("I2C initialized!");
#endif
initSPI();
#if SERIAL_INFO == true
Serial.println("SPI initialized!");
#endif
initSD();
#if SERIAL_INFO == true
Serial.println("SD initialized!");
#endif
initFlash();
#if SERIAL_INFO == true
Serial.println("Flash initialized!");
#endif
initIMU();
#if SERIAL_INFO == true
Serial.println("IMU initialized!");
#endif
initBarometer();
#if SERIAL_INFO == true
Serial.println("Barometer initialized!");
#endif
initGPS();
#if SERIAL_INFO == true
Serial.println("GPS initialized!");
Serial.println("Init done!");
#endif
}
void testEverything(){
for (const auto& test : test_registry) {
Serial.print("Running test: ");
Serial.println(test.first.c_str());
test.second();
Serial.print("Finished test: ");
Serial.println(test.first.c_str());
}
}
void initPeripherals(){
initEverything();
delay(1000); // wait for sensors to settle
testEverything();
}