hd44780_shift_register.c 2.9 KB

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