Fixed I2C error checking and added sensor detection

This commit is contained in:
mj 2022-01-02 15:48:44 +01:00
parent ac68334919
commit 98e6a7f93d
4 changed files with 28 additions and 31 deletions

View File

@ -36,8 +36,9 @@ typedef enum {
SCD4X_START_PERIODIC_MEASUREMENT = 0x21B1, SCD4X_START_PERIODIC_MEASUREMENT = 0x21B1,
SCD4X_READ_MEASUREMENT = 0xEC05, SCD4X_READ_MEASUREMENT = 0xEC05,
SCD4X_STOP_PERIODIC_MEASUREMENT = 0x3F86, SCD4X_STOP_PERIODIC_MEASUREMENT = 0x3F86,
SCD4X_GET_DATA_READY_STATUS = 0xe4b8, SCD4X_GET_DATA_READY_STATUS = 0xE4B8,
SCD4X_PERFORM_FACTORY_RESET = 0x3632 SCD4X_PERFORM_FACTORY_RESET = 0x3632,
SCD4X_GET_SERIAL_NUMBER = 0x3682
} scd4x_cmd_t; } scd4x_cmd_t;
/* /*

View File

@ -21,15 +21,11 @@ int8_t i2c_init(i2c_context_t *context)
int8_t i2c_transmit(uint8_t address, uint8_t *buffer, int len) int8_t i2c_transmit(uint8_t address, uint8_t *buffer, int len)
{ {
/* prevent interrupts during I2C communication (e.g. collision with MODBUS) */
// LL_LPUART_Disable(LPUART1);
// LL_LPUART_DisableIT_RXNE(LPUART1);
// __disable_irq();
LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len, LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len,
LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE); LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
int i = 0; int i = 0;
// Autoend mode will raise STOP flag if NACK is detected /* Autoend mode will raise STOP flag if NACK is detected
// (or if desired number of bytes is transmitted) * (or if desired number of bytes is transmitted) */
while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) { while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
if (LL_I2C_IsActiveFlag_TXE(i2c_context->i2c)) { if (LL_I2C_IsActiveFlag_TXE(i2c_context->i2c)) {
if (i < len) { if (i < len) {
@ -38,25 +34,20 @@ int8_t i2c_transmit(uint8_t address, uint8_t *buffer, int len)
} }
} }
LL_I2C_ClearFlag_STOP(i2c_context->i2c); LL_I2C_ClearFlag_STOP(i2c_context->i2c);
if (LL_I2C_IsActiveFlag_NACK(i2c_context->i2c)) {
return I2C_ERROR_NACK;
}
if (len != i) { if (len != i) {
// this will probably never happen, as NACK flag /* If we detect NACK during transaction (before the end of the last byte) */
// is raised everytime len != number of TXed bytes
return I2C_ERROR_TX_INCOMPLETE; return I2C_ERROR_TX_INCOMPLETE;
} }
// __enable_irq(); /* NACK after last byte is ok */
// LL_LPUART_Enable(LPUART1); // if (LL_I2C_IsActiveFlag_NACK(i2c_context->i2c)) {
// LL_LPUART_EnableIT_RXNE(LPUART1); //
// return I2C_ERROR_NACK;
// }
return I2C_OK; return I2C_OK;
} }
int8_t i2c_receive(uint8_t address, uint8_t *buffer, int len) int8_t i2c_receive(uint8_t address, uint8_t *buffer, int len)
{ {
// __disable_irq();
// LL_LPUART_Disable(LPUART1);
// LL_LPUART_DisableIT_RXNE(LPUART1);
LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len, LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len,
LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ); LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
int i = 0; int i = 0;
@ -71,8 +62,6 @@ int8_t i2c_receive(uint8_t address, uint8_t *buffer, int len)
if (len != i) { if (len != i) {
return I2C_ERROR_RX_INCOMPLETE; return I2C_ERROR_RX_INCOMPLETE;
} }
// __enable_irq();
// LL_LPUART_Enable(LPUART1); return I2C_OK;
// LL_LPUART_EnableIT_RXNE(LPUART1);
return I2C_OK; // TODO error detection
} }

View File

@ -187,7 +187,7 @@ int main(void)
MX_TIM21_Init(); MX_TIM21_Init();
MX_TIM2_Init(); MX_TIM2_Init();
MX_TIM22_Init(); MX_TIM22_Init();
MX_IWDG_Init(); // MX_IWDG_Init();
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
/* Turn on MAGENTA LED to signal startup state */ /* Turn on MAGENTA LED to signal startup state */
@ -246,25 +246,23 @@ int main(void)
LL_mDelay(2000); LL_mDelay(2000);
scd4x_start_periodic_measurement(); scd4x_start_periodic_measurement();
uint8_t scd4x_is_connected = 1; uint8_t scd4x_is_connected = 0;
uint8_t sps30_is_connected = 0; uint8_t sps30_is_connected = 0;
/* USER CODE END 2 */ /* USER CODE END 2 */
/* Infinite loop */ /* Infinite loop */
/* USER CODE BEGIN WHILE */ /* USER CODE BEGIN WHILE */
/*uint8_t scd4x_is_connected = 0;
if (scd4x_start_periodic_measurement() == SCD4X_OK) if (scd4x_start_periodic_measurement() == SCD4X_OK)
{ {
scd4x_is_connected = 1; scd4x_is_connected = 1;
}*/ }
/* Attempt to start SPS30 measurement and check if it's connected */ /* Attempt to start SPS30 measurement and check if it's connected */
/*sps30_reset(); sps30_reset();
uint8_t sps30_is_connected = 0;
if (sps30_start_measurement() == SPS30_OK) if (sps30_start_measurement() == SPS30_OK)
{ {
sps30_is_connected = 1; sps30_is_connected = 1;
}*/ }
/* Wait 1000ms for sensors initialization */ /* Wait 1000ms for sensors initialization */
/* SHT4x Init Time: max 1 ms (datasheet pg. 8) */ /* SHT4x Init Time: max 1 ms (datasheet pg. 8) */

View File

@ -17,13 +17,22 @@ int8_t scd4x_send_cmd(scd4x_cmd_t cmd)
buffer[0] = cmd >> 8; buffer[0] = cmd >> 8;
buffer[1] = cmd & 0x00ff; buffer[1] = cmd & 0x00ff;
result = i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2); result = i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2);
if (result != I2C_OK) { if (result == I2C_ERROR_TX_INCOMPLETE) {
return SCD4X_ERROR; return SCD4X_ERROR;
} }
/* Sensirion sensors return NACK after last byte (so NACK at the end is ok) */
return SCD4X_OK; return SCD4X_OK;
} }
int8_t scd4x_get_serial(uint8_t serial[6])
{
uint8_t buffer[16];
scd4x_send_cmd(SCD4X_GET_SERIAL_NUMBER);
i2c_receive(SCD4X_I2C_ADDRESS << 1, buffer, 9);
}
int8_t scd4x_read_data(uint8_t *buffer, int len) int8_t scd4x_read_data(uint8_t *buffer, int len)
{ {
return SCD4X_OK; return SCD4X_OK;