перенесла работу с регистрами для setclock, setmode в spi.в процессе оптимизация в begin
This commit is contained in:
parent
b528af8a90
commit
fec81e89e7
@ -419,6 +419,17 @@ static inline __attribute__((always_inline)) void HAL_GPIO_TogglePin(GPIO_TypeDe
|
||||
GPIO_x->OUTPUT_ ^= pin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Возвращает направление вывода при работе в режиме вход/выход
|
||||
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
|
||||
* @param pin маска вывода порта GPIO_x, направление которого необходимо узнать.
|
||||
* @return Возвращает направление вывода - input или output.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) HAL_GPIO_ModeTypeDef HAL_GPIO_GetPinDirection(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
|
||||
{
|
||||
return (GPIO_x->DIRECTION_IN & pin) == 0 ? HAL_GPIO_MODE_GPIO_OUTPUT : HAL_GPIO_MODE_GPIO_INPUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получить состояние линии прерывания.
|
||||
* @param irqLine номер линии прерывания.
|
||||
|
||||
@ -253,7 +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_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);
|
||||
|
||||
void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi, uint8_t clockDiv);
|
||||
void HAL_SPI_Set_Clock_Mode(SPI_HandleTypeDef *hspi, uint8_t CLKPhase, uint8_t CLKPolarity);
|
||||
|
||||
/**
|
||||
* @brief Разрешить прерывания в соответствии с маской.
|
||||
|
||||
@ -282,6 +282,49 @@ HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
|
||||
return error_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Установить новый делитель частоты
|
||||
*
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param clockDiv делитель частоты в пределах от SPI_BAUDRATE_DIV4 до SPI_BAUDRATE_DIV256
|
||||
*/
|
||||
void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi, uint8_t clockDiv)
|
||||
{
|
||||
uint32_t config = hspi->Instance->CONFIG;
|
||||
HAL_SPI_Disable(hspi);
|
||||
hspi->Init.BaudRateDiv = clockDiv;
|
||||
config &= ~(0b111 << SPI_CONFIG_BAUD_RATE_DIV_S); // очистить
|
||||
config |= (hspi->Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S); // установить новое
|
||||
hspi->Instance->CONFIG = config; // сохранить конфигурацию
|
||||
HAL_SPI_Enable(hspi);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Установить новый режим работы
|
||||
*
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля 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)
|
||||
{
|
||||
uint32_t config = hspi->Instance->CONFIG;
|
||||
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 |= ((hspi->Init.CLKPhase << SPI_CONFIG_CLK_PH_S) |
|
||||
(hspi->Init.CLKPolarity << SPI_CONFIG_CLK_POL_S)); // установить новые значения
|
||||
hspi->Instance->CONFIG = config; // сохранить конфигурацию
|
||||
HAL_SPI_Enable(hspi);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Очистить буфер TX_FIFO.
|
||||
*
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "SPI.h"
|
||||
#include "mik32_hal_spi.h"
|
||||
#include "utility/spiElbear.h"
|
||||
|
||||
SPI_HandleTypeDef hspi;
|
||||
bool newConfig = false;
|
||||
@ -50,54 +51,18 @@ void SPISettings::spiUpdateSettings(uint32_t speedMaximum, uint8_t dataOrder, ui
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ //
|
||||
// pins shift in gpio register
|
||||
#define PIN_1_3_GPIO_S 3
|
||||
#define PIN_1_4_GPIO_S 4
|
||||
|
||||
|
||||
SPIClass SPI;
|
||||
bool SPIClass::spiInUse = false;
|
||||
uint8_t SPIClass::interruptMode = 0;
|
||||
uint8_t SPIClass::interruptMask = 0;
|
||||
|
||||
#define PAD_GET_PIN_CONFIG(port, pin) (((PAD_CONFIG->port) & (0b11<<(2*pin))) >> (2*pin))
|
||||
|
||||
void SPIClass::begin()
|
||||
{
|
||||
// there is a seller on pin 1.6 which replace D10 from spi NSS pin 1.3 to pin 1.4,
|
||||
// because spi needs pin 1.3 for correct work
|
||||
|
||||
// replace config from 1.3 to 1.4
|
||||
uint8_t config = ((PAD_CONFIG->PORT_1_CFG) & (0b11<<(2*PIN_1_3_GPIO_S))) >> (2*PIN_1_3_GPIO_S);
|
||||
if (config == 0) // common gpio
|
||||
{
|
||||
// pin direction
|
||||
uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<<PIN_1_3_GPIO_S)) >> PIN_1_3_GPIO_S;
|
||||
if (direction == 1) // input
|
||||
GPIO_1->DIRECTION_IN |= (1<<PIN_1_4_GPIO_S);
|
||||
else // output
|
||||
GPIO_1->DIRECTION_OUT |= (1<<PIN_1_4_GPIO_S);
|
||||
|
||||
// pull up/down
|
||||
uint8_t pupd_1_3 = ((PAD_CONFIG ->PORT_1_PUPD) & (0b11<<(2*PIN_1_3_GPIO_S))) >> (2*PIN_1_3_GPIO_S);
|
||||
PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_4_GPIO_S))); // clear
|
||||
PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_3&0b11)<<(2*PIN_1_4_GPIO_S)); // set new
|
||||
|
||||
//current state
|
||||
uint8_t state1_3 = ((GPIO_1->OUTPUT_) & (1<<PIN_1_3_GPIO_S)) >> PIN_1_3_GPIO_S;
|
||||
GPIO_1->OUTPUT_ &= (~(0b1<<PIN_1_4_GPIO_S)); // clear
|
||||
GPIO_1->OUTPUT_ |= ((state1_3&0b1)<<PIN_1_4_GPIO_S); // set new
|
||||
}
|
||||
else if(config == 2) // timer for pwm
|
||||
{
|
||||
// if D10 (spi NSS pin) was used as pwm, we need to stop timer,
|
||||
// because 1.4 don't support timer
|
||||
analogWriteStop(10);
|
||||
ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running");
|
||||
}
|
||||
|
||||
// switch seller to pin 1.4
|
||||
HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_6, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_HIGH);
|
||||
blockSpiPin();
|
||||
|
||||
spiElbear_prepareBegin();
|
||||
spiInUse = true;
|
||||
}
|
||||
|
||||
@ -108,32 +73,32 @@ void SPIClass::end()
|
||||
// turn off spi
|
||||
HAL_SPI_Disable(&hspi);
|
||||
|
||||
// deinit spi gpio pins
|
||||
if (hspi.Instance == SPI_1) // only spi1 is using in currunt version
|
||||
{
|
||||
HAL_GPIO_PinConfig(GPIO_1, (HAL_PinsTypeDef)(GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2),
|
||||
HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||
}
|
||||
// // deinit spi gpio pins
|
||||
// if (hspi.Instance == SPI_1) // only spi1 is using in currunt version
|
||||
// {
|
||||
// HAL_GPIO_PinConfig(GPIO_1, (HAL_PinsTypeDef)(GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2),
|
||||
// HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||
// }
|
||||
|
||||
// return D10 with common gpio config to pin 1.3
|
||||
PAD_CONFIG->PORT_1_CFG &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // set config to 0 - common gpio mode
|
||||
// // return D10 with common gpio config to pin 1.3
|
||||
// PAD_CONFIG->PORT_1_CFG &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // set config to 0 - common gpio mode
|
||||
|
||||
// pin direction
|
||||
uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<<PIN_1_4_GPIO_S)) >> PIN_1_4_GPIO_S;
|
||||
if (direction == 1) // input
|
||||
GPIO_1->DIRECTION_IN |= (1<<PIN_1_3_GPIO_S);
|
||||
else // output
|
||||
GPIO_1->DIRECTION_OUT |= (1<<PIN_1_3_GPIO_S);
|
||||
// // pin direction
|
||||
// uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<<PIN_1_4_GPIO_S)) >> PIN_1_4_GPIO_S;
|
||||
// if (direction == 1) // input
|
||||
// GPIO_1->DIRECTION_IN |= (1<<PIN_1_3_GPIO_S);
|
||||
// else // output
|
||||
// GPIO_1->DIRECTION_OUT |= (1<<PIN_1_3_GPIO_S);
|
||||
|
||||
// pull up/down
|
||||
uint8_t pupd_1_4 = ((PAD_CONFIG ->PORT_1_PUPD) & (0b11<<(2*PIN_1_4_GPIO_S))) >> (2*PIN_1_4_GPIO_S);
|
||||
PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // clear
|
||||
PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_4&0b11)<<(2*PIN_1_3_GPIO_S)); // set new
|
||||
// // pull up/down
|
||||
// uint8_t pupd_1_4 = ((PAD_CONFIG ->PORT_1_PUPD) & (0b11<<(2*PIN_1_4_GPIO_S))) >> (2*PIN_1_4_GPIO_S);
|
||||
// PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // clear
|
||||
// PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_4&0b11)<<(2*PIN_1_3_GPIO_S)); // set new
|
||||
|
||||
// current state
|
||||
uint8_t state1_4 = ((GPIO_1->OUTPUT_) & (1<<PIN_1_4_GPIO_S)) >> PIN_1_4_GPIO_S;
|
||||
GPIO_1->OUTPUT_ &= (~(0b1<<PIN_1_3_GPIO_S)); // clear
|
||||
GPIO_1->OUTPUT_ |= ((state1_4&0b1)<<PIN_1_3_GPIO_S); // set new
|
||||
// // current state
|
||||
// uint8_t state1_4 = ((GPIO_1->OUTPUT_) & (1<<PIN_1_4_GPIO_S)) >> PIN_1_4_GPIO_S;
|
||||
// GPIO_1->OUTPUT_ &= (~(0b1<<PIN_1_3_GPIO_S)); // clear
|
||||
// GPIO_1->OUTPUT_ |= ((state1_4&0b1)<<PIN_1_3_GPIO_S); // set new
|
||||
|
||||
// switch seller back to pin 1.3
|
||||
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_LOW);
|
||||
@ -304,30 +269,22 @@ void SPIClass::setBitOrder(uint8_t bitOrder)
|
||||
|
||||
void SPIClass::setDataMode(uint8_t dataMode)
|
||||
{
|
||||
uint32_t config = hspi.Instance->CONFIG;
|
||||
HAL_SPI_Disable(&hspi);
|
||||
hspi.Init.CLKPhase = dataMode & 0b00000001;
|
||||
hspi.Init.CLKPolarity = (dataMode & 0b00000010)>>1;
|
||||
config &= ~((1 << SPI_CONFIG_CLK_PH_S) | (1 << SPI_CONFIG_CLK_POL_S)); // clear
|
||||
config |= ((hspi.Init.CLKPhase << SPI_CONFIG_CLK_PH_S) |
|
||||
(hspi.Init.CLKPolarity << SPI_CONFIG_CLK_POL_S)); // set new
|
||||
hspi.Instance->CONFIG = config;
|
||||
HAL_SPI_Enable(&hspi);
|
||||
// ClkPhase ClkPolarity
|
||||
HAL_SPI_Set_Clock_Mode(&hspi, (dataMode&0b00000001), (dataMode&0b00000010)>>1);
|
||||
}
|
||||
|
||||
void SPIClass::setClockDivider(uint8_t clockDiv)
|
||||
{
|
||||
// if divider is in valid range
|
||||
if ((clockDiv >= SPI_CLOCK_DIV4) && (clockDiv <= SPI_CLOCK_DIV256))
|
||||
// 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))
|
||||
{
|
||||
uint32_t config = hspi.Instance->CONFIG;
|
||||
HAL_SPI_Disable(&hspi);
|
||||
hspi.Init.BaudRateDiv = clockDiv;
|
||||
config &= ~(0b111 << SPI_CONFIG_BAUD_RATE_DIV_S); // clear
|
||||
config |= (hspi.Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S); // set new
|
||||
hspi.Instance->CONFIG = config;
|
||||
HAL_SPI_Enable(&hspi);
|
||||
HAL_SPI_Set_Clock_Divider(&hspi, clockDiv);
|
||||
}
|
||||
else
|
||||
ErrorMsgHandler("SPI.setClockDivider(): Invalid clock devider");
|
||||
}
|
||||
|
||||
static uint8_t reverse_bits(uint8_t byte)
|
||||
|
||||
49
libraries/SPI/src/utility/spiElbear.cpp
Normal file
49
libraries/SPI/src/utility/spiElbear.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include "Arduino.h"
|
||||
#include "spiElbear.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include "xprintf.h"
|
||||
|
||||
// pins shift in registers
|
||||
#define PIN_3_SHIFT 3
|
||||
#define PIN_4_SHIFT 4
|
||||
#define PORT1_GET_PAD_CONFIG(pinShift) ((PAD_CONFIG->PORT_1_CFG >> (pinShift<<1)) & 0b11)
|
||||
#define PORT1_GET_PAD_PUPD(pinShift) ((PAD_CONFIG->PORT_1_PUPD >> (pinShift<<1)) & 0b11)
|
||||
#define PORT1_GET_GPIO_STATE(pinShift) ((GPIO_1->OUTPUT_ >> pinShift) & 0b1)
|
||||
|
||||
void spiElbear_prepareBegin(void)
|
||||
{
|
||||
// there is a seller on pin 1.6 which replace D10 from spi NSS pin 1.3 to pin 1.4,
|
||||
// because spi needs pin 1.3 for correct work
|
||||
|
||||
// replace config from 1.3 to 1.4
|
||||
uint8_t config = PORT1_GET_PAD_CONFIG(PIN_3_SHIFT);
|
||||
if (config == 0) // common gpio
|
||||
{
|
||||
// pin direction
|
||||
HAL_GPIO_ModeTypeDef pin3_direction = HAL_GPIO_GetPinDirection(GPIO_1, GPIO_PIN_3);
|
||||
// pull up/down
|
||||
HAL_GPIO_PullTypeDef pin3_pupd = (HAL_GPIO_PullTypeDef)PORT1_GET_PAD_PUPD(PIN_3_SHIFT);
|
||||
//current state
|
||||
uint8_t pin3_state = PORT1_GET_GPIO_STATE(PIN_3_SHIFT);
|
||||
|
||||
// init and set state
|
||||
HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_4, pin3_direction, pin3_pupd, HAL_GPIO_DS_2MA);
|
||||
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_4, pin3_state);
|
||||
// todo ПРОВЕРИТЬ, что по факту устанавливается то, что я говорю в HAL_GPIO_PinConfig
|
||||
|
||||
}
|
||||
else if(config == 2) // timer for pwm
|
||||
{
|
||||
// вместо это возвращать что-то, что покажет, что это не gpio и снаружи выбросит предупреждение это
|
||||
|
||||
// // if D10 (spi NSS pin) was used as pwm, we need to stop timer,
|
||||
// // because 1.4 don't support timer
|
||||
// analogWriteStop(10);
|
||||
// ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running");
|
||||
}
|
||||
|
||||
// switch seller to pin 1.4
|
||||
HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_6, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_HIGH);
|
||||
blockSpiPin();
|
||||
}
|
||||
2
libraries/SPI/src/utility/spiElbear.h
Normal file
2
libraries/SPI/src/utility/spiElbear.h
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
void spiElbear_prepareBegin(void);
|
||||
Loading…
Reference in New Issue
Block a user