|
@@ -0,0 +1,109 @@
|
|
|
|
|
+#include <stdint.h>
|
|
|
|
|
+#include <stddef.h>
|
|
|
|
|
+#include <stdbool.h>
|
|
|
|
|
+
|
|
|
|
|
+#include <cx/chlcd.h>
|
|
|
|
|
+#include <cx/chlcd/__helper.h>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+static chlcd_error_t __chlcd_hd44780_shift_register_set_byte(
|
|
|
|
|
+ chlcd_hd44780_shift_register_connector_t *self,
|
|
|
|
|
+ uint8_t content
|
|
|
|
|
+) {
|
|
|
|
|
+ for (uint8_t count = 0; count < 8; ++count) {
|
|
|
|
|
+ bool current = (content & 0b10000000) != 0x00;
|
|
|
|
|
+ content = content << 1;
|
|
|
|
|
+
|
|
|
|
|
+ __R(chlcd_pin_write(self->register_data, current));
|
|
|
|
|
+ __R(chlcd_pin_write(self->register_clock, true));
|
|
|
|
|
+ __R(chlcd_sleep_us(20));
|
|
|
|
|
+ __R(chlcd_pin_write(self->register_clock, false));
|
|
|
|
|
+ __R(chlcd_sleep_us(20));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ __R(chlcd_pin_write(self->register_latch, true));
|
|
|
|
|
+ __R(chlcd_sleep_us(20));
|
|
|
|
|
+ __R(chlcd_pin_write(self->register_latch, false));
|
|
|
|
|
+
|
|
|
|
|
+ self->last_state = content;
|
|
|
|
|
+ return CHLCD_SUCCESS;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+chlcd_error_t chlcd_hd44780_shift_register_init(void *self_pointer) {
|
|
|
|
|
+ chlcd_hd44780_shift_register_connector_t *self
|
|
|
|
|
+ = (chlcd_hd44780_shift_register_connector_t *) self_pointer;
|
|
|
|
|
+
|
|
|
|
|
+ __R(chlcd_pin_set_output(self->register_latch));
|
|
|
|
|
+ __R(chlcd_pin_set_output(self->register_clock));
|
|
|
|
|
+ __R(chlcd_pin_set_output(self->register_data));
|
|
|
|
|
+
|
|
|
|
|
+ __R(chlcd_pin_write(self->register_data, false));
|
|
|
|
|
+ __R(chlcd_pin_write(self->register_clock, false));
|
|
|
|
|
+ __R(chlcd_pin_write(self->register_latch, false));
|
|
|
|
|
+
|
|
|
|
|
+ __R(chlcd_sleep_us(20));
|
|
|
|
|
+
|
|
|
|
|
+ __R(__chlcd_hd44780_shift_register_set_byte(self, 0x00));
|
|
|
|
|
+
|
|
|
|
|
+ return CHLCD_SUCCESS;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+chlcd_error_t __chlcd_hd44780_shift_register_send_half_byte(
|
|
|
|
|
+ chlcd_hd44780_shift_register_connector_t *self,
|
|
|
|
|
+ uint8_t content,
|
|
|
|
|
+ bool is_command
|
|
|
|
|
+) {
|
|
|
|
|
+ uint8_t d7 = (content & 0b10000000) ? 0b1 : 0b0;
|
|
|
|
|
+ uint8_t d6 = (content & 0b01000000) ? 0b1 : 0b0;
|
|
|
|
|
+ uint8_t d5 = (content & 0b00100000) ? 0b1 : 0b0;
|
|
|
|
|
+ uint8_t d4 = (content & 0b00010000) ? 0b1 : 0b0;
|
|
|
|
|
+ uint8_t rs = is_command ? 0b0 : 0b1;
|
|
|
|
|
+ uint8_t e_mask = 0b1 << self->e;
|
|
|
|
|
+
|
|
|
|
|
+ uint8_t target = 0x00;
|
|
|
|
|
+ target |= (d7 << self->d7);
|
|
|
|
|
+ target |= (d6 << self->d6);
|
|
|
|
|
+ target |= (d5 << self->d5);
|
|
|
|
|
+ target |= (d4 << self->d4);
|
|
|
|
|
+ target |= (rs << self->rs);
|
|
|
|
|
+ target |= e_mask;
|
|
|
|
|
+
|
|
|
|
|
+ __R(__chlcd_hd44780_shift_register_set_byte(self, target));
|
|
|
|
|
+ __R(chlcd_sleep_us(2000));
|
|
|
|
|
+
|
|
|
|
|
+ target &= ~e_mask;
|
|
|
|
|
+
|
|
|
|
|
+ __R(__chlcd_hd44780_shift_register_set_byte(self, target));
|
|
|
|
|
+ __R(chlcd_sleep_us(2000));
|
|
|
|
|
+
|
|
|
|
|
+ return CHLCD_SUCCESS;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+chlcd_error_t chlcd_hd44780_shift_register_sender(
|
|
|
|
|
+ void *self_pointer,
|
|
|
|
|
+ chlcd_data_t content,
|
|
|
|
|
+ bool is_command,
|
|
|
|
|
+ bool is_half_word
|
|
|
|
|
+) {
|
|
|
|
|
+ chlcd_hd44780_shift_register_connector_t *self
|
|
|
|
|
+ = (chlcd_hd44780_shift_register_connector_t *) self_pointer;
|
|
|
|
|
+
|
|
|
|
|
+ if (!is_half_word) {
|
|
|
|
|
+ __R(__chlcd_hd44780_shift_register_send_half_byte(
|
|
|
|
|
+ self,
|
|
|
|
|
+ content,
|
|
|
|
|
+ is_command
|
|
|
|
|
+ ));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ content = content << 4;
|
|
|
|
|
+
|
|
|
|
|
+ __R(__chlcd_hd44780_shift_register_send_half_byte(
|
|
|
|
|
+ self,
|
|
|
|
|
+ content,
|
|
|
|
|
+ is_command
|
|
|
|
|
+ ));
|
|
|
|
|
+
|
|
|
|
|
+ return CHLCD_SUCCESS;
|
|
|
|
|
+}
|
|
|
|
|
+
|