blob: e04ea38b8aefc363e73a68a4e6ed0ce1c9e22ffe [file]
#pragma once
#include "SPI.h"
#include <Arduino.h>
#include <stdint.h>
#include "pw_bytes/span.h"
#include "pw_result/result.h"
#include "pw_span/span.h"
#include "pw_status/status.h"
using pw::span;
using pw::Status;
namespace gonk::adc {
const uint32_t kFramedProtoMagicConstant = 0x7DAABB99;
const uint8_t kTotalAdcCount = 11;
const uint8_t kMaxStreamingAdcCount = 11;
class Adc {
public:
Adc(Stream &serial_stream, SPIClass &fpga_spi, uint32_t fpga_spi_baudrate,
uint16_t fpga_cs_pin, uint16_t fpga_mode_pin, uint16_t fpga_reset_pin,
uint16_t fpga_valid_pin);
void InitInterrupts();
Status InitAdcs();
Status CheckAllAdcs();
void SetReadWriteMode();
void SetContinuousReadMode();
Status UpdateContinuousMeasurements();
Status WriteMeasurementPacket();
// Writing and reading data over SPI.
void StartSpiTransaction();
void EndSpiTransaction();
void WriteAddress(uint32_t adc_address);
Status WriteData(pw::ByteSpan write_buffer);
pw::Result<pw::ConstByteSpan> ReadData(pw::ByteSpan read_buffer);
// ADC Register Manipulation.
pw::Result<pw::ConstByteSpan> GetRegister(uint8_t adc_number,
uint8_t adc_register);
Status WriteRegister(uint8_t adc_number, uint8_t adc_register,
pw::ByteSpan write_buffer);
Status WriteRegisterAll(uint8_t adc_register, pw::ByteSpan write_buffer);
Status SelectContinuousReadAdcs(uint16_t adc_selection);
// ADC Specific functions.
pw::Result<pw::ConstByteSpan> GetManufacturerID(uint8_t adc_number);
pw::Result<pw::ConstByteSpan> GetADCConfiguration(uint8_t adc_number);
Status SetADCConfiguration(uint8_t adc_number, pw::ByteSpan write_buffer);
pw::Result<pw::ConstByteSpan> GetShuntCalibration(uint8_t adc_number);
pw::Result<int32_t> GetShuntVoltageMeasurement(uint8_t adc_number);
pw::Result<int32_t> GetBusVoltageMeasurement(uint8_t adc_number);
private:
struct Measurement {
std::array<std::byte, 3> vbus_bytes_;
std::array<std::byte, 3> vshunt_bytes_;
int32_t vbus_value_;
int32_t vshunt_value_;
};
std::array<Measurement, kMaxStreamingAdcCount> measurements_;
uint32_t previous_timestamp_;
uint32_t measurement_timestamp_;
uint32_t measurement_delta_micros_;
uint16_t fpga_reset_;
uint16_t fpga_mode_;
uint16_t fpga_valid_;
uint16_t fpga_cs_;
Stream &serial_;
SPIClass &fpga_spi_;
SPISettings spi_settings_;
uint8_t sampled_adc_count_;
uint8_t sample_read_index_;
std::array<uint32_t, 16> sample_read_time_;
Status WaitForFpgaIOValid(uint32_t timeout_ms);
Status WaitForFpgaIOValidPulse(uint32_t timeout_ms);
// FPGA ADC Address selection.
uint32_t ADCAddress(uint8_t adc_number, uint8_t adc_command, uint8_t mode);
uint32_t ADCAddressWrite(uint8_t adc_number, uint8_t adc_command);
uint32_t ADCAddressWriteAll(uint8_t adc_command);
uint32_t ADCAddressWriteSelection(uint16_t adc_selection,
uint8_t adc_command);
pw::Result<pw::ConstByteSpan> GetThreeBytes();
// INA229 register value interpretation.
pw::Result<uint8_t> RegisterSize(uint8_t adc_register);
int32_t VoltageMeasurement(pw::ConstByteSpan read_buffer);
};
} // namespace gonk::adc