/* Copyright 2022, Savanni D'Gerinel This file is part of Savanni's AVR library. This AVR library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This AVR library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this AVR library. If not, see . */ #include #include #include #include #include "display.h" #define ENABLE _BV(5) #define CHARCODE _BV(4) void ping(dio_t *light) { dio_set(light, 1); _delay_ms(100); dio_set(light, 0); _delay_ms(100); } void send_half_code(display_t *disp, uint8_t reg, uint8_t data) { sr_send_msb(&disp->reg, (reg ? CHARCODE : 0) | data << 2); _delay_us(1); sr_send_msb(&disp->reg, (ENABLE | (reg ? CHARCODE : 0) | data) << 2); _delay_us(1); sr_send_msb(&disp->reg, ((reg ? CHARCODE : 0) | data) << 2); _delay_us(1); } void send_code(display_t *disp, uint8_t reg, uint8_t data) { send_half_code(disp, reg, data >> 4); send_half_code(disp, reg, data & 0xf); } void write_instruction(display_t *disp, uint8_t bitcode) { send_code(disp, 0, bitcode); } void write_char(display_t *disp, uint8_t bitcode) { send_code(disp, 1, bitcode); _delay_us(100); } void display_init(display_t *disp) { sr_initialize(&disp->reg); /* Initializing for 4-bit channel */ send_half_code(disp, 0, 0b0011); _delay_ms(5); send_half_code(disp, 0, 0b0011); _delay_us(150); send_half_code(disp, 0, 0b0011); _delay_us(100); send_half_code(disp, 0, 0b0010); _delay_us(100); /* Function set, 4-bit channel, two lines, 5x10 dots */ write_instruction(disp, 0b00101000); _delay_us(100); /* display off */ write_instruction(disp, 0b00001000); _delay_us(100); /* display clear */ write_instruction(disp, 0b00000001); _delay_ms(3); /* set entry mode */ write_instruction(disp, 0b00000110); _delay_us(100); /* display on */ write_instruction(disp, 0b00001100); _delay_us(100); } void display_clear(display_t *disp) { write_instruction(disp, 0b00000001); _delay_us(100); write_instruction(disp, 0b00000010); _delay_us(100); } void display_enable(display_t *disp) { write_instruction(disp, _BV(5)); _delay_us(100); write_instruction(disp, _BV(5) | _BV(3)); _delay_us(100); } void display_set_location(display_t *disp, size_t row, size_t column) { size_t addr = row * 40 + column; write_instruction(disp, 0b10000000 | addr); _delay_us(100); } void display_write_message(display_t *disp, const char *msg) { for (size_t i = 0; msg[i] != 0; i++) { write_char(disp, msg[i]); } } void display_write_bit_pattern(display_t *disp, const uint8_t pattern) { char msg[16]; sprintf(msg, "* "); for (int i = 7; i >= 0; i--) { if (pattern & _BV(i)) { display_write_message(disp, "1"); } else { display_write_message(disp, "0"); } } }