инициализация структуры spi перенесена в spi.begin, т.к. до этого функции-сеттеры зависали при попытке поработать с элементами этой структуры. Сами сеттеры тоже немного изменены

This commit is contained in:
klassents 2024-09-12 14:12:24 +07:00
parent 63e718e83f
commit 63217147e5
3 changed files with 46 additions and 37 deletions

View File

@ -253,8 +253,8 @@ void HAL_SPI_CS_Disable(SPI_HandleTypeDef *hspi);
HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout); HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size); HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size);
void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi, uint8_t clockDiv); void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi);
void HAL_SPI_Set_Clock_Mode(SPI_HandleTypeDef *hspi, uint8_t CLKPhase, uint8_t CLKPolarity); void HAL_SPI_Set_Clock_Mode(SPI_HandleTypeDef *hspi);
/** /**
* @brief Разрешить прерывания в соответствии с маской. * @brief Разрешить прерывания в соответствии с маской.

View File

@ -287,17 +287,14 @@ HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
* *
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI. * информацию о конфигурации для модуля SPI.
* @param clockDiv делитель частоты в пределах от SPI_BAUDRATE_DIV4 до SPI_BAUDRATE_DIV256
*/ */
void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi, uint8_t clockDiv) void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi)
{ {
uint32_t config = hspi->Instance->CONFIG; uint32_t config = hspi->Instance->CONFIG;
HAL_SPI_Disable(hspi); HAL_SPI_Disable(hspi);
hspi->Init.BaudRateDiv = clockDiv;
config &= ~(0b111 << SPI_CONFIG_BAUD_RATE_DIV_S); // очистить config &= ~(0b111 << SPI_CONFIG_BAUD_RATE_DIV_S); // очистить
config |= (hspi->Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S); // установить новое config |= (hspi->Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S); // установить новое
hspi->Instance->CONFIG = config; // сохранить конфигурацию hspi->Instance->CONFIG = config; // сохранить конфигурацию
HAL_SPI_Enable(hspi);
} }
/** /**
@ -305,24 +302,15 @@ void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi, uint8_t clockDiv)
* *
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI. * информацию о конфигурации для модуля SPI.
* @param CLKPhase фаза тактирующего сигнала:
* 1 - тактовая частота SPI неактивна вне слова,
* 0 - тактовая частота SPI активна вне слова
* @param CLKPolarity полярность тактирующего сигнала
* 1 - тактовый сигнал удерживается на высоком уровне,
* 0 - тактовый сигнал удерживается на низком уровне
*/ */
void HAL_SPI_Set_Clock_Mode(SPI_HandleTypeDef *hspi, uint8_t CLKPhase, uint8_t CLKPolarity) void HAL_SPI_Set_Clock_Mode(SPI_HandleTypeDef *hspi)
{ {
uint32_t config = hspi->Instance->CONFIG; uint32_t config = hspi->Instance->CONFIG;
HAL_SPI_Disable(hspi); HAL_SPI_Disable(hspi);
hspi->Init.CLKPhase = CLKPhase;
hspi->Init.CLKPolarity = CLKPolarity;
config &= ~((1 << SPI_CONFIG_CLK_PH_S) | (1 << SPI_CONFIG_CLK_POL_S)); // очистить config &= ~((1 << SPI_CONFIG_CLK_PH_S) | (1 << SPI_CONFIG_CLK_POL_S)); // очистить
config |= ((hspi->Init.CLKPhase << SPI_CONFIG_CLK_PH_S) | config |= ((hspi->Init.CLKPhase << SPI_CONFIG_CLK_PH_S) |
(hspi->Init.CLKPolarity << SPI_CONFIG_CLK_POL_S)); // установить новые значения (hspi->Init.CLKPolarity << SPI_CONFIG_CLK_POL_S)); // установить новые значения
hspi->Instance->CONFIG = config; // сохранить конфигурацию hspi->Instance->CONFIG = config; // сохранить конфигурацию
HAL_SPI_Enable(hspi);
} }
/** /**

View File

@ -2,10 +2,11 @@
#include "mik32_hal_spi.h" #include "mik32_hal_spi.h"
SPI_HandleTypeDef hspi; SPI_HandleTypeDef hspi;
bool newConfig = false; bool newConfig = false;
bool isInited = false; bool isInited = false;
uint32_t currentSpeed = 0; uint32_t currentSpeed = 0;
int8_t currentDataOrder = -1; int8_t currentDataOrder = MSBFIRST;
int8_t currentDataMode = -1; int8_t currentDataMode = -1;
static uint8_t reverse_bits(uint8_t byte); static uint8_t reverse_bits(uint8_t byte);
@ -31,16 +32,10 @@ void SPISettings::spiUpdateSettings(uint32_t speedMaximum, uint8_t dataOrder, ui
} }
// if break didn't call in cycle, it will be the greatest divRegVal (and divider) // if break didn't call in cycle, it will be the greatest divRegVal (and divider)
// update config // update params in struct
hspi.Instance = SPI_1;
hspi.Init.SPI_Mode = HAL_SPI_MODE_MASTER; // only master mode
hspi.Init.CLKPhase = dataMode & 0b00000001; hspi.Init.CLKPhase = dataMode & 0b00000001;
hspi.Init.CLKPolarity = (dataMode & 0b00000010)>>1; hspi.Init.CLKPolarity = (dataMode & 0b00000010)>>1;
hspi.Init.ThresholdTX = 4;
hspi.Init.BaudRateDiv = divRegVal; hspi.Init.BaudRateDiv = divRegVal;
hspi.Init.Decoder = SPI_DECODER_NONE;
hspi.Init.ManualCS = SPI_MANUALCS_ON;
hspi.Init.ChipSelect = SPI_CS_NONE;
currentSpeed = speedMaximum; currentSpeed = speedMaximum;
currentDataOrder = dataOrder; currentDataOrder = dataOrder;
@ -51,18 +46,27 @@ void SPISettings::spiUpdateSettings(uint32_t speedMaximum, uint8_t dataOrder, ui
// ------------------------------------------------------------------ // // ------------------------------------------------------------------ //
SPIClass SPI; SPIClass SPI;
bool SPIClass::spiInUse = false; bool SPIClass::spiInUse = false;
uint8_t SPIClass::interruptMode = 0; uint8_t SPIClass::interruptMode = 0;
uint8_t SPIClass::interruptMask = 0; uint8_t SPIClass::interruptMask = 0;
#define PAD_GET_PIN_CONFIG(port, pin) (((PAD_CONFIG->port) & (0b11<<(2*pin))) >> (2*pin))
void SPIClass::begin() void SPIClass::begin()
{ {
spi_onBegin(); spi_onBegin();
// set constant parameters in spi struct
hspi.Instance = SPI_1;
hspi.Init.SPI_Mode = HAL_SPI_MODE_MASTER; // only master mode used
hspi.Init.ThresholdTX = 4;
hspi.Init.Decoder = SPI_DECODER_NONE;
hspi.Init.ManualCS = SPI_MANUALCS_ON;
hspi.Init.ChipSelect = SPI_CS_NONE;
// adjustable parameters default values as in SPISettings()
hspi.Init.BaudRateDiv = SPI_CLOCK_DIV8;
hspi.Init.CLKPhase = SPI_MODE0 & 0b00000001;
hspi.Init.CLKPolarity = (SPI_MODE0 & 0b00000010)>>1;
spiInUse = true; spiInUse = true;
} }
@ -242,27 +246,44 @@ void SPIClass::endTransaction(void)
// ------------------------------------ // // ------------------------------------ //
void SPIClass::setBitOrder(uint8_t bitOrder) void SPIClass::setBitOrder(uint8_t bitOrder)
{ {
currentDataOrder = bitOrder; if (spiInUse)
currentDataOrder = bitOrder;
else
ErrorMsgHandler("SPI.setBitOrder():SPI.begin() need to be called first");
} }
void SPIClass::setDataMode(uint8_t dataMode) void SPIClass::setDataMode(uint8_t dataMode)
{ {
// ClkPhase ClkPolarity if (spiInUse)
HAL_SPI_Set_Clock_Mode(&hspi, (dataMode&0b00000001), (dataMode&0b00000010)>>1); {
hspi.Init.CLKPhase = (dataMode&0b00000001);
hspi.Init.CLKPolarity = (dataMode&0b00000010)>>1;
HAL_SPI_Set_Clock_Mode(&hspi);
currentDataMode = dataMode;
}
else
ErrorMsgHandler("SPI.setDataMode():SPI.begin() need to be called first");
} }
void SPIClass::setClockDivider(uint8_t clockDiv) void SPIClass::setClockDivider(uint8_t clockDiv)
{ {
// if divider is valid if (spiInUse)
if ((clockDiv == SPI_CLOCK_DIV4) || (clockDiv == SPI_CLOCK_DIV8) ||
(clockDiv == SPI_CLOCK_DIV16) || (clockDiv == SPI_CLOCK_DIV32) ||
(clockDiv == SPI_CLOCK_DIV64) || (clockDiv == SPI_CLOCK_DIV128) ||
(clockDiv == SPI_CLOCK_DIV256))
{ {
HAL_SPI_Set_Clock_Divider(&hspi, clockDiv); // if divider is valid
if ((clockDiv == SPI_CLOCK_DIV4) || (clockDiv == SPI_CLOCK_DIV8) ||
(clockDiv == SPI_CLOCK_DIV16) || (clockDiv == SPI_CLOCK_DIV32) ||
(clockDiv == SPI_CLOCK_DIV64) || (clockDiv == SPI_CLOCK_DIV128) ||
(clockDiv == SPI_CLOCK_DIV256))
{
hspi.Init.BaudRateDiv = clockDiv;
currentSpeed = F_CPU >> (clockDiv+1);
HAL_SPI_Set_Clock_Divider(&hspi);
}
else
ErrorMsgHandler("SPI.setClockDivider(): Invalid clock devider");
} }
else else
ErrorMsgHandler("SPI.setClockDivider(): Invalid clock devider"); ErrorMsgHandler("SPI.setClockDivider():SPI.begin() need to be called first");
} }
static uint8_t reverse_bits(uint8_t byte) static uint8_t reverse_bits(uint8_t byte)