From f4476439c9ddfba61e6f3a86581418e1222256ba Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 11 Feb 2024 19:47:47 -0800 Subject: [PATCH 1/8] Working Altimeter and working and updated Memory drivers with in-line comments --- altimeter_ms5607_spi/altimeter_ms5607_spi.cc | 108 +++++++++ altimeter_ms5607_spi/altimeter_ms5607_spi.h | 67 +++++ .../memory_w25q1128jv_spi.cc | 228 ++++++++++++++++++ memory_w25q1128jv_spi/memory_w25q1128jv_spi.h | 137 +++++++++++ 4 files changed, 540 insertions(+) create mode 100644 altimeter_ms5607_spi/altimeter_ms5607_spi.cc create mode 100644 altimeter_ms5607_spi/altimeter_ms5607_spi.h create mode 100644 memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc create mode 100644 memory_w25q1128jv_spi/memory_w25q1128jv_spi.h diff --git a/altimeter_ms5607_spi/altimeter_ms5607_spi.cc b/altimeter_ms5607_spi/altimeter_ms5607_spi.cc new file mode 100644 index 0000000..d7402cd --- /dev/null +++ b/altimeter_ms5607_spi/altimeter_ms5607_spi.cc @@ -0,0 +1,108 @@ +#include "altimeter_ms5607_spi.h" + +AltimeterMs5607Spi::AltimeterMs5607Spi(SPI_HandleTypeDef *hspi, GPIO_TypeDef *csPort, uint16_t csPin, GPIO_TypeDef *misoPort, uint16_t misoPin, double seaLevelPressure) + : _hspi(hspi), _csPort(csPort), _csPin(csPin), _misoPort(misoPort), _misoPin(misoPin), _seaLevelPressure(seaLevelPressure) {} + +int AltimeterMs5607Spi::Reset() { + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); + // reset, opcode 0x1E + if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x1E}, 1, SERIAL_TIMEOUT) != HAL_OK) return -1; + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); + return 0; +} + +int AltimeterMs5607Spi::Init() { + for (int i = 0; i < 6; i++) { + uint8_t buffer[2] = {0}; + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); + // PROM read, opcode 0b1010xxx0 + uint8_t command[1] = {(uint8_t)(0b10100000 | ((i + 1) << 1))}; + if (HAL_SPI_Transmit(_hspi, command, 1, SERIAL_TIMEOUT) != HAL_OK) return -1; + if (HAL_SPI_Receive(_hspi, buffer, 2, SERIAL_TIMEOUT) != HAL_OK) return -1; + _coefficients[i] = ((uint16_t)buffer[0] << 8) | (uint16_t)buffer[1]; + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); + } + return 0; + + // TODO: check CRC +} + +AltimeterMs5607Spi::Data AltimeterMs5607Spi::Read() { + AltimeterMs5607Spi::Data data; + + uint32_t d1 = 0; + uint32_t d2 = 0; + + { + uint8_t buffer[3] = {0}; + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); + // convert D1 pressure, 4096x oversampling, opcode 0x48 + if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x48}, 1, SERIAL_TIMEOUT) != HAL_OK) return data; + // poll for conversion complete + int readStatus = 0; + while (readStatus == 0) { + readStatus = HAL_GPIO_ReadPin(_misoPort, _misoPin); + } + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); + + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); + // read data, opcode 0x00 + if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x00}, 1, SERIAL_TIMEOUT) != HAL_OK) return data; + if (HAL_SPI_Receive(_hspi, buffer, 3, SERIAL_TIMEOUT) != HAL_OK) return data; + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); + d1 = ((uint32_t)buffer[0] << 16) | ((uint32_t)buffer[1] << 8) | ((uint32_t)buffer[2]); + } + + { + uint8_t buffer[3] = {0}; + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); + // convert D2 temperature, 4096x oversampling, opcode 0x58 + if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x58}, 1, SERIAL_TIMEOUT) != HAL_OK) return data; + // poll for conversion complete + int readStatus = 0; + while (readStatus == 0) { + readStatus = HAL_GPIO_ReadPin(_misoPort, _misoPin); + } + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); + readStatus = 0; + + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); + // read data, opcode 0x00 + if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x00}, 1, SERIAL_TIMEOUT) != HAL_OK) return data; + if (HAL_SPI_Receive(_hspi, buffer, 3, SERIAL_TIMEOUT) != HAL_OK) return data; + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); + d2 = ((uint32_t)buffer[0] << 16) | ((uint32_t)buffer[1] << 8) | ((uint32_t)buffer[2]); + } + + int64_t dt = d2 - _coefficients[4] * 256; + int64_t t = 2000 + dt * _coefficients[5] / 8388608; + + int64_t off = _coefficients[1] * 131072 + (_coefficients[3] * dt) / 64; + int64_t sens = _coefficients[0] * 65536 + (_coefficients[2] * dt) / 128; + + int64_t t2 = 0; + int64_t off2 = 0; + int64_t sens2 = 0; + + if (t < 2000) { + int64_t a = t - 2000; + t2 = dt * dt / 2147483648; + off2 = 61 * a * a / 16; + sens2 = 2 * a * a; + + if (t < -1500) { + int64_t b = t + 1500; + off2 += 15 * b * b; + sens2 += 8 * b * b; + } + } + + t -= t2; + off -= off2; + sens -= sens2; + + data.temperature = t / 100.0; + data.pressure = (d1 * sens / 2097152 - off) / 3276800.0; + data.altitude = 44307.7 * (1 - pow(data.pressure / _seaLevelPressure, 0.190284)); + return data; +} diff --git a/altimeter_ms5607_spi/altimeter_ms5607_spi.h b/altimeter_ms5607_spi/altimeter_ms5607_spi.h new file mode 100644 index 0000000..e149b2a --- /dev/null +++ b/altimeter_ms5607_spi/altimeter_ms5607_spi.h @@ -0,0 +1,67 @@ +#pragma once + +#include + +#if defined(STM32F1) +#include "stm32f1xx_hal.h" +#endif + +#ifndef SERIAL_TIMEOUT +#define SERIAL_TIMEOUT 10 +#endif + +class AltimeterMs5607Spi { + public: + struct Data { + // temperature data in degrees celsius + double temperature = std::nan(""); + // pressure data in millibars or hPa + double pressure = std::nan(""); + // altitude data in meters + double altitude = std::nan(""); + }; + + /** + * @param hspi SPI bus handler + * @param csPort chip select GPIO port + * @param csPin chip select GPIO pin + * @param misoPort MISO GPIO port + * @param misoPin MISO GPIO pin + * @param seaLevelPressure sea level pressure in hPa or millibars + */ + AltimeterMs5607Spi(SPI_HandleTypeDef *hspi, GPIO_TypeDef *csPort, uint16_t csPin, GPIO_TypeDef *misoPort, uint16_t misoPin, double seaLevelPressure); + + /** + * @brief Resets the altimeter + * @retval Operation status, 0 for success + */ + int Reset(); + + /** + * @brief Initializes the altimeter by reading calibration coefficients + * @retval Operation status, 0 for success + */ + int Init(); + + /** + * @brief Reads pressure and temperature data from the altimeter and calculates altitude + * @retval Altimeter data frame that contains pressure, temperature, and altitude + */ + Data Read(); + + private: + // SPI bus handler + SPI_HandleTypeDef *_hspi; + // chip select GPIO port + GPIO_TypeDef *_csPort; + // chip select GPIO pin + uint16_t _csPin; + // MISO GPIO port + GPIO_TypeDef *_misoPort; + // MISO GPIO pin + uint16_t _misoPin; + // sea level pressure in hPa or millibars + double _seaLevelPressure; + // factory calibration coefficients + int64_t _coefficients[6]; +}; diff --git a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc new file mode 100644 index 0000000..09205d0 --- /dev/null +++ b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc @@ -0,0 +1,228 @@ +#include + +MemoryW25q1128jvSpi::MemoryW25q1128jvSpi(SPI_HandleTypeDef *_spi, GPIO_TypeDef *_csPort, uint16_t _csPin, GPIO_TypeDef *_holdPort, uint16_t _holdPin, GPIO_TypeDef *_wpPort, uint16_t _wpPin) + + : spi(_spi), csPort(_csPort), csPin(_csPin), holdPort(_holdPort), holdPin(_holdPin), wpPort(_wpPort), wpPin(_wpPin) {} + +uint8_t MemoryW25q1128jvSpi::Init() { + // making sure control pins are always high + HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // Data holder for reading address + TelemetryData _init_Data; + // Reads Chip ID, if chip ID is not W25Q128JV_MEMORY, then return 0 + if (DeviceID() != 0xEF17) return 0; + + // while loop to read through every memory page + // Result, address starts in the first empty page + while (1) { + // Reads a page of memory + Chip_Read(address); + // sets first 64 byte data package into variable + _init_Data = Data_Bundle[0]; + + // compares data package type variable with + if (_init_Data.type != (uint8_t)(0x00)) break; + address++; + } + return 1; +} + +uint16_t MemoryW25q1128jvSpi::DeviceID() { + // making sure control pins are always high + HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // input instruction hex + 3 dummy bytes + uint8_t in[4] = {0x90, 0x00, 0x00, 0x00}; + // output array of bytes + uint8_t out[2] = {0}; + + // SPI protocol + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(spi, in, 4, 10) != HAL_OK) return 0; + if (HAL_SPI_Receive(spi, out, 2, 10) != HAL_OK) return 0; + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // returns the 2 bytes as a uint16_t + return (uint16_t)(out[0] << 8 | out[1]); +} + +uint8_t MemoryW25q1128jvSpi::Read_Status_Reg1(uint8_t Reg_check, uint8_t Reg_until) { + // making sure that control pins are always high + HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // input operation code for reading status register 1 + uint8_t in[1] = {0x05}; + // output -- 8 bit value of the status register + uint8_t out[1] = {0}; + + // do while loop of reading status register + // loop ends when the input Reg_check value == Reg_until + do { + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(spi, in, 1, 10) != HAL_OK) return 0; + if (HAL_SPI_Receive(spi, out, 1, 10) != HAL_OK) return 0; + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + } while ((out[0] & Reg_check) == Reg_until); + + return 1; +} + +uint8_t MemoryW25q1128jvSpi::Chip_Erase() { + // making sure that control pins are always high + HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // instruction array for chip enable command + uint8_t chip_enable[1] = {0x06}; + // instruction array for chip erase command + uint8_t chip_erase[1] = {0xC7}; + + // 1. enable chip with Chip_enable + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(spi, chip_enable, 1, 10) != HAL_OK) return 0; + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // Checks and waits until status register write enable latch is = 1 + if (MemoryW25q1128jvSpi::Read_Status_Reg1(0x02, 0) == 0) return 0; + + // 2. runs chip erase command + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(spi, chip_erase, 1, 10) != HAL_OK) return 0; + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // Checks and waits until status register busy bit is = 0 + if (MemoryW25q1128jvSpi::Read_Status_Reg1(0x01, 1) == 0) return 0; + + return 1; +} + +uint8_t MemoryW25q1128jvSpi::Chip_Write(TelemetryData data) { + // making sure that control pins are always high + HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // if address variable goes over the amount of pages memory has + // no more collected data will be written into the memory + if (address > 0xFFFF) return 0; + + // Bundles Telemetry data struct into a 4 element array + // Telemetry data is written into the array until all 4 elements are full + if (Data_Bundle_Size < 3) { + Data_Bundle[Data_Bundle_Size] = data; + Data_Bundle_Size++; + return 1; + } + + // resets bundled data variable and inserts the last Telemetry data values + Data_Bundle[3] = data; + Data_Bundle_Size = 0; + + // Chip enable instruction command + uint8_t chip_enable[1] = {0x06}; + // Page Program instruction command + uint8_t Page_program[4] = {0x02, (uint8_t)(address >> 8), (uint8_t)(address), 0x00}; // instruction opcode for Page Program + + // chip enable instruction to enable chip + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(spi, chip_enable, 1, SPI_Timeout) != HAL_OK) return 0; + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // Checks and waits until status register write bit is = 0 + // waits until Chip enable is done + if (MemoryW25q1128jvSpi::Read_Status_Reg1(2, 1) == 0) return 0; + + // Write Data bundle into memory + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(spi, Page_program, 4, SPI_Timeout) != HAL_OK) return 0; + if (HAL_SPI_Transmit(spi, (uint8_t *)Data_Bundle, 256, SPI_Timeout) != HAL_OK) return 0; + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // Checks and waits until status register busy bit is = 0 + // waits until page write is done + if (MemoryW25q1128jvSpi::Read_Status_Reg1(1, 0) == 0) return 0; + + //increments to the next page address + address++; + + return 1; +} + +MemoryW25q1128jvSpi::TelemetryData *MemoryW25q1128jvSpi::Chip_Read(uint32_t read_address) { + // making sure that control pins are always high + HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // initalisation of input, output, and dumby telemtrydata variable for temporary writing to DataBundle + uint8_t Read_Data[4] = {0x03, (uint8_t)(read_address >> 8), (uint8_t)(read_address), 0x00}; + uint8_t out[256] = {0}; + MemoryW25q1128jvSpi::TelemetryData Data; + + //Reads address page in memory + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(spi, Read_Data, 4, SPI_Timeout) != HAL_OK) return Data_Bundle; + if (HAL_SPI_Receive(spi, out, 256, SPI_Timeout) != HAL_OK) return Data_Bundle; + HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); + + // Checks and waits until status register busy bit is = 0 + // waits until page read is done + if (MemoryW25q1128jvSpi::Read_Status_Reg1(0x01, 1) == 0) return 0; + + //organisation of Databundle from read page until Data_Bundle array + for (int i = 0; i < 4; i++) + { + //Specifier for telemetry data + Data.type = out[(64 * i)]; + //Timestamp for data + Data.timestamp = ((out[(64 * i) + 4] << 24) | (out[(64 * i) + 3] << 16) | (out[(64 * i) + 2] << 8) | (out[(64 * i) + 1])); + //What state AFS was in + Data.state = ((out[(64 * i) + 6] << 8) | (out[(64 * i) + 5])); + + //IMU Gyroscope data + Data.imuGyroscopeX = ((out[(64 * i) + 8] << 8) | (out[(64 * i) + 7])); + Data.imuGyroscopeY = ((out[(64 * i) + 10] << 8) | (out[(64 * i) + 9])); + Data.imuGyroscopeZ = ((out[(64 * i) + 12] << 8) | (out[(64 * i) + 11]));; + + //IMU Accelerometer data + Data.imuAccelerometerX = ((out[(64 * i) + 14] << 8) | (out[(64 * i) + 13])); + Data.imuAccelerometerY = ((out[(64 * i) + 16] << 8) | (out[(64 * i) + 15])); + Data.imuAccelerometerZ = ((out[(64 * i) + 18] << 8) | (out[(64 * i) + 17])); + + //IMU Magnetometer data + Data.imuMagnetometerX = ((out[(64 * i) + 20] << 8) | (out[(64 * i) + 19])); + Data.imuMagnetometerY = ((out[(64 * i) + 22] << 8) | (out[(64 * i) + 21])); + Data.imuMagnetometerZ = ((out[(64 * i) + 24] << 8) | (out[(64 * i) + 23])); + + //altimeter data being concentated into corresponeding byes + Data.altimeterTemperature = ((out[(64 * i) + 25] << 8) | (out[(64 * i) + 24])); + Data.altimeterAltitude = ((out[(64 * i) + 29] << 24) | (out[(64 * i) + 28] << 16) | (out[(64 * i) + 27] << 8) | (out[(64 * i) + 26])); + + //GNSS Earth-Centered Earth-Fixed xyz position data + Data.gnssEcefPositionX = ((out[(64 * i) + 33] << 24) | (out[(64 * i) + 32] << 16) | (out[(64 * i) + 31] << 8) | (out[(64 * i) + 30])); + Data.gnssEcefPositionY = ((out[(64 * i) + 37] << 24) | (out[(64 * i) + 36] << 16) | (out[(64 * i) + 35] << 8) | (out[(64 * i) + 34])); + Data.gnssEcefPositionZ = ((out[(64 * i) + 41] << 24) | (out[(64 * i) + 40] << 16) | (out[(64 * i) + 39] << 8) | (out[(64 * i) + 38])); + Data.gnssPositionAccuracy = ((out[(64 * i) + 45] << 24) | (out[(64 * i) + 44] << 16) | (out[(64 * i) + 43] << 8) | (out[(64 * i) + 42])); + + //GNSS Earth-Centered Earth-Fixed xyz velocity data + Data.gnssEcefPositionX = ((out[(64 * i) + 50] << 24) | (out[(64 * i) + 49] << 16) | (out[(64 * i) + 48] << 8) | (out[(64 * i) + 47])); + Data.gnssEcefPositionY = ((out[(64 * i) + 54] << 24) | (out[(64 * i) + 53] << 16) | (out[(64 * i) + 52] << 8) | (out[(64 * i) + 51])); + Data.gnssEcefPositionZ = ((out[(64 * i) + 58] << 24) | (out[(64 * i) + 57] << 16) | (out[(64 * i) + 56] << 8) | (out[(64 * i) + 55])); + Data.gnssPositionAccuracy = ((out[(64 * i) + 62] << 24) | (out[(64 * i) + 61] << 16) | (out[(64 * i) + 60] << 8) | (out[(64 * i) + 59])); + + //ctc table + Data.crc =0x0000; + + //insertion of organised data into data bundle + Data_Bundle[i] = Data; + } + return Data_Bundle; +} diff --git a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h new file mode 100644 index 0000000..ad9d458 --- /dev/null +++ b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h @@ -0,0 +1,137 @@ +/* + * W25Q128JV_MEMORY.h + * + * Created on: Jan 1, 2024 + * Author: rober + */ +#pragma once + +#include + +#if defined(STM32F1) +#include "stm32f1xx_hal.h" +#endif + +#ifndef SPI_Timeout +#define SPI_Timeout 10 +#endif + +class MemoryW25q1128jvSpi { + public: +#pragma pack(push, 1) + struct TelemetryData { + uint8_t type = 0x00; + uint32_t timestamp = 0xFFFFFFFF; // ms since startup + uint8_t state = 0x00; // state for AFS, unused on ECU + int16_t imuGyroscopeX = 0xFFFF; // 0.061 deg/s per LSB + int16_t imuGyroscopeY = 0xFFFF; // 0.061 deg/s per LSB + int16_t imuGyroscopeZ = 0xFFFF; // 0.061 deg/s per LSB + int16_t imuAccelerometerX = 0xFFFF; // 0.00073g per LSB + int16_t imuAccelerometerY = 0xFFFF; // 0.00073g per LSB + int16_t imuAccelerometerZ = 0xFFFF; // 0.00073g per LSB + int16_t imuMagnetometerX = 0xFFFF; // 0.063 uT per LSB + int16_t imuMagnetometerY = 0xFFFF; // 0.063 uT per LSB + int16_t imuMagnetometerZ = 0xFFFF; // 0.063 uT per LSB + int16_t altimeterTemperature = 0xFFFF; // 10^-2 C + int32_t altimeterAltitude = 0xFFFFFFFF; // cm + int32_t gnssEcefPositionX = 0xFFFFFFFF; // cm + int32_t gnssEcefPositionY = 0xFFFFFFFF; // cm + int32_t gnssEcefPositionZ = 0xFFFFFFFF; // cm + uint32_t gnssPositionAccuracy = 0xFFFFFFFF; // cm + int32_t gnssEcefVelocityX = 0xFFFFFFFF; // cm/s + int32_t gnssEcefVelocityY = 0xFFFFFFFF; // cm/s + int32_t gnssEcefVelocityZ = 0xFFFFFFFF; // cm/s + uint32_t gnssVelocityAccuracy = 0xFFFFFFFF; // cm/s + uint16_t crc = 0x0000; + }; +#pragma pack(pop) + +#pragma pack(push, 1) + struct AfsState { + bool armPinState : 1; // 0: unarmed, 1: armed + bool drogueContinuity : 1; // 0: no continuity, 1: continuity + bool mainContinuity : 1; // 0: no continuity, 1: continuity + uint16_t : 1; // reserved + /** + * 0x0: standby + * 0x1: armed + * 0x2: boost + * 0x3: coast + * 0x4: apogee + * 0x5: drogue fired + * 0x6: drogue opened + * 0x7 drogue failure + * 0x8: main fired + * 0x9: main opened + * 0xA: main failure + * 0xB: land + */ + uint8_t state : 4; + }; +#pragma pack(pop) + + /** + * @param _spi SPI bus handler + * @param _csPort chip select GPIO port + * @param _csPin chip select GPIO pin + * @param _holdPort Write HOLD GPIO port + * @param _holdPin Write HOLD GPIO pin + * @param _wpPort Write Protect GPIO port + * @param _wpPin Write Protect GPIO pin + */ + MemoryW25q1128jvSpi(SPI_HandleTypeDef *_spi, GPIO_TypeDef *_csPort, uint16_t _csPin, GPIO_TypeDef *_holdPort, uint16_t _holdPin, GPIO_TypeDef *_wpPort, uint16_t); + + /** + * @brief Initialises the memory by reading and incrementing to the first non-written page + * @retval Operation status, 1 for success + */ + uint8_t Init(); + + /** + * @brief Reads the device ID of the memory/ + * Should output 0xEF for manufacturer ID, + * Should output 0x90 for Device ID + */ + uint16_t DeviceID(); + + /** + * @brief Reads the first status register from memort + * 2 inputs + * Reg_check, Status Register bit to check status of + * Reg_until, wait until Status register bit = Reg_until value + * @retval Operation status, 1 for success + */ + uint8_t Read_Status_Reg1(uint8_t Reg_check, uint8_t Reg_until); + + /** + * @brief Erases all data on chip + * @retval Operation status, 1 for success + */ + uint8_t Chip_Erase(); + + /** + * @brief Writes Telemetrydata stuct into TelemetryData Data_Bundle[4] array + * @retval Operation status, 1 for success + */ + uint8_t Chip_Write(TelemetryData data); + + /** + * @brief Reads read_addess page data and returns eturns pointer to Data_Bundle array + * + */ + TelemetryData *Chip_Read(uint32_t read_address); + + // Data bundle array consisting of 4, 64 byte, data packages outlined in struct Telemetrydata + MemoryW25q1128jvSpi::TelemetryData Data_Bundle[4]; + + private: + SPI_HandleTypeDef *spi; + GPIO_TypeDef *csPort; + uint16_t csPin; + GPIO_TypeDef *holdPort; + uint16_t holdPin; + GPIO_TypeDef *wpPort; + uint16_t wpPin; + uint8_t Data_Bundle_Size = 0; + uint32_t address = 0x00000000; +}; From 78fb587510c2af6ad46c7018e2c886789dae3343 Mon Sep 17 00:00:00 2001 From: Robert Woo <119546571+rawoo714@users.noreply.github.com> Date: Mon, 12 Feb 2024 18:03:10 -0800 Subject: [PATCH 2/8] Delete altimeter_ms5607_spi directory --- altimeter_ms5607_spi/altimeter_ms5607_spi.cc | 108 ------------------- altimeter_ms5607_spi/altimeter_ms5607_spi.h | 67 ------------ 2 files changed, 175 deletions(-) delete mode 100644 altimeter_ms5607_spi/altimeter_ms5607_spi.cc delete mode 100644 altimeter_ms5607_spi/altimeter_ms5607_spi.h diff --git a/altimeter_ms5607_spi/altimeter_ms5607_spi.cc b/altimeter_ms5607_spi/altimeter_ms5607_spi.cc deleted file mode 100644 index d7402cd..0000000 --- a/altimeter_ms5607_spi/altimeter_ms5607_spi.cc +++ /dev/null @@ -1,108 +0,0 @@ -#include "altimeter_ms5607_spi.h" - -AltimeterMs5607Spi::AltimeterMs5607Spi(SPI_HandleTypeDef *hspi, GPIO_TypeDef *csPort, uint16_t csPin, GPIO_TypeDef *misoPort, uint16_t misoPin, double seaLevelPressure) - : _hspi(hspi), _csPort(csPort), _csPin(csPin), _misoPort(misoPort), _misoPin(misoPin), _seaLevelPressure(seaLevelPressure) {} - -int AltimeterMs5607Spi::Reset() { - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); - // reset, opcode 0x1E - if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x1E}, 1, SERIAL_TIMEOUT) != HAL_OK) return -1; - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); - return 0; -} - -int AltimeterMs5607Spi::Init() { - for (int i = 0; i < 6; i++) { - uint8_t buffer[2] = {0}; - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); - // PROM read, opcode 0b1010xxx0 - uint8_t command[1] = {(uint8_t)(0b10100000 | ((i + 1) << 1))}; - if (HAL_SPI_Transmit(_hspi, command, 1, SERIAL_TIMEOUT) != HAL_OK) return -1; - if (HAL_SPI_Receive(_hspi, buffer, 2, SERIAL_TIMEOUT) != HAL_OK) return -1; - _coefficients[i] = ((uint16_t)buffer[0] << 8) | (uint16_t)buffer[1]; - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); - } - return 0; - - // TODO: check CRC -} - -AltimeterMs5607Spi::Data AltimeterMs5607Spi::Read() { - AltimeterMs5607Spi::Data data; - - uint32_t d1 = 0; - uint32_t d2 = 0; - - { - uint8_t buffer[3] = {0}; - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); - // convert D1 pressure, 4096x oversampling, opcode 0x48 - if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x48}, 1, SERIAL_TIMEOUT) != HAL_OK) return data; - // poll for conversion complete - int readStatus = 0; - while (readStatus == 0) { - readStatus = HAL_GPIO_ReadPin(_misoPort, _misoPin); - } - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); - - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); - // read data, opcode 0x00 - if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x00}, 1, SERIAL_TIMEOUT) != HAL_OK) return data; - if (HAL_SPI_Receive(_hspi, buffer, 3, SERIAL_TIMEOUT) != HAL_OK) return data; - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); - d1 = ((uint32_t)buffer[0] << 16) | ((uint32_t)buffer[1] << 8) | ((uint32_t)buffer[2]); - } - - { - uint8_t buffer[3] = {0}; - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); - // convert D2 temperature, 4096x oversampling, opcode 0x58 - if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x58}, 1, SERIAL_TIMEOUT) != HAL_OK) return data; - // poll for conversion complete - int readStatus = 0; - while (readStatus == 0) { - readStatus = HAL_GPIO_ReadPin(_misoPort, _misoPin); - } - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); - readStatus = 0; - - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); - // read data, opcode 0x00 - if (HAL_SPI_Transmit(_hspi, (uint8_t *)(const uint8_t[]){0x00}, 1, SERIAL_TIMEOUT) != HAL_OK) return data; - if (HAL_SPI_Receive(_hspi, buffer, 3, SERIAL_TIMEOUT) != HAL_OK) return data; - HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); - d2 = ((uint32_t)buffer[0] << 16) | ((uint32_t)buffer[1] << 8) | ((uint32_t)buffer[2]); - } - - int64_t dt = d2 - _coefficients[4] * 256; - int64_t t = 2000 + dt * _coefficients[5] / 8388608; - - int64_t off = _coefficients[1] * 131072 + (_coefficients[3] * dt) / 64; - int64_t sens = _coefficients[0] * 65536 + (_coefficients[2] * dt) / 128; - - int64_t t2 = 0; - int64_t off2 = 0; - int64_t sens2 = 0; - - if (t < 2000) { - int64_t a = t - 2000; - t2 = dt * dt / 2147483648; - off2 = 61 * a * a / 16; - sens2 = 2 * a * a; - - if (t < -1500) { - int64_t b = t + 1500; - off2 += 15 * b * b; - sens2 += 8 * b * b; - } - } - - t -= t2; - off -= off2; - sens -= sens2; - - data.temperature = t / 100.0; - data.pressure = (d1 * sens / 2097152 - off) / 3276800.0; - data.altitude = 44307.7 * (1 - pow(data.pressure / _seaLevelPressure, 0.190284)); - return data; -} diff --git a/altimeter_ms5607_spi/altimeter_ms5607_spi.h b/altimeter_ms5607_spi/altimeter_ms5607_spi.h deleted file mode 100644 index e149b2a..0000000 --- a/altimeter_ms5607_spi/altimeter_ms5607_spi.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include - -#if defined(STM32F1) -#include "stm32f1xx_hal.h" -#endif - -#ifndef SERIAL_TIMEOUT -#define SERIAL_TIMEOUT 10 -#endif - -class AltimeterMs5607Spi { - public: - struct Data { - // temperature data in degrees celsius - double temperature = std::nan(""); - // pressure data in millibars or hPa - double pressure = std::nan(""); - // altitude data in meters - double altitude = std::nan(""); - }; - - /** - * @param hspi SPI bus handler - * @param csPort chip select GPIO port - * @param csPin chip select GPIO pin - * @param misoPort MISO GPIO port - * @param misoPin MISO GPIO pin - * @param seaLevelPressure sea level pressure in hPa or millibars - */ - AltimeterMs5607Spi(SPI_HandleTypeDef *hspi, GPIO_TypeDef *csPort, uint16_t csPin, GPIO_TypeDef *misoPort, uint16_t misoPin, double seaLevelPressure); - - /** - * @brief Resets the altimeter - * @retval Operation status, 0 for success - */ - int Reset(); - - /** - * @brief Initializes the altimeter by reading calibration coefficients - * @retval Operation status, 0 for success - */ - int Init(); - - /** - * @brief Reads pressure and temperature data from the altimeter and calculates altitude - * @retval Altimeter data frame that contains pressure, temperature, and altitude - */ - Data Read(); - - private: - // SPI bus handler - SPI_HandleTypeDef *_hspi; - // chip select GPIO port - GPIO_TypeDef *_csPort; - // chip select GPIO pin - uint16_t _csPin; - // MISO GPIO port - GPIO_TypeDef *_misoPort; - // MISO GPIO pin - uint16_t _misoPin; - // sea level pressure in hPa or millibars - double _seaLevelPressure; - // factory calibration coefficients - int64_t _coefficients[6]; -}; From 0c53ba215b0c8784ba3567977e1f67ab59505ef5 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 12 Feb 2024 18:17:57 -0800 Subject: [PATCH 3/8] ran working pre-commit text cleaners --- .../memory_w25q1128jv_spi.cc | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc index 09205d0..0ef9459 100644 --- a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc +++ b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc @@ -143,14 +143,14 @@ uint8_t MemoryW25q1128jvSpi::Chip_Write(TelemetryData data) { // Write Data bundle into memory HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); if (HAL_SPI_Transmit(spi, Page_program, 4, SPI_Timeout) != HAL_OK) return 0; - if (HAL_SPI_Transmit(spi, (uint8_t *)Data_Bundle, 256, SPI_Timeout) != HAL_OK) return 0; + if (HAL_SPI_Transmit(spi, (uint8_t *)Data_Bundle, 256, SPI_Timeout) != HAL_OK) return 0; HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); // Checks and waits until status register busy bit is = 0 // waits until page write is done - if (MemoryW25q1128jvSpi::Read_Status_Reg1(1, 0) == 0) return 0; + if (MemoryW25q1128jvSpi::Read_Status_Reg1(1, 0) == 0) return 0; - //increments to the next page address + // increments to the next page address address++; return 1; @@ -167,7 +167,7 @@ MemoryW25q1128jvSpi::TelemetryData *MemoryW25q1128jvSpi::Chip_Read(uint32_t read uint8_t out[256] = {0}; MemoryW25q1128jvSpi::TelemetryData Data; - //Reads address page in memory + // Reads address page in memory HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); if (HAL_SPI_Transmit(spi, Read_Data, 4, SPI_Timeout) != HAL_OK) return Data_Bundle; if (HAL_SPI_Receive(spi, out, 256, SPI_Timeout) != HAL_OK) return Data_Bundle; @@ -177,51 +177,51 @@ MemoryW25q1128jvSpi::TelemetryData *MemoryW25q1128jvSpi::Chip_Read(uint32_t read // waits until page read is done if (MemoryW25q1128jvSpi::Read_Status_Reg1(0x01, 1) == 0) return 0; - //organisation of Databundle from read page until Data_Bundle array - for (int i = 0; i < 4; i++) - { - //Specifier for telemetry data + // organisation of Databundle from read page until Data_Bundle array + for (int i = 0; i < 4; i++) { + // Specifier for telemetry data Data.type = out[(64 * i)]; - //Timestamp for data + // Timestamp for data Data.timestamp = ((out[(64 * i) + 4] << 24) | (out[(64 * i) + 3] << 16) | (out[(64 * i) + 2] << 8) | (out[(64 * i) + 1])); - //What state AFS was in + // What state AFS was in Data.state = ((out[(64 * i) + 6] << 8) | (out[(64 * i) + 5])); - //IMU Gyroscope data - Data.imuGyroscopeX = ((out[(64 * i) + 8] << 8) | (out[(64 * i) + 7])); - Data.imuGyroscopeY = ((out[(64 * i) + 10] << 8) | (out[(64 * i) + 9])); - Data.imuGyroscopeZ = ((out[(64 * i) + 12] << 8) | (out[(64 * i) + 11]));; + // IMU Gyroscope data + Data.imuGyroscopeX = ((out[(64 * i) + 8] << 8) | (out[(64 * i) + 7])); + Data.imuGyroscopeY = ((out[(64 * i) + 10] << 8) | (out[(64 * i) + 9])); + Data.imuGyroscopeZ = ((out[(64 * i) + 12] << 8) | (out[(64 * i) + 11])); + ; - //IMU Accelerometer data + // IMU Accelerometer data Data.imuAccelerometerX = ((out[(64 * i) + 14] << 8) | (out[(64 * i) + 13])); Data.imuAccelerometerY = ((out[(64 * i) + 16] << 8) | (out[(64 * i) + 15])); Data.imuAccelerometerZ = ((out[(64 * i) + 18] << 8) | (out[(64 * i) + 17])); - //IMU Magnetometer data + // IMU Magnetometer data Data.imuMagnetometerX = ((out[(64 * i) + 20] << 8) | (out[(64 * i) + 19])); Data.imuMagnetometerY = ((out[(64 * i) + 22] << 8) | (out[(64 * i) + 21])); Data.imuMagnetometerZ = ((out[(64 * i) + 24] << 8) | (out[(64 * i) + 23])); - //altimeter data being concentated into corresponeding byes + // altimeter data being concentated into corresponeding byes Data.altimeterTemperature = ((out[(64 * i) + 25] << 8) | (out[(64 * i) + 24])); - Data.altimeterAltitude = ((out[(64 * i) + 29] << 24) | (out[(64 * i) + 28] << 16) | (out[(64 * i) + 27] << 8) | (out[(64 * i) + 26])); + Data.altimeterAltitude = ((out[(64 * i) + 29] << 24) | (out[(64 * i) + 28] << 16) | (out[(64 * i) + 27] << 8) | (out[(64 * i) + 26])); - //GNSS Earth-Centered Earth-Fixed xyz position data - Data.gnssEcefPositionX = ((out[(64 * i) + 33] << 24) | (out[(64 * i) + 32] << 16) | (out[(64 * i) + 31] << 8) | (out[(64 * i) + 30])); - Data.gnssEcefPositionY = ((out[(64 * i) + 37] << 24) | (out[(64 * i) + 36] << 16) | (out[(64 * i) + 35] << 8) | (out[(64 * i) + 34])); - Data.gnssEcefPositionZ = ((out[(64 * i) + 41] << 24) | (out[(64 * i) + 40] << 16) | (out[(64 * i) + 39] << 8) | (out[(64 * i) + 38])); + // GNSS Earth-Centered Earth-Fixed xyz position data + Data.gnssEcefPositionX = ((out[(64 * i) + 33] << 24) | (out[(64 * i) + 32] << 16) | (out[(64 * i) + 31] << 8) | (out[(64 * i) + 30])); + Data.gnssEcefPositionY = ((out[(64 * i) + 37] << 24) | (out[(64 * i) + 36] << 16) | (out[(64 * i) + 35] << 8) | (out[(64 * i) + 34])); + Data.gnssEcefPositionZ = ((out[(64 * i) + 41] << 24) | (out[(64 * i) + 40] << 16) | (out[(64 * i) + 39] << 8) | (out[(64 * i) + 38])); Data.gnssPositionAccuracy = ((out[(64 * i) + 45] << 24) | (out[(64 * i) + 44] << 16) | (out[(64 * i) + 43] << 8) | (out[(64 * i) + 42])); - //GNSS Earth-Centered Earth-Fixed xyz velocity data - Data.gnssEcefPositionX = ((out[(64 * i) + 50] << 24) | (out[(64 * i) + 49] << 16) | (out[(64 * i) + 48] << 8) | (out[(64 * i) + 47])); - Data.gnssEcefPositionY = ((out[(64 * i) + 54] << 24) | (out[(64 * i) + 53] << 16) | (out[(64 * i) + 52] << 8) | (out[(64 * i) + 51])); - Data.gnssEcefPositionZ = ((out[(64 * i) + 58] << 24) | (out[(64 * i) + 57] << 16) | (out[(64 * i) + 56] << 8) | (out[(64 * i) + 55])); + // GNSS Earth-Centered Earth-Fixed xyz velocity data + Data.gnssEcefPositionX = ((out[(64 * i) + 50] << 24) | (out[(64 * i) + 49] << 16) | (out[(64 * i) + 48] << 8) | (out[(64 * i) + 47])); + Data.gnssEcefPositionY = ((out[(64 * i) + 54] << 24) | (out[(64 * i) + 53] << 16) | (out[(64 * i) + 52] << 8) | (out[(64 * i) + 51])); + Data.gnssEcefPositionZ = ((out[(64 * i) + 58] << 24) | (out[(64 * i) + 57] << 16) | (out[(64 * i) + 56] << 8) | (out[(64 * i) + 55])); Data.gnssPositionAccuracy = ((out[(64 * i) + 62] << 24) | (out[(64 * i) + 61] << 16) | (out[(64 * i) + 60] << 8) | (out[(64 * i) + 59])); - //ctc table - Data.crc =0x0000; + // ctc table + Data.crc = 0x0000; - //insertion of organised data into data bundle + // insertion of organised data into data bundle Data_Bundle[i] = Data; } return Data_Bundle; From fec92dd3af413a5f2f1f102fde9766a83d283d57 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 12 Feb 2024 18:38:24 -0800 Subject: [PATCH 4/8] New AFStelemetrydata package struct variables --- .../memory_w25q1128jv_spi.cc | 55 +++++++++---------- memory_w25q1128jv_spi/memory_w25q1128jv_spi.h | 50 ++++++++--------- 2 files changed, 50 insertions(+), 55 deletions(-) diff --git a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc index 0ef9459..75402f7 100644 --- a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc +++ b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc @@ -11,7 +11,7 @@ uint8_t MemoryW25q1128jvSpi::Init() { HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); // Data holder for reading address - TelemetryData _init_Data; + afsTelemetryData _init_Data; // Reads Chip ID, if chip ID is not W25Q128JV_MEMORY, then return 0 if (DeviceID() != 0xEF17) return 0; @@ -19,12 +19,7 @@ uint8_t MemoryW25q1128jvSpi::Init() { // Result, address starts in the first empty page while (1) { // Reads a page of memory - Chip_Read(address); - // sets first 64 byte data package into variable - _init_Data = Data_Bundle[0]; - - // compares data package type variable with - if (_init_Data.type != (uint8_t)(0x00)) break; + Chip_Read(address);afsTelemetryData; address++; } return 1; @@ -104,7 +99,7 @@ uint8_t MemoryW25q1128jvSpi::Chip_Erase() { return 1; } -uint8_t MemoryW25q1128jvSpi::Chip_Write(TelemetryData data) { +uint8_t MemoryW25q1128jvSpi::Chip_Write(afsTelemetryData data) { // making sure that control pins are always high HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); @@ -156,7 +151,7 @@ uint8_t MemoryW25q1128jvSpi::Chip_Write(TelemetryData data) { return 1; } -MemoryW25q1128jvSpi::TelemetryData *MemoryW25q1128jvSpi::Chip_Read(uint32_t read_address) { +MemoryW25q1128jvSpi::afsTelemetryData *MemoryW25q1128jvSpi::Chip_Read(uint32_t read_address) { // making sure that control pins are always high HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); @@ -165,7 +160,7 @@ MemoryW25q1128jvSpi::TelemetryData *MemoryW25q1128jvSpi::Chip_Read(uint32_t read // initalisation of input, output, and dumby telemtrydata variable for temporary writing to DataBundle uint8_t Read_Data[4] = {0x03, (uint8_t)(read_address >> 8), (uint8_t)(read_address), 0x00}; uint8_t out[256] = {0}; - MemoryW25q1128jvSpi::TelemetryData Data; + MemoryW25q1128jvSpi::afsTelemetryData Data; // Reads address page in memory HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); @@ -187,36 +182,36 @@ MemoryW25q1128jvSpi::TelemetryData *MemoryW25q1128jvSpi::Chip_Read(uint32_t read Data.state = ((out[(64 * i) + 6] << 8) | (out[(64 * i) + 5])); // IMU Gyroscope data - Data.imuGyroscopeX = ((out[(64 * i) + 8] << 8) | (out[(64 * i) + 7])); - Data.imuGyroscopeY = ((out[(64 * i) + 10] << 8) | (out[(64 * i) + 9])); - Data.imuGyroscopeZ = ((out[(64 * i) + 12] << 8) | (out[(64 * i) + 11])); + Data.angularVelocityX = ((out[(64 * i) + 8] << 8) | (out[(64 * i) + 7])); + Data.angularVelocityY = ((out[(64 * i) + 10] << 8) | (out[(64 * i) + 9])); + Data.angularVelocityZ = ((out[(64 * i) + 12] << 8) | (out[(64 * i) + 11])); ; // IMU Accelerometer data - Data.imuAccelerometerX = ((out[(64 * i) + 14] << 8) | (out[(64 * i) + 13])); - Data.imuAccelerometerY = ((out[(64 * i) + 16] << 8) | (out[(64 * i) + 15])); - Data.imuAccelerometerZ = ((out[(64 * i) + 18] << 8) | (out[(64 * i) + 17])); + Data.accelerationX = ((out[(64 * i) + 14] << 8) | (out[(64 * i) + 13])); + Data.accelerationY = ((out[(64 * i) + 16] << 8) | (out[(64 * i) + 15])); + Data.accelerationZ = ((out[(64 * i) + 18] << 8) | (out[(64 * i) + 17])); // IMU Magnetometer data - Data.imuMagnetometerX = ((out[(64 * i) + 20] << 8) | (out[(64 * i) + 19])); - Data.imuMagnetometerY = ((out[(64 * i) + 22] << 8) | (out[(64 * i) + 21])); - Data.imuMagnetometerZ = ((out[(64 * i) + 24] << 8) | (out[(64 * i) + 23])); + Data.magneticFieldX = ((out[(64 * i) + 20] << 8) | (out[(64 * i) + 19])); + Data.magneticFieldY = ((out[(64 * i) + 22] << 8) | (out[(64 * i) + 21])); + Data.magneticFieldZ = ((out[(64 * i) + 24] << 8) | (out[(64 * i) + 23])); // altimeter data being concentated into corresponeding byes - Data.altimeterTemperature = ((out[(64 * i) + 25] << 8) | (out[(64 * i) + 24])); - Data.altimeterAltitude = ((out[(64 * i) + 29] << 24) | (out[(64 * i) + 28] << 16) | (out[(64 * i) + 27] << 8) | (out[(64 * i) + 26])); + Data.temperature = ((out[(64 * i) + 25] << 8) | (out[(64 * i) + 24])); + Data.altitude = ((out[(64 * i) + 29] << 24) | (out[(64 * i) + 28] << 16) | (out[(64 * i) + 27] << 8) | (out[(64 * i) + 26])); - // GNSS Earth-Centered Earth-Fixed xyz position data - Data.gnssEcefPositionX = ((out[(64 * i) + 33] << 24) | (out[(64 * i) + 32] << 16) | (out[(64 * i) + 31] << 8) | (out[(64 * i) + 30])); - Data.gnssEcefPositionY = ((out[(64 * i) + 37] << 24) | (out[(64 * i) + 36] << 16) | (out[(64 * i) + 35] << 8) | (out[(64 * i) + 34])); - Data.gnssEcefPositionZ = ((out[(64 * i) + 41] << 24) | (out[(64 * i) + 40] << 16) | (out[(64 * i) + 39] << 8) | (out[(64 * i) + 38])); - Data.gnssPositionAccuracy = ((out[(64 * i) + 45] << 24) | (out[(64 * i) + 44] << 16) | (out[(64 * i) + 43] << 8) | (out[(64 * i) + 42])); + // ECEF Earth-Centered Earth-Fixed xyz position data + Data.ecefPositionX = ((out[(64 * i) + 33] << 24) | (out[(64 * i) + 32] << 16) | (out[(64 * i) + 31] << 8) | (out[(64 * i) + 30])); + Data.ecefPositionY = ((out[(64 * i) + 37] << 24) | (out[(64 * i) + 36] << 16) | (out[(64 * i) + 35] << 8) | (out[(64 * i) + 34])); + Data.ecefPositionZ = ((out[(64 * i) + 41] << 24) | (out[(64 * i) + 40] << 16) | (out[(64 * i) + 39] << 8) | (out[(64 * i) + 38])); + Data.ecefPositionAccuracy = ((out[(64 * i) + 45] << 24) | (out[(64 * i) + 44] << 16) | (out[(64 * i) + 43] << 8) | (out[(64 * i) + 42])); // GNSS Earth-Centered Earth-Fixed xyz velocity data - Data.gnssEcefPositionX = ((out[(64 * i) + 50] << 24) | (out[(64 * i) + 49] << 16) | (out[(64 * i) + 48] << 8) | (out[(64 * i) + 47])); - Data.gnssEcefPositionY = ((out[(64 * i) + 54] << 24) | (out[(64 * i) + 53] << 16) | (out[(64 * i) + 52] << 8) | (out[(64 * i) + 51])); - Data.gnssEcefPositionZ = ((out[(64 * i) + 58] << 24) | (out[(64 * i) + 57] << 16) | (out[(64 * i) + 56] << 8) | (out[(64 * i) + 55])); - Data.gnssPositionAccuracy = ((out[(64 * i) + 62] << 24) | (out[(64 * i) + 61] << 16) | (out[(64 * i) + 60] << 8) | (out[(64 * i) + 59])); + Data.ecefVelocityX = ((out[(64 * i) + 50] << 24) | (out[(64 * i) + 49] << 16) | (out[(64 * i) + 48] << 8) | (out[(64 * i) + 47])); + Data.ecefVelocityY = ((out[(64 * i) + 54] << 24) | (out[(64 * i) + 53] << 16) | (out[(64 * i) + 52] << 8) | (out[(64 * i) + 51])); + Data.ecefVelocityZ = ((out[(64 * i) + 58] << 24) | (out[(64 * i) + 57] << 16) | (out[(64 * i) + 56] << 8) | (out[(64 * i) + 55])); + Data.ecefVelocityAccuracy = ((out[(64 * i) + 62] << 24) | (out[(64 * i) + 61] << 16) | (out[(64 * i) + 60] << 8) | (out[(64 * i) + 59])); // ctc table Data.crc = 0x0000; diff --git a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h index ad9d458..c0bf53a 100644 --- a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h +++ b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h @@ -19,29 +19,29 @@ class MemoryW25q1128jvSpi { public: #pragma pack(push, 1) - struct TelemetryData { + struct afsTelemetryData { uint8_t type = 0x00; - uint32_t timestamp = 0xFFFFFFFF; // ms since startup - uint8_t state = 0x00; // state for AFS, unused on ECU - int16_t imuGyroscopeX = 0xFFFF; // 0.061 deg/s per LSB - int16_t imuGyroscopeY = 0xFFFF; // 0.061 deg/s per LSB - int16_t imuGyroscopeZ = 0xFFFF; // 0.061 deg/s per LSB - int16_t imuAccelerometerX = 0xFFFF; // 0.00073g per LSB - int16_t imuAccelerometerY = 0xFFFF; // 0.00073g per LSB - int16_t imuAccelerometerZ = 0xFFFF; // 0.00073g per LSB - int16_t imuMagnetometerX = 0xFFFF; // 0.063 uT per LSB - int16_t imuMagnetometerY = 0xFFFF; // 0.063 uT per LSB - int16_t imuMagnetometerZ = 0xFFFF; // 0.063 uT per LSB - int16_t altimeterTemperature = 0xFFFF; // 10^-2 C - int32_t altimeterAltitude = 0xFFFFFFFF; // cm - int32_t gnssEcefPositionX = 0xFFFFFFFF; // cm - int32_t gnssEcefPositionY = 0xFFFFFFFF; // cm - int32_t gnssEcefPositionZ = 0xFFFFFFFF; // cm - uint32_t gnssPositionAccuracy = 0xFFFFFFFF; // cm - int32_t gnssEcefVelocityX = 0xFFFFFFFF; // cm/s - int32_t gnssEcefVelocityY = 0xFFFFFFFF; // cm/s - int32_t gnssEcefVelocityZ = 0xFFFFFFFF; // cm/s - uint32_t gnssVelocityAccuracy = 0xFFFFFFFF; // cm/s + uint32_t timestamp; + uint8_t state; + int16_t angularVelocityX = 0xFFFF; + int16_t angularVelocityY = 0xFFFF; + int16_t angularVelocityZ = 0xFFFF; + int16_t accelerationX = 0xFFFF; + int16_t accelerationY = 0xFFFF; + int16_t accelerationZ = 0xFFFF; + int16_t magneticFieldX = 0xFFFF; + int16_t magneticFieldY = 0xFFFF; + int16_t magneticFieldZ = 0xFFFF; + int16_t temperature = 0xFFFF; + int32_t altitude = 0xFFFFFFFF; + int32_t ecefPositionX = 0xFFFFFFFF; + int32_t ecefPositionY = 0xFFFFFFFF; + int32_t ecefPositionZ = 0xFFFFFFFF; + uint32_t ecefPositionAccuracy = 0xFFFFFFFF; + int32_t ecefVelocityX = 0xFFFFFFFF; + int32_t ecefVelocityY = 0xFFFFFFFF; + int32_t ecefVelocityZ = 0xFFFFFFFF; + uint32_t ecefVelocityAccuracy = 0xFFFFFFFF; uint16_t crc = 0x0000; }; #pragma pack(pop) @@ -113,16 +113,16 @@ class MemoryW25q1128jvSpi { * @brief Writes Telemetrydata stuct into TelemetryData Data_Bundle[4] array * @retval Operation status, 1 for success */ - uint8_t Chip_Write(TelemetryData data); + uint8_t Chip_Write(afsTelemetryData data); /** * @brief Reads read_addess page data and returns eturns pointer to Data_Bundle array * */ - TelemetryData *Chip_Read(uint32_t read_address); + afsTelemetryData *Chip_Read(uint32_t read_address); // Data bundle array consisting of 4, 64 byte, data packages outlined in struct Telemetrydata - MemoryW25q1128jvSpi::TelemetryData Data_Bundle[4]; + MemoryW25q1128jvSpi::afsTelemetryData Data_Bundle[4]; private: SPI_HandleTypeDef *spi; From 6b6a6216132e0c05066e95cbe12469f0b404fc5b Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 21 Feb 2024 17:36:25 -0800 Subject: [PATCH 5/8] Working Imu code --- imu_bmi088_spi/imu_bmi088_spi.cpp | 150 ++++++++++++++++++++++++++++++ imu_bmi088_spi/imu_bmi088_spi.h | 96 +++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 imu_bmi088_spi/imu_bmi088_spi.cpp create mode 100644 imu_bmi088_spi/imu_bmi088_spi.h diff --git a/imu_bmi088_spi/imu_bmi088_spi.cpp b/imu_bmi088_spi/imu_bmi088_spi.cpp new file mode 100644 index 0000000..7c5e111 --- /dev/null +++ b/imu_bmi088_spi/imu_bmi088_spi.cpp @@ -0,0 +1,150 @@ +#include "imu_bmi088_spi.h" + +ImuBmi088Spi::ImuBmi088Spi(SPI_HandleTypeDef *hspi, + GPIO_TypeDef *accCsPort, uint16_t accCsPin, + GPIO_TypeDef *gyroCsPort, uint16_t gyroCsPin) + : + + _hspi(hspi), + _accCsPort(accCsPort), _accCsPin(accCsPin), + _gyroCsPort(gyroCsPort), _gyroCsPin(gyroCsPin) +{ +} + +/* Notes */ +// | 0x00 is for write, | 0x80 is for read +// Accelerometer instruction has a 2nd dummy byte after instruction for reads +// Any array in UPPER_SNAKE_CASE functions as a constant variable + +int ImuBmi088Spi::Reset() +{ + // setting the chip select pins high + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET); + + /* Accelerometer softreset */ + // Accelerometer will be in suspend mode afterwards + uint8_t ACC_SOFTRESET[2] = {0x7E | 0x00, 0xB6}; + + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, ACC_SOFTRESET, 2, SERIAL_TIMEOUT) != HAL_OK) return 1; + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); + + /* Gyroscope softreset */ + uint8_t GYRO_SOFTRESET[2] = {0x14 | 0x00, 0xB6}; + + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, GYRO_SOFTRESET, 2, SERIAL_TIMEOUT) != HAL_OK) return 1; + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET); + + // Delay for Gyro_softreset to complete + HAL_Delay(30); + + return 0; +} + +int ImuBmi088Spi::Init() +{ + // setting the chip select pins high + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET); + + /* Accelerometer power on sequence */ + // Switches the Accelerometer from suspend to normal mode + uint8_t ACC_PWR_CONF[2] = {0x7C | 0x00, 0x00}; + + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, ACC_PWR_CONF, 2, SERIAL_TIMEOUT) != HAL_OK) return 1; + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); + + // Switches Accelerometer on + // 0x04 for for accelerometer on + uint8_t ACC_PWR_CTRL[2] = {0x7D | 0x00, 0x04}; + + // spi write to ACC_PWR_CTRL register to move to normal mode + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, ACC_PWR_CTRL, 2, SERIAL_TIMEOUT) != HAL_OK) return 1; + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); + + // 1 ms delay after change to normal mode + HAL_Delay(1); + + /* Setting Accelerometer range to +- 24g */ + uint8_t ACC_RANGE[2] = {0x41 | 0x00, 0x03}; + + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, ACC_RANGE, 2, SERIAL_TIMEOUT) != HAL_OK) return 1; + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); + // + + /* Gyro power normal power mode */ + // Switches Gyro from suspend to normal mode + // 0x00 for set to normal mode + uint8_t gyro_Lpm1[2] = {0x11 | 0x00, 0x00}; + + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, gyro_Lpm1, 2, SERIAL_TIMEOUT) != HAL_OK) return 1; + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET); + + // Delay to ensure state change + HAL_Delay(30); + + /* Accelerometer Chip ID read */ + // Dummy byte 0x00 + uint8_t ACC_CHIP_ID[2] = {0x00 | 0x80, 0x00}; + uint8_t accID[1] = {0}; + + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, ACC_CHIP_ID, 2, SERIAL_TIMEOUT) != HAL_OK) return 1; + if (HAL_SPI_Receive(_hspi, accID, 1, SERIAL_TIMEOUT) != HAL_OK) return 1; + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); + + /* Gyroscope Chip ID read */ + uint8_t GYRO_CHIP_ID[1] = {0x00 | 0x80}; + uint8_t gyroID[1] = {0}; + + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, GYRO_CHIP_ID, 1, SERIAL_TIMEOUT) != HAL_OK) return 1; + if (HAL_SPI_Receive(_hspi, gyroID, 1, SERIAL_TIMEOUT) != HAL_OK) return 1; + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET); + + /* Self check if device ID of gyro and accelerometer are correct */ + if (accID[0] != 0x1E) return 2; + if (gyroID[0] != 0x0F) return 3; + + return 0; +} + +ImuBmi088Spi::Data ImuBmi088Spi::Read() +{ + ImuBmi088Spi::Data data; + + /* Accelerometer data registers read */ + uint8_t ACC_DATA_REGISTERS[2] = {0x12 | 0x80, 0x00}; + uint8_t accelerometerData[6] = {0}; + + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, ACC_DATA_REGISTERS, 2, SERIAL_TIMEOUT) != HAL_OK) return data; + if (HAL_SPI_Receive(_hspi, accelerometerData, 6, SERIAL_TIMEOUT) != HAL_OK) return data; + HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); + + /* Gyroscope data registers read */ + uint8_t GYRO_DATA_REGISTERS[1] = {0x02 | 0x80}; + uint8_t gyroscopeData[6] = {0}; + + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_RESET); + if (HAL_SPI_Transmit(_hspi, GYRO_DATA_REGISTERS, 1, SERIAL_TIMEOUT) != HAL_OK) return data; + if (HAL_SPI_Receive(_hspi, gyroscopeData, 6, SERIAL_TIMEOUT) != HAL_OK) return data; + HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET); + + // Acceleration and angular velocity data being attributed into the Data struct + data.accelerationX = ((accelerometerData[1] << 8) + (accelerometerData[0])); + data.accelerationY = ((accelerometerData[3] << 8) + (accelerometerData[2])); + data.accelerationZ = ((accelerometerData[5] << 8) + (accelerometerData[4])); + + data.angularVelocityX = ((gyroscopeData[1] << 8) + (gyroscopeData[0])); + data.angularVelocityY = ((gyroscopeData[3] << 8) + (gyroscopeData[2])); + data.angularVelocityZ = ((gyroscopeData[5] << 8) + (gyroscopeData[4])); + + return data; +} diff --git a/imu_bmi088_spi/imu_bmi088_spi.h b/imu_bmi088_spi/imu_bmi088_spi.h new file mode 100644 index 0000000..f483aba --- /dev/null +++ b/imu_bmi088_spi/imu_bmi088_spi.h @@ -0,0 +1,96 @@ +#pragma once + +#if defined(STM32F1) +#include "stm32f1xx_hal.h" +#elif defined(STM32F4xx) +#include "stm32f4xx_hal.h" +#endif + +#ifndef SERIAL_TIMEOUT +#define SERIAL_TIMEOUT 10 +#endif + +/* Datasheet */ +/* https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmi088-ds001.pdf */ + +class ImuBmi088Spi +{ + public: + struct Data + { + // Angular velocity counterclockwise along x-axis, launch vehicle frame + // Units 6.1*10^-2 degree/s + int16_t angularVelocityX = 0xFFFF; + + // Angular velocity counterclockwise along y-axis, launch vehicle frame + // Units 6.1*10^-2 degree/s + int16_t angularVelocityY = 0xFFFF; + + // Angular velocity counterclockwise along z-axis, launch vehicle frame + // Units 6.1*10^-2 degree/s + int16_t angularVelocityZ = 0xFFFF; + + // Acceleration along x-axis, launch vehicle frame + // Units: 7.3 * 10^-4 g + int16_t accelerationX = 0xFFFF; + + // Acceleration along y-axis, launch vehicle frame + // Units: 7.3 * 10^-4 g + int16_t accelerationY = 0xFFFF; + + // Acceleration along x-axis, launch vehicle frame + // Units: 7.3 * 10^-4 g + int16_t accelerationZ = 0xFFFF; + }; + + /** + * @param hspi SPI bus handler + * @param accCsPort chip select port accelerometer + * @param accCsPin chip select pin accelerometer + * @param gyroCsPort chip select port gyroscope + * @param gyroCsPin chip select pin gyroscope + */ + + ImuBmi088Spi(SPI_HandleTypeDef *hspi, + GPIO_TypeDef *accCsPort, uint16_t accCsPin, + GPIO_TypeDef *gyroCsPort, uint16_t gyroCsPin); + + /** + * @brief Resets the IMU + * @retval Operation status, 0 for success + * @retval Operation failure, 1 for SPI transmit/recieve failure + */ + int Reset(); + + /** + * @brief Initializes the IMU + * @retval Operation status, 0 for success + * @retval Operation failure, 1 for SPI transmit/recieve failure + * @retval Operation failure, 2 for accelerometer ID fault + * @retval Operation failure, 3 for gyroscope ID fault + */ + int Init(); + + /** + * @brief Reads Gyroscope and Acceleration data + * @retval Output is struct Data + * @retval if any values = FFFF, then ERROR + */ + Data Read(); + + private: + // SPI bus handler + SPI_HandleTypeDef *_hspi; + + // Chip select port + GPIO_TypeDef *_accCsPort; + + // chip select pin accelerometer + uint16_t _accCsPin; + + // chip select port gyroscope + GPIO_TypeDef *_gyroCsPort; + + // chip select pin gyroscope + uint16_t _gyroCsPin; +}; From 907fbc50cc3b364e4cb7fc8be1a3326cb6a1a914 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 21 Feb 2024 18:14:54 -0800 Subject: [PATCH 6/8] deleted the uckery --- .../memory_w25q1128jv_spi.cc | 223 ------------------ memory_w25q1128jv_spi/memory_w25q1128jv_spi.h | 137 ----------- 2 files changed, 360 deletions(-) delete mode 100644 memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc delete mode 100644 memory_w25q1128jv_spi/memory_w25q1128jv_spi.h diff --git a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc deleted file mode 100644 index 75402f7..0000000 --- a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.cc +++ /dev/null @@ -1,223 +0,0 @@ -#include - -MemoryW25q1128jvSpi::MemoryW25q1128jvSpi(SPI_HandleTypeDef *_spi, GPIO_TypeDef *_csPort, uint16_t _csPin, GPIO_TypeDef *_holdPort, uint16_t _holdPin, GPIO_TypeDef *_wpPort, uint16_t _wpPin) - - : spi(_spi), csPort(_csPort), csPin(_csPin), holdPort(_holdPort), holdPin(_holdPin), wpPort(_wpPort), wpPin(_wpPin) {} - -uint8_t MemoryW25q1128jvSpi::Init() { - // making sure control pins are always high - HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // Data holder for reading address - afsTelemetryData _init_Data; - // Reads Chip ID, if chip ID is not W25Q128JV_MEMORY, then return 0 - if (DeviceID() != 0xEF17) return 0; - - // while loop to read through every memory page - // Result, address starts in the first empty page - while (1) { - // Reads a page of memory - Chip_Read(address);afsTelemetryData; - address++; - } - return 1; -} - -uint16_t MemoryW25q1128jvSpi::DeviceID() { - // making sure control pins are always high - HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // input instruction hex + 3 dummy bytes - uint8_t in[4] = {0x90, 0x00, 0x00, 0x00}; - // output array of bytes - uint8_t out[2] = {0}; - - // SPI protocol - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); - if (HAL_SPI_Transmit(spi, in, 4, 10) != HAL_OK) return 0; - if (HAL_SPI_Receive(spi, out, 2, 10) != HAL_OK) return 0; - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // returns the 2 bytes as a uint16_t - return (uint16_t)(out[0] << 8 | out[1]); -} - -uint8_t MemoryW25q1128jvSpi::Read_Status_Reg1(uint8_t Reg_check, uint8_t Reg_until) { - // making sure that control pins are always high - HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // input operation code for reading status register 1 - uint8_t in[1] = {0x05}; - // output -- 8 bit value of the status register - uint8_t out[1] = {0}; - - // do while loop of reading status register - // loop ends when the input Reg_check value == Reg_until - do { - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); - if (HAL_SPI_Transmit(spi, in, 1, 10) != HAL_OK) return 0; - if (HAL_SPI_Receive(spi, out, 1, 10) != HAL_OK) return 0; - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - } while ((out[0] & Reg_check) == Reg_until); - - return 1; -} - -uint8_t MemoryW25q1128jvSpi::Chip_Erase() { - // making sure that control pins are always high - HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // instruction array for chip enable command - uint8_t chip_enable[1] = {0x06}; - // instruction array for chip erase command - uint8_t chip_erase[1] = {0xC7}; - - // 1. enable chip with Chip_enable - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); - if (HAL_SPI_Transmit(spi, chip_enable, 1, 10) != HAL_OK) return 0; - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // Checks and waits until status register write enable latch is = 1 - if (MemoryW25q1128jvSpi::Read_Status_Reg1(0x02, 0) == 0) return 0; - - // 2. runs chip erase command - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); - if (HAL_SPI_Transmit(spi, chip_erase, 1, 10) != HAL_OK) return 0; - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // Checks and waits until status register busy bit is = 0 - if (MemoryW25q1128jvSpi::Read_Status_Reg1(0x01, 1) == 0) return 0; - - return 1; -} - -uint8_t MemoryW25q1128jvSpi::Chip_Write(afsTelemetryData data) { - // making sure that control pins are always high - HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // if address variable goes over the amount of pages memory has - // no more collected data will be written into the memory - if (address > 0xFFFF) return 0; - - // Bundles Telemetry data struct into a 4 element array - // Telemetry data is written into the array until all 4 elements are full - if (Data_Bundle_Size < 3) { - Data_Bundle[Data_Bundle_Size] = data; - Data_Bundle_Size++; - return 1; - } - - // resets bundled data variable and inserts the last Telemetry data values - Data_Bundle[3] = data; - Data_Bundle_Size = 0; - - // Chip enable instruction command - uint8_t chip_enable[1] = {0x06}; - // Page Program instruction command - uint8_t Page_program[4] = {0x02, (uint8_t)(address >> 8), (uint8_t)(address), 0x00}; // instruction opcode for Page Program - - // chip enable instruction to enable chip - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); - if (HAL_SPI_Transmit(spi, chip_enable, 1, SPI_Timeout) != HAL_OK) return 0; - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // Checks and waits until status register write bit is = 0 - // waits until Chip enable is done - if (MemoryW25q1128jvSpi::Read_Status_Reg1(2, 1) == 0) return 0; - - // Write Data bundle into memory - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); - if (HAL_SPI_Transmit(spi, Page_program, 4, SPI_Timeout) != HAL_OK) return 0; - if (HAL_SPI_Transmit(spi, (uint8_t *)Data_Bundle, 256, SPI_Timeout) != HAL_OK) return 0; - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // Checks and waits until status register busy bit is = 0 - // waits until page write is done - if (MemoryW25q1128jvSpi::Read_Status_Reg1(1, 0) == 0) return 0; - - // increments to the next page address - address++; - - return 1; -} - -MemoryW25q1128jvSpi::afsTelemetryData *MemoryW25q1128jvSpi::Chip_Read(uint32_t read_address) { - // making sure that control pins are always high - HAL_GPIO_WritePin(wpPort, wpPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(holdPort, holdPin, GPIO_PIN_SET); - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // initalisation of input, output, and dumby telemtrydata variable for temporary writing to DataBundle - uint8_t Read_Data[4] = {0x03, (uint8_t)(read_address >> 8), (uint8_t)(read_address), 0x00}; - uint8_t out[256] = {0}; - MemoryW25q1128jvSpi::afsTelemetryData Data; - - // Reads address page in memory - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_RESET); - if (HAL_SPI_Transmit(spi, Read_Data, 4, SPI_Timeout) != HAL_OK) return Data_Bundle; - if (HAL_SPI_Receive(spi, out, 256, SPI_Timeout) != HAL_OK) return Data_Bundle; - HAL_GPIO_WritePin(csPort, csPin, GPIO_PIN_SET); - - // Checks and waits until status register busy bit is = 0 - // waits until page read is done - if (MemoryW25q1128jvSpi::Read_Status_Reg1(0x01, 1) == 0) return 0; - - // organisation of Databundle from read page until Data_Bundle array - for (int i = 0; i < 4; i++) { - // Specifier for telemetry data - Data.type = out[(64 * i)]; - // Timestamp for data - Data.timestamp = ((out[(64 * i) + 4] << 24) | (out[(64 * i) + 3] << 16) | (out[(64 * i) + 2] << 8) | (out[(64 * i) + 1])); - // What state AFS was in - Data.state = ((out[(64 * i) + 6] << 8) | (out[(64 * i) + 5])); - - // IMU Gyroscope data - Data.angularVelocityX = ((out[(64 * i) + 8] << 8) | (out[(64 * i) + 7])); - Data.angularVelocityY = ((out[(64 * i) + 10] << 8) | (out[(64 * i) + 9])); - Data.angularVelocityZ = ((out[(64 * i) + 12] << 8) | (out[(64 * i) + 11])); - ; - - // IMU Accelerometer data - Data.accelerationX = ((out[(64 * i) + 14] << 8) | (out[(64 * i) + 13])); - Data.accelerationY = ((out[(64 * i) + 16] << 8) | (out[(64 * i) + 15])); - Data.accelerationZ = ((out[(64 * i) + 18] << 8) | (out[(64 * i) + 17])); - - // IMU Magnetometer data - Data.magneticFieldX = ((out[(64 * i) + 20] << 8) | (out[(64 * i) + 19])); - Data.magneticFieldY = ((out[(64 * i) + 22] << 8) | (out[(64 * i) + 21])); - Data.magneticFieldZ = ((out[(64 * i) + 24] << 8) | (out[(64 * i) + 23])); - - // altimeter data being concentated into corresponeding byes - Data.temperature = ((out[(64 * i) + 25] << 8) | (out[(64 * i) + 24])); - Data.altitude = ((out[(64 * i) + 29] << 24) | (out[(64 * i) + 28] << 16) | (out[(64 * i) + 27] << 8) | (out[(64 * i) + 26])); - - // ECEF Earth-Centered Earth-Fixed xyz position data - Data.ecefPositionX = ((out[(64 * i) + 33] << 24) | (out[(64 * i) + 32] << 16) | (out[(64 * i) + 31] << 8) | (out[(64 * i) + 30])); - Data.ecefPositionY = ((out[(64 * i) + 37] << 24) | (out[(64 * i) + 36] << 16) | (out[(64 * i) + 35] << 8) | (out[(64 * i) + 34])); - Data.ecefPositionZ = ((out[(64 * i) + 41] << 24) | (out[(64 * i) + 40] << 16) | (out[(64 * i) + 39] << 8) | (out[(64 * i) + 38])); - Data.ecefPositionAccuracy = ((out[(64 * i) + 45] << 24) | (out[(64 * i) + 44] << 16) | (out[(64 * i) + 43] << 8) | (out[(64 * i) + 42])); - - // GNSS Earth-Centered Earth-Fixed xyz velocity data - Data.ecefVelocityX = ((out[(64 * i) + 50] << 24) | (out[(64 * i) + 49] << 16) | (out[(64 * i) + 48] << 8) | (out[(64 * i) + 47])); - Data.ecefVelocityY = ((out[(64 * i) + 54] << 24) | (out[(64 * i) + 53] << 16) | (out[(64 * i) + 52] << 8) | (out[(64 * i) + 51])); - Data.ecefVelocityZ = ((out[(64 * i) + 58] << 24) | (out[(64 * i) + 57] << 16) | (out[(64 * i) + 56] << 8) | (out[(64 * i) + 55])); - Data.ecefVelocityAccuracy = ((out[(64 * i) + 62] << 24) | (out[(64 * i) + 61] << 16) | (out[(64 * i) + 60] << 8) | (out[(64 * i) + 59])); - - // ctc table - Data.crc = 0x0000; - - // insertion of organised data into data bundle - Data_Bundle[i] = Data; - } - return Data_Bundle; -} diff --git a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h b/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h deleted file mode 100644 index c0bf53a..0000000 --- a/memory_w25q1128jv_spi/memory_w25q1128jv_spi.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * W25Q128JV_MEMORY.h - * - * Created on: Jan 1, 2024 - * Author: rober - */ -#pragma once - -#include - -#if defined(STM32F1) -#include "stm32f1xx_hal.h" -#endif - -#ifndef SPI_Timeout -#define SPI_Timeout 10 -#endif - -class MemoryW25q1128jvSpi { - public: -#pragma pack(push, 1) - struct afsTelemetryData { - uint8_t type = 0x00; - uint32_t timestamp; - uint8_t state; - int16_t angularVelocityX = 0xFFFF; - int16_t angularVelocityY = 0xFFFF; - int16_t angularVelocityZ = 0xFFFF; - int16_t accelerationX = 0xFFFF; - int16_t accelerationY = 0xFFFF; - int16_t accelerationZ = 0xFFFF; - int16_t magneticFieldX = 0xFFFF; - int16_t magneticFieldY = 0xFFFF; - int16_t magneticFieldZ = 0xFFFF; - int16_t temperature = 0xFFFF; - int32_t altitude = 0xFFFFFFFF; - int32_t ecefPositionX = 0xFFFFFFFF; - int32_t ecefPositionY = 0xFFFFFFFF; - int32_t ecefPositionZ = 0xFFFFFFFF; - uint32_t ecefPositionAccuracy = 0xFFFFFFFF; - int32_t ecefVelocityX = 0xFFFFFFFF; - int32_t ecefVelocityY = 0xFFFFFFFF; - int32_t ecefVelocityZ = 0xFFFFFFFF; - uint32_t ecefVelocityAccuracy = 0xFFFFFFFF; - uint16_t crc = 0x0000; - }; -#pragma pack(pop) - -#pragma pack(push, 1) - struct AfsState { - bool armPinState : 1; // 0: unarmed, 1: armed - bool drogueContinuity : 1; // 0: no continuity, 1: continuity - bool mainContinuity : 1; // 0: no continuity, 1: continuity - uint16_t : 1; // reserved - /** - * 0x0: standby - * 0x1: armed - * 0x2: boost - * 0x3: coast - * 0x4: apogee - * 0x5: drogue fired - * 0x6: drogue opened - * 0x7 drogue failure - * 0x8: main fired - * 0x9: main opened - * 0xA: main failure - * 0xB: land - */ - uint8_t state : 4; - }; -#pragma pack(pop) - - /** - * @param _spi SPI bus handler - * @param _csPort chip select GPIO port - * @param _csPin chip select GPIO pin - * @param _holdPort Write HOLD GPIO port - * @param _holdPin Write HOLD GPIO pin - * @param _wpPort Write Protect GPIO port - * @param _wpPin Write Protect GPIO pin - */ - MemoryW25q1128jvSpi(SPI_HandleTypeDef *_spi, GPIO_TypeDef *_csPort, uint16_t _csPin, GPIO_TypeDef *_holdPort, uint16_t _holdPin, GPIO_TypeDef *_wpPort, uint16_t); - - /** - * @brief Initialises the memory by reading and incrementing to the first non-written page - * @retval Operation status, 1 for success - */ - uint8_t Init(); - - /** - * @brief Reads the device ID of the memory/ - * Should output 0xEF for manufacturer ID, - * Should output 0x90 for Device ID - */ - uint16_t DeviceID(); - - /** - * @brief Reads the first status register from memort - * 2 inputs - * Reg_check, Status Register bit to check status of - * Reg_until, wait until Status register bit = Reg_until value - * @retval Operation status, 1 for success - */ - uint8_t Read_Status_Reg1(uint8_t Reg_check, uint8_t Reg_until); - - /** - * @brief Erases all data on chip - * @retval Operation status, 1 for success - */ - uint8_t Chip_Erase(); - - /** - * @brief Writes Telemetrydata stuct into TelemetryData Data_Bundle[4] array - * @retval Operation status, 1 for success - */ - uint8_t Chip_Write(afsTelemetryData data); - - /** - * @brief Reads read_addess page data and returns eturns pointer to Data_Bundle array - * - */ - afsTelemetryData *Chip_Read(uint32_t read_address); - - // Data bundle array consisting of 4, 64 byte, data packages outlined in struct Telemetrydata - MemoryW25q1128jvSpi::afsTelemetryData Data_Bundle[4]; - - private: - SPI_HandleTypeDef *spi; - GPIO_TypeDef *csPort; - uint16_t csPin; - GPIO_TypeDef *holdPort; - uint16_t holdPin; - GPIO_TypeDef *wpPort; - uint16_t wpPin; - uint8_t Data_Bundle_Size = 0; - uint32_t address = 0x00000000; -}; From b13bb5100c4509d5a8e343ebd01c81d0053c7eef Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 21 Feb 2024 18:29:36 -0800 Subject: [PATCH 7/8] Thank krin --- imu_bmi088_spi/imu_bmi088_spi.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imu_bmi088_spi/imu_bmi088_spi.cpp b/imu_bmi088_spi/imu_bmi088_spi.cpp index 7c5e111..cbc598d 100644 --- a/imu_bmi088_spi/imu_bmi088_spi.cpp +++ b/imu_bmi088_spi/imu_bmi088_spi.cpp @@ -16,6 +16,9 @@ ImuBmi088Spi::ImuBmi088Spi(SPI_HandleTypeDef *hspi, // Accelerometer instruction has a 2nd dummy byte after instruction for reads // Any array in UPPER_SNAKE_CASE functions as a constant variable + + + int ImuBmi088Spi::Reset() { // setting the chip select pins high From 348b1f8dc2b5647ad355167e16028402e21fc915 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 21 Feb 2024 18:32:41 -0800 Subject: [PATCH 8/8] thanks miky and danny --- imu_bmi088_spi/imu_bmi088_spi.cpp | 24 ++++++++---------------- imu_bmi088_spi/imu_bmi088_spi.h | 10 +++------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/imu_bmi088_spi/imu_bmi088_spi.cpp b/imu_bmi088_spi/imu_bmi088_spi.cpp index cbc598d..4bec3b7 100644 --- a/imu_bmi088_spi/imu_bmi088_spi.cpp +++ b/imu_bmi088_spi/imu_bmi088_spi.cpp @@ -1,26 +1,20 @@ #include "imu_bmi088_spi.h" -ImuBmi088Spi::ImuBmi088Spi(SPI_HandleTypeDef *hspi, - GPIO_TypeDef *accCsPort, uint16_t accCsPin, - GPIO_TypeDef *gyroCsPort, uint16_t gyroCsPin) +ImuBmi088Spi::ImuBmi088Spi(SPI_HandleTypeDef *hspi, GPIO_TypeDef *accCsPort, uint16_t accCsPin, GPIO_TypeDef *gyroCsPort, uint16_t gyroCsPin) : _hspi(hspi), - _accCsPort(accCsPort), _accCsPin(accCsPin), - _gyroCsPort(gyroCsPort), _gyroCsPin(gyroCsPin) -{ -} + _accCsPort(accCsPort), + _accCsPin(accCsPin), + _gyroCsPort(gyroCsPort), + _gyroCsPin(gyroCsPin) {} /* Notes */ // | 0x00 is for write, | 0x80 is for read // Accelerometer instruction has a 2nd dummy byte after instruction for reads // Any array in UPPER_SNAKE_CASE functions as a constant variable - - - -int ImuBmi088Spi::Reset() -{ +int ImuBmi088Spi::Reset() { // setting the chip select pins high HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET); @@ -46,8 +40,7 @@ int ImuBmi088Spi::Reset() return 0; } -int ImuBmi088Spi::Init() -{ +int ImuBmi088Spi::Init() { // setting the chip select pins high HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET); HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET); @@ -118,8 +111,7 @@ int ImuBmi088Spi::Init() return 0; } -ImuBmi088Spi::Data ImuBmi088Spi::Read() -{ +ImuBmi088Spi::Data ImuBmi088Spi::Read() { ImuBmi088Spi::Data data; /* Accelerometer data registers read */ diff --git a/imu_bmi088_spi/imu_bmi088_spi.h b/imu_bmi088_spi/imu_bmi088_spi.h index f483aba..9f1dbff 100644 --- a/imu_bmi088_spi/imu_bmi088_spi.h +++ b/imu_bmi088_spi/imu_bmi088_spi.h @@ -13,11 +13,9 @@ /* Datasheet */ /* https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmi088-ds001.pdf */ -class ImuBmi088Spi -{ +class ImuBmi088Spi { public: - struct Data - { + struct Data { // Angular velocity counterclockwise along x-axis, launch vehicle frame // Units 6.1*10^-2 degree/s int16_t angularVelocityX = 0xFFFF; @@ -51,9 +49,7 @@ class ImuBmi088Spi * @param gyroCsPin chip select pin gyroscope */ - ImuBmi088Spi(SPI_HandleTypeDef *hspi, - GPIO_TypeDef *accCsPort, uint16_t accCsPin, - GPIO_TypeDef *gyroCsPort, uint16_t gyroCsPin); + ImuBmi088Spi(SPI_HandleTypeDef *hspi, GPIO_TypeDef *accCsPort, uint16_t accCsPin, GPIO_TypeDef *gyroCsPort, uint16_t gyroCsPin); /** * @brief Resets the IMU