bmp180 update

This commit is contained in:
lilian 2017-08-04 00:13:51 -03:00
parent a731034e65
commit d0ee1b06f3
3 changed files with 79 additions and 71 deletions

View file

@ -13,18 +13,25 @@
// BMP180 driver // BMP180 driver
#include "bmp180/bmp180.h" #include "bmp180/bmp180.h"
#define MY_EVT_TIMER 0x01 #define I2C_BUS 0
#define MY_EVT_BMP180 0x02
#define SCL_PIN GPIO_ID_PIN((0)) #define SCL_PIN GPIO_ID_PIN((0))
#define SDA_PIN GPIO_ID_PIN((2)) #define SDA_PIN GPIO_ID_PIN((2))
#define MY_EVT_TIMER 0x01
#define MY_EVT_BMP180 0x02
typedef struct typedef struct
{ {
uint8_t event_type; uint8_t event_type;
bmp180_result_t bmp180_data; bmp180_result_t bmp180_data;
} my_event_t; } my_event_t;
//device descriptor
i2c_dev_t dev = {
.addr = BMP180_DEVICE_ADDRESS,
.bus = I2C_BUS,
};
// Communication Queue // Communication Queue
static QueueHandle_t mainqueue; static QueueHandle_t mainqueue;
static TimerHandle_t timerHandle; static TimerHandle_t timerHandle;
@ -70,7 +77,7 @@ void bmp180_task(void *pvParameters)
case MY_EVT_TIMER: case MY_EVT_TIMER:
printf("%s: Received Timer Event\n", __FUNCTION__); printf("%s: Received Timer Event\n", __FUNCTION__);
bmp180_trigger_measurement(com_queue); bmp180_trigger_measurement(&dev, com_queue);
break; break;
case MY_EVT_BMP180: case MY_EVT_BMP180:
printf("%s: Received BMP180 Event temp:=%d.%dC press=%d.%02dhPa\n", __FUNCTION__, \ printf("%s: Received BMP180 Event temp:=%d.%dC press=%d.%02dhPa\n", __FUNCTION__, \
@ -91,6 +98,9 @@ void user_setup(void)
// Give the UART some time to settle // Give the UART some time to settle
sdk_os_delay_us(500); sdk_os_delay_us(500);
// Init I2C bus Interface
i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_100K);
} }
void user_init(void) void user_init(void)
@ -107,7 +117,7 @@ void user_init(void)
bmp180_informUser = bmp180_i2c_informUser; bmp180_informUser = bmp180_i2c_informUser;
// Init BMP180 Interface // Init BMP180 Interface
bmp180_init(SCL_PIN, SDA_PIN); bmp180_init(&dev);
// Create Main Communication Queue // Create Main Communication Queue
mainqueue = xQueueCreate(10, sizeof(my_event_t)); mainqueue = xQueueCreate(10, sizeof(my_event_t));

View file

