diff --git a/.gitmodules b/.gitmodules index 8b8a7fc..a3d5b53 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "fw/Libs/rgbled"] path = fw/Libs/rgbled url = git@gitlab.com:VelesLabs/stm32libs/rgbled.git +[submodule "fw/Libs/sps30"] + path = fw/Libs/sps30 + url = git@gitlab.com:VelesLabs/stm32libs/sps30.git diff --git a/fw/.cproject b/fw/.cproject index f852c90..ef4b314 100644 --- a/fw/.cproject +++ b/fw/.cproject @@ -36,6 +36,7 @@ + @@ -69,6 +70,7 @@ + @@ -103,6 +105,7 @@ + @@ -140,6 +143,7 @@ + @@ -172,6 +176,7 @@ + diff --git a/fw/Core/Inc/sps30.h b/fw/Core/Inc/sps30.h deleted file mode 100644 index 9b1b943..0000000 --- a/fw/Core/Inc/sps30.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * sps30.h - * - * Created on: Jul 18, 2021 - * Author: mrs - */ - -#ifndef INC_SPS30_H_ -#define INC_SPS30_H_ - -#include "stdint.h" -#include "stm32l0xx_ll_i2c.h" -#include "stm32l0xx_ll_utils.h" -#include "i2c.h" -#include "crc8.h" - -/* - * Defines & macros - */ - -#define SPS30_I2C_ADDRESS 0x69 -#define SPS30_MEASURED_VALUES_COUNT 10 - -/* - * Return values - */ - -#define SPS30_OK 0 -#define SPS30_ERROR -1 // generic error -#define SPS30_CRC8_ERROR -2 // checksum failed - -/* - * Data types - */ - -typedef enum { - SPS30_START_MEASUREMENT = 0x0010, - SPS30_STOP_MEASUREMENT = 0x0104, - SPS30_READ_DATA_READY_FLAG = 0x0202, - SPS30_READ_MEASURED_VALUES = 0x0300, - SPS30_SLEEP = 0x1001, - SPS30_WAKE_UP = 0x1103, - SPS30_START_FAN_CLEANING = 0x5607, - SPS30_READ_AUTO_CLEANING_INTERVAL = 0x8004, - SPS30_WRITE_AUTO_CLEANING_INTERVAL = 0x8004, - SPS30_READ_PRODUCT_TYPE = 0xD002, - SPS30_READ_SERIAL_NUMBER = 0xD033, - SPS30_READ_VERSION = 0xD100, - SPS30_READ_DEVICE_STATUS_REGISTER = 0xD206, - SPS30_CLEAR_DEVICE_STATUS_REGISTER = 0xD210, - SPS30_RESET = 0xD304 -} sps30_cmd_t; - -typedef enum { - SPS30_FLOAT_FORMAT = 0x03, - SPS30_UINT16_FORMAT = 0x05 -} sps30_data_format_t; - -typedef enum { - PM0_5 = 0, /* this category is used only for number concentration */ - PM1_0, - PM2_5, - PM4_0, - PM10_0, - SPS30_PM_CATEGORIES_COUNT -} sps30_pm_categories_t; - -typedef struct { - /* PM0.5 is skipped for mass concentration */ - uint16_t mass_concentration[SPS30_PM_CATEGORIES_COUNT]; /* ug / m^3 */ - uint16_t number_concentration[SPS30_PM_CATEGORIES_COUNT]; /* 1 / cm^3 */ - uint16_t typical_particle_size; /* nm */ -} sps30_data_t; - -int8_t sps30_send_cmd(sps30_cmd_t cmd); - -int8_t sps30_start_measurement( void ); -int8_t sps30_stop_measurement( void ); -int8_t sps30_read_measured_values(sps30_data_t *measured_data); - -int8_t sps30_sleep( void ); -int8_t sps30_wake_up( void ); - -int8_t sps30_start_fan_cleaning( void ); - -int8_t sps30_reset( void ); - -int8_t sps30_read_status_register ( void ); - -int8_t sps30_read_firmware_version ( uint8_t * fw_ver_hi, uint8_t * fw_ver_lo ); - -#endif /* INC_SPS30_H_ */ diff --git a/fw/Core/Src/sps30.c b/fw/Core/Src/sps30.c deleted file mode 100644 index 884395d..0000000 --- a/fw/Core/Src/sps30.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * sps30.c - * - * Created on: Jul 18, 2021 - * Author: david - */ - -#include "sps30.h" -#include "main.h" /* for uart_disable_interrupts() */ - -int8_t sps30_send_cmd(sps30_cmd_t cmd) -{ - uint8_t buffer[32]; - uint8_t result; - - // start measurement - buffer[0] = cmd >> 8; - buffer[1] = cmd & 0x00ff; - uart_disable_interrupts(); - result = i2c_transmit(SPS30_I2C_ADDRESS<<1, buffer, 2); - uart_enable_interrupts(); - // TODO: Proc to vraci NACK? Vyresit. - if (result != I2C_OK) { - return SPS30_ERROR; - } - - return SPS30_OK; -} - -int8_t sps30_start_measurement( void ) -{ - uint8_t buffer[5]; - uint8_t result; - - buffer[0] = SPS30_START_MEASUREMENT >> 8; - buffer[1] = SPS30_START_MEASUREMENT & 0x00ff; - buffer[2] = SPS30_UINT16_FORMAT; - buffer[3] = 0x00; - buffer[4] = crc8_calculate(buffer + 2, 2); - - uart_disable_interrupts(); - result = i2c_transmit(SPS30_I2C_ADDRESS<<1, buffer, 5); - uart_enable_interrupts(); - - if (result != I2C_OK) { - return SPS30_ERROR; - } - return SPS30_OK; -} - -int8_t sps30_stop_measurement( void ) -{ - return sps30_send_cmd(SPS30_STOP_MEASUREMENT); -} - -int8_t sps30_read_measured_values(sps30_data_t *measured_data) -{ - uint8_t buffer[32]; - - uint8_t result; - - // start measurement - buffer[0] = SPS30_READ_MEASURED_VALUES >> 8; - buffer[1] = SPS30_READ_MEASURED_VALUES & 0xFF; - uart_disable_interrupts(); - result = i2c_transmit(SPS30_I2C_ADDRESS<<1, buffer, 2); - uart_enable_interrupts(); - if (result != I2C_OK) { - return SPS30_ERROR; - } - LL_mDelay(10); // 10 ms should be enough - // read out - uart_disable_interrupts(); - result = i2c_receive(SPS30_I2C_ADDRESS<<1, buffer, 3 * SPS30_MEASURED_VALUES_COUNT); - uart_enable_interrupts(); - if (result != I2C_OK) - { - return SPS30_ERROR; - } - /* check data integrity */ - for (uint8_t i = 0; i < SPS30_MEASURED_VALUES_COUNT; i++) - { - uint8_t checksum_calculated = crc8_calculate(buffer + 3*i, 2); - uint8_t checksum_received = buffer[3*i + 2]; - if (checksum_calculated != checksum_received) { - return SPS30_CRC8_ERROR; - } - } - /* copy to output struct */ - /* mass concencration [ug / m^3] */ - int pos = 0; - for (int i = 0; i < 4; i++) { - /* i + 1 because mass concentration starts at PM1.0 (there is no PM0.5) */ - measured_data->mass_concentration[i + 1] = (buffer[pos] << 8) + buffer[pos + 1]; - pos += 3; /* 2 B data, 1 B crc */ - } - /* number concentration [1 / cm^3] */ - for (int i = 0; i < 5; i++) { - measured_data->number_concentration[i] = (buffer[pos] << 8) + buffer[pos + 1]; - pos += 3; - } - /* typical particle size [nm] */ - measured_data->typical_particle_size = (buffer[pos] << 8) + buffer[pos + 1]; - - return SPS30_OK; -} - -int8_t sps30_sleep( void ) -{ - return sps30_send_cmd(SPS30_SLEEP); -} - -int8_t sps30_wake_up( void ) -{ - return sps30_send_cmd(SPS30_WAKE_UP); -} - -int8_t sps30_start_fan_cleaning( void ) -{ - return sps30_send_cmd(SPS30_START_FAN_CLEANING); -} - -int8_t sps30_reset( void ) -{ - return sps30_send_cmd(SPS30_RESET); -} - -int8_t sps30_read_status_register ( void ) -{ - uint8_t buffer[6]; - - uint8_t result; - - // start measurement - buffer[0] = SPS30_READ_DEVICE_STATUS_REGISTER >> 8; - buffer[1] = SPS30_READ_DEVICE_STATUS_REGISTER & 0x00ff; - uart_disable_interrupts(); - result = i2c_transmit(SPS30_I2C_ADDRESS<<1, buffer, 2); - uart_enable_interrupts(); - if (result != I2C_OK) { - return SPS30_ERROR; - } - LL_mDelay(10); // 10 ms should be enough - // read out - uart_disable_interrupts(); - result = i2c_receive(SPS30_I2C_ADDRESS<<1, buffer, 6); - uart_enable_interrupts(); - // TODO - - return SPS30_OK; -} - -int8_t sps30_read_firmware_version ( uint8_t * fw_ver_hi, uint8_t * fw_ver_lo ) -{ - uint8_t i2c_tx_buffer[2]; - uint8_t i2c_rx_buffer[3]; - - uint8_t result; - - // start measurement - i2c_tx_buffer[0] = SPS30_READ_VERSION >> 8; - i2c_tx_buffer[1] = SPS30_READ_VERSION & 0x00ff; - uart_disable_interrupts(); - result = i2c_transmit(SPS30_I2C_ADDRESS<<1, i2c_tx_buffer, 2); - uart_enable_interrupts(); - - // TODO: Proc to vraci NACK? Vyresit. - /*if (result != I2C_OK) { - return SPS30_ERROR; - } - return SPS30_OK;*/ - - LL_mDelay(1); // 10 ms should be enough - // read out - uart_disable_interrupts(); - result = i2c_receive(SPS30_I2C_ADDRESS<<1, i2c_rx_buffer, 3); - uart_enable_interrupts(); - /*if (result != I2C_OK) - { - return SPS30_ERROR; - }*/ - - *fw_ver_hi = i2c_rx_buffer[0]; - *fw_ver_lo = i2c_rx_buffer[1]; - - return SPS30_OK; -} diff --git a/fw/Libs/sps30 b/fw/Libs/sps30 new file mode 160000 index 0000000..35a281c --- /dev/null +++ b/fw/Libs/sps30 @@ -0,0 +1 @@ +Subproject commit 35a281c505effbc1db8c37ed2ff681c04bdba269