You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
BUTCube/modules/Sun_sensor/fw/MLX75306/MLX75306.hpp

187 lines
6.0 KiB

/**
* @file SPI_camera.hpp
* @author Petr Malaník (TheColonelYoung(at)gmail(dot)com)
* @brief
* @version 0.1
* @date 1.03.2023
*/
#pragma once
#include "stm32l4xx_hal.h"
#include <array>
using namespace std;
typedef unsigned int uint;
/**
* @brief Linear optical sensor array, including a 142 x 1 array of photodiodes
* associated charge amplifier circuitry and a pixel data-hold function that
* provides simultaneous integration start and stop times for all pixels.
*/
class MLX75306
{
public:
/**
* @brief Describes GPIO which serves as SPI chip select pin
*/
struct Chip_select_pin {
GPIO_TypeDef *port;
uint16_t pin;
};
/**
* @brief Command for MLX75306, whole command composes of 3 bytes, first byte is from enum below
* Other two bytes are payload which could be command specific or empty
*/
enum class Commands: uint8_t {
Idle = 0b00000000,
Chip_reset = 0b11110000,
Read_thresholds = 0b11011000,
Write_thresholds = 0b11001100,
Start_integration = 0b10111000,
Start_integration_long = 0b10110100,
Read_out_1b = 0b10011100,
Read_out_1b5 = 0b10010110,
Read_out_4b = 0b10010011,
Read_out_8b = 0b10011001,
Test_zebra_pattern_1 = 0b11101000,
Test_zebra_pattern_2 = 0b11100100,
Test_zebra_pattern_12 = 0b11100010,
Test_zebra_pattern_0 = 0b11100001,
Sleep_mode = 0b11000110,
Wake_up = 0b11000011,
};
/**
* @brief Structure of MLX75306 status byte
*/
struct __attribute__((packed)) __attribute__((__may_alias__)) Status_byte{
uint8_t command_counter : 5; // Counter of valid commands
uint8_t device_mode : 1; // Device mode: 0-Test 1-User
uint8_t power_up_in_progress : 1; // Set after first Chip_reset command, clear after power-up
uint8_t operational_mode : 1; // Device operational mode: 0-Sleep 1-Normal
};
protected:
/*
* @brief HAL handle of SPI to which is ArduChip connected
*/
SPI_HandleTypeDef SPI_handle;
/**
* @brief GPIO description which serves as SPI Chip select
*/
Chip_select_pin SPI_CS;
public:
/**
* @brief Construct a new MLX75306 object
*
* @param SPI_handle HAL handle of SPI to which is sensor connected
* @param SPI_CS GPIO description which serves as SPI Chip select
*/
MLX75306(SPI_HandleTypeDef SPI_handle, Chip_select_pin SPI_CS);
/**
* @brief Initialize sensor by reset
*/
void Init();
/**
* @brief Reset sensor, reset must be done after power-up, reset all registers
*/
void Reset();
/**
* @brief Change operational mode of sensor to Normal
* During normal mode an integration and readout could be performed.
*/
void Wake_up();
/**
* @brief Change operational mode of sensor to Sleep
* During sleep mode an integration and readout could not be performed.
* But power draw of sensor is reduced.
*/
void Sleep_mode();
/**
* @brief Sensor will charge photodiodes to defined levels to create test pattern
* Every odd pixel is charged to high level of charge, even pixel to low level of charge
* This command is used instead of Integration start
*/
void Zebra_pattern_1();
/**
* @brief Time in micro second to integrate charge photodiodes
* The shortest time is 0.1 us, the longest is 100 ms, values above or below are capped
*/
void Integrate(double time_us);
/**
* @brief Reads Status byte of sensor by using Idle command
*
* @return Status_byte Structured status byte of sensor
*/
Status_byte Status();
/**
* @brief Perform readout of all output registers and pixels from sensor
*
* @return array<uint8_t, 159> Output registers of sensor containing metadata and pixels
*/
array<uint8_t, 159> Read_all_8bit();
protected:
/**
* @brief Send command to sensor and return answer (mostly status byte and empty bytes)
*
* @tparam array_size Size of returned answer on bytes, default is 3
* @param command Command from available Commands of sensor
* @param payload Payload (parameters) of command, mostly empty but could contain integration time, atc.
* @return array<uint8_t, array_size> Answer to command, example: status byte, readout bytes, etc.
*/
template <size_t array_size = 3>
array<uint8_t, array_size> Command(Commands command, array<uint8_t, 2> payload){
array<uint8_t, array_size> byte_stream = { 0 };
byte_stream[0] = (uint8_t) command;
byte_stream[1] = payload[0];
byte_stream[2] = payload[1];
return Transmit_and_receive(byte_stream);
}
/**
* @brief Transmit bytes to sensor and receive answer
*
* @tparam array_size Amount of bytes to transfer and receive
* @param byte_stream Array of bytes to transmit
* @return array<uint8_t, array_size> Array of received bytes
*/
template <size_t array_size>
array<uint8_t, array_size> Transmit_and_receive(array<uint8_t, array_size> &byte_stream){
array<uint8_t, array_size> received = { 0 };
CS_enable();
HAL_SPI_TransmitReceive(&SPI_handle, byte_stream.data(), received.data(), byte_stream.size(), byte_stream.size());
CS_disable();
return received;
}
/**
* @brief Enables communication with sensor via SPI, CS signal is active low
*/
void CS_enable(){ HAL_GPIO_WritePin(SPI_CS.port, SPI_CS.pin, GPIO_PIN_RESET); };
/**
* @brief Disables communication with sensor via SPI, CS signal is active low
*/
void CS_disable(){ HAL_GPIO_WritePin(SPI_CS.port, SPI_CS.pin, GPIO_PIN_SET); };
};