summaryrefslogtreecommitdiff
path: root/LiquidCrystal.c
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2015-05-31 15:48:15 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2015-05-31 15:48:15 +0200
commit8f45739d02f02c226452f7f62c4dc195e6e13b38 (patch)
tree4531e03453f54da36d865b3bfe6b23253edb9dbe /LiquidCrystal.c
parent4d0ab32f13438f7f911062088d9bdfb786a3dfce (diff)
downloadphone_remote_nrf51-8f45739d02f02c226452f7f62c4dc195e6e13b38.tar.gz
phone_remote_nrf51-8f45739d02f02c226452f7f62c4dc195e6e13b38.tar.bz2
phone_remote_nrf51-8f45739d02f02c226452f7f62c4dc195e6e13b38.tar.xz
phone_remote_nrf51-8f45739d02f02c226452f7f62c4dc195e6e13b38.zip
o Party functional LCD code.
Diffstat (limited to 'LiquidCrystal.c')
-rw-r--r--LiquidCrystal.c197
1 files changed, 129 insertions, 68 deletions
diff --git a/LiquidCrystal.c b/LiquidCrystal.c
index becc07e..eed30c8 100644
--- a/LiquidCrystal.c
+++ b/LiquidCrystal.c
@@ -1,13 +1,14 @@
#include "LiquidCrystal.h"
+#include "nrf_delay.h"
+#include "nrf_error.h"
#include "nrf_gpio.h"
-#include "app_timer.h"
/*
* Arduino | LCD | nrf51
* D4 | DB4 | P0.16
* D5 | DB5 | P0.17
* D6 | DB6 | P0.18
- * D7 | DB7 | P0.10
+ * D7 | DB7 | P0.19
* D8 | RS | P0.20, register select. 0=instruction (write), 0=busy (read), 1=data
* D9 | EN | P0.23, clock, data is clocked in/out on falling edge
* D10 | DB4 | P0.24
@@ -31,103 +32,109 @@ static struct {
uint8_t pin_db7;
uint8_t pin_rs;
uint8_t pin_en;
-
- app_gpiote_user_id_t gpio_user_id;
} data = { .pin_db4 = 16, .pin_db5 = 17, .pin_db6 = 18, .pin_db7 = 19, .pin_rs =
20, .pin_en = 23, };
-static uint32_t ticks_per_ms;
-
-static void event_handler() {
-}
-
-static void wait_ms(uint32_t ms) {
- uint32_t ticks;
-
- app_timer_cnt_get(&ticks);
-
- const uint32_t end_ticks = ticks + ms * ticks_per_ms;
-
- do {
- app_timer_cnt_get(&ticks);
- } while (ticks < end_ticks);
-}
-
static void write_4(uint8_t value) {
nrf_gpio_pin_write(data.pin_db4, value & 0x01);
nrf_gpio_pin_write(data.pin_db5, value & 0x02);
nrf_gpio_pin_write(data.pin_db6, value & 0x04);
nrf_gpio_pin_write(data.pin_db7, value & 0x08);
+ nrf_delay_us(10);
nrf_gpio_pin_set(data.pin_en);
+ nrf_delay_us(10); // 450ns is supposed to be sufficient
nrf_gpio_pin_clear(data.pin_en);
}
-static void write_value(uint8_t value, bool is_data) {
+static void write_value(uint8_t value, bool is_data, uint32_t delay) {
nrf_gpio_pin_write(data.pin_rs, is_data);
write_4(value >> 4);
write_4(value);
-}
-
-static void begin() {
- nrf_gpio_pin_clear(data.pin_rs);
- nrf_gpio_pin_clear(data.pin_en);
- // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
- // according to datasheet, we need at least 40ms after power rises above 2.7V
- // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
- wait_ms(50);
-
- write_4(0x03);
- wait_ms(5); // 4.5ms
-
- write_4(0x03);
- wait_ms(5); // 4.5ms
-
- write_4(0x03);
- wait_ms(5); // 4.5ms
-
- write_4(0x02);
-
- write_value(LIQUID_CRYSTAL_CMD_DISPLAY, false);
-
-// _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
- liquid_crystal_display(true, true, true);
+ nrf_delay_us(delay);
}
void liquid_crystal_write_char(char chr) {
- write_value(chr, true);
+ write_value(chr, true, 50);
}
void liquid_crystal_write_string(char *chr) {
- while (*chr != '\0') {
+ for (; *chr != '\0'; chr++) {
liquid_crystal_write_char(*chr);
}
}
-uint32_t liquid_crystal_display(bool display_on, bool cursor_on, bool blink) {
- uint8_t value = LIQUID_CRYSTAL_CMD_DISPLAY;
-
- value |= display_on ? 0x04 : 0x00;
- value |= cursor_on ? 0x02 : 0x00;
- value |= blink ? 0x01 : 0x00;
-
- write_value(value, false);
-
- return NRF_SUCCESS;
+void liquid_crystal_clear() {
+ // The documentation doesn't specify a value, but everything else is 37us
+ write_value(LIQUID_CRYSTAL_CMD_CLEAR, false, 50);
}
-uint32_t liquid_crystal_init(uint32_t _ticks_per_ms) {
- ticks_per_ms = _ticks_per_ms;
+void liquid_crystal_return_home() {
+ write_value(LIQUID_CRYSTAL_CMD_RETURN_HOME, false, 2000);
+}
- uint32_t err_code = app_gpiote_user_register(&data.gpio_user_id, 0x0000,
- 0x0000, event_handler);
+static struct {
+ union {
+ uint8_t value;
+ struct {
+ bool shift :1;
+ bool increment :1;
+ int :6;
+ } fields __attribute__((packed));
+ };
+}__attribute__((packed)) entry_mode_state;
+
+void liquid_crystal_entry_mode_set(bool increment, bool shift) {
+ /*
+ uint8_t value = LIQUID_CRYSTAL_CMD_ENTRY_MODE_SET;
+
+ value |= increment ? 0x02 : 0x00;
+ value |= shift ? 0x01 : 0x00;
+
+ write_value(value, false);
+ */
+
+ entry_mode_state.fields.increment = increment;
+ entry_mode_state.fields.shift = shift;
+ write_value(entry_mode_state.value, false, 50);
+}
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
+static struct {
+ union {
+ uint8_t value;
+ struct {
+ bool blink :1;
+ bool cursor_on :1;
+ bool display_on :1;
+ int :5;
+ } fields __attribute__((packed));
+ };
+}__attribute__((packed)) display_state;
+
+void liquid_crystal_display(bool display_on, bool cursor_on, bool blink) {
+ display_state.fields.display_on = display_on;
+ display_state.fields.cursor_on = cursor_on;
+ display_state.fields.blink = blink;
+
+ write_value(display_state.value, false, 50);
+}
+static struct {
+ union {
+ uint8_t value;
+ struct {
+ int :2;
+ bool many_dots :1;
+ bool two_line :1;
+ bool data_length :1;
+ int :3;
+ } fields __attribute__((packed));
+ };
+}__attribute__((packed)) function_set_state;
+
+void liquid_crystal_init(bool data_length, bool two_line, bool many_dots) {
nrf_gpio_cfg_output(data.pin_db4);
nrf_gpio_cfg_output(data.pin_db5);
nrf_gpio_cfg_output(data.pin_db6);
@@ -135,7 +142,61 @@ uint32_t liquid_crystal_init(uint32_t _ticks_per_ms) {
nrf_gpio_cfg_output(data.pin_rs);
nrf_gpio_cfg_output(data.pin_en);
- begin(data);
+ display_state.value = LIQUID_CRYSTAL_CMD_DISPLAY;
+ entry_mode_state.value = LIQUID_CRYSTAL_CMD_ENTRY_MODE_SET;
+ function_set_state.value = LIQUID_CRYSTAL_CMD_FUNCTION_SET;
+
+ function_set_state.fields.data_length = data_length;
+ function_set_state.fields.two_line = two_line;
+ function_set_state.fields.many_dots = many_dots;
+
+ for (int i = 0; i < 3; i++) {
+ nrf_gpio_pin_set(data.pin_en);
+ nrf_delay_ms(100);
+ nrf_gpio_pin_clear(data.pin_en);
+ nrf_delay_ms(100);
+ }
+
+ // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
+ // according to datasheet, we need at least 40ms after power rises above 2.7V
+ // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
+ nrf_delay_ms(50);
+
+ nrf_gpio_pin_clear(data.pin_rs);
+ nrf_gpio_pin_clear(data.pin_en);
+
+ write_4(0x03);
+ nrf_delay_us(4500);
+
+ write_4(0x03);
+ nrf_delay_us(4500);
+
+ write_4(0x03);
+ nrf_delay_us(150);
+
+ write_4(0x02);
+
+ write_value(function_set_state.value, false, 50);
+}
+
+void liquid_crystal_reset() {
+ liquid_crystal_clear();
+ liquid_crystal_return_home();
+ liquid_crystal_entry_mode_set(true, false);
+}
+
+void liquid_crystal_set_cursor(int column, int row) {
+ uint8_t value = LIQUID_CRYSTAL_CMD_SET_DDRAM_ADDDRESS;
+
+ if (row == 1) {
+ value += 0x40;
+ } else if (row == 2) {
+ value += 14;
+ } else if (row == 3) {
+ value += 54;
+ }
+
+ value += column;
- return NRF_SUCCESS;
+ write_value(value, false, 50);
}