LibDriver MLX90614  1.0.0
MLX90614 full-featured driver
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
driver_mlx90614.c
Go to the documentation of this file.
1 
37 #include "driver_mlx90614.h"
38 #include <math.h>
39 
43 #define CHIP_NAME "Melexis MLX90614"
44 #define MANUFACTURER_NAME "Melexis"
45 #define SUPPLY_VOLTAGE_MIN 4.5f
46 #define SUPPLY_VOLTAGE_MAX 5.5f
47 #define MAX_CURRENT 2.5f
48 #define TEMPERATURE_MIN -40.0f
49 #define TEMPERATURE_MAX 125.0f
50 #define DRIVER_VERSION 1000
55 #define COMMAND_READ_FLAGS 0xF0
56 #define COMMAND_ENTER_SLEEP 0xFF
61 #define MLX90614_REG_RAM_RAW_DATA_IR_CHANNEL_1 0x04
62 #define MLX90614_REG_RAM_RAW_DATA_IR_CHANNEL_2 0x05
63 #define MLX90614_REG_RAM_TA 0x06
64 #define MLX90614_REG_RAM_TOBJ1 0x07
65 #define MLX90614_REG_RAM_TOBJ2 0x08
66 #define MLX90614_REG_EEPROM_TO_MAX 0x20
67 #define MLX90614_REG_EEPROM_TO_MIN 0x21
68 #define MLX90614_REG_EEPROM_PWM_CTRL 0x22
69 #define MLX90614_REG_EEPROM_TA_RANGE 0x23
70 #define MLX90614_REG_EEPROM_EMISSIVITY 0x24
71 #define MLX90614_REG_EEPROM_CONFIG1 0x25
72 #define MLX90614_REG_EEPROM_ADDRESS 0x2E
73 #define MLX90614_REG_EEPROM_ID1_NUMBER 0x3C
74 #define MLX90614_REG_EEPROM_ID2_NUMBER 0x3D
75 #define MLX90614_REG_EEPROM_ID3_NUMBER 0x3E
76 #define MLX90614_REG_EEPROM_ID4_NUMBER 0x3F
85 static uint8_t a_mlx90614_calculate_crc(uint8_t *addr, uint8_t len)
86 {
87  uint8_t crc = 0;
88 
89  while (len != 0) /* check the len */
90  {
91  uint8_t i;
92  uint8_t in_byte = *addr++;
93 
94  for (i = 8; i != 0; i--) /* 8 times */
95  {
96  uint8_t carry = (crc ^ in_byte ) & 0x80; /* set carry */
97 
98  crc <<= 1; /* left shift 1 */
99  if (carry != 0) /* check carry */
100  {
101  crc ^= 0x7; /* xor 0x7 */
102  }
103  in_byte <<= 1; /* left shift 1 */
104  }
105  len--; /* len-- */
106  }
107 
108  return crc; /* return crc */
109 }
110 
111 
122 static uint8_t a_mlx90614_read(mlx90614_handle_t *handle, uint8_t command, uint16_t *data)
123 {
124  uint8_t pec;
125  uint8_t arr[5];
126  uint8_t buf[3];
127  uint8_t times = 0x03;
128 
129  while (1)
130  {
131  memset(buf, 0, sizeof(uint8_t) * 3); /* clear the buffer */
132  if (handle->iic_read(handle->iic_addr, command, (uint8_t *)buf, 3) != 0) /* read data */
133  {
134  return 1; /* return error */
135  }
136 
137  arr[0] = handle->iic_addr; /* set read addr */
138  arr[1] = command; /* set command */
139  arr[2] = handle->iic_addr + 1; /* set write addr */
140  arr[3] = buf[0]; /* set buf 0 */
141  arr[4] = buf[1]; /* set buf 1 */
142  pec = a_mlx90614_calculate_crc((uint8_t *)arr, 5); /* calculate pec */
143  if ((pec != buf[2]) && (times != 0)) /* check */
144  {
145  times--; /* times-- */
146  handle->delay_ms(5); /* delay ms */
147 
148  continue; /* continue */
149  }
150  if (times == 0) /* timeout */
151  {
152  return 1; /* return error */
153  }
154 
155  *data = (uint16_t)(((uint16_t)buf[1] << 8) | buf[0]); /* get data */
156 
157  return 0; /* success return 0 */
158  }
159 }
160 
171 static uint8_t a_mlx90614_write(mlx90614_handle_t *handle, uint8_t command, uint16_t data)
172 {
173  uint8_t data_l;
174  uint8_t data_h;
175  uint8_t arr[4];
176  uint8_t buf[3];
177  uint8_t pec;
178 
179  if ((command & 0x20) != 0) /* if eeprom */
180  {
181  data_l = 0x00; /* get lsb */
182  data_h = 0x00; /* get msb */
183  arr[0] = handle->iic_addr; /* set address */
184  arr[1] = command; /* set command */
185  arr[2] = data_l; /* set lsb */
186  arr[3] = data_h; /* set msb */
187  pec = a_mlx90614_calculate_crc((uint8_t *)arr, 4); /* calculate pec */
188  buf[0] = data_l; /* set lsb */
189  buf[1] = data_h; /* set msb */
190  buf[2] = pec; /* set pec */
191  if (handle->iic_write(handle->iic_addr, command, (uint8_t *)buf, 3) != 0) /* write command */
192  {
193  return 1; /* return error */
194  }
195  handle->delay_ms(10); /* delay 10 ms */
196  data_l = (uint8_t)(data & 0xFF); /* get lsb */
197  data_h = (uint8_t)((data & 0xFF00U) >> 8); /* get msb */
198  arr[0] = handle->iic_addr; /* set address */
199  arr[1] = command; /* set command */
200  arr[2] = data_l; /* set lsb */
201  arr[3] = data_h; /* set msb */
202  pec = a_mlx90614_calculate_crc((uint8_t *)arr, 4); /* calculate pec */
203  buf[0] = data_l; /* set lsb */
204  buf[1] = data_h; /* set msb */
205  buf[2] = pec; /* set pec */
206  if (handle->iic_write(handle->iic_addr, command, (uint8_t *)buf, 3) != 0) /* write data */
207  {
208  return 1; /* return error */
209  }
210  handle->delay_ms(10); /* delay 10 ms */
211 
212  return 0; /* success return 0 */
213  }
214  else /* ram */
215  {
216  data_l = (uint8_t)(data & 0xFF); /* get lsb */
217  data_h = (uint8_t)((data & 0xFF00U) >> 8); /* get msb */
218  arr[0] = handle->iic_addr; /* set address */
219  arr[1] = command; /* set command */
220  arr[2] = data_l; /* set lsb */
221  arr[3] = data_h; /* set msb */
222  pec = a_mlx90614_calculate_crc((uint8_t *)arr, 4); /* calculate pec */
223  buf[0] = data_l; /* set lsb */
224  buf[1] = data_h; /* set msb */
225  buf[2] = pec; /* set pec */
226 
227  if (handle->iic_write(handle->iic_addr, command, (uint8_t *)buf, 3) != 0) /* write data */
228  {
229  return 1; /* return error */
230  }
231 
232  return 0; /* success return 0 */
233  }
234 }
235 
245 uint8_t mlx90614_set_addr(mlx90614_handle_t *handle, uint8_t addr)
246 {
247  if (handle == NULL) /* check handle */
248  {
249  return 2; /* return error */
250  }
251 
252  handle->iic_addr = addr; /* set addr */
253 
254  return 0; /* success return 0 */
255 }
256 
266 uint8_t mlx90614_get_addr(mlx90614_handle_t *handle, uint8_t *addr)
267 {
268  if (handle == NULL) /* check handle */
269  {
270  return 2; /* return error */
271  }
272 
273  *addr = handle->iic_addr; /* get addr */
274 
275  return 0; /* success return 0 */
276 }
277 
289 uint8_t mlx90614_write_addr(mlx90614_handle_t *handle, uint8_t addr)
290 {
291  uint8_t res;
292  uint16_t prev;
293 
294  if (handle == NULL) /* check handle */
295  {
296  return 2; /* return error */
297  }
298  if (handle->inited != 1) /* check handle initialization */
299  {
300  return 3; /* return error */
301  }
302 
303  handle->iic_addr = 0x00; /* set 0x00 */
304  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_ADDRESS, (uint16_t *)&prev); /* read eeprom address */
305  if (res != 0) /* check result */
306  {
307  handle->debug_print("mlx90614: read eeprom address failed.\n"); /* read eeprom address failed */
308 
309  return 1; /* return error */
310  }
311  prev |= addr; /* set address */
312  res = a_mlx90614_write(handle, MLX90614_REG_EEPROM_ADDRESS, prev); /* write eeprom address */
313  if (res != 0) /* check result */
314  {
315  handle->debug_print("mlx90614: write eeprom address failed.\n"); /* write eeprom address failed */
316 
317  return 1; /* return error */
318  }
319  handle->iic_addr = addr; /* set address */
320 
321  return 0; /* success return 0 */
322 }
323 
335 uint8_t mlx90614_read_addr(mlx90614_handle_t *handle, uint8_t *addr)
336 {
337  uint8_t res;
338  uint16_t prev;
339 
340  if (handle == NULL) /* check handle */
341  {
342  return 2; /* return error */
343  }
344  if (handle->inited != 1) /* check handle initialization */
345  {
346  return 3; /* return error */
347  }
348 
349  handle->iic_addr = 0x00; /* set 0x00 */
350  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_ADDRESS, (uint16_t *)&prev); /* read eeprom address */
351  if (res != 0) /* check result */
352  {
353  handle->debug_print("mlx90614: read eeprom address failed.\n"); /* read eeprom address failed */
354 
355  return 1; /* return error */
356  }
357  handle->iic_addr = (uint8_t)((prev >> 0) & 0x0F); /* set iic address */
358  *addr = handle->iic_addr; /* get addr */
359 
360  return 0; /* success return 0 */
361 }
362 
375 {
376  uint8_t res;
377  uint16_t prev;
378 
379  if (handle == NULL) /* check handle */
380  {
381  return 2; /* return error */
382  }
383  if (handle->inited != 1) /* check handle initialization */
384  {
385  return 3; /* return error */
386  }
387 
388  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
389  if (res != 0) /* check result */
390  {
391  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
392 
393  return 1; /* return error */
394  }
395  prev &= ~(0x07 << 8); /* clear config */
396  prev |= len << 8; /* set length */
397 
398  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t )prev); /* write config */
399 }
400 
413 {
414  uint8_t res;
415  uint16_t prev;
416 
417  if (handle == NULL) /* check handle */
418  {
419  return 2; /* return error */
420  }
421  if (handle->inited != 1) /* check handle initialization */
422  {
423  return 3; /* return error */
424  }
425 
426  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
427  if (res != 0) /* check result */
428  {
429  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
430 
431  return 1; /* return error */
432  }
433  prev &= (0x07 << 8); /* get config */
434  *len = (mlx90614_fir_length_t)(0x07 & (prev >> 8)); /* get length */
435 
436  return 0; /* success return 0 */
437 }
438 
451 {
452  uint8_t res;
453  uint16_t prev;
454 
455  if (handle == NULL) /* check handle */
456  {
457  return 2; /* return error */
458  }
459  if (handle->inited != 1) /* check handle initialization */
460  {
461  return 3; /* return error */
462  }
463 
464  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
465  if (res != 0) /* check result */
466  {
467  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
468 
469  return 1; /* return error */
470  }
471  prev &= ~0x07; /* clear config */
472  prev |= iir; /* set param */
473 
474  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t )prev); /* write config */
475 }
476 
489 {
490  uint8_t res;
491  uint16_t prev;
492 
493  if (handle == NULL) /* check handle */
494  {
495  return 2; /* return error */
496  }
497  if (handle->inited != 1) /* check handle initialization */
498  {
499  return 3; /* return error */
500  }
501 
502  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
503  if (res != 0) /* check result */
504  {
505  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
506 
507  return 1; /* return error */
508  }
509  prev &= 0x07; /* get config */
510  *iir = (mlx90614_iir_t)(0x07 & prev); /* get param */
511 
512  return 0; /* success return 0 */
513 }
514 
527 {
528  uint8_t res;
529  uint16_t prev;
530 
531  if (handle == NULL) /* check handle */
532  {
533  return 2; /* return error */
534  }
535  if (handle->inited != 1) /* check handle initialization */
536  {
537  return 3; /* return error */
538  }
539 
540  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
541  if (res != 0) /* check result */
542  {
543  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
544 
545  return 1; /* return error */
546  }
547  prev &= ~(0x03 << 4); /* clear config */
548  prev |= mode << 4; /* set param */
549 
550  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t )prev); /* write config */
551 }
552 
565 {
566  uint8_t res;
567  uint16_t prev;
568 
569  if (handle == NULL) /* check handle */
570  {
571  return 2; /* return error */
572  }
573  if (handle->inited != 1) /* check handle initialization */
574  {
575  return 3; /* return error */
576  }
577 
578  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
579  if (res != 0) /* check result */
580  {
581  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
582 
583  return 1; /* return error */
584  }
585  prev &= (0x03 << 4); /* clear config */
586  *mode = (mlx90614_mode_t)(0x03 & (prev >> 4)); /* get mode */
587 
588  return 0; /* success return 0 */
589 }
590 
603 {
604  uint8_t res;
605  uint16_t prev;
606 
607  if (handle == NULL) /* check handle */
608  {
609  return 2; /* return error */
610  }
611  if (handle->inited != 1) /* check handle initialization */
612  {
613  return 3; /* return error */
614  }
615 
616  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
617  if (res != 0) /* check result */
618  {
619  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
620 
621  return 1; /* return error */
622  }
623  prev &= ~(0x01 << 6); /* clear config */
624  prev |= sensor << 6; /* set param */
625 
626  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t )prev); /* write config */
627 }
628 
641 {
642  uint8_t res;
643  uint16_t prev;
644 
645  if (handle == NULL) /* check handle */
646  {
647  return 2; /* return error */
648  }
649  if (handle->inited != 1) /* check handle initialization */
650  {
651  return 3; /* return error */
652  }
653 
654  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
655  if (res != 0) /* check result */
656  {
657  handle->debug_print("mlx90614: read config failed.\n"); /* return error */
658 
659  return 1;
660  }
661  prev &= (0x01 << 6); /* get config */
662  *sensor = (mlx90614_ir_sensor_t)(0x01 & (prev >> 6)); /* ge sensor */
663 
664  return 0; /* success return 0 */
665 }
666 
679 {
680  uint8_t res;
681  uint16_t prev;
682 
683  if (handle == NULL) /* check handle */
684  {
685  return 2; /* return error */
686  }
687  if (handle->inited != 1) /* check handle initialization */
688  {
689  return 3; /* return error */
690  }
691 
692  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
693  if (res != 0) /* check result */
694  {
695  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
696 
697  return 1; /* return error */
698  }
699  prev &= ~(0x01 << 7); /* clear config */
700  prev |= ks << 7; /* set param */
701 
702  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t )prev); /* write config */
703 }
704 
717 {
718  uint8_t res;
719  uint16_t prev;
720 
721  if (handle == NULL) /* check handle */
722  {
723  return 2; /* return error */
724  }
725  if (handle->inited != 1) /* check handle initialization */
726  {
727  return 3; /* return error */
728  }
729 
730  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
731  if (res != 0) /* check result */
732  {
733  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
734 
735  return 1; /* return error */
736  }
737  prev &= (0x01 << 7); /* get config */
738  *ks = (mlx90614_ks_t)(0x01 & (prev >> 7)); /* get ks */
739 
740  return 0; /* success return 0 */
741 }
742 
755 {
756  uint8_t res;
757  uint16_t prev;
758 
759  if (handle == NULL) /* check handle */
760  {
761  return 2; /* return error */
762  }
763  if (handle->inited != 1) /* check handle initialization */
764  {
765  return 3; /* return error */
766  }
767 
768  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
769  if (res != 0) /* check result */
770  {
771  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed. */
772 
773  return 1; /* return error */
774  }
775  prev &= ~(0x01 << 14); /* clear config */
776  prev |= kt2 << 14; /* set param */
777 
778  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t )prev); /* write config */
779 }
780 
793 {
794  uint8_t res;
795  uint16_t prev;
796 
797  if (handle == NULL) /* check handle */
798  {
799  return 2; /* return error */
800  }
801  if (handle->inited != 1) /* check handle initialization */
802  {
803  return 3; /* return error */
804  }
805 
806  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
807  if (res != 0) /* check result */
808  {
809  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
810 
811  return 1; /* return error */
812  }
813  prev &= (0x01 << 14); /* get config */
814  *kt2 = (mlx90614_kt2_t)(0x01 & (prev >> 14)); /* get kt2 */
815 
816  return 0; /* success return 0 */
817 }
818 
831 {
832  uint8_t res;
833  uint16_t prev;
834 
835  if (handle == NULL) /* check handle */
836  {
837  return 2; /* return error */
838  }
839  if (handle->inited != 1) /* check handle initialization */
840  {
841  return 3; /* return error */
842  }
843 
844  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
845  if (res != 0) /* check result */
846  {
847  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
848 
849  return 1; /* return error */
850  }
851  prev &= ~(0x07 << 11); /* clear config */
852  prev |= gain << 11; /* set param */
853 
854  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t )prev); /* write config */
855 }
856 
869 {
870  uint8_t res;
871  uint16_t prev;
872 
873  if (handle == NULL) /* check handle */
874  {
875  return 2; /* return error */
876  }
877  if (handle->inited != 1) /* check handle initialization */
878  {
879  return 3; /* return error */
880  }
881 
882  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
883  if (res != 0) /* check result */
884  {
885  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
886 
887  return 1; /* return error */
888  }
889  prev &= 0x07 << 11; /* get config */
890  *gain = (mlx90614_gain_t)(0x07 & (prev >> 11)); /* get param */
891 
892  return 0; /* success return 0 */
893 }
894 
907 {
908  uint8_t res;
909  uint16_t prev;
910 
911  if (handle == NULL) /* check handle */
912  {
913  return 2; /* return error */
914  }
915  if (handle->inited != 1) /* check handle initialization */
916  {
917  return 3; /* return error */
918  }
919 
920  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
921  if (res != 0) /* check result */
922  {
923  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
924 
925  return 1; /* return error */
926  }
927  prev &= ~(0x01 << 15); /* clear config */
928  prev |= enable << 15; /* set param */
929 
930  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t )prev); /* write config */
931 }
932 
945 {
946  uint8_t res;
947  uint16_t prev;
948 
949  if (handle == NULL) /* check handle */
950  {
951  return 2; /* return error */
952  }
953  if (handle->inited != 1) /* check handle initialization */
954  {
955  return 3; /* return error */
956  }
957 
958  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
959  if (res != 0) /* check result */
960  {
961  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
962 
963  return 1; /* return error */
964  }
965  prev &= 0x01 << 15; /* get config */
966  *enable = (mlx90614_bool_t)(0x01 & (prev >> 15)); /* set param */
967 
968  return 0; /* success return 0 */
969 }
970 
983 {
984  uint8_t res;
985  uint16_t prev;
986 
987  if (handle == NULL) /* check handle */
988  {
989  return 2; /* return error */
990  }
991  if (handle->inited != 1) /* check handle initialization */
992  {
993  return 3; /* return error */
994  }
995 
996  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
997  if (res != 0) /* check result */
998  {
999  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
1000 
1001  return 1; /* return error */
1002  }
1003  prev &= ~(0x01 << 3); /* clear config */
1004  prev |= enable << 3; /* set param */
1005 
1006  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t )prev); /* write config */
1007 }
1008 
1021 {
1022  uint8_t res;
1023  uint16_t prev;
1024 
1025  if (handle == NULL) /* check handle */
1026  {
1027  return 2; /* return error */
1028  }
1029  if (handle->inited != 1) /* check handle initialization */
1030  {
1031  return 3; /* return error */
1032  }
1033 
1034  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_CONFIG1, (uint16_t *)&prev); /* read config */
1035  if (res != 0) /* check result */
1036  {
1037  handle->debug_print("mlx90614: read config failed.\n"); /* read config failed */
1038 
1039  return 1; /* return error */
1040  }
1041  prev &= 0x01 << 3; /* get config */
1042  *enable = (mlx90614_bool_t)(0x01 & (prev >> 3)); /* set param */
1043 
1044  return 0; /* success return 0 */
1045 }
1046 
1059 {
1060  if (handle == NULL) /* check handle */
1061  {
1062  return 2; /* return error */
1063  }
1064  if (handle->inited != 1) /* check handle initialization */
1065  {
1066  return 3; /* return error */
1067  }
1068 
1069  return a_mlx90614_write(handle, MLX90614_REG_EEPROM_EMISSIVITY, value); /* write config */
1070 }
1071 
1084 {
1085  if (handle == NULL) /* check handle */
1086  {
1087  return 2; /* return error */
1088  }
1089  if (handle->inited != 1) /* check handle initialization */
1090  {
1091  return 3; /* return error */
1092  }
1093 
1094  return a_mlx90614_read(handle, MLX90614_REG_EEPROM_EMISSIVITY, value); /* write config */
1095 }
1096 
1111 {
1112  if (handle == NULL) /* check handle */
1113  {
1114  return 2; /* return error */
1115  }
1116  if (handle->inited != 1) /* check handle initialization */
1117  {
1118  return 3; /* return error */
1119  }
1120  if (s > 1.0) /* check s */
1121  {
1122  handle->debug_print("mlx90614: s is over 1.0.\n"); /* return error */
1123 
1124  return 4; /* return error */
1125  }
1126 
1127  *reg = (uint16_t)(round((double)65535 * s)); /* set reg */
1128 
1129  return 0; /* success return 0 */
1130 }
1131 
1145 {
1146  if (handle == NULL) /* check handle */
1147  {
1148  return 2; /* return error */
1149  }
1150  if (handle->inited != 1) /* check handle initialization */
1151  {
1152  return 3; /* return error */
1153  }
1154 
1155  *s = (double) reg / 65535; /* convert reg */
1156 
1157  return 0; /* success return 0 */
1158 }
1159 
1172 uint8_t mlx90614_read_raw_ir_channel(mlx90614_handle_t *handle, uint16_t *channel_1, uint16_t *channel_2)
1173 {
1174  uint8_t res;
1175 
1176  if (handle == NULL) /* check handle */
1177  {
1178  return 2; /* return error */
1179  }
1180  if (handle->inited != 1) /* check handle initialization */
1181  {
1182  return 3; /* return error */
1183  }
1184 
1185  res = a_mlx90614_read(handle, MLX90614_REG_RAM_RAW_DATA_IR_CHANNEL_1, (uint16_t *)channel_1); /* read data */
1186  if (res != 0) /* check result */
1187  {
1188  handle->debug_print("mlx90614: read raw channel 1 failed.\n"); /* read raw channel 1 failed */
1189 
1190  return 1; /* return error */
1191  }
1192  res = a_mlx90614_read(handle, MLX90614_REG_RAM_RAW_DATA_IR_CHANNEL_2, (uint16_t *)channel_2); /* read data */
1193  if (res != 0) /* check result */
1194  {
1195  handle->debug_print("mlx90614: read raw channel 2 failed.\n"); /* read raw channel 2 failed */
1196 
1197  return 1; /* return error */
1198  }
1199 
1200  return 0; /* success return 0 */
1201 }
1202 
1215 uint8_t mlx90614_read_ambient(mlx90614_handle_t *handle, uint16_t *raw, float *celsius)
1216 {
1217  uint8_t res;
1218 
1219  if (handle == NULL) /* check handle */
1220  {
1221  return 2; /* return error */
1222  }
1223  if (handle->inited != 1) /* check handle initialization */
1224  {
1225  return 3; /* return error */
1226  }
1227 
1228  res = a_mlx90614_read(handle, MLX90614_REG_RAM_TA, (uint16_t *)raw); /* read data */
1229  if (res != 0) /* check result */
1230  {
1231  handle->debug_print("mlx90614: read raw ta failed.\n"); /* read raw ta failed */
1232 
1233  return 1; /* return error */
1234  }
1235  *celsius = (float)(*raw) * 0.02f - 273.15f; /* get celsius */
1236 
1237  return 0; /* success return 0 */
1238 }
1239 
1253 uint8_t mlx90614_read_object1(mlx90614_handle_t *handle, uint16_t *raw, float *celsius)
1254 {
1255  uint8_t res;
1256 
1257  if (handle == NULL) /* check handle */
1258  {
1259  return 2; /* return error */
1260  }
1261  if (handle->inited != 1) /* check handle initialization */
1262  {
1263  return 3; /* return error */
1264  }
1265 
1266  res = a_mlx90614_read(handle, MLX90614_REG_RAM_TOBJ1, (uint16_t *)raw); /* read data */
1267  if (res != 0) /* check result */
1268  {
1269  handle->debug_print("mlx90614: read ram tobj1 failed.\n"); /* read ram tobj1 failed. */
1270 
1271  return 1; /* return error */
1272  }
1273  if (((*raw) & 0x8000U) != 0) /* check result */
1274  {
1275  handle->debug_print("mlx90614: flag error.\n"); /* flag error */
1276 
1277  return 4; /* return error */
1278  }
1279  *celsius = (float)(*raw) * 0.02f - 273.15f; /* get celsius */
1280 
1281  return 0; /* success return 0 */
1282 }
1283 
1297 uint8_t mlx90614_read_object2(mlx90614_handle_t *handle, uint16_t *raw, float *celsius)
1298 {
1299  uint8_t res;
1300 
1301  if (handle == NULL) /* check handle */
1302  {
1303  return 2; /* return error */
1304  }
1305  if (handle->inited != 1) /* check handle initialization */
1306  {
1307  return 3; /* return error */
1308  }
1309 
1310  res = a_mlx90614_read(handle, MLX90614_REG_RAM_TOBJ2, (uint16_t *)raw); /* read data */
1311  if (res != 0) /* check result */
1312  {
1313  handle->debug_print("mlx90614: read ram tobj2 failed.\n"); /* read ram tobj2 failed. */
1314 
1315  return 1; /* return error */
1316  }
1317  if (((*raw) & 0x8000U) != 0) /* check result */
1318  {
1319  handle->debug_print("mlx90614: flag error.\n"); /* flag error */
1320 
1321  return 4; /* return error */
1322  }
1323  *celsius = (float)(*raw) * 0.02f - 273.15f; /* get celsius */
1324 
1325  return 0; /* success return 0 */
1326 }
1327 
1339 uint8_t mlx90614_get_id(mlx90614_handle_t *handle, uint16_t id[4])
1340 {
1341  uint8_t res;
1342 
1343  if (handle == NULL) /* check handle */
1344  {
1345  return 2; /* return error */
1346  }
1347  if (handle->inited != 1) /* check handle initialization */
1348  {
1349  return 3; /* return error */
1350  }
1351 
1352  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_ID1_NUMBER, (uint16_t *)&id[0]); /* read data */
1353  if (res != 0) /* check result */
1354  {
1355  handle->debug_print("mlx90614: read id1 failed.\n"); /* read id1 failed */
1356 
1357  return 1; /* return error */
1358  }
1359  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_ID2_NUMBER, (uint16_t *)&id[1]); /* read data */
1360  if (res != 0) /* check result */
1361  {
1362  handle->debug_print("mlx90614: read id2 failed.\n"); /* read id2 failed */
1363 
1364  return 1; /* return error */
1365  }
1366  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_ID3_NUMBER, (uint16_t *)&id[2]); /* read data */
1367  if (res != 0) /* check result */
1368  {
1369  handle->debug_print("mlx90614: read id3 failed.\n"); /* read id3 failed */
1370 
1371  return 1; /* return error */
1372  }
1373  res = a_mlx90614_read(handle, MLX90614_REG_EEPROM_ID4_NUMBER, (uint16_t *)&id[3]); /* read data */
1374  if (res != 0) /* check result */
1375  {
1376  handle->debug_print("mlx90614: read id4 failed.\n"); /* read id4 failed */
1377 
1378  return 1; /* return error */
1379  }
1380 
1381  return 0; /* success return 0 */
1382 }
1383 
1395 uint8_t mlx90614_get_flag(mlx90614_handle_t *handle, uint16_t *flag)
1396 {
1397  if (handle == NULL) /* check handle */
1398  {
1399  return 2; /* return error */
1400  }
1401  if (handle->inited != 1) /* check handle initialization */
1402  {
1403  return 3; /* return error */
1404  }
1405 
1406  if (handle->iic_read(handle->iic_addr, COMMAND_READ_FLAGS, (uint8_t *)flag, 1) != 0) /* read config */
1407  {
1408  return 1; /* return error */
1409  }
1410  else
1411  {
1412  return 0; /* success return 0 */
1413  }
1414 }
1415 
1427 {
1428  uint8_t crc;
1429  uint8_t buf[2];
1430 
1431  if (handle == NULL) /* check handle */
1432  {
1433  return 2; /* return error */
1434  }
1435  if (handle->inited != 1) /* check handle initialization */
1436  {
1437  return 3; /* return error */
1438  }
1439 
1440  buf[0] = handle->iic_addr; /* set iic address */
1441  buf[1] = COMMAND_ENTER_SLEEP; /* set command */
1442  crc = a_mlx90614_calculate_crc((uint8_t *)buf, 2); /* set crc */
1443 
1444  if (handle->iic_write(handle->iic_addr, COMMAND_ENTER_SLEEP, (uint8_t *)&crc, 1) != 0) /* write config */
1445  {
1446  return 1; /* return error */
1447  }
1448  else
1449  {
1450  return 0; /* success return 0 */
1451  }
1452 }
1453 
1465 {
1466  uint8_t res;
1467 
1468  if (handle == NULL) /* check handle */
1469  {
1470  return 2; /* return error */
1471  }
1472  if (handle->inited != 1) /* check handle initialization */
1473  {
1474  return 3; /* return error */
1475  }
1476 
1477  res = handle->scl_write(0); /* set scl low */
1478  if (res != 0) /* check result */
1479  {
1480  handle->debug_print("mlx90614: write scl failed.\n"); /* write scl failed */
1481 
1482  return 1; /* return error */
1483  }
1484  handle->delay_ms(5); /* delay 5 ms */
1485  res = handle->scl_write(1); /* set scl high */
1486  if (res != 0) /* check result */
1487  {
1488  handle->debug_print("mlx90614: write scl failed.\n"); /* write scl failed */
1489 
1490  return 1; /* return error */
1491  }
1492 
1493  return 0; /* success return 0 */
1494 }
1495 
1507 {
1508  uint8_t res;
1509 
1510  if (handle == NULL) /* check handle */
1511  {
1512  return 2; /* return error */
1513  }
1514  if (handle->inited != 1) /* check handle initialization */
1515  {
1516  return 3; /* return error */
1517  }
1518 
1519  res = handle->scl_write(1); /* write scl 1 */
1520  if (res != 0) /* check result */
1521  {
1522  handle->debug_print("mlx90614: write scl failed.\n"); /* write scl failed */
1523 
1524  return 1; /* return error */
1525  }
1526  res = handle->sda_write(1); /* write sda 1 */
1527  if (res != 0) /* check result */
1528  {
1529  handle->debug_print("mlx90614: write sda failed.\n"); /* write sda failed */
1530 
1531  return 1; /* return error */
1532  }
1533  handle->delay_ms(1); /* delay 1 ms */
1534  res = handle->sda_write(0); /* write sda 0 */
1535  if (res != 0) /* check result */
1536  {
1537  handle->debug_print("mlx90614: write sda failed.\n"); /* write sda failed */
1538 
1539  return 1; /* return error */
1540  }
1541  handle->delay_ms(50); /* delay 50 ms */
1542  res = handle->sda_write(1); /* write sda 1 */
1543  if (res != 0) /* return error */
1544  {
1545  handle->debug_print("mlx90614: write sda failed.\n"); /* write sda failed */
1546 
1547  return 1; /* return error */
1548  }
1549  handle->delay_ms(260); /* delay 260 ms */
1550 
1551  return 0; /* success return 0 */
1552 }
1553 
1565 {
1566  if (handle == NULL) /* check handle */
1567  {
1568  return 2; /* return error */
1569  }
1570  if (handle->debug_print == NULL) /* check debug_print */
1571  {
1572  return 3; /* return error */
1573  }
1574  if (handle->iic_init == NULL) /* check iic_init */
1575  {
1576  handle->debug_print("mlx90614: iic_init is null.\n"); /* iic_init is null */
1577 
1578  return 3; /* return error */
1579  }
1580  if (handle->iic_deinit == NULL) /* check iic_deinit */
1581  {
1582  handle->debug_print("mlx90614: iic_deinit is null.\n"); /* iic_deinit is null */
1583 
1584  return 3; /* return error */
1585  }
1586  if (handle->iic_read == NULL) /* check iic_read */
1587  {
1588  handle->debug_print("mlx90614: iic_read is null.\n"); /* iic_read is null */
1589 
1590  return 3; /* return error */
1591  }
1592  if (handle->iic_write == NULL) /* check iic_write */
1593  {
1594  handle->debug_print("mlx90614: iic_write is null.\n"); /* iic_write is null */
1595 
1596  return 3; /* return error */
1597  }
1598  if (handle->scl_write == NULL) /* check scl_write */
1599  {
1600  handle->debug_print("mlx90614: scl_write is null.\n"); /* scl_write is null */
1601 
1602  return 3; /* return error */
1603  }
1604  if (handle->sda_write == NULL) /* check sda_write */
1605  {
1606  handle->debug_print("mlx90614: sda_write is null.\n"); /* sda_write is null */
1607 
1608  return 3; /* return error */
1609  }
1610  if (handle->delay_ms == NULL) /* check delay_ms */
1611  {
1612  handle->debug_print("mlx90614: delay_ms is null.\n"); /* delay_ms is null */
1613 
1614  return 3; /* return error */
1615  }
1616 
1617  if (handle->iic_init() != 0) /* iic init */
1618  {
1619  handle->debug_print("mlx90614: iic init failed.\n"); /* iic init failed */
1620 
1621  return 1; /* return error */
1622  }
1623  handle->inited = 1; /* flag finish initialization */
1624 
1625  return 0; /* success return 0 */
1626 }
1627 
1639 {
1640  uint8_t res;
1641 
1642  if (handle == NULL) /* check handle */
1643  {
1644  return 2; /* return error */
1645  }
1646  if (handle->inited != 1) /* check handle initialization */
1647  {
1648  return 3; /* return error */
1649  }
1650 
1651  res = handle->iic_deinit(); /* iic deinit */
1652  if (res != 0) /* check result */
1653  {
1654  handle->debug_print("mlx90614: iic deinit failed.\n"); /* iic deinit failed */
1655 
1656  return 1; /* return error */
1657  }
1658  handle->inited = 0; /* flag close */
1659 
1660  return 0; /* success return 0 */
1661 }
1662 
1675 uint8_t mlx90614_set_reg(mlx90614_handle_t *handle, uint8_t reg, uint16_t data)
1676 {
1677  if (handle == NULL) /* check handle */
1678  {
1679  return 2; /* return error */
1680  }
1681  if (handle->inited != 1) /* check handle initialization */
1682  {
1683  return 3; /* return error */
1684  }
1685 
1686  return a_mlx90614_write(handle, reg, data); /* write data */
1687 }
1688 
1701 uint8_t mlx90614_get_reg(mlx90614_handle_t *handle, uint8_t reg, uint16_t *data)
1702 {
1703  if (handle == NULL) /* check handle */
1704  {
1705  return 2; /* return error */
1706  }
1707  if (handle->inited != 1) /* check handle initialization */
1708  {
1709  return 3; /* return error */
1710  }
1711 
1712  return a_mlx90614_read(handle, reg, data); /* write data */
1713 }
1714 
1724 {
1725  if (info == NULL) /* check handle */
1726  {
1727  return 2; /* return error */
1728  }
1729 
1730  memset(info, 0, sizeof(mlx90614_info_t)); /* initialize mlx90614 info structure */
1731  strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
1732  strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
1733  strncpy(info->interface, "IIC", 8); /* copy interface name */
1734  info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
1735  info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
1736  info->max_current_ma = MAX_CURRENT; /* set maximum current */
1737  info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
1738  info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
1739  info->driver_version = DRIVER_VERSION; /* set driver version */
1740 
1741  return 0; /* success return 0 */
1742 }
#define MLX90614_REG_EEPROM_ID1_NUMBER
#define MLX90614_REG_EEPROM_EMISSIVITY
#define MAX_CURRENT
#define MLX90614_REG_RAM_TA
#define COMMAND_ENTER_SLEEP
#define MLX90614_REG_EEPROM_ID4_NUMBER
#define MLX90614_REG_EEPROM_ADDRESS
#define MLX90614_REG_EEPROM_ID3_NUMBER
#define SUPPLY_VOLTAGE_MAX
#define MLX90614_REG_RAM_TOBJ1
#define MLX90614_REG_EEPROM_ID2_NUMBER
#define TEMPERATURE_MAX
#define MLX90614_REG_RAM_RAW_DATA_IR_CHANNEL_2
#define MANUFACTURER_NAME
#define TEMPERATURE_MIN
#define SUPPLY_VOLTAGE_MIN
#define MLX90614_REG_RAM_TOBJ2
#define MLX90614_REG_RAM_RAW_DATA_IR_CHANNEL_1
chip register definition
#define MLX90614_REG_EEPROM_CONFIG1
#define CHIP_NAME
chip information definition
#define COMMAND_READ_FLAGS
chip command definition
#define DRIVER_VERSION
driver mlx90614 header file
uint8_t mlx90614_set_gain(mlx90614_handle_t *handle, mlx90614_gain_t gain)
set the gain param
mlx90614_gain_t
mlx90614 gain enumeration definition
mlx90614_ir_sensor_t
mlx90614 ir sensor enumeration definition
mlx90614_ks_t
mlx90614 ks enumeration definition
uint8_t mlx90614_emissivity_correction_coefficient_convert_to_data(mlx90614_handle_t *handle, uint16_t reg, double *s)
emissivity correction coefficient convert to data
uint8_t mlx90614_set_fir_length(mlx90614_handle_t *handle, mlx90614_fir_length_t len)
set the ir sensor fir length
uint8_t mlx90614_get_emissivity_correction_coefficient(mlx90614_handle_t *handle, uint16_t *value)
get the emissivity correction coefficient
uint8_t mlx90614_set_repeat_sensor_test(mlx90614_handle_t *handle, mlx90614_bool_t enable)
enable or disable the repeat sensor test
uint8_t mlx90614_get_id(mlx90614_handle_t *handle, uint16_t id[4])
get the chip id
uint8_t mlx90614_get_mode(mlx90614_handle_t *handle, mlx90614_mode_t *mode)
get the mode
uint8_t mlx90614_set_mode(mlx90614_handle_t *handle, mlx90614_mode_t mode)
set the mode
uint8_t mlx90614_set_emissivity_correction_coefficient(mlx90614_handle_t *handle, uint16_t value)
set the emissivity correction coefficient
uint8_t mlx90614_get_kt2(mlx90614_handle_t *handle, mlx90614_kt2_t *kt2)
get the kt2 param
uint8_t mlx90614_get_sensor_test(mlx90614_handle_t *handle, mlx90614_bool_t *enable)
get the sensor test status
mlx90614_bool_t
mlx90614 bool enumeration definition
uint8_t mlx90614_get_flag(mlx90614_handle_t *handle, uint16_t *flag)
get the flag
uint8_t mlx90614_set_iir(mlx90614_handle_t *handle, mlx90614_iir_t iir)
set the iir param
uint8_t mlx90614_set_ir_sensor(mlx90614_handle_t *handle, mlx90614_ir_sensor_t sensor)
set the ir sensor mode
uint8_t mlx90614_get_gain(mlx90614_handle_t *handle, mlx90614_gain_t *gain)
get the gain param
uint8_t mlx90614_get_repeat_sensor_test(mlx90614_handle_t *handle, mlx90614_bool_t *enable)
get the repeat sensor test status
uint8_t mlx90614_get_iir(mlx90614_handle_t *handle, mlx90614_iir_t *iir)
get the iir param
uint8_t mlx90614_exit_sleep_mode(mlx90614_handle_t *handle)
exit from sleep mode
uint8_t mlx90614_set_ks(mlx90614_handle_t *handle, mlx90614_ks_t ks)
set the ks param
uint8_t mlx90614_get_ks(mlx90614_handle_t *handle, mlx90614_ks_t *ks)
get the ks param
mlx90614_mode_t
mlx90614 mode enumeration definition
uint8_t mlx90614_pwm_to_smbus(mlx90614_handle_t *handle)
change pwm mode to smbus mode
mlx90614_iir_t
mlx90614 iir enumeration definition
uint8_t mlx90614_get_ir_sensor(mlx90614_handle_t *handle, mlx90614_ir_sensor_t *sensor)
get the ir sensor mode
uint8_t mlx90614_set_kt2(mlx90614_handle_t *handle, mlx90614_kt2_t kt2)
set the kt2 param
uint8_t mlx90614_set_sensor_test(mlx90614_handle_t *handle, mlx90614_bool_t enable)
enable or disable the sensor test
uint8_t mlx90614_get_fir_length(mlx90614_handle_t *handle, mlx90614_fir_length_t *len)
get the ir sensor fir length
uint8_t mlx90614_enter_sleep_mode(mlx90614_handle_t *handle)
enter to sleep mode
mlx90614_kt2_t
mlx90614 kt2 enumeration definition
uint8_t mlx90614_emissivity_correction_coefficient_convert_to_register(mlx90614_handle_t *handle, double s, uint16_t *reg)
convert the emissivity correction coefficient to the register raw data
mlx90614_fir_length_t
mlx90614 fir length enumeration definition
uint8_t mlx90614_read_raw_ir_channel(mlx90614_handle_t *handle, uint16_t *channel_1, uint16_t *channel_2)
read the ir channel raw data
uint8_t mlx90614_read_object1(mlx90614_handle_t *handle, uint16_t *raw, float *celsius)
read the object1
uint8_t mlx90614_info(mlx90614_info_t *info)
get chip information
uint8_t mlx90614_get_addr(mlx90614_handle_t *handle, uint8_t *addr)
get the address
uint8_t mlx90614_init(mlx90614_handle_t *handle)
initialize the chip
uint8_t mlx90614_set_addr(mlx90614_handle_t *handle, uint8_t addr)
set the address
uint8_t mlx90614_read_ambient(mlx90614_handle_t *handle, uint16_t *raw, float *celsius)
read the ambient
uint8_t mlx90614_deinit(mlx90614_handle_t *handle)
close the chip
uint8_t mlx90614_read_object2(mlx90614_handle_t *handle, uint16_t *raw, float *celsius)
read the object2
uint8_t mlx90614_read_addr(mlx90614_handle_t *handle, uint8_t *addr)
read the address
uint8_t mlx90614_write_addr(mlx90614_handle_t *handle, uint8_t addr)
write the address
uint8_t mlx90614_get_reg(mlx90614_handle_t *handle, uint8_t reg, uint16_t *data)
get the chip register
uint8_t mlx90614_set_reg(mlx90614_handle_t *handle, uint8_t reg, uint16_t data)
set the chip register
mlx90614 handle structure definition
uint8_t(* sda_write)(uint8_t v)
void(* delay_ms)(uint32_t ms)
void(* debug_print)(const char *const fmt,...)
uint8_t(* iic_init)(void)
uint8_t(* scl_write)(uint8_t v)
uint8_t(* iic_write)(uint8_t addr, uint8_t reg, uint8_t *buf, uint16_t len)
uint8_t(* iic_read)(uint8_t addr, uint8_t reg, uint8_t *buf, uint16_t len)
uint8_t(* iic_deinit)(void)
mlx90614 information structure definition
uint32_t driver_version
char manufacturer_name[32]