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.
187 lines
6.0 KiB
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); };
|
|
};
|