225 lines
4.3 KiB
C++
225 lines
4.3 KiB
C++
/*
|
|
* peripherals_hal_st.hpp
|
|
*
|
|
* Created on: Mar 30, 2021
|
|
* Author: erki
|
|
*/
|
|
|
|
#ifndef PERIPHERALS_INC_PERIPHERALS_HAL_ST_HPP_
|
|
#define PERIPHERALS_INC_PERIPHERALS_HAL_ST_HPP_
|
|
|
|
#include <main.h>
|
|
|
|
#include "peripherals_utility.hpp"
|
|
|
|
#define USE_DELAY_US
|
|
|
|
namespace Peripherals
|
|
{
|
|
namespace Hal
|
|
{
|
|
namespace St
|
|
{
|
|
|
|
struct StaticHal
|
|
{
|
|
static void Initialize()
|
|
{
|
|
#ifdef USE_DELAY_US
|
|
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
|
DWT->CYCCNT = 0;
|
|
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
|
#endif
|
|
}
|
|
|
|
static void Delay(const std::uint32_t milliseconds)
|
|
{
|
|
HAL_Delay(milliseconds);
|
|
}
|
|
|
|
static void DelayUs(const std::uint32_t micros)
|
|
{
|
|
#ifdef USE_DELAY_US
|
|
const std::uint32_t tick_start = DWT->CYCCNT;
|
|
const std::uint32_t ticks_delay = micros * (SystemCoreClock / 1'000'000);
|
|
|
|
while (DWT->CYCCNT - tick_start < ticks_delay);
|
|
#else
|
|
(void)micros;
|
|
#endif
|
|
}
|
|
};
|
|
|
|
#ifdef HAL_GPIO_MODULE_ENABLED
|
|
|
|
struct Gpio
|
|
{
|
|
GPIO_TypeDef* port;
|
|
std::uint16_t pin;
|
|
|
|
Gpio() = delete;
|
|
explicit Gpio(GPIO_TypeDef* port, const std::uint16_t pin)
|
|
: port(port)
|
|
, pin(pin)
|
|
{ }
|
|
|
|
void Set(const bool& state)
|
|
{
|
|
HAL_GPIO_WritePin(port, pin, GPIO_PinState(state));
|
|
}
|
|
|
|
void Toggle()
|
|
{
|
|
HAL_GPIO_TogglePin(port, pin);
|
|
}
|
|
|
|
bool Read() const
|
|
{
|
|
return HAL_GPIO_ReadPin(port, pin);
|
|
}
|
|
};
|
|
|
|
#endif // HAL_GPIO_MODULE_ENABLED
|
|
|
|
template<typename T,
|
|
HAL_StatusTypeDef (*transmit)(T*, std::uint8_t* data, std::uint16_t data_len, std::uint32_t timeout),
|
|
HAL_StatusTypeDef (*receive)(T*, std::uint8_t* data, std::uint16_t data_len, std::uint32_t timeout)>
|
|
struct SerialInterface
|
|
{
|
|
using underlying_handle_type = T;
|
|
underlying_handle_type* handle;
|
|
|
|
SerialInterface() = delete;
|
|
explicit SerialInterface(underlying_handle_type* handle)
|
|
: handle(handle)
|
|
{ }
|
|
|
|
bool Transmit(std::uint8_t* data, const std::uint32_t data_len)
|
|
{
|
|
return transmit(handle, data, data_len, 100) == HAL_StatusTypeDef::HAL_OK;
|
|
}
|
|
|
|
bool Receive(std::uint8_t* data, const std::uint32_t data_len)
|
|
{
|
|
return transmit(handle, data, data_len, 100) == HAL_StatusTypeDef::HAL_OK;
|
|
}
|
|
};
|
|
|
|
#ifdef HAL_SPI_MODULE_ENABLED
|
|
|
|
using SpiInterface = SerialInterface<SPI_HandleTypeDef, HAL_SPI_Transmit, HAL_SPI_Receive>;
|
|
|
|
struct SpiRegisters
|
|
{
|
|
SpiInterface handle;
|
|
Gpio chip_select;
|
|
|
|
SpiRegisters() = delete;
|
|
explicit SpiRegisters(const SpiInterface& handle, const Gpio& chip_select)
|
|
: handle(handle)
|
|
, chip_select(chip_select)
|
|
{ }
|
|
|
|
void WriteRegister(std::uint8_t reg, uint8_t data)
|
|
{
|
|
chip_select.Set(false);
|
|
|
|
handle.Transmit(®, 1);
|
|
handle.Transmit(&data, 1);
|
|
|
|
chip_select.Set(true);
|
|
}
|
|
|
|
void WriteRegisterMultibyte(std::uint8_t reg, std::uint8_t* data, const std::uint32_t len)
|
|
{
|
|
chip_select.Set(false);
|
|
|
|
handle.Transmit(®, 1);
|
|
handle.Transmit(data, len);
|
|
|
|
chip_select.Set(true);
|
|
}
|
|
|
|
std::uint8_t ReadRegister(std::uint8_t reg, const std::uint32_t read_delay = 0)
|
|
{
|
|
chip_select.Set(false);
|
|
|
|
handle.Transmit(®, 1);
|
|
|
|
std::uint8_t output = 255;
|
|
|
|
if (read_delay)
|
|
StaticHal::DelayUs(read_delay);
|
|
|
|
handle.Receive(&output, 1);
|
|
|
|
chip_select.Set(true);
|
|
|
|
return output;
|
|
}
|
|
|
|
void ReadRegisterMultibyte(std::uint8_t reg, std::uint8_t* data, const std::uint32_t len, const std::uint32_t read_delay = 0)
|
|
{
|
|
chip_select.Set(false);
|
|
|
|
handle.Transmit(®, 1);
|
|
|
|
if (read_delay)
|
|
StaticHal::DelayUs(read_delay);
|
|
|
|
handle.Receive(data, len);
|
|
|
|
chip_select.Set(true);
|
|
}
|
|
};
|
|
|
|
#endif // HAL_SPI_MODULE_ENABLED
|
|
|
|
#ifdef HAL_UART_MODULE_ENABLED
|
|
|
|
using UartInterface = SerialInterface<UART_HandleTypeDef, HAL_UART_Transmit, HAL_UART_Receive>;
|
|
|
|
#endif // HAL_UART_MODULE_ENABLED
|
|
|
|
#ifdef HAL_TIM_MODULE_ENABLED
|
|
|
|
struct PwmChannel
|
|
{
|
|
TIM_HandleTypeDef* handle;
|
|
std::uint32_t channel;
|
|
|
|
PwmChannel() = delete;
|
|
explicit PwmChannel(TIM_HandleTypeDef* handle, const std::uint32_t channel)
|
|
: handle(handle)
|
|
, channel(channel)
|
|
{ }
|
|
|
|
void Enable()
|
|
{
|
|
HAL_TIM_PWM_Start(handle, channel);
|
|
}
|
|
|
|
void Disable()
|
|
{
|
|
HAL_TIM_PWM_Stop(handle, channel);
|
|
}
|
|
|
|
void SetCompare(const std::uint32_t compare)
|
|
{
|
|
__HAL_TIM_SET_COMPARE(handle, channel, compare);
|
|
}
|
|
|
|
std::uint32_t MaxValue()
|
|
{
|
|
return handle->Init.Period;
|
|
}
|
|
};
|
|
|
|
#endif // HAL_TIM_MODULE_ENABLED
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif /* PERIPHERALS_INC_PERIPHERALS_HAL_ST_HPP_ */
|