hd44780_shift_register.c 3.0 KB

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