Paparazzi UAS  v5.18.0_stable
Paparazzi is a free software Unmanned Aircraft System.
ir_mlx.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Martin Mueller
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22 
30 #include "modules/meteo/ir_mlx.h"
31 
32 #include "mcu_periph/sys_time.h"
33 #include "mcu_periph/i2c.h"
34 #include "led.h"
35 #include "mcu_periph/uart.h"
36 #include "pprzlink/messages.h"
38 
39 
40 #ifndef MLX_I2C_DEV
41 #define MLX_I2C_DEV i2c0
42 #endif
43 
45 
53 
54 /* I2C address is set to 6 (8 bit) */
55 #ifndef MLX90614_ADDR
56 #define MLX90614_ADDR 0x06
57 #endif
58 
59 #define MLX90614_GENERAL_ADDR 0
60 
61 // printf("Ta = %2.2f°C (0x%04X)\n", (tp*0.02)-273.15, tp);
62 
63 void ir_mlx_crc(unsigned char addr, volatile unsigned char *data)
64 {
65  unsigned char i, bit, crc = 0;
66 
67  for (i = 0; i < 4; i++) {
68  if (i != 0) { crc ^= (data[i - 1]); }
69  else { crc ^= addr; }
70  for (bit = 8; bit > 0; bit--) {
71  if (crc & 0x80)
72  /* SMBus x^8 + x^2 + x + 1 */
73  {
74  crc = (crc << 1) ^ 0x107;
75  } else {
76  crc = (crc << 1);
77  }
78  }
79  }
80  data[3] = crc;
81 }
82 
83 void ir_mlx_init(void)
84 {
85 #ifdef IR_MLX_ONE_TIME_CONFIG
86 #warning Starting MLX90614 in CONFIGURATION MODE, do this only once for
87 #warning setup, then turn this MODE off again and recompile/flash
89 #else
91 #endif
92 }
93 
94 void ir_mlx_periodic(void)
95 {
96 #ifdef IR_MLX_ONE_TIME_CONFIG
97  if (sys_time.nb_sec > 4) {
98 #else
99  if (sys_time.nb_sec > 1) {
100 #endif
101  if (ir_mlx_status >= IR_MLX_IDLE) {
102  /* start two byte case temperature */
106  /* send serial number every 30 seconds */
107  RunOnceEvery((8 * 30), DOWNLINK_SEND_MLX_SERIAL(DefaultChannel, DefaultDevice, &ir_mlx_id_01, &ir_mlx_id_23));
108  } else if (ir_mlx_status == IR_MLX_UNINIT) {
109  /* start two byte ID 0 */
113  }
114  }
115 #ifdef IR_MLX_ONE_TIME_CONFIG
116  else if ((sys_time.nb_sec > 1) && (ir_mlx_status == IR_MLX_ADDR_CHANGE)) {
117  /* erase address by writing zero to SMBus address register */
120  mlx_trans.buf[1] = 0;
121  mlx_trans.buf[2] = 0;
124  } else if ((sys_time.nb_sec > 2) && (ir_mlx_status == IR_MLX_ADDR_ERASE)) {
125  /* set address by writing it to AMBus address register */
128  mlx_trans.buf[1] = MLX90614_ADDR >> 1;
129  mlx_trans.buf[2] = 0;
132  } else if ((sys_time.nb_sec > 3) && (ir_mlx_status == IR_MLX_ADDR_SET)) {
134  }
135 #endif
136 }
137 
138 void ir_mlx_event(void)
139 {
140  if ((mlx_trans.status == I2CTransSuccess)) {
141  switch (ir_mlx_status) {
142 
143  case IR_MLX_RD_ID_0:
144  /* read two byte ID 0 */
146  ir_mlx_id_01 |= mlx_trans.buf[1] << 8;
147  /* start two byte ID 1 */
151  break;
152 
153  case IR_MLX_RD_ID_1:
154  /* read two byte ID 1 */
155  ir_mlx_id_01 |= mlx_trans.buf[0] << 16;
156  ir_mlx_id_01 |= mlx_trans.buf[1] << 24;
157  /* start two byte ID 2 */
161  break;
162 
163  case IR_MLX_RD_ID_2:
164  /* read two byte ID 2 */
166  ir_mlx_id_23 |= mlx_trans.buf[1] << 8;
167  /* start two byte ID 3 */
171  break;
172 
173  case IR_MLX_RD_ID_3:
174  /* read two byte ID 3 */
175  ir_mlx_id_23 |= mlx_trans.buf[0] << 16;
176  ir_mlx_id_23 |= mlx_trans.buf[1] << 24;
179  DOWNLINK_SEND_MLX_SERIAL(DefaultChannel, DefaultDevice, &ir_mlx_id_01, &ir_mlx_id_23);
180  break;
181 
182  case IR_MLX_RD_CASE_TEMP:
183  /* read two byte case temperature */
184  ir_mlx_itemp_case = mlx_trans.buf[1] << 8;
186  ir_mlx_temp_case = ir_mlx_itemp_case * 0.02 - 273.15;
187 
188  /* start two byte obj temperature */
192  break;
193 
194  case IR_MLX_RD_OBJ_TEMP:
195  /* read two byte obj temperature */
196  ir_mlx_itemp_obj = mlx_trans.buf[1] << 8;
198  ir_mlx_temp_obj = ir_mlx_itemp_obj * 0.02 - 273.15;
200 
201  DOWNLINK_SEND_MLX_STATUS(DefaultChannel, DefaultDevice,
205  &ir_mlx_temp_obj);
206  break;
207  default:
209  break;
210  }
211  }
212 }
ir_mlx_id_23
uint32_t ir_mlx_id_23
Definition: ir_mlx.c:52
uint16_t
unsigned short uint16_t
Definition: types.h:16
i2c_transaction::buf
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition: i2c.h:122
ir_mlx_id_01
uint32_t ir_mlx_id_01
Definition: ir_mlx.c:51
MLX90614_TA
#define MLX90614_TA
Definition: ir_mlx.h:6
IR_MLX_ADDR_ERASE
@ IR_MLX_ADDR_ERASE
Definition: ir_mlx.h:16
MLX90614_ID_0
#define MLX90614_ID_0
Definition: ir_mlx.h:9
MLX90614_ID_3
#define MLX90614_ID_3
Definition: ir_mlx.h:12
MLX90614_ID_1
#define MLX90614_ID_1
Definition: ir_mlx.h:10
MLX90614_TOBJ
#define MLX90614_TOBJ
Definition: ir_mlx.h:7
IR_MLX_ADDR_CHANGE
@ IR_MLX_ADDR_CHANGE
Definition: ir_mlx.h:15
ir_mlx_event
void ir_mlx_event(void)
Definition: ir_mlx.c:138
IR_MLX_RD_ID_1
@ IR_MLX_RD_ID_1
Definition: ir_mlx.h:20
ir_mlx_itemp_obj
uint16_t ir_mlx_itemp_obj
Definition: ir_mlx.c:49
uint32_t
unsigned long uint32_t
Definition: types.h:18
I2CTransSuccess
@ I2CTransSuccess
transaction successfully finished by I2C driver
Definition: i2c.h:57
IR_MLX_UNINIT
@ IR_MLX_UNINIT
Definition: ir_mlx.h:18
ir_mlx_itemp_case
uint16_t ir_mlx_itemp_case
Definition: ir_mlx.c:47
uart.h
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
ir_mlx_crc
void ir_mlx_crc(unsigned char addr, volatile unsigned char *data)
Definition: ir_mlx.c:63
i2c_transmit
bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
Definition: i2c.c:324
mlx_trans
struct i2c_transaction mlx_trans
Definition: ir_mlx.c:44
MLX90614_SADR
#define MLX90614_SADR
Definition: ir_mlx.h:8
IR_MLX_ADDR_SET
@ IR_MLX_ADDR_SET
Definition: ir_mlx.h:17
MLX90614_ADDR
#define MLX90614_ADDR
Definition: ir_mlx.c:56
i2c_transceive
bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
Definition: i2c.c:344
ir_mlx_temp_case
float ir_mlx_temp_case
Definition: ir_mlx.c:48
ir_mlx_periodic
void ir_mlx_periodic(void)
Definition: ir_mlx.c:94
sys_time.h
Architecture independent timing functions.
uint8_t
unsigned char uint8_t
Definition: types.h:14
ir_mlx_temp_obj
float ir_mlx_temp_obj
Definition: ir_mlx.c:50
i2c_transaction::status
enum I2CTransactionStatus status
Transaction status.
Definition: i2c.h:126
led.h
arch independent LED (Light Emitting Diodes) API
ir_mlx_init
void ir_mlx_init(void)
Definition: ir_mlx.c:83
i2c_transaction
I2C transaction structure.
Definition: i2c.h:93
MLX90614_GENERAL_ADDR
#define MLX90614_GENERAL_ADDR
Definition: ir_mlx.c:59
MLX90614_ID_2
#define MLX90614_ID_2
Definition: ir_mlx.h:11
IR_MLX_RD_ID_2
@ IR_MLX_RD_ID_2
Definition: ir_mlx.h:21
ir_mlx_status
uint8_t ir_mlx_status
Definition: ir_mlx.c:46
IR_MLX_RD_CASE_TEMP
@ IR_MLX_RD_CASE_TEMP
Definition: ir_mlx.h:24
sys_time
Definition: sys_time.h:71
IR_MLX_RD_OBJ_TEMP
@ IR_MLX_RD_OBJ_TEMP
Definition: ir_mlx.h:25
I2CTransDone
@ I2CTransDone
transaction set to done by user level
Definition: i2c.h:59
IR_MLX_RD_ID_0
@ IR_MLX_RD_ID_0
Definition: ir_mlx.h:19
ir_mlx.h
sys_time::nb_sec
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:72
IR_MLX_IDLE
@ IR_MLX_IDLE
Definition: ir_mlx.h:23
i2c.h
IR_MLX_RD_ID_3
@ IR_MLX_RD_ID_3
Definition: ir_mlx.h:22
MLX_I2C_DEV
#define MLX_I2C_DEV
Definition: ir_mlx.c:41