/** * @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 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 Output registers of sensor containing metadata and pixels */ array 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 Answer to command, example: status byte, readout bytes, etc. */ template array Command(Commands command, array payload){ array 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 Array of received bytes */ template array Transmit_and_receive(array &byte_stream){ array 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); }; };