LibDriver TM1638  1.0.0
TM1638 full-featured driver
driver_tm1638.c
Go to the documentation of this file.
1 
37 #include "driver_tm1638.h"
38 
42 #define CHIP_NAME "Titan Micro Electronics TM1638"
43 #define MANUFACTURER_NAME "Titan Micro Electronics"
44 #define SUPPLY_VOLTAGE_MIN 3.0f
45 #define SUPPLY_VOLTAGE_MAX 6.0f
46 #define MAX_CURRENT 200.0f
47 #define TEMPERATURE_MIN -40.0f
48 #define TEMPERATURE_MAX 125.0f
49 #define DRIVER_VERSION 1000
54 #define TM1638_COMMAND_DATA (1 << 6)
55 #define TM1638_COMMAND_DISPLAY (2 << 6)
56 #define TM1638_COMMAND_ADDRESS (3 << 6)
64 static uint8_t a_high_low_shift(uint8_t data)
65 {
66  uint8_t output;
67 
68  output = (data << 4) | (data >> 4); /* part 1 */
69  output = ((output << 2) & 0xCC) | ((output >> 2) & 0x33); /* part 2 */
70  output = ((output << 1) & 0xAA) | ((output >> 1) & 0x55); /* part 3 */
71 
72  return output; /* return output */
73 }
74 
86 static uint8_t a_tm1638_write(tm1638_handle_t *handle, uint8_t cmd, uint8_t *buf, uint16_t len)
87 {
88  uint8_t inner_buffer[32];
89  uint16_t i;
90 
91  if (len > 32) /* check len */
92  {
93  return 1; /* return error */
94  }
95  for (i = 0; i < len; i++) /* loop all */
96  {
97  inner_buffer[i] = a_high_low_shift(buf[i]); /* shift */
98  }
99  if (handle->spi_write(a_high_low_shift(cmd), inner_buffer, len) != 0) /* write data */
100  {
101  return 1; /* return error */
102  }
103 
104  return 0; /* success return 0 */
105 }
106 
118 static uint8_t a_tm1638_read(tm1638_handle_t *handle, uint8_t cmd, uint8_t *buf, uint16_t len)
119 {
120  uint16_t i;
121 
122  if (handle->spi_read(a_high_low_shift(cmd), buf, len) != 0) /* read data */
123  {
124  return 1; /* return error */
125  }
126  for (i = 0; i < len; i++) /* loop all */
127  {
128  buf[i] = a_high_low_shift(buf[i]); /* shift */
129  }
130 
131  return 0; /* success return 0 */
132 }
133 
144 uint8_t tm1638_init(tm1638_handle_t *handle)
145 {
146  if (handle == NULL) /* check handle */
147  {
148  return 2; /* return error */
149  }
150  if (handle->debug_print == NULL) /* check debug_print */
151  {
152  return 3; /* return error */
153  }
154  if (handle->spi_init == NULL) /* check spi_init */
155  {
156  handle->debug_print("tm1638: spi_init is null.\n"); /* spi_init is null */
157 
158  return 3; /* return error */
159  }
160  if (handle->spi_deinit == NULL) /* check spi_deinit */
161  {
162  handle->debug_print("tm1638: spi_deinit is null.\n"); /* spi_deinit is null */
163 
164  return 3; /* return error */
165  }
166  if (handle->spi_write == NULL) /* check spi_write */
167  {
168  handle->debug_print("tm1638: spi_write is null.\n"); /* spi_write is null */
169 
170  return 3; /* return error */
171  }
172  if (handle->spi_read == NULL) /* check spi_read */
173  {
174  handle->debug_print("tm1638: spi_read is null.\n"); /* spi_read is null */
175 
176  return 3; /* return error */
177  }
178  if (handle->delay_ms == NULL) /* check delay_ms */
179  {
180  handle->debug_print("tm1638: delay_ms is null.\n"); /* delay_ms is null */
181 
182  return 3; /* return error */
183  }
184 
185  if (handle->spi_init() != 0) /* spi init */
186  {
187  handle->debug_print("tm1638: spi init failed.\n"); /* spi init failed */
188 
189  return 1; /* return error */
190  }
191  handle->data_conf = 0x00; /* init 0 */
192  handle->display_conf = 0x00; /* init 0 */
193  handle->inited = 1; /* flag inited */
194 
195  return 0; /* success return 0 */
196 }
197 
210 {
211  uint8_t res;
212  uint8_t cmd;
213 
214  if (handle == NULL) /* check handle */
215  {
216  return 2; /* return error */
217  }
218  if (handle->inited != 1) /* check handle initialization */
219  {
220  return 3; /* return error */
221  }
222 
223  handle->display_conf &= ~(1 << 3); /* clear settings */
224  cmd = TM1638_COMMAND_DISPLAY | handle->display_conf; /* set the command */
225  res = a_tm1638_write(handle, cmd, NULL, 0); /* write */
226  if (res != 0) /* check error */
227  {
228  handle->debug_print("tm1638: write failed.\n"); /* write failed */
229 
230  return 4; /* return error */
231  }
232 
233  res = handle->spi_deinit(); /* close spi */
234  if (res != 0) /* check the result */
235  {
236  handle->debug_print("tm1638: spi deinit failed.\n"); /* spi deinit failed */
237 
238  return 1; /* return error */
239  }
240  handle->inited = 0; /* flag close */
241 
242  return 0; /* success return 0 */
243 }
244 
257 {
258  uint8_t res;
259  uint8_t cmd;
260 
261  if (handle == NULL) /* check handle */
262  {
263  return 2; /* return error */
264  }
265  if (handle->inited != 1) /* check handle initialization */
266  {
267  return 3; /* return error */
268  }
269 
270  handle->display_conf &= ~(7 << 0); /* clear settings */
271  handle->display_conf |= width; /* set display conf */
272  cmd = TM1638_COMMAND_DISPLAY | handle->display_conf; /* set the command */
273  res = a_tm1638_write(handle, cmd, NULL, 0); /* write */
274  if (res != 0) /* check error */
275  {
276  handle->debug_print("tm1638: write failed.\n"); /* write failed */
277 
278  return 1; /* return error */
279  }
280 
281  return 0; /* success return 0 */
282 }
283 
295 {
296  if (handle == NULL) /* check handle */
297  {
298  return 2; /* return error */
299  }
300  if (handle->inited != 1) /* check handle initialization */
301  {
302  return 3; /* return error */
303  }
304 
305  *width = (tm1638_pulse_width_t)(handle->display_conf & 0x7); /* get width */
306 
307  return 0; /* success return 0 */
308 }
309 
322 {
323  uint8_t res;
324  uint8_t cmd;
325 
326  if (handle == NULL) /* check handle */
327  {
328  return 2; /* return error */
329  }
330  if (handle->inited != 1) /* check handle initialization */
331  {
332  return 3; /* return error */
333  }
334 
335  handle->display_conf &= ~(1 << 3); /* clear settings */
336  handle->display_conf |= enable << 3; /* set display conf */
337  cmd = TM1638_COMMAND_DISPLAY | handle->display_conf; /* set the command */
338  res = a_tm1638_write(handle, cmd, NULL, 0); /* write */
339  if (res != 0) /* check error */
340  {
341  handle->debug_print("tm1638: write failed.\n"); /* write failed */
342 
343  return 1; /* return error */
344  }
345 
346  return 0; /* success return 0 */
347 }
348 
360 {
361  if (handle == NULL) /* check handle */
362  {
363  return 2; /* return error */
364  }
365  if (handle->inited != 1) /* check handle initialization */
366  {
367  return 3; /* return error */
368  }
369 
370  *enable = (tm1638_bool_t)((handle->display_conf >> 3) & 0x01); /* get bool */
371 
372  return 0; /* success return 0 */
373 }
374 
387 {
388  uint8_t res;
389  uint8_t cmd;
390 
391  if (handle == NULL) /* check handle */
392  {
393  return 2; /* return error */
394  }
395  if (handle->inited != 1) /* check handle initialization */
396  {
397  return 3; /* return error */
398  }
399 
400  handle->data_conf &= ~(1 << 2); /* clear settings */
401  handle->data_conf |= mode << 2; /* set address mode */
402  cmd = TM1638_COMMAND_DATA | handle->data_conf; /* set the command */
403  res = a_tm1638_write(handle, cmd, NULL, 0); /* write */
404  if (res != 0) /* check error */
405  {
406  handle->debug_print("tm1638: write failed.\n"); /* write failed */
407 
408  return 1; /* return error */
409  }
410 
411  return 0; /* success return 0 */
412 }
413 
425 {
426  if (handle == NULL) /* check handle */
427  {
428  return 2; /* return error */
429  }
430  if (handle->inited != 1) /* check handle initialization */
431  {
432  return 3; /* return error */
433  }
434 
435  *mode = (tm1638_address_mode_t)((handle->data_conf >> 2) & 0x01); /* get address mode */
436 
437  return 0; /* success return 0 */
438 }
439 
452 {
453  uint8_t res;
454  uint8_t cmd;
455 
456  if (handle == NULL) /* check handle */
457  {
458  return 2; /* return error */
459  }
460  if (handle->inited != 1) /* check handle initialization */
461  {
462  return 3; /* return error */
463  }
464 
465  handle->data_conf &= ~(1 << 3); /* clear settings */
466  handle->data_conf |= enable << 3; /* set test mode */
467  cmd = TM1638_COMMAND_DATA | handle->data_conf; /* set the command */
468  res = a_tm1638_write(handle, cmd, NULL, 0); /* write */
469  if (res != 0) /* check error */
470  {
471  handle->debug_print("tm1638: write failed.\n"); /* write failed */
472 
473  return 1; /* return error */
474  }
475 
476  return 0; /* success return 0 */
477 }
478 
490 {
491  if (handle == NULL) /* check handle */
492  {
493  return 2; /* return error */
494  }
495  if (handle->inited != 1) /* check handle initialization */
496  {
497  return 3; /* return error */
498  }
499 
500  *enable = (tm1638_bool_t)((handle->data_conf >> 3) & 0x01); /* get test mode */
501 
502  return 0; /* success return 0 */
503 }
504 
516 {
517  uint8_t res;
518  uint8_t i;
519  uint8_t cmd;
520  uint16_t data[8] = {0};
521 
522  if (handle == NULL) /* check handle */
523  {
524  return 2; /* return error */
525  }
526  if (handle->inited != 1) /* check handle initialization */
527  {
528  return 3; /* return error */
529  }
530 
531  cmd = TM1638_COMMAND_DATA | handle->data_conf; /* set the command */
532  res = a_tm1638_write(handle, cmd, NULL, 0); /* write */
533  if (res != 0) /* check error */
534  {
535  handle->debug_print("tm1638: write failed.\n"); /* write failed */
536 
537  return 1; /* return error */
538  }
539 
540  if ((handle->data_conf & (1 << 2)) != 0) /* fixed address mode */
541  {
542  for (i = 0; i < 8; i++) /* loop all */
543  {
544  uint8_t temp;
545 
546  cmd = TM1638_COMMAND_ADDRESS | (i * 2); /* set the command */
547  temp = (data[i] >> 0) & 0xFF; /* set lsb */
548  res = a_tm1638_write(handle, cmd, &temp, 1); /* write */
549  if (res != 0) /* check error */
550  {
551  handle->debug_print("tm1638: write failed.\n"); /* write failed */
552 
553  return 1; /* return error */
554  }
555 
556  cmd = TM1638_COMMAND_ADDRESS | (i * 2 + 1); /* set the command */
557  temp = (data[i] >> 8) & 0xFF; /* set msb */
558  res = a_tm1638_write(handle, cmd, &temp, 1); /* write */
559  if (res != 0) /* check error */
560  {
561  handle->debug_print("tm1638: write failed.\n"); /* write failed */
562 
563  return 1; /* return error */
564  }
565  }
566  }
567  else /* auto increment 1 mode */
568  {
569  uint8_t temp[16];
570 
571  for (i = 0; i < 8; i++) /* loop all */
572  {
573  temp[i * 2 + 0] = data[i] & 0xFF; /* set lsb */
574  temp[i * 2 + 1] = (data[i] >> 8) & 0xFF; /* set msb */
575  }
576  cmd = TM1638_COMMAND_ADDRESS; /* set the command */
577  res = a_tm1638_write(handle, cmd, temp, 8 * 2); /* write */
578  if (res != 0) /* check error */
579  {
580  handle->debug_print("tm1638: write failed.\n"); /* write failed */
581 
582  return 1; /* return error */
583  }
584  }
585 
586  return 0; /* success return 0 */
587 }
588 
603 uint8_t tm1638_write_segment(tm1638_handle_t *handle, uint8_t addr, uint16_t *data, uint8_t len)
604 {
605  uint8_t res;
606  uint8_t i;
607  uint8_t cmd;
608 
609  if (handle == NULL) /* check handle */
610  {
611  return 2; /* return error */
612  }
613  if (handle->inited != 1) /* check handle initialization */
614  {
615  return 3; /* return error */
616  }
617  if (addr + len > 8) /* check range */
618  {
619  handle->debug_print("tm1638: addr + len > 8.\n"); /* addr + len > 8 */
620 
621  return 4; /* return error */
622  }
623 
624  cmd = TM1638_COMMAND_DATA | handle->data_conf; /* set the command */
625  res = a_tm1638_write(handle, cmd, NULL, 0); /* write */
626  if (res != 0) /* check error */
627  {
628  handle->debug_print("tm1638: write failed.\n"); /* write failed */
629 
630  return 1; /* return error */
631  }
632 
633  if ((handle->data_conf & (1 << 2)) != 0) /* fixed address mode */
634  {
635  for (i = 0; i < len; i++) /* loop all */
636  {
637  uint8_t temp;
638 
639  cmd = TM1638_COMMAND_ADDRESS | (addr * 2 + i * 2); /* set the command */
640  temp = (data[i] >> 0) & 0xFF; /* set lsb */
641  res = a_tm1638_write(handle, cmd, &temp, 1); /* write */
642  if (res != 0) /* check error */
643  {
644  handle->debug_print("tm1638: write failed.\n"); /* write failed */
645 
646  return 1; /* return error */
647  }
648 
649  cmd = TM1638_COMMAND_ADDRESS | (addr * 2 + i * 2 + 1); /* set the command */
650  temp = (data[i] >> 8) & 0xFF; /* set msb */
651  res = a_tm1638_write(handle, cmd, &temp, 1); /* write */
652  if (res != 0) /* check error */
653  {
654  handle->debug_print("tm1638: write failed.\n"); /* write failed */
655 
656  return 1; /* return error */
657  }
658  }
659  }
660  else /* auto increment 1 mode */
661  {
662  uint8_t temp[16];
663 
664  for (i = 0; i < len; i++) /* loop all */
665  {
666  temp[i * 2 + 0] = data[i] & 0xFF; /* set lsb */
667  temp[i * 2 + 1] = (data[i] >> 8) & 0xFF; /* set msb */
668  }
669  cmd = TM1638_COMMAND_ADDRESS | addr * 2; /* set the command */
670  res = a_tm1638_write(handle, cmd, temp, len * 2); /* write */
671  if (res != 0) /* check error */
672  {
673  handle->debug_print("tm1638: write failed.\n"); /* write failed */
674 
675  return 1; /* return error */
676  }
677  }
678 
679  return 0; /* success return 0 */
680 }
681 
693 uint8_t tm1638_read_segment(tm1638_handle_t *handle, uint8_t segk[4])
694 {
695  uint8_t res;
696  uint8_t cmd;
697 
698  if (handle == NULL) /* check handle */
699  {
700  return 2; /* return error */
701  }
702  if (handle->inited != 1) /* check handle initialization */
703  {
704  return 3; /* return error */
705  }
706 
707  cmd = TM1638_COMMAND_DATA | handle->data_conf | (1 << 1); /* set the command */
708  res = a_tm1638_read(handle, cmd, segk, 4); /* read */
709  if (res != 0) /* check error */
710  {
711  handle->debug_print("tm1638: write failed.\n"); /* write failed */
712 
713  return 1; /* return error */
714  }
715 
716  return 0; /* success return 0 */
717 }
718 
732 uint8_t tm1638_set_reg(tm1638_handle_t *handle, uint8_t cmd, uint8_t *data, uint8_t len)
733 {
734  uint8_t res;
735 
736  if (handle == NULL) /* check handle */
737  {
738  return 2; /* return error */
739  }
740  if (handle->inited != 1) /* check handle initialization */
741  {
742  return 3; /* return error */
743  }
744 
745  res = a_tm1638_write(handle, cmd, data, len); /* write */
746  if (res != 0) /* check error */
747  {
748  handle->debug_print("tm1638: write failed.\n"); /* write failed */
749 
750  return 1; /* return error */
751  }
752 
753  return 0; /* success return 0 */
754 }
755 
769 uint8_t tm1638_get_reg(tm1638_handle_t *handle, uint8_t cmd, uint8_t *data, uint8_t len)
770 {
771  uint8_t res;
772 
773  if (handle == NULL) /* check handle */
774  {
775  return 2; /* return error */
776  }
777  if (handle->inited != 1) /* check handle initialization */
778  {
779  return 3; /* return error */
780  }
781 
782  res = a_tm1638_read(handle, cmd, data, len); /* read */
783  if (res != 0) /* check error */
784  {
785  handle->debug_print("tm1638: read failed.\n"); /* read failed */
786 
787  return 1; /* return error */
788  }
789 
790  return 0; /* success return 0 */
791 }
792 
802 {
803  if (info == NULL) /* check handle */
804  {
805  return 2; /* return error */
806  }
807 
808  memset(info, 0, sizeof(tm1638_info_t)); /* initialize tm1638 info structure */
809  strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
810  strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
811  strncpy(info->interface, "SPI", 8); /* copy interface name */
812  info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
813  info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
814  info->max_current_ma = MAX_CURRENT; /* set maximum current */
815  info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
816  info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
817  info->driver_version = DRIVER_VERSION; /* set driver version */
818 
819  return 0; /* success return 0 */
820 }
#define TM1638_COMMAND_DISPLAY
Definition: driver_tm1638.c:55
#define MAX_CURRENT
Definition: driver_tm1638.c:46
#define SUPPLY_VOLTAGE_MAX
Definition: driver_tm1638.c:45
#define TEMPERATURE_MAX
Definition: driver_tm1638.c:48
#define MANUFACTURER_NAME
Definition: driver_tm1638.c:43
#define TEMPERATURE_MIN
Definition: driver_tm1638.c:47
#define SUPPLY_VOLTAGE_MIN
Definition: driver_tm1638.c:44
#define TM1638_COMMAND_ADDRESS
Definition: driver_tm1638.c:56
#define CHIP_NAME
chip information definition
Definition: driver_tm1638.c:42
#define DRIVER_VERSION
Definition: driver_tm1638.c:49
#define TM1638_COMMAND_DATA
chip command definition
Definition: driver_tm1638.c:54
driver tm1638 header file
uint8_t tm1638_get_test_mode(tm1638_handle_t *handle, tm1638_bool_t *enable)
get test mode status
uint8_t tm1638_write_segment(tm1638_handle_t *handle, uint8_t addr, uint16_t *data, uint8_t len)
write segment
tm1638_bool_t
tm1638 bool enumeration definition
Definition: driver_tm1638.h:72
uint8_t tm1638_set_address_mode(tm1638_handle_t *handle, tm1638_address_mode_t mode)
set address mode
tm1638_address_mode_t
tm1638 address mode enumeration definition
Definition: driver_tm1638.h:63
uint8_t tm1638_set_pulse_width(tm1638_handle_t *handle, tm1638_pulse_width_t width)
set pulse width
uint8_t tm1638_deinit(tm1638_handle_t *handle)
close the chip
uint8_t tm1638_clear_segment(tm1638_handle_t *handle)
clear segment
uint8_t tm1638_init(tm1638_handle_t *handle)
initialize the chip
uint8_t tm1638_read_segment(tm1638_handle_t *handle, uint8_t segk[4])
read segment
uint8_t tm1638_set_display(tm1638_handle_t *handle, tm1638_bool_t enable)
enable or disable display
tm1638_pulse_width_t
tm1638 pulse width enumeration definition
Definition: driver_tm1638.h:81
uint8_t tm1638_get_display(tm1638_handle_t *handle, tm1638_bool_t *enable)
get display status
uint8_t tm1638_get_address_mode(tm1638_handle_t *handle, tm1638_address_mode_t *mode)
get address mode
uint8_t tm1638_set_test_mode(tm1638_handle_t *handle, tm1638_bool_t enable)
enable or disable test mode
uint8_t tm1638_info(tm1638_info_t *info)
get chip's information
uint8_t tm1638_get_pulse_width(tm1638_handle_t *handle, tm1638_pulse_width_t *width)
get pulse width
uint8_t tm1638_set_reg(tm1638_handle_t *handle, uint8_t cmd, uint8_t *data, uint8_t len)
set the chip register
uint8_t tm1638_get_reg(tm1638_handle_t *handle, uint8_t cmd, uint8_t *data, uint8_t len)
get the chip register
tm1638 handle structure definition
uint8_t(* spi_init)(void)
void(* delay_ms)(uint32_t ms)
uint8_t display_conf
void(* debug_print)(const char *const fmt,...)
uint8_t(* spi_deinit)(void)
uint8_t(* spi_write)(uint8_t addr, uint8_t *buf, uint16_t len)
uint8_t(* spi_read)(uint8_t addr, uint8_t *buf, uint16_t len)
tm1638 information structure definition
float temperature_max
float supply_voltage_max_v
uint32_t driver_version
float temperature_min
float max_current_ma
char manufacturer_name[32]
float supply_voltage_min_v
char interface[8]
char chip_name[32]