34 #if defined(PIOS_INCLUDE_MS5611_SPI)
42 #define PIOS_MS5611_OVERSAMPLING oversampling
43 #define MS5611_TASK_PRIORITY PIOS_THREAD_PRIO_HIGHEST
44 #define MS5611_TASK_STACK_BYTES 512
47 #define MS5611_RESET 0x1E
48 #define MS5611_CALIB_ADDR 0xA2
49 #define MS5611_CALIB_LEN 16
50 #define MS5611_ADC_READ 0x00
51 #define MS5611_PRES_ADDR 0x40
52 #define MS5611_TEMP_ADDR 0x50
53 #define MS5611_ADC_MSB 0xF6
54 #define MS5611_P0 101.3250f
57 static int32_t PIOS_MS5611_Read(uint8_t address, uint8_t * buffer, uint8_t len);
58 static int32_t PIOS_MS5611_WriteCommand(uint8_t command);
59 static void PIOS_MS5611_Task(
void *parameters);
65 enum pios_ms5611_dev_magic {
66 PIOS_MS5611_DEV_MAGIC = 0xefba8e10,
69 enum conversion_type {
78 struct pios_thread *
task;
81 int64_t pressure_unscaled;
82 int64_t temperature_unscaled;
83 uint16_t calibration[6];
84 enum conversion_type current_conversion_type;
85 enum pios_ms5611_dev_magic
magic;
90 static struct ms5611_dev *dev;
95 static struct ms5611_dev * PIOS_MS5611_alloc(
void)
97 struct ms5611_dev *ms5611_dev;
99 ms5611_dev = (
struct ms5611_dev *)
PIOS_malloc(
sizeof(*ms5611_dev));
103 memset(ms5611_dev, 0,
sizeof(*ms5611_dev));
106 if (ms5611_dev->queue == NULL) {
111 ms5611_dev->magic = PIOS_MS5611_DEV_MAGIC;
123 static int32_t PIOS_MS5611_Validate(
struct ms5611_dev *dev)
127 if (dev->magic != PIOS_MS5611_DEV_MAGIC)
129 if (dev->spi_id == 0)
140 dev = (
struct ms5611_dev *)PIOS_MS5611_alloc();
144 dev->spi_id = spi_id;
145 dev->slave_num = slave_num;
149 if (PIOS_MS5611_WriteCommand(MS5611_RESET) != 0)
158 PIOS_MS5611_Read(MS5611_CALIB_ADDR +
i * 2, data, 2);
159 dev->calibration[
i] = (data[0] << 8) | data[1];
165 PIOS_MS5611_Task,
"pios_ms5611", MS5611_TASK_STACK_BYTES, NULL, MS5611_TASK_PRIORITY);
176 static int32_t PIOS_MS5611_ClaimDevice(
void)
187 static int32_t PIOS_MS5611_ReleaseDevice(
void)
198 static int32_t PIOS_MS5611_ClaimBus(
void)
200 if (PIOS_MS5611_Validate(dev) != 0)
215 static int32_t PIOS_MS5611_ReleaseBus(
void)
217 if (PIOS_MS5611_Validate(dev) != 0)
230 static int32_t PIOS_MS5611_StartADC(
enum conversion_type
type)
232 if (PIOS_MS5611_Validate(dev) != 0)
237 case TEMPERATURE_CONV:
238 while (PIOS_MS5611_WriteCommand(MS5611_TEMP_ADDR + dev->cfg->oversampling) != 0)
242 while (PIOS_MS5611_WriteCommand(MS5611_PRES_ADDR + dev->cfg->oversampling) != 0)
249 dev->current_conversion_type =
type;
257 static int32_t PIOS_MS5611_GetDelay()
259 if (PIOS_MS5611_Validate(dev) != 0)
262 switch(dev->cfg->oversampling) {
283 static int32_t PIOS_MS5611_ReadADC(
void)
285 if (PIOS_MS5611_Validate(dev) != 0)
290 static int64_t delta_temp;
291 static int64_t temperature;
294 if (dev->current_conversion_type == TEMPERATURE_CONV) {
295 uint32_t raw_temperature;
297 if (PIOS_MS5611_Read(MS5611_ADC_READ, data, 3) != 0)
300 raw_temperature = (data[0] << 16) | (data[1] << 8) | data[2];
302 delta_temp = (int32_t)raw_temperature - (dev->calibration[4] << 8);
303 temperature = 2000 + ((delta_temp * dev->calibration[5]) >> 23);
304 dev->temperature_unscaled = temperature;
307 if (temperature < 2000)
308 dev->temperature_unscaled -= (delta_temp * delta_temp) >> 31;
313 uint32_t raw_pressure;
316 if (PIOS_MS5611_Read(MS5611_ADC_READ, data, 3) != 0)
319 raw_pressure = (data[0] << 16) | (data[1] << 8) | (data[2] << 0);
321 offset = ((int64_t)dev->calibration[1] << 16) + (((int64_t)dev->calibration[3] * delta_temp) >> 7);
322 sens = (int64_t)dev->calibration[0] << 15;
323 sens = sens + ((((int64_t) dev->calibration[2]) * delta_temp) >> 8);
326 if (temperature < 2000) {
327 offset -= (5 * (temperature - 2000) * (temperature - 2000)) >> 1;
328 sens -= (5 * (temperature - 2000) * (temperature - 2000)) >> 2;
330 if (dev->temperature_unscaled < -1500) {
331 offset -= 7 * (temperature + 1500) * (temperature + 1500);
332 sens -= (11 * (temperature + 1500) * (temperature + 1500)) >> 1;
336 dev->pressure_unscaled = ((((int64_t)raw_pressure * sens) >> 21) - offset) >> 15;
351 static int32_t PIOS_MS5611_Read(uint8_t address, uint8_t *buffer, uint8_t len)
353 if (PIOS_MS5611_Validate(dev) != 0)
356 if (PIOS_MS5611_ClaimBus() != 0)
371 PIOS_MS5611_ReleaseBus();
385 static int32_t PIOS_MS5611_WriteCommand(uint8_t command)
387 if (PIOS_MS5611_Validate(dev) != 0)
390 if (PIOS_MS5611_ClaimBus() != 0)
395 PIOS_MS5611_ReleaseBus();
404 int32_t PIOS_MS5611_SPI_Test()
406 if (PIOS_MS5611_Validate(dev) != 0)
410 PIOS_MS5611_ClaimDevice();
411 PIOS_MS5611_StartADC(TEMPERATURE_CONV);
413 PIOS_MS5611_ReadADC();
414 PIOS_MS5611_ReleaseDevice();
416 PIOS_MS5611_ClaimDevice();
417 PIOS_MS5611_StartADC(PRESSURE_CONV);
419 PIOS_MS5611_ReadADC();
420 PIOS_MS5611_ReleaseDevice();
424 if (dev->temperature_unscaled < -4000 ||
425 dev->temperature_unscaled > 8500 ||
426 dev->pressure_unscaled < 1000 ||
427 dev->pressure_unscaled > 120000)
433 static void PIOS_MS5611_Task(
void *parameters)
436 uint32_t temp_press_interleave_count = 1;
437 int32_t read_adc_result = 0;
441 --temp_press_interleave_count;
443 if (temp_press_interleave_count == 0)
446 PIOS_MS5611_ClaimDevice();
447 PIOS_MS5611_StartADC(TEMPERATURE_CONV);
449 PIOS_MS5611_ReadADC();
450 PIOS_MS5611_ReleaseDevice();
452 temp_press_interleave_count = dev->cfg->temperature_interleaving;
453 if (temp_press_interleave_count == 0)
454 temp_press_interleave_count = 1;
458 PIOS_MS5611_ClaimDevice();
459 PIOS_MS5611_StartADC(PRESSURE_CONV);
461 read_adc_result = PIOS_MS5611_ReadADC();
462 PIOS_MS5611_ReleaseDevice();
466 data.
temperature = ((float) dev->temperature_unscaled) / 100.0f;
467 data.pressure = ((float) dev->pressure_unscaled) / 1000.0f;
468 data.altitude = 44330.0f * (1.0f - powf(data.pressure / MS5611_P0, (1.0f / 5.255f)));
471 if (read_adc_result == 0) {
struct pios_queue * PIOS_Queue_Create(size_t queue_length, size_t item_size)
#define PIOS_SEMAPHORE_TIMEOUT_MAX
Main PiOS header to include all the compiled in PiOS options.
int32_t PIOS_SPI_RC_PinSet(pios_spi_t spi_dev, uint32_t slave_id, bool pin_value)
int32_t PIOS_MS5611_SPI_Init(pios_spi_t spi_id, uint32_t slave_num, const struct pios_ms5611_cfg *cfg)
int32_t PIOS_SPI_ClaimBus(pios_spi_t spi_dev)
void * PIOS_malloc(size_t size)
bool PIOS_Queue_Send(struct pios_queue *queuep, const void *itemp, uint32_t timeout_ms)
uint8_t data[XFER_BYTES_PER_PACKET]
Configuration structure for the MS5611 driver.
static struct flyingpicmd_cfg_fa cfg
struct pios_semaphore * PIOS_Semaphore_Create(void)
Creates a binary semaphore.
uint8_t PIOS_SPI_TransferByte(pios_spi_t spi_dev, uint8_t b)
int32_t PIOS_SPI_TransferBlock(pios_spi_t spi_dev, const uint8_t *send_buffer, uint8_t *receive_buffer, uint16_t len)
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
int32_t PIOS_SENSORS_Register(enum pios_sensor_type type, struct pios_queue *queue)
Register a queue-based sensor with the PIOS_SENSORS interface.
static TaskInfoRunningElem task
Pios sensor structure for generic baro data.
bool PIOS_Semaphore_Give(struct pios_semaphore *sema)
Gives binary semaphore.
void PIOS_free(void *buf)
void PIOS_Thread_Sleep(uint32_t time_ms)
bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms)
Takes binary semaphore.
int32_t PIOS_SPI_ReleaseBus(pios_spi_t spi_dev)
static struct pios_queue * queue
#define PIOS_Assert(test)
int32_t PIOS_DELAY_WaitmS(uint32_t mS)