forked from Elron_dev/elbear_arduino_bsp
dev0.2_halRevision (#1)
- Реализация части функций в библиотеках hal перенесена в заголовочный файл, функции определены как inline. - В модулях Tone, SPI, Wire работа с регистрами вынесена в библиотеку hal или в платозависимые файлы pins_arduino.h, variants.c - В модуле wiring_analog при отключении работы ШИМ сначала проверяется, включен ли ШИМ на указанной ноге. Если включен, вывод после отключения таймера конфигурируется на вход. Reviewed-on: Elron_dev/elbear_arduino_bsp#1
This commit is contained in:
1 parent
f020720e1f
commit
8f0a5b0a94
17 files changed
+433
-313
No files matched your search
+16
-81
@@ -50,53 +50,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();
|
||||
spi_onBegin();
|
||||
|
||||
spiInUse = true;
|
||||
}
|
||||
@@ -113,31 +78,9 @@ void SPIClass::end()
|
||||
{
|
||||
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
|
||||
|
||||
// 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
|
||||
|
||||
// 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);
|
||||
unblockSpiPin();
|
||||
spi_onEnd();
|
||||
|
||||
spiInUse = false;
|
||||
isInited = false;
|
||||
@@ -304,30 +247,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)
|
||||
|
||||
@@ -88,36 +88,22 @@ void twi_deinit(void)
|
||||
{
|
||||
uint32_t EPICmask;
|
||||
|
||||
HAL_I2C_Disable(&hi2c);
|
||||
// disable clock
|
||||
#if I2C_NUM == 0
|
||||
hi2c.Instance = I2C_0;
|
||||
EPICmask = HAL_EPIC_I2C_0_MASK;
|
||||
__HAL_PCC_I2C_0_CLK_DISABLE();
|
||||
#elif I2C_NUM == 1
|
||||
hi2c.Instance = I2C_1;
|
||||
EPICmask = HAL_EPIC_I2C_1_MASK;
|
||||
__HAL_PCC_I2C_1_CLK_DISABLE();
|
||||
#else
|
||||
#error "Unsupported I2C_NUM value in pins_arduino.h"
|
||||
#endif
|
||||
|
||||
HAL_I2C_Deinit(&hi2c);
|
||||
|
||||
// for slave mode disable interrupts from i2c
|
||||
if (hi2c.Init.Mode == HAL_I2C_MODE_SLAVE)
|
||||
HAL_EPIC_MaskLevelClear(EPICmask);
|
||||
|
||||
// reconfigure pins to z state
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct));
|
||||
// SDA
|
||||
GPIO_InitStruct.Pin = (HAL_PinsTypeDef)digitalPinToBitMask(PIN_WIRE_SDA);
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(digitalPinToPort(PIN_WIRE_SDA), &GPIO_InitStruct);
|
||||
// SCL
|
||||
GPIO_InitStruct.Pin = (HAL_PinsTypeDef)digitalPinToBitMask(PIN_WIRE_SCL);
|
||||
HAL_GPIO_Init(digitalPinToPort(PIN_WIRE_SCL), &GPIO_InitStruct);
|
||||
|
||||
twiIsOn = false;
|
||||
}
|
||||
|
||||
@@ -252,7 +238,7 @@ uint8_t twi_masterWriteTo(uint8_t address, uint8_t* data, uint8_t length, uint8_
|
||||
|
||||
// parse errors
|
||||
// check separately, because in hal libraries not all functions look at this
|
||||
if (hi2c.Instance->ISR & I2C_ISR_NACKF_M)
|
||||
if (HAL_I2C_Get_Interrupts_Status(&hi2c) & I2C_ISR_NACKF_M)
|
||||
hi2c.ErrorCode = I2C_ERROR_NACK;
|
||||
if (hi2c.ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_TIMEOUT) ret = I2C_TIMEOUT; // timeout
|
||||
else if (hi2c.ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_NACK) ret = I2C_NACK_DATA; // didn't receive ACK
|
||||
@@ -275,39 +261,35 @@ i2c_status_e twi_slaveWrite(uint8_t *txData, uint8_t bytesNum)
|
||||
if ((hi2c.ErrorCode != I2C_ERROR_NONE))
|
||||
HAL_I2C_Reset(&hi2c);
|
||||
|
||||
// отправка данных
|
||||
// send data
|
||||
HAL_StatusTypeDef error_code = HAL_OK;
|
||||
|
||||
hi2c.Instance->CR2 &= ~I2C_CR2_RELOAD_M;
|
||||
HAL_I2C_Clear_Reload(&hi2c);
|
||||
if (!(HAL_I2C_Get_CR1_Content(&hi2c) & I2C_CR1_NOSTRETCH_M)) // NOSTRETCH = 0
|
||||
HAL_I2C_Reset_TXDR_Content(&hi2c);
|
||||
HAL_I2C_Write_TXDR(&hi2c, txData[0]); // first recording is made in advance
|
||||
|
||||
if (!(hi2c.Instance->CR1 & I2C_CR1_NOSTRETCH_M)) // NOSTRETCH = 0
|
||||
hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents
|
||||
|
||||
hi2c.Instance->TXDR = txData[0]; // The first recording is made in advance
|
||||
|
||||
// Запись байта
|
||||
// write byte
|
||||
for (uint32_t tx_count = 1; tx_count < bytesNum; tx_count++)
|
||||
{
|
||||
if ((error_code = HAL_I2C_Slave_WaitTXIS(&hi2c, TIMEOUT_TICKS)) != HAL_OK)
|
||||
{
|
||||
// неудачная запись
|
||||
hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents
|
||||
hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus
|
||||
// failed to write
|
||||
HAL_I2C_Reset_TXDR_Content(&hi2c);
|
||||
HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus
|
||||
HAL_I2C_Reset(&hi2c);
|
||||
return I2C_TIMEOUT;
|
||||
}
|
||||
hi2c.Instance->TXDR = txData[tx_count];
|
||||
HAL_I2C_Write_TXDR(&hi2c, txData[tx_count]);
|
||||
}
|
||||
|
||||
if ((error_code = HAL_I2C_WaitBusy(&hi2c, TIMEOUT_TICKS)) != HAL_OK)
|
||||
{
|
||||
// неудачное завершение транзакции
|
||||
// failed to complete transaction
|
||||
HAL_I2C_Reset(&hi2c);
|
||||
return I2C_TIMEOUT;
|
||||
}
|
||||
|
||||
hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents
|
||||
hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus
|
||||
HAL_I2C_Reset_TXDR_Content(&hi2c);
|
||||
HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus
|
||||
|
||||
return I2C_OK;
|
||||
}
|
||||
@@ -343,25 +325,24 @@ void twi_attachSlaveTxEvent( void (*function)(void) )
|
||||
*/
|
||||
void twi_interruptHandler(void)
|
||||
{
|
||||
uint32_t int_mask = hi2c.Instance->CR1 & I2C_INTMASK; // interrupts allowed
|
||||
uint32_t interrupt_status = hi2c.Instance->ISR; // current flags
|
||||
uint32_t int_mask = HAL_I2C_Get_CR1_Content(&hi2c) & I2C_INTMASK; // interrupts allowed
|
||||
uint32_t interrupt_status = HAL_I2C_Get_Interrupts_Status(&hi2c); // current flags
|
||||
|
||||
// master calls by address, device in slave mode
|
||||
if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M))
|
||||
{
|
||||
// reset ADDR flag
|
||||
hi2c.Instance->ICR |= I2C_ICR_ADDRCF_M;
|
||||
HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_ADDRCF_M);
|
||||
|
||||
// look at the transmission direction and respond to the request
|
||||
if (interrupt_status & I2C_ISR_DIR_M) // master reads, slave sends
|
||||
// отправляем данные
|
||||
twi_onSlaveTransmit();
|
||||
twi_onSlaveTransmit(); // slave send data
|
||||
else // master writes, slave reads
|
||||
{
|
||||
twi_rxBufferIndex = 0; // write from the beginning of the buffer
|
||||
hi2c.State = HAL_I2C_STATE_BUSY;
|
||||
hi2c.Instance->CR2 &= ~I2C_CR2_RELOAD_M;
|
||||
// wait for interrupts because of receiving a byte or a stop condition
|
||||
HAL_I2C_Clear_Reload(&hi2c);
|
||||
// wait for interrupts by receiving a byte or a stop condition
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,15 +350,15 @@ void twi_interruptHandler(void)
|
||||
if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M))
|
||||
{
|
||||
// put new byte into buffer
|
||||
twi_rxBuffer[twi_rxBufferIndex++] = (uint8_t)hi2c.Instance->RXDR;
|
||||
twi_rxBuffer[twi_rxBufferIndex++] = HAL_I2C_Get_RXDR(&hi2c);
|
||||
}
|
||||
|
||||
// master sent a STOP to the bus
|
||||
if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M))
|
||||
{
|
||||
hi2c.State = HAL_I2C_STATE_END;
|
||||
hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents
|
||||
hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus
|
||||
HAL_I2C_Reset_TXDR_Content(&hi2c);
|
||||
HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus
|
||||
// pass the received data to callback function
|
||||
twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user