|
@@ -74,7 +74,7 @@ static uint8_t tubesBuffer[SPI_BUFFER_SIZE] = {0};
|
|
|
static rtc_t Clock;
|
|
|
static struct bme280_dev SensorDev;
|
|
|
static struct bme280_data SensorData;
|
|
|
-static int8_t rsltSensor = -1; //BME280_OK;
|
|
|
+static int8_t rsltSensor;
|
|
|
static int16_t Humidity, Temperature, Pressure;
|
|
|
/* USER CODE END PV */
|
|
|
|
|
@@ -93,6 +93,7 @@ static void showDigit(tube_pos_t pos, uint8_t dig);
|
|
|
static void SPI_StartTX(void);
|
|
|
int8_t user_i2c_read(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
|
|
int8_t user_i2c_write(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
|
|
+int8_t i2c_check_err(void);
|
|
|
/* USER CODE END PFP */
|
|
|
|
|
|
/* Private user code ---------------------------------------------------------*/
|
|
@@ -179,7 +180,6 @@ int main(void)
|
|
|
IN15_OFF;
|
|
|
|
|
|
RTC_Init();
|
|
|
- while (Flag.I2C_TX_End == 0) { __NOP(); };
|
|
|
|
|
|
SensorDev.dev_id = (BME280_I2C_ADDR_PRIM << 1);
|
|
|
SensorDev.intf = BME280_I2C_INTF;
|
|
@@ -188,14 +188,12 @@ int main(void)
|
|
|
SensorDev.delay_ms = tdelay_ms;
|
|
|
rsltSensor = bme280_init(&SensorDev);
|
|
|
if (rsltSensor == BME280_OK) {
|
|
|
-COLOR_RGB(255, 0, 0);
|
|
|
Flag.BME280 = 1;
|
|
|
}
|
|
|
/* USER CODE END 2 */
|
|
|
|
|
|
/* USER CODE BEGIN WHILE */
|
|
|
RTC_ReadAll(&Clock);
|
|
|
- while (Flag.I2C_RX_End == 0) { __NOP(); };
|
|
|
|
|
|
if (Flag.BME280 != 0) {
|
|
|
/* BME280 Recommended mode of operation: Indoor navigation */
|
|
@@ -204,19 +202,11 @@ COLOR_RGB(255, 0, 0);
|
|
|
SensorDev.settings.osr_t = BME280_OVERSAMPLING_2X;
|
|
|
SensorDev.settings.filter = BME280_FILTER_COEFF_16;
|
|
|
rsltSensor = bme280_set_sensor_settings((BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL), &SensorDev);
|
|
|
-// rsltSensor = bme280_set_sensor_mode(BME280_FORCED_MODE, &SensorDev);
|
|
|
-// SensorDev.delay_ms(50);
|
|
|
-// rsltSensor = bme280_get_sensor_data(BME280_ALL, &SensorData, &SensorDev);
|
|
|
}
|
|
|
- /* bme280_get_sensor_data(...) returns:
|
|
|
- * - temperature in DegC, resolution is 0.01 DegC. Output value of "5123" equals 51.23 DegC.
|
|
|
- * - pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
|
|
|
- * Output value "24674867" represents 24674867/256 = 96386.2 Pa = 963.862 hPa. -- for 64bit
|
|
|
- * - humidity in %RH as unsigned 32 bit integer in Q22.10 format.
|
|
|
- * Output value of "47445" represents 47445/1024 = 46.333 %RH
|
|
|
- */
|
|
|
+
|
|
|
uint8_t temp_l, temp_h, hum_h, hum_l, pres_h, pres_l;
|
|
|
uint32_t tmp;
|
|
|
+
|
|
|
/* Infinite loop */
|
|
|
while (1)
|
|
|
{
|
|
@@ -231,7 +221,7 @@ COLOR_RGB(255, 0, 0);
|
|
|
if (Flag.RTC_IRQ != 0) {
|
|
|
Flag.RTC_IRQ = 0;
|
|
|
IN15_Minus;
|
|
|
- COLOR_RGB(0xFF, 0x12, 0x0); // FF7E00 or FFBF00
|
|
|
+ COLOR_RGB(0xFF, 0x12, 0x0); // Nixie color. FF7E00 or FFBF00
|
|
|
}
|
|
|
if (Flag.BME280 != 0) {
|
|
|
rsltSensor = bme280_get_sensor_data(BME280_ALL, &SensorData, &SensorDev);
|
|
@@ -240,13 +230,6 @@ COLOR_RGB(255, 0, 0);
|
|
|
/* USER CODE END WHILE */
|
|
|
|
|
|
/* USER CODE BEGIN 3 */
|
|
|
-/*
|
|
|
- showDigit(Tube_A, Clock.Min >> 4);
|
|
|
- showDigit(Tube_B, Clock.Min & 0xf);
|
|
|
- showDigit(Tube_D, Clock.Sec >> 4);
|
|
|
- showDigit(Tube_E, Clock.Sec & 0xf);
|
|
|
-*/
|
|
|
-
|
|
|
if (rsltSensor == BME280_OK) {
|
|
|
tmp = SensorData.temperature + 50;
|
|
|
temp_h = (uint8_t)(tmp / 100);
|
|
@@ -291,12 +274,36 @@ static void SPI_StartTX(void) {
|
|
|
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Check I2C fjr errors.
|
|
|
+ * @retval I2C return code
|
|
|
+ */
|
|
|
+int8_t i2c_check_err(void) {
|
|
|
+ int8_t r = I2C_RET_OK;
|
|
|
+
|
|
|
+ if ((I2C1->ISR & I2C_ISR_NACKF) != 0) {
|
|
|
+ /* device not present */
|
|
|
+ r = I2C_RET_NACK;
|
|
|
+ } else {
|
|
|
+ /* other error */
|
|
|
+ r = I2C_RET_ERR;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (r != I2C_RET_OK) {
|
|
|
+ I2C1->CR1 &= ~I2C_CR1_PE;
|
|
|
+ while ((I2C1->CR1 & I2C_CR1_PE) != 0) {};
|
|
|
+ I2C1->CR1 |= I2C_CR1_PE;
|
|
|
+ }
|
|
|
+
|
|
|
+ return r;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* @brief Read len bytes from I2C bus to data by reg_addr.
|
|
|
* @retval I2C return code
|
|
|
*/
|
|
|
int8_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *data, const uint16_t len) {
|
|
|
- int8_t r = 0;
|
|
|
+ int8_t r = I2C_RET_OK;
|
|
|
|
|
|
Flag.I2C_RX_End = 0;
|
|
|
Flag.I2C_RX_Err = 0;
|
|
@@ -311,47 +318,25 @@ int8_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *data, co
|
|
|
/* gen START */
|
|
|
I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
|
|
|
- /* wait for start end */
|
|
|
-// while ( !( I2C1->CR2 & I2C_CR2_START ) ) {};
|
|
|
-
|
|
|
/* wait for byte request or any error */
|
|
|
while ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) { __NOP(); };
|
|
|
|
|
|
if ((I2C2->ISR & I2C_ISR_TXE) != 0) {
|
|
|
/* device ok, send reg addr */
|
|
|
I2C1->TXDR = reg_addr;
|
|
|
- } else if ((I2C1->ISR & I2C_ISR_NACKF) != 0) {
|
|
|
- /* device not present */
|
|
|
- r = I2C_RET_NACK;
|
|
|
} else {
|
|
|
- /* other error */
|
|
|
- r = I2C_RET_ERR;
|
|
|
- }
|
|
|
- if (r != 0) {
|
|
|
- Flag.I2C_TX_Err = 1;
|
|
|
- Flag.I2C_TX_End = 1;
|
|
|
- I2C1->CR1 &= ~I2C_CR1_PE;
|
|
|
- while ((I2C1->CR1 & I2C_CR1_PE) != 0) {};
|
|
|
- I2C1->CR1 |= I2C_CR1_PE;
|
|
|
- return r;
|
|
|
+ r = i2c_check_err();
|
|
|
+ if (r != I2C_RET_OK) {
|
|
|
+ Flag.I2C_TX_Err = 1;
|
|
|
+ return r;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* wait for i2c or any error */
|
|
|
while (((I2C1->ISR & I2C_ISR_BUSY) != 0) && ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF)) == 0)) { __NOP(); };
|
|
|
-
|
|
|
- /* check for errors */
|
|
|
- if ((I2C1->ISR & I2C_ISR_NACKF) != 0) {
|
|
|
- /* device not present */
|
|
|
- r = I2C_RET_NACK;
|
|
|
- } else if ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR)) != 0) {
|
|
|
- /* other error */
|
|
|
- r = I2C_RET_ERR;
|
|
|
- }
|
|
|
- if (r != 0) {
|
|
|
+ r = i2c_check_err();
|
|
|
+ if (r != I2C_RET_OK) {
|
|
|
Flag.I2C_TX_Err = 1;
|
|
|
- I2C1->CR1 &= ~I2C_CR1_PE;
|
|
|
- while ((I2C1->CR1 & I2C_CR1_PE) != 0) { __NOP(); };
|
|
|
- I2C1->CR1 |= I2C_CR1_PE;
|
|
|
return r;
|
|
|
}
|
|
|
|
|
@@ -369,9 +354,9 @@ int8_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *data, co
|
|
|
I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
|
|
|
/* wait for receiving data */
|
|
|
- while (Flag.I2C_RX_End == 0) {};
|
|
|
+ while ((Flag.I2C_RX_End == 0) && (Flag.I2C_RX_Err == 0)) { __WFI(); };
|
|
|
|
|
|
- return I2C_RET_OK;
|
|
|
+ return r;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -379,10 +364,11 @@ int8_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *data, co
|
|
|
* @retval I2C return code
|
|
|
*/
|
|
|
int8_t user_i2c_write(const uint8_t id, const uint8_t reg_addr, uint8_t *data, const uint16_t len) {
|
|
|
+ int8_t r = I2C_RET_OK;
|
|
|
+
|
|
|
Flag.I2C_TX_End = 0;
|
|
|
Flag.I2C_TX_Err = 0;
|
|
|
|
|
|
- //DMA1_Channel3->CCR &= ~DMA_CCR_EN;
|
|
|
DMA1_Channel3->CMAR = (uint32_t)data;
|
|
|
DMA1_Channel3->CPAR = (uint32_t)&(I2C1->TXDR);
|
|
|
DMA1_Channel3->CNDTR = len;
|
|
@@ -393,21 +379,21 @@ int8_t user_i2c_write(const uint8_t id, const uint8_t reg_addr, uint8_t *data, c
|
|
|
I2C1->CR2 |= ( id | (len + 1) << I2C_CR2_NBYTES_Pos );
|
|
|
I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
|
|
|
-// while ( !( I2C1->CR2 & I2C_CR2_START ) ) {};
|
|
|
while ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) { __NOP(); };
|
|
|
if ((I2C2->ISR & I2C_ISR_TXE) != 0) {
|
|
|
I2C1->TXDR = reg_addr;
|
|
|
- } else { /* if ((I2C1->ISR & I2C_ISR_NACKF) != 0) */
|
|
|
- I2C1->CR1 &= ~I2C_CR1_PE;
|
|
|
- while ((I2C1->CR1 & I2C_CR1_PE) != 0) {};
|
|
|
- I2C1->CR1 |= I2C_CR1_PE;
|
|
|
- return I2C_RET_ERR;
|
|
|
+ } else {
|
|
|
+ r = i2c_check_err();
|
|
|
+ if (r != I2C_RET_OK) {
|
|
|
+ Flag.I2C_TX_Err = 1;
|
|
|
+ return r;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
DMA1_Channel3->CCR |= DMA_CCR_EN;
|
|
|
I2C1->CR1 |= ( I2C_CR1_TXDMAEN );
|
|
|
|
|
|
- return I2C_RET_OK;
|
|
|
+ return r;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -498,8 +484,6 @@ static void MX_I2C1_Init(void)
|
|
|
|
|
|
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PRIORITY_MEDIUM);
|
|
|
|
|
|
-// LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MODE_CIRCULAR);
|
|
|
-
|
|
|
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PERIPH_NOINCREMENT);
|
|
|
|
|
|
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MEMORY_INCREMENT);
|
|
@@ -515,8 +499,6 @@ static void MX_I2C1_Init(void)
|
|
|
|
|
|
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PRIORITY_MEDIUM);
|
|
|
|
|
|
-// LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_CIRCULAR);
|
|
|
-
|
|
|
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PERIPH_NOINCREMENT);
|
|
|
|
|
|
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MEMORY_INCREMENT);
|
|
@@ -526,8 +508,6 @@ static void MX_I2C1_Init(void)
|
|
|
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE);
|
|
|
|
|
|
/* I2C1 interrupt Init */
|
|
|
-// NVIC_SetPriority(I2C1_IRQn, 0);
|
|
|
-// NVIC_EnableIRQ(I2C1_IRQn);
|
|
|
|
|
|
/* USER CODE BEGIN I2C1_Init 1 */
|
|
|
/* Enable DMA transfer complete/error interrupts */
|
|
@@ -553,8 +533,6 @@ static void MX_I2C1_Init(void)
|
|
|
LL_I2C_DisableClockStretching(I2C1);
|
|
|
LL_I2C_Init(I2C1, &I2C_InitStruct);
|
|
|
/* USER CODE BEGIN I2C1_Init 2 */
|
|
|
-// LL_I2C_EnableIT_NACK(I2C1);
|
|
|
-// LL_I2C_EnableIT_ERR(I2C1);
|
|
|
|
|
|
/* USER CODE END I2C1_Init 2 */
|
|
|
|
|
@@ -587,7 +565,7 @@ static void MX_SPI1_Init(void)
|
|
|
GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
|
|
|
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
|
|
|
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
|
|
|
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; //LL_GPIO_OUTPUT_PUSHPULL;
|
|
|
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
|
|
|
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
|
|
|
GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
|
|
|
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
|
@@ -595,7 +573,7 @@ static void MX_SPI1_Init(void)
|
|
|
GPIO_InitStruct.Pin = LL_GPIO_PIN_5;
|
|
|
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
|
|
|
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
|
|
|
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; //LL_GPIO_OUTPUT_PUSHPULL;
|
|
|
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
|
|
|
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
|
|
|
GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
|
|
|
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|