hd44780_shift_register.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <stdint.h>
  2. #include <stddef.h>
  3. #include <stdbool.h>
  4. #include <cx/chlcd.h>
  5. #include <cx/chlcd/__helper.h>
  6. static chlcd_error_t __chlcd_hd44780_shift_register_set_byte(
  7. chlcd_hd44780_shift_register_connector_t *self,
  8. uint8_t content
  9. ) {
  10. self->last_state = content;
  11. uint8_t mask = 0b10000000;
  12. for (uint8_t count = 0; count < 8; ++count) {
  13. bool current = (content & mask) != 0x00;
  14. mask = mask >> 1;
  15. __R(chlcd_pin_write(self->register_data, current));
  16. __R(chlcd_sleep_us(2000));
  17. __R(chlcd_pin_write(self->register_clock, true));
  18. __R(chlcd_sleep_us(2000));
  19. __R(chlcd_pin_write(self->register_clock, false));
  20. __R(chlcd_sleep_us(2000));
  21. }
  22. __R(chlcd_pin_write(self->register_latch, true));
  23. __R(chlcd_sleep_us(2000));
  24. __R(chlcd_pin_write(self->register_latch, false));
  25. return CHLCD_SUCCESS;
  26. }
  27. chlcd_error_t chlcd_hd44780_shift_register_init(void *self_pointer) {
  28. chlcd_hd44780_shift_register_connector_t *self
  29. = (chlcd_hd44780_shift_register_connector_t *) self_pointer;
  30. __R(chlcd_pin_set_output(self->register_latch));
  31. __R(chlcd_pin_set_output(self->register_clock));
  32. __R(chlcd_pin_set_output(self->register_data));
  33. __R(chlcd_pin_write(self->register_data, false));
  34. __R(chlcd_pin_write(self->register_clock, false));
  35. __R(chlcd_pin_write(self->register_latch, false));
  36. __R(chlcd_sleep_us(200));
  37. __R(__chlcd_hd44780_shift_register_set_byte(self, 0x00));
  38. return CHLCD_SUCCESS;
  39. }
  40. chlcd_error_t __chlcd_hd44780_shift_register_send_half_byte(
  41. chlcd_hd44780_shift_register_connector_t *self,
  42. uint8_t content,
  43. bool is_command
  44. ) {
  45. uint8_t d7 = (content & 0b10000000) ? 0b1 : 0b0;
  46. uint8_t d6 = (content & 0b01000000) ? 0b1 : 0b0;
  47. uint8_t d5 = (content & 0b00100000) ? 0b1 : 0b0;
  48. uint8_t d4 = (content & 0b00010000) ? 0b1 : 0b0;
  49. uint8_t rs = is_command ? 0b0 : 0b1;
  50. uint8_t e_mask = 0b1 << self->e;
  51. uint8_t target = 0x00;
  52. target |= (d7 << self->d7);
  53. target |= (d6 << self->d6);
  54. target |= (d5 << self->d5);
  55. target |= (d4 << self->d4);
  56. target |= (rs << self->rs);
  57. target |= e_mask;
  58. __R(__chlcd_hd44780_shift_register_set_byte(self, target));
  59. __R(chlcd_sleep_us(2000));
  60. target &= ~e_mask;
  61. __R(__chlcd_hd44780_shift_register_set_byte(self, target));
  62. __R(chlcd_sleep_us(2000));
  63. return CHLCD_SUCCESS;
  64. }
  65. chlcd_error_t chlcd_hd44780_shift_register_sender(
  66. void *self_pointer,
  67. chlcd_data_t content,
  68. bool is_command,
  69. bool is_half_word
  70. ) {
  71. chlcd_hd44780_shift_register_connector_t *self
  72. = (chlcd_hd44780_shift_register_connector_t *) self_pointer;
  73. if (!is_half_word) {
  74. __R(__chlcd_hd44780_shift_register_send_half_byte(
  75. self,
  76. content,
  77. is_command
  78. ));
  79. }
  80. content = content << 4;
  81. __R(__chlcd_hd44780_shift_register_send_half_byte(
  82. self,
  83. content,
  84. is_command
  85. ));
  86. return CHLCD_SUCCESS;
  87. }