@ -7,13 +7,9 @@
#include "espressif/esp_common.h" #include "espressif/esp_common.h"
#include "espressif/sdk_private.h" #include "espressif/sdk_private.h"
#include "i2c/i2c.h"
#define BMP180_RX_QUEUE_SIZE 10 #define BMP180_RX_QUEUE_SIZE 10
#define BMP180_TASK_PRIORITY 9 #define BMP180_TASK_PRIORITY 9
#define BMP180_DEVICE_ADDRESS 0x77
#define BMP180_VERSION_REG 0xD0 #define BMP180_VERSION_REG 0xD0
#define BMP180_CONTROL_REG 0xF4 #define BMP180_CONTROL_REG 0xF4
#define BMP180_RESET_REG 0xE0 #define BMP180_RESET_REG 0xE0
@ -39,43 +35,43 @@
// //
#define BMP180_RESET_VALUE 0xB6 #define BMP180_RESET_VALUE 0xB6
static int bmp180_readRegister16(uint8_t reg, int16_t *r) static int bmp180_readRegister16(i2c_dev_t *dev, uint8_t reg, int16_t *r)
{ {
uint8_t d[] = { 0, 0 }; uint8_t d[] = { 0, 0 };
int error ; int error ;
if ((error = i2c_slave_read(BMP180_DEVICE_ADDRESS, &reg, d, 2))) if ((error = i2c_slave_read(dev->bus, dev->addr, &reg, d, 2)))
return error; return error;
*r = ((int16_t)d[0] << 8) | (d[1]); *r = ((int16_t)d[0] << 8) | (d[1]);
return 0; return 0;
} }
static int bmp180_start_Messurement(uint8_t cmd) static int bmp180_start_Messurement(i2c_dev_t *dev, uint8_t cmd)
{ {
uint8_t reg = BMP180_CONTROL_REG ; uint8_t reg = BMP180_CONTROL_REG ;
return i2c_slave_write(BMP180_DEVICE_ADDRESS, &reg, &cmd, 1); return i2c_slave_write(dev->bus, dev->addr, &reg, &cmd, 1);
} }
static bool bmp180_get_uncompensated_temperature(int32_t *ut) static bool bmp180_get_uncompensated_temperature(i2c_dev_t *dev, int32_t *ut)
{ {
// Write Start Code into reg 0xF4. // Write Start Code into reg 0xF4.
if (bmp180_start_Messurement(BMP180_MEASURE_TEMP)) if (bmp180_start_Messurement(dev, BMP180_MEASURE_TEMP))
return false; return false;
// Wait 5ms, datasheet states 4.5ms // Wait 5ms, datasheet states 4.5ms
sdk_os_delay_us(5000); sdk_os_delay_us(5000);
int16_t v; int16_t v;
if (bmp180_readRegister16(BMP180_OUT_MSB_REG, &v)) if (bmp180_readRegister16(dev, BMP180_OUT_MSB_REG, &v))
return false; return false;
*ut = v; *ut = v;
return true; return true;
} }
static bool bmp180_get_uncompensated_pressure(uint8_t oss, uint32_t *up) static bool bmp180_get_uncompensated_pressure(i2c_dev_t *dev, uint8_t oss, uint32_t *up)
{ {
uint16_t us; uint16_t us;
@ -89,14 +85,14 @@ static bool bmp180_get_uncompensated_pressure(uint8_t oss, uint32_t *up)
} }
// Write Start Code into reg 0xF4 // Write Start Code into reg 0xF4
if (bmp180_start_Messurement(BMP180_MEASURE_PRESS | (oss << 6))) if (bmp180_start_Messurement(dev, BMP180_MEASURE_PRESS | (oss << 6)))
return false; return false;
sdk_os_delay_us(us); sdk_os_delay_us(us);
uint8_t d[] = { 0, 0, 0 }; uint8_t d[] = { 0, 0, 0 };
uint8_t reg = BMP180_OUT_MSB_REG; uint8_t reg = BMP180_OUT_MSB_REG;
if (i2c_slave_read(BMP180_DEVICE_ADDRESS, &reg, d, 3)) if (i2c_slave_read(dev->bus, dev->addr, &reg, d, 3))
return false; return false;
uint32_t r = ((uint32_t)d[0] << 16) | ((uint32_t)d[1] << 8) | d[2]; uint32_t r = ((uint32_t)d[0] << 16) | ((uint32_t)d[1] << 8) | d[2];
@ -106,19 +102,19 @@ static bool bmp180_get_uncompensated_pressure(uint8_t oss, uint32_t *up)
} }
// Returns true of success else false. // Returns true of success else false.
bool bmp180_fillInternalConstants(bmp180_constants_t *c) bool bmp180_fillInternalConstants(i2c_dev_t *dev, bmp180_constants_t *c)
{ {
if (bmp180_readRegister16(BMP180_CALIBRATION_REG+0, &c->AC1) || if (bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+0, &c->AC1) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+2, &c->AC2) || bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+2, &c->AC2) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+4, &c->AC3) || bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+4, &c->AC3) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+6, (int16_t *)&c->AC4) || bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+6, (int16_t *)&c->AC4) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+8, (int16_t *)&c->AC5) || bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+8, (int16_t *)&c->AC5) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+10, (int16_t *)&c->AC6) || bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+10, (int16_t *)&c->AC6) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+12, &c->B1) || bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+12, &c->B1) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+14, &c->B2) || bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+14, &c->B2) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+16, &c->MB) || bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+16, &c->MB) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+18, &c->MC) || bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+18, &c->MC) ||
bmp180_readRegister16(BMP180_CALIBRATION_REG+20, &c->MD)) { bmp180_readRegister16(dev, BMP180_CALIBRATION_REG+20, &c->MD)) {
return false; return false;
} }
@ -139,16 +135,16 @@ bool bmp180_fillInternalConstants(bmp180_constants_t *c)
c->MB == 0xffff || c->MC == 0xffff || c->MD == 0xffff); c->MB == 0xffff || c->MC == 0xffff || c->MD == 0xffff);
} }
bool bmp180_is_available() bool bmp180_is_available(i2c_dev_t *dev)
{ {
uint8_t id; uint8_t id;
uint8_t reg = BMP180_VERSION_REG; uint8_t reg = BMP180_VERSION_REG;
if (i2c_slave_read(BMP180_DEVICE_ADDRESS, &reg, &id, 1)) if (i2c_slave_read(dev->bus, dev->addr, &reg, &id, 1))
return false; return false;
return id == BMP180_CHIP_ID; return id == BMP180_CHIP_ID;
} }
bool bmp180_measure(bmp180_constants_t *c, int32_t *temperature, bool bmp180_measure(i2c_dev_t *dev, bmp180_constants_t *c, int32_t *temperature,
uint32_t *pressure, uint8_t oss) uint32_t *pressure, uint8_t oss)
{ {
int32_t T, P; int32_t T, P;
@ -160,7 +156,7 @@ bool bmp180_measure(bmp180_constants_t *c, int32_t *temperature,
// //
// Calculation taken from BMP180 Datasheet // Calculation taken from BMP180 Datasheet
int32_t UT, X1, X2, B5; int32_t UT, X1, X2, B5;
if (!bmp180_get_uncompensated_temperature(&UT)) if (!bmp180_get_uncompensated_temperature(dev, &UT))
return false; return false;
X1 = ((UT - (int32_t)c->AC6) * (int32_t)c->AC5) >> 15; X1 = ((UT - (int32_t)c->AC6) * (int32_t)c->AC5) >> 15;
@ -177,7 +173,7 @@ bool bmp180_measure(bmp180_constants_t *c, int32_t *temperature,
int32_t X3, B3, B6; int32_t X3, B3, B6;
uint32_t B4, B7, UP; uint32_t B4, B7, UP;
if (!bmp180_get_uncompensated_pressure(oss, &UP)) if (!bmp180_get_uncompensated_pressure(dev, oss, &UP))
return false; return false;
// Calculation taken from BMP180 Datasheet // Calculation taken from BMP180 Datasheet
@ -220,8 +216,8 @@ typedef struct
} bmp180_command_t; } bmp180_command_t;
// Just works due to the fact that QueueHandle_t is a "void *" // Just works due to the fact that QueueHandle_t is a "void *"
static QueueHandle_t bmp180_rx_queue = NULL; static QueueHandle_t bmp180_rx_queue[MAX_I2C_BUS] = { NULL };
static TaskHandle_t bmp180_task_handle = NULL; static TaskHandle_t bmp180_task_handle[MAX_I2C_BUS] = { NULL };
// //
// Forward declarations // Forward declarations
@ -237,6 +233,7 @@ static void bmp180_driver_task(void *pvParameters)
// Data to be received from user // Data to be received from user
bmp180_command_t current_command; bmp180_command_t current_command;
bmp180_constants_t bmp180_constants; bmp180_constants_t bmp180_constants;
i2c_dev_t *dev = (i2c_dev_t*)pvParameters;
#ifdef BMP180_DEBUG #ifdef BMP180_DEBUG
// Wait for commands from the outside // Wait for commands from the outside
@ -244,14 +241,14 @@ static void bmp180_driver_task(void *pvParameters)
#endif #endif
// Initialize all internal constants. // Initialize all internal constants.
if (!bmp180_fillInternalConstants(&bmp180_constants)) { if (!bmp180_fillInternalConstants(dev, &bmp180_constants)) {
printf("%s: reading internal constants failed\n", __FUNCTION__); printf("%s: reading internal constants failed\n", __FUNCTION__);
vTaskDelete(NULL); vTaskDelete(NULL);
} }
while(1) { while(1) {
// Wait for user to insert commands // Wait for user to insert commands
if (xQueueReceive(bmp180_rx_queue, &current_command, portMAX_DELAY) == pdTRUE) { if (xQueueReceive(bmp180_rx_queue[dev->bus], &current_command, portMAX_DELAY) == pdTRUE) {
#ifdef BMP180_DEBUG #ifdef BMP180_DEBUG
printf("%s: Received user command %d 0x%p\n", __FUNCTION__, current_command.cmd, current_command.resultQueue); printf("%s: Received user command %d 0x%p\n", __FUNCTION__, current_command.cmd, current_command.resultQueue);
#endif #endif
@ -261,7 +258,7 @@ static void bmp180_driver_task(void *pvParameters)
int32_t T = 0; int32_t T = 0;
uint32_t P = 0; uint32_t P = 0;
if (bmp180_measure(&bmp180_constants, &T, (current_command.cmd & BMP180_PRESSURE) ? &P : NULL, 3)) { if (bmp180_measure(dev, &bmp180_constants, &T, (current_command.cmd & BMP180_PRESSURE) ? &P : NULL, 3)) {
// Inform the user ... // Inform the user ...
if (!bmp180_informUser(current_command.resultQueue, if (!bmp180_informUser(current_command.resultQueue,
current_command.cmd, current_command.cmd,
@ -276,22 +273,22 @@ static void bmp180_driver_task(void *pvParameters)
} }
} }
static bool bmp180_create_communication_queues() static bool bmp180_create_communication_queues(i2c_dev_t *dev)
{ {
// Just create them once // Just create them once by bus
if (bmp180_rx_queue == NULL) if (bmp180_rx_queue[dev->bus] == NULL)
bmp180_rx_queue = xQueueCreate(BMP180_RX_QUEUE_SIZE, sizeof(bmp180_result_t)); bmp180_rx_queue[dev->bus] = xQueueCreate(BMP180_RX_QUEUE_SIZE, sizeof(bmp180_result_t));
return bmp180_rx_queue != NULL; return bmp180_rx_queue[dev->bus] != NULL;
} }
static bool bmp180_createTask() static bool bmp180_createTask(i2c_dev_t *dev)
{ {
// We already have a task // We already have a task
portBASE_TYPE x = pdPASS; portBASE_TYPE x = pdPASS;
if (bmp180_task_handle == NULL) { if (bmp180_task_handle[dev->bus] == NULL) {
x = xTaskCreate(bmp180_driver_task, "bmp180_driver_task", 256, NULL, BMP180_TASK_PRIORITY, &bmp180_task_handle); x = xTaskCreate(bmp180_driver_task, "bmp180_driver_task", 256, (void*)dev, BMP180_TASK_PRIORITY, &bmp180_task_handle[dev->bus]); //TODO: name task with i2c bus
} }
return x == pdPASS; return x == pdPASS;
} }
@ -309,54 +306,51 @@ static bool bmp180_informUser_Impl(const QueueHandle_t* resultQueue, uint8_t cmd
} }
// Just init all needed queues // Just init all needed queues
bool bmp180_init(uint8_t scl, uint8_t sda) bool bmp180_init(i2c_dev_t *dev)
{ {
// 1. Create required queues // 1. Create required queues
bool result = false; bool result = false;
if (bmp180_create_communication_queues()) { if (bmp180_create_communication_queues(dev)) {
// 2. Init i2c driver // 2. Check for bmp180 ...
i2c_init(scl, sda); if (bmp180_is_available(dev)) {
// 3. Check for bmp180 ... // 3. Start driver task
if (bmp180_is_available()) { if (bmp180_createTask(dev)) {
// 4. Start driver task
if (bmp180_createTask()) {
// We are finished // We are finished
result = true; result = true;
} }
} }
} }
return result; return result;
} }
void bmp180_trigger_measurement(const QueueHandle_t* resultQueue) void bmp180_trigger_measurement(i2c_dev_t *dev, const QueueHandle_t* resultQueue)
{ {
bmp180_command_t c; bmp180_command_t c;
c.cmd = BMP180_PRESSURE + BMP180_TEMPERATURE; c.cmd = BMP180_PRESSURE + BMP180_TEMPERATURE;
c.resultQueue = resultQueue; c.resultQueue = resultQueue;
xQueueSend(bmp180_rx_queue, &c, 0); xQueueSend(bmp180_rx_queue[dev->bus], &c, 0);
} }
void bmp180_trigger_pressure_measurement(const QueueHandle_t* resultQueue) void bmp180_trigger_pressure_measurement(i2c_dev_t *dev, const QueueHandle_t* resultQueue)
{ {
bmp180_command_t c; bmp180_command_t c;
c.cmd = BMP180_PRESSURE; c.cmd = BMP180_PRESSURE;
c.resultQueue = resultQueue; c.resultQueue = resultQueue;
xQueueSend(bmp180_rx_queue, &c, 0); xQueueSend(bmp180_rx_queue[dev->bus], &c, 0);
} }
void bmp180_trigger_temperature_measurement(const QueueHandle_t* resultQueue) void bmp180_trigger_temperature_measurement(i2c_dev_t *dev, const QueueHandle_t* resultQueue)
{ {
bmp180_command_t c; bmp180_command_t c;
c.cmd = BMP180_TEMPERATURE; c.cmd = BMP180_TEMPERATURE;
c.resultQueue = resultQueue; c.resultQueue = resultQueue;
xQueueSend(bmp180_rx_queue, &c, 0); xQueueSend(bmp180_rx_queue[dev->bus], &c, 0);
} }

View file

@ -14,9 +14,13 @@
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "queue.h" #include "queue.h"
#include "i2c/i2c.h"
// Uncomment to enable debug output // Uncomment to enable debug output
//#define BMP180_DEBUG //#define BMP180_DEBUG
#define BMP180_DEVICE_ADDRESS 0x77
#define BMP180_TEMPERATURE (1<<0) #define BMP180_TEMPERATURE (1<<0)
#define BMP180_PRESSURE (1<<1) #define BMP180_PRESSURE (1<<1)
@ -42,16 +46,16 @@ typedef struct
} bmp180_result_t; } bmp180_result_t;
// Init bmp180 driver ... // Init bmp180 driver ...
bool bmp180_init(uint8_t scl, uint8_t sda); bool bmp180_init(i2c_dev_t *dev);
// Trigger a "complete" measurement (temperature and pressure will be valid when given to "bmp180_informUser) // Trigger a "complete" measurement (temperature and pressure will be valid when given to "bmp180_informUser)
void bmp180_trigger_measurement(const QueueHandle_t* resultQueue); void bmp180_trigger_measurement(i2c_dev_t *dev, const QueueHandle_t* resultQueue);
// Trigger a "temperature only" measurement (only temperature will be valid when given to "bmp180_informUser) // Trigger a "temperature only" measurement (only temperature will be valid when given to "bmp180_informUser)
void bmp180_trigger_temperature_measurement(const QueueHandle_t* resultQueue); void bmp180_trigger_temperature_measurement(i2c_dev_t *dev, const QueueHandle_t* resultQueue);
// Trigger a "pressure only" measurement (only pressure will be valid when given to "bmp180_informUser) // Trigger a "pressure only" measurement (only pressure will be valid when given to "bmp180_informUser)
void bmp180_trigger_pressure_measurement(const QueueHandle_t* resultQueue); void bmp180_trigger_pressure_measurement(i2c_dev_t *dev, const QueueHandle_t* resultQueue);
// Give the user the chance to create it's own handler // Give the user the chance to create it's own handler
extern bool (*bmp180_informUser)(const QueueHandle_t* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure); extern bool (*bmp180_informUser)(const QueueHandle_t* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure);
@ -75,12 +79,12 @@ typedef struct
} bmp180_constants_t; } bmp180_constants_t;
// Returns true if the bmp180 is detected. // Returns true if the bmp180 is detected.
bool bmp180_is_available(); bool bmp180_is_available(i2c_dev_t *dev);
// Reads all the internal constants, returning true on success. // Reads all the internal constants, returning true on success.
bool bmp180_fillInternalConstants(bmp180_constants_t *c); bool bmp180_fillInternalConstants(i2c_dev_t *dev, bmp180_constants_t *c);
// Reads an optional temperature and pressure. The over sampling // Reads an optional temperature and pressure. The over sampling
// setting, oss, may be 0 to 3. Returns true on success. // setting, oss, may be 0 to 3. Returns true on success.
bool bmp180_measure(bmp180_constants_t *c, int32_t *temperature, bool bmp180_measure(i2c_dev_t *dev, bmp180_constants_t *c, int32_t *temperature,
uint32_t *pressure, uint8_t oss); uint32_t *pressure, uint8_t oss);
#ifdef __cplusplus #ifdef __cplusplus