diff --git a/TWI/TWI/KS0066.cpp b/TWI/TWI/KS0066.cpp new file mode 100644 index 0000000..b01d355 --- /dev/null +++ b/TWI/TWI/KS0066.cpp @@ -0,0 +1,227 @@ +#include "KS0066.h" + +#include + +KS0066::KS0066() +{ + +} + +KS0066::KS0066(ShiftRegister &shiftRegister) +{ + setShiftRegister(shiftRegister); +} + +void KS0066::setShiftRegister(ShiftRegister &shiftRegister) +{ + m_shiftRegister = &shiftRegister; + + initDisplay(); +} + +void KS0066::initDisplay() +{ + _delay_ms(30); + + execute((1 << m_db5) | 1 << m_db4); + _delay_ms(5); + execute((1 << m_db5) | 1 << m_db4); + _delay_us(100); + execute((1 << m_db5) | 1 << m_db4); + execute((1 << m_db5)); + + functionSet(false, true, true); + + onOffControl(true, false, false); + displayClear(); + + entryMode(true, false); + + sendString("ready."); +} + +void KS0066::functionSet(bool interface8bit, bool twoLine, bool displayFont) +{ + uint8_t command = 0b00100000; + + if (interface8bit) + { + command |= (1 << 4); + } + + if (twoLine) + { + command |= (1 << 3); + } + + if (displayFont) + { + command |= (1 << 2); + } + + sendCommand(command); + + _delay_us(53); +} + +void KS0066::onOffControl(bool displayOn, bool cursorOn, bool blinkingOn) +{ + uint8_t command = 0b00001000; + + if (displayOn) + { + command |= (1 << 2); + } + + if (cursorOn) + { + command |= (1 << 1); + } + + if (blinkingOn) + { + command |= (1 << 0); + } + + sendCommand(command); + + _delay_us(53); +} + +void KS0066::displayClear() +{ + uint8_t command = 0b00000001; + + sendCommand(command); + + _delay_ms(2.16); +} + +void KS0066::entryMode(bool incrementMode, bool entireShift) +{ + uint8_t command = 0b00000100; + + if (incrementMode) + { + command |= (1 << 1); + } + + if (entireShift) + { + command |= (1 << 0); + } + + sendCommand(command); + + _delay_us(53); +} + +void KS0066::setCursorPos(uint8_t line, uint8_t column) +{ + sendCommand(0b10000000 + column + (line * 40)); +} + +void KS0066::sendCommand(uint8_t data) +{ + sendByte(data, true); +} + +void KS0066::sendChar(char c) +{ + sendByte(c, false); + + _delay_us(53); +} + +void KS0066::sendString(const char *string) +{ + uint8_t count = 0; + while (string != nullptr && *string != 0 && count < (m_lines * m_columns)) + { + if (count % m_columns == 0) + { + setCursorPos(count / m_columns, 0); + } + sendChar(*string); + string++; + count++; + } +} + +void KS0066::sendByte(uint8_t data, bool isCommand) +{ + uint8_t registerValue = 0; + + if (!isCommand) + { + registerValue |= (1 << m_rs); + } + + if (data & (1 << 7)) + { + registerValue |= (1 << m_db7); + } + + if (data & (1 << 6)) + { + registerValue |= (1 << m_db6); + } + + if (data & (1 << 5)) + { + registerValue |= (1 << m_db5); + } + + if (data & (1 << 4)) + { + registerValue |= (1 << m_db4); + } + + execute(registerValue); + + registerValue &= (1 << m_rs); + + if (data & (1 << 3)) + { + registerValue |= (1 << m_db7); + } + + if (data & (1 << 2)) + { + registerValue |= (1 << m_db6); + } + + if (data & (1 << 1)) + { + registerValue |= (1 << m_db5); + } + + if (data & (1 << 0)) + { + registerValue |= (1 << m_db4); + } + + execute(registerValue); +} + +void KS0066::execute(uint8_t registerValue) +{ + registerValue |= (1 << m_e); + m_shiftRegister->output(registerValue); + _delay_us(2); + + registerValue &= ~(1 << m_e); + m_shiftRegister->output(registerValue); +} + +void KS0066::set(const char *string) +{ + displayClear(); + sendString(string); +} + +void KS0066::clear() +{ + displayClear(); +} + diff --git a/TWI/TWI/KS0066.h b/TWI/TWI/KS0066.h new file mode 100644 index 0000000..87f98dc --- /dev/null +++ b/TWI/TWI/KS0066.h @@ -0,0 +1,55 @@ +#pragma once + +#include "environment.h" + +#include + +#include "ShiftRegister.h" + +class KS0066 +{ +private: + ShiftRegister *m_shiftRegister; + + static const uint8_t m_rs = 1; + static const uint8_t m_rw = 2; + static const uint8_t m_e = 3; + static const uint8_t m_db4 = 4; + static const uint8_t m_db5 = 5; + static const uint8_t m_db6 = 6; + static const uint8_t m_db7 = 7; + + uint8_t m_lines = 2; + uint8_t m_columns = 16; + +public: + KS0066(); + KS0066(ShiftRegister &shiftRegister); + + void setShiftRegister(ShiftRegister &shiftRegister); + + void clear(); + + void set(const char *string); + + +private: + + void initDisplay(); + + void functionSet(bool interface8bit, bool twoLine, bool displayOn); + void onOffControl(bool displayOn, bool cursorOn, bool blinkingOn); + void entryMode(bool incrementMode, bool entireShift); + void displayClear(); + + void setCursorPos(uint8_t line, uint8_t column); + + void sendCommand(uint8_t data); + + void sendChar(char c); + void sendString(const char *string); + + void sendByte(uint8_t data, bool isCommand); + + void execute(uint8_t registerValue); +}; \ No newline at end of file diff --git a/TWI/TWI/ShiftRegister.cpp b/TWI/TWI/ShiftRegister.cpp new file mode 100644 index 0000000..75e22bf --- /dev/null +++ b/TWI/TWI/ShiftRegister.cpp @@ -0,0 +1,23 @@ +#include "ShiftRegister.h" + +ShiftRegister::ShiftRegister(volatile uint8_t *shiftClockPort, uint8_t shiftClockPin, + volatile uint8_t *dataPort, uint8_t dataPin, + volatile uint8_t *latchClockPort, uint8_t latchClockPin) + : m_shiftClockPin(shiftClockPort, shiftClockPin) + , m_dataPin(dataPort, dataPin) + , m_latchClockPin(latchClockPort, latchClockPin) +{ + +} + +void ShiftRegister::output(int8_t value) +{ + for (int8_t bitIdx = 7; bitIdx >= 0; --bitIdx) + { + m_dataPin.set(value & (1 << bitIdx)); + m_shiftClockPin.pulse(); + } + + m_latchClockPin.pulse(); +} + diff --git a/TWI/TWI/ShiftRegister.h b/TWI/TWI/ShiftRegister.h new file mode 100644 index 0000000..a2b2e4d --- /dev/null +++ b/TWI/TWI/ShiftRegister.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "Pin.h" + +class ShiftRegister +{ + Pin m_shiftClockPin; + Pin m_dataPin; + Pin m_latchClockPin; + +public: + ShiftRegister(volatile uint8_t *shiftClockPort, uint8_t shiftClockPin, + volatile uint8_t *dataPort, uint8_t dataPin, + volatile uint8_t *latchClockPort, uint8_t latchClockPin); + + void output(int8_t value); +}; diff --git a/TWI/TWI/TWI.cpp b/TWI/TWI/TWI.cpp index dc0c91e..8e446c9 100644 --- a/TWI/TWI/TWI.cpp +++ b/TWI/TWI/TWI.cpp @@ -7,6 +7,8 @@ #include #include "Pin.h" +#include "ShiftRegister.h" +#include "KS0066.h" void I2C_init(uint8_t address) { @@ -23,7 +25,9 @@ void I2C_stop(void) TWCR &= ~( (1< - True - True - True - True - False - True - True - - - NDEBUG - - - Optimize for size (-Os) - True - True - True - True - True - - - NDEBUG - - - Optimize for size (-Os) - True - True - True - - - libm - - - + True + True + True + True + False + True + True + True + True + True + True + True + True + True + True + -std=c++11 + libm + NDEBUG + Optimize for size (-Os) + NDEBUG + Optimize for size (-Os) + - True - True - True - True - False - True - True - - - DEBUG - - - Optimize (-O1) - True - True - Default (-g2) - True - True - True - - - DEBUG - - - Optimize (-O1) - True - True - Default (-g2) - True - - - libm - - - Default (-Wa,-g) - + True + True + True + True + False + True + True + True + True + True + True + True + True + True + True + -std=c++11 + libm + DEBUG + Optimize (-O1) + Default (-g2) + DEBUG + Optimize (-O1) + Default (-g2) + Default (-Wa,-g) + compile + + compile + + + compile + compile compile + + compile + + + compile + compile