Added LCD library and preparing to start work on OS.
This commit is contained in:
parent
4dfad70e9b
commit
d041658da9
|
@ -8,7 +8,7 @@
|
|||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/avr-gcc",
|
||||
"cStandard": "gnu17",
|
||||
"cStandard": "gnu11",
|
||||
"cppStandard": "gnu++14",
|
||||
"intelliSenseMode": "gcc-avr",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
|
|
73
build.d
73
build.d
|
@ -22,30 +22,66 @@ const string BUILD_DIR = "bin";
|
|||
|
||||
const string[] COMPILER_FLAGS = [
|
||||
"-Wall",
|
||||
"-Os"
|
||||
"-Os",
|
||||
"-g",
|
||||
"-DF_CPU=16000000UL",
|
||||
"-mmcu=atmega328p"
|
||||
];
|
||||
|
||||
int main(string[] args) {
|
||||
if (args.length < 2) {
|
||||
return build();
|
||||
}
|
||||
string command = args[1].strip.toLower;
|
||||
if (command == "flash") {
|
||||
build().quitIfNonZero();
|
||||
return flashToMCU(buildPath("bin", "gympal.hex"));
|
||||
}
|
||||
if (command == "build") return build(true);
|
||||
if (command == "clean") return clean();
|
||||
alias BuildCommand = int function(string[]);
|
||||
|
||||
writefln!"Unknown command: \"%s\"."(command);
|
||||
int main(string[] args) {
|
||||
string command;
|
||||
if (args.length < 2) {
|
||||
command = "help";
|
||||
} else {
|
||||
command = args[1].strip.toLower;
|
||||
}
|
||||
|
||||
BuildCommand[string] commandMap = [
|
||||
"build": &buildCommand,
|
||||
"flash": &flashCommand,
|
||||
"clean": &clean,
|
||||
"help": &helpCommand
|
||||
];
|
||||
|
||||
if (command !in commandMap) {
|
||||
command = "help";
|
||||
}
|
||||
|
||||
BuildCommand func = commandMap[command];
|
||||
string[] commandArgs = [];
|
||||
if (args.length > 2) commandArgs = args[2 .. $];
|
||||
return func(commandArgs);
|
||||
}
|
||||
|
||||
int helpCommand(string[] args) {
|
||||
writeln("build.d - A simple build script for C files.");
|
||||
writeln("The following commands are available:");
|
||||
writeln("build [-f] - Compiles source code. Use -f to force rebuild.");
|
||||
writeln(" By default, sources are hashed, and only built if changes are detected.");
|
||||
writeln("flash [buildArgs] - Flashes code onto a connected AVR device via AVRDude.");
|
||||
writeln("clean - Removes all build files.");
|
||||
writeln("help - Shows this help information.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int clean() {
|
||||
int clean(string[] args) {
|
||||
rmdirRecurse(BUILD_DIR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int buildCommand(string[] args) {
|
||||
import std.algorithm : canFind;
|
||||
return build(canFind(args, "-f"));
|
||||
}
|
||||
|
||||
int flashCommand(string[] args) {
|
||||
int result = buildCommand(args);
|
||||
if (result != 0) return result;
|
||||
return flashToMCU(buildPath("bin", "gympal.hex"));
|
||||
}
|
||||
|
||||
int build(bool force = false) {
|
||||
if (!exists(BUILD_DIR)) mkdir(BUILD_DIR);
|
||||
string[] sources = findFiles(SOURCE_DIR, ".c");
|
||||
|
@ -104,10 +140,8 @@ string compileSourceToObject(string sourcePath, bool force = false) {
|
|||
return objectPath;
|
||||
}
|
||||
|
||||
string cmd = format!"avr-gcc %s -DF_CPU=%dUL -mmcu=%s -c -o %s %s"(
|
||||
string cmd = format!"avr-gcc %s -c -o %s %s"(
|
||||
flags,
|
||||
CPU_FREQ,
|
||||
MCU_ID,
|
||||
objectPath,
|
||||
sourcePath
|
||||
);
|
||||
|
@ -138,7 +172,7 @@ string linkObjects(string[] objectPaths) {
|
|||
|
||||
string copyToHex(string elfFile) {
|
||||
string hexFile = buildPath(BUILD_DIR, "gympal.hex");
|
||||
string cmd = format!"avr-objcopy -O ihex -R .eeprom %s %s"(
|
||||
string cmd = format!"avr-objcopy -j .data -j .text -O ihex %s %s"(
|
||||
elfFile,
|
||||
hexFile
|
||||
);
|
||||
|
@ -148,9 +182,8 @@ string copyToHex(string elfFile) {
|
|||
}
|
||||
|
||||
int flashToMCU(string hexFile) {
|
||||
string cmd = format!"avrdude -c %s -p %s -P /dev/ttyUSB0 -b %d flash:w:%s:i"(
|
||||
string cmd = format!"avrdude -c %s -p m328p -P /dev/ttyUSB0 -b %d -u -U flash:w:%s:i"(
|
||||
BOOTLOADER,
|
||||
MCU_ID,
|
||||
AVRDUDE_BAUDRATE,
|
||||
hexFile
|
||||
);
|
||||
|
|
|
@ -29,8 +29,7 @@ void ctl_init() {
|
|||
(1 << CTL_ROTARY_ENCODER_DT) |
|
||||
(1 << CTL_ROTARY_ENCODER_CLK) |
|
||||
(1 << CTL_BUTTON_A) |
|
||||
(1 << CTL_BUTTON_B) |
|
||||
(1 << CTL_BUTTON_C)
|
||||
(1 << CTL_BUTTON_B)
|
||||
);
|
||||
// Set up interrupts for handling control pin state changes.
|
||||
// Luckily, all interrupts happen on PCINT[16..23] so we only need one interrupt to handle them all.
|
||||
|
@ -39,8 +38,7 @@ void ctl_init() {
|
|||
(1 << CTL_ROTARY_ENCODER_DT_INT) |
|
||||
(1 << CTL_ROTARY_ENCODER_CLK_INT) |
|
||||
(1 << CTL_BUTTON_A_INT) |
|
||||
(1 << CTL_BUTTON_B_INT) |
|
||||
(1 << CTL_BUTTON_C_INT)
|
||||
(1 << CTL_BUTTON_B_INT)
|
||||
);
|
||||
// Enable the global interrupt flag.
|
||||
sei();
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include "display.h"
|
||||
|
||||
struct st7735 lcd;
|
||||
|
||||
void display_init() {
|
||||
ST7735_Init (&display_lcd);
|
||||
ST7735_CommandSend (&display_lcd, MADCTL);
|
||||
ST7735_Data8BitsSend (&display_lcd, 0x00);
|
||||
ST7735_ClearScreen (&display_lcd, BLACK);
|
||||
ST7735_SetPosition (5, 10);
|
||||
ST7735_DrawString (&display_lcd, "Testing", WHITE, X1);
|
||||
}
|
||||
|
||||
void display_show_str(char* str) {
|
||||
ST7735_ClearScreen(&display_lcd, BLACK);
|
||||
ST7735_SetPosition(5, 10);
|
||||
ST7735_DrawString(&display_lcd, str, WHITE, X1);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef DISPLAY_H
|
||||
#define DISPLAY_H
|
||||
|
||||
#include "st7735.h"
|
||||
|
||||
// A wrapper around the ST7735 library, which handles all of the gympal-specific display code.
|
||||
|
||||
// Internal IO definition needed by the st7735 library.
|
||||
// Chip Select
|
||||
struct signal cs = { .ddr = &DDRB, .port = &PORTB, .pin = 2 };
|
||||
// Back Light
|
||||
struct signal bl = { .ddr = &DDRB, .port = &PORTB, .pin = 1 };
|
||||
// Data / Command
|
||||
struct signal dc = { .ddr = &DDRB, .port = &PORTB, .pin = 0 };
|
||||
// Reset
|
||||
struct signal rs = { .ddr = &DDRD, .port = &PORTD, .pin = 7 };
|
||||
// LCD struct
|
||||
struct st7735 display_lcd = { .cs = &cs, .bl = &bl, .dc = &dc, .rs = &rs };
|
||||
|
||||
/**
|
||||
* @brief Initializes the display.
|
||||
*/
|
||||
void display_init();
|
||||
|
||||
void display_show_str(char* str);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* ---------------------------------------------------------------+
|
||||
* @desc FONTs
|
||||
* ---------------------------------------------------------------+
|
||||
* Copyright (C) 2020 Marian Hrinko.
|
||||
* Written by Marian Hrinko (mato.hrinko@gmail.com)
|
||||
*
|
||||
* @author Marian Hrinko
|
||||
* @datum 07.10.2020
|
||||
* @file font.c
|
||||
* @tested AVR Atmega16
|
||||
*
|
||||
* @depend
|
||||
* ---------------------------------------------------------------+
|
||||
*/
|
||||
#include "font.h"
|
||||
|
||||
/** @array Charset */
|
||||
const uint8_t FONTS[][5] PROGMEM = {
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, // 20 space
|
||||
{ 0x81, 0x81, 0x18, 0x81, 0x81 }, // 21 !
|
||||
// { 0x00, 0x00, 0x5f, 0x00, 0x00 }, // 21 !
|
||||
{ 0x00, 0x07, 0x00, 0x07, 0x00 }, // 22 "
|
||||
{ 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // 23 #
|
||||
{ 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // 24 $
|
||||
{ 0x23, 0x13, 0x08, 0x64, 0x62 }, // 25 %
|
||||
{ 0x36, 0x49, 0x55, 0x22, 0x50 }, // 26 &
|
||||
{ 0x00, 0x05, 0x03, 0x00, 0x00 }, // 27 '
|
||||
{ 0x00, 0x1c, 0x22, 0x41, 0x00 }, // 28 (
|
||||
{ 0x00, 0x41, 0x22, 0x1c, 0x00 }, // 29 )
|
||||
{ 0x14, 0x08, 0x3e, 0x08, 0x14 }, // 2a *
|
||||
{ 0x08, 0x08, 0x3e, 0x08, 0x08 }, // 2b +
|
||||
{ 0x00, 0x50, 0x30, 0x00, 0x00 }, // 2c ,
|
||||
{ 0x08, 0x08, 0x08, 0x08, 0x08 }, // 2d -
|
||||
{ 0x00, 0x60, 0x60, 0x00, 0x00 }, // 2e .
|
||||
{ 0x20, 0x10, 0x08, 0x04, 0x02 }, // 2f /
|
||||
{ 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 30 0
|
||||
{ 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 31 1
|
||||
{ 0x42, 0x61, 0x51, 0x49, 0x46 }, // 32 2
|
||||
{ 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 33 3
|
||||
{ 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 34 4
|
||||
{ 0x27, 0x45, 0x45, 0x45, 0x39 }, // 35 5
|
||||
{ 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 36 6
|
||||
{ 0x01, 0x71, 0x09, 0x05, 0x03 }, // 37 7
|
||||
{ 0x36, 0x49, 0x49, 0x49, 0x36 }, // 38 8
|
||||
{ 0x06, 0x49, 0x49, 0x29, 0x1e }, // 39 9
|
||||
{ 0x00, 0x36, 0x36, 0x00, 0x00 }, // 3a :
|
||||
{ 0x00, 0x56, 0x36, 0x00, 0x00 }, // 3b ;
|
||||
{ 0x08, 0x14, 0x22, 0x41, 0x00 }, // 3c <
|
||||
{ 0x14, 0x14, 0x14, 0x14, 0x14 }, // 3d =
|
||||
{ 0x00, 0x41, 0x22, 0x14, 0x08 }, // 3e >
|
||||
{ 0x02, 0x01, 0x51, 0x09, 0x06 }, // 3f ?
|
||||
{ 0x32, 0x49, 0x79, 0x41, 0x3e }, // 40 @
|
||||
{ 0x7e, 0x11, 0x11, 0x11, 0x7e }, // 41 A
|
||||
{ 0x7f, 0x49, 0x49, 0x49, 0x36 }, // 42 B
|
||||
{ 0x3e, 0x41, 0x41, 0x41, 0x22 }, // 43 C
|
||||
{ 0x7f, 0x41, 0x41, 0x22, 0x1c }, // 44 D
|
||||
{ 0x7f, 0x49, 0x49, 0x49, 0x41 }, // 45 E
|
||||
{ 0x7f, 0x09, 0x09, 0x09, 0x01 }, // 46 F
|
||||
{ 0x3e, 0x41, 0x49, 0x49, 0x7a }, // 47 G
|
||||
{ 0x7f, 0x08, 0x08, 0x08, 0x7f }, // 48 H
|
||||
{ 0x00, 0x41, 0x7f, 0x41, 0x00 }, // 49 I
|
||||
{ 0x20, 0x40, 0x41, 0x3f, 0x01 }, // 4a J
|
||||
{ 0x7f, 0x08, 0x14, 0x22, 0x41 }, // 4b K
|
||||
{ 0x7f, 0x40, 0x40, 0x40, 0x40 }, // 4c L
|
||||
{ 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // 4d M
|
||||
{ 0x7f, 0x04, 0x08, 0x10, 0x7f }, // 4e N
|
||||
{ 0x3e, 0x41, 0x41, 0x41, 0x3e }, // 4f O
|
||||
{ 0x7f, 0x09, 0x09, 0x09, 0x06 }, // 50 P
|
||||
{ 0x3e, 0x41, 0x51, 0x21, 0x5e }, // 51 Q
|
||||
{ 0x7f, 0x09, 0x19, 0x29, 0x46 }, // 52 R
|
||||
{ 0x46, 0x49, 0x49, 0x49, 0x31 }, // 53 S
|
||||
{ 0x01, 0x01, 0x7f, 0x01, 0x01 }, // 54 T
|
||||
{ 0x3f, 0x40, 0x40, 0x40, 0x3f }, // 55 U
|
||||
{ 0x1f, 0x20, 0x40, 0x20, 0x1f }, // 56 V
|
||||
{ 0x3f, 0x40, 0x38, 0x40, 0x3f }, // 57 W
|
||||
{ 0x63, 0x14, 0x08, 0x14, 0x63 }, // 58 X
|
||||
{ 0x07, 0x08, 0x70, 0x08, 0x07 }, // 59 Y
|
||||
{ 0x61, 0x51, 0x49, 0x45, 0x43 }, // 5a Z
|
||||
{ 0x00, 0x7f, 0x41, 0x41, 0x00 }, // 5b [
|
||||
{ 0x02, 0x04, 0x08, 0x10, 0x20 }, // 5c backslash
|
||||
{ 0x00, 0x41, 0x41, 0x7f, 0x00 }, // 5d ]
|
||||
{ 0x04, 0x02, 0x01, 0x02, 0x04 }, // 5e ^
|
||||
{ 0x40, 0x40, 0x40, 0x40, 0x40 }, // 5f _
|
||||
{ 0x00, 0x01, 0x02, 0x04, 0x00 }, // 60 `
|
||||
{ 0x20, 0x54, 0x54, 0x54, 0x78 }, // 61 a
|
||||
{ 0x7f, 0x48, 0x44, 0x44, 0x38 }, // 62 b
|
||||
{ 0x38, 0x44, 0x44, 0x44, 0x20 }, // 63 c
|
||||
{ 0x38, 0x44, 0x44, 0x48, 0x7f }, // 64 d
|
||||
{ 0x38, 0x54, 0x54, 0x54, 0x18 }, // 65 e
|
||||
{ 0x08, 0x7e, 0x09, 0x01, 0x02 }, // 66 f
|
||||
{ 0x0c, 0x52, 0x52, 0x52, 0x3e }, // 67 g
|
||||
{ 0x7f, 0x08, 0x04, 0x04, 0x78 }, // 68 h
|
||||
{ 0x00, 0x44, 0x7d, 0x40, 0x00 }, // 69 i
|
||||
{ 0x20, 0x40, 0x44, 0x3d, 0x00 }, // 6a j
|
||||
{ 0x7f, 0x10, 0x28, 0x44, 0x00 }, // 6b k
|
||||
{ 0x00, 0x41, 0x7f, 0x40, 0x00 }, // 6c l
|
||||
{ 0x7c, 0x04, 0x18, 0x04, 0x78 }, // 6d m
|
||||
{ 0x7c, 0x08, 0x04, 0x04, 0x78 }, // 6e n
|
||||
{ 0x38, 0x44, 0x44, 0x44, 0x38 }, // 6f o
|
||||
{ 0x7c, 0x14, 0x14, 0x14, 0x08 }, // 70 p
|
||||
{ 0x08, 0x14, 0x14, 0x14, 0x7c }, // 71 q
|
||||
{ 0x7c, 0x08, 0x04, 0x04, 0x08 }, // 72 r
|
||||
{ 0x48, 0x54, 0x54, 0x54, 0x20 }, // 73 s
|
||||
{ 0x04, 0x3f, 0x44, 0x40, 0x20 }, // 74 t
|
||||
{ 0x3c, 0x40, 0x40, 0x20, 0x7c }, // 75 u
|
||||
{ 0x1c, 0x20, 0x40, 0x20, 0x1c }, // 76 v
|
||||
{ 0x3c, 0x40, 0x30, 0x40, 0x3c }, // 77 w
|
||||
{ 0x44, 0x28, 0x10, 0x28, 0x44 }, // 78 x
|
||||
{ 0x0c, 0x50, 0x50, 0x50, 0x3c }, // 79 y
|
||||
{ 0x44, 0x64, 0x54, 0x4c, 0x44 }, // 7a z
|
||||
{ 0x00, 0x08, 0x36, 0x41, 0x00 }, // 7b {
|
||||
{ 0x00, 0x00, 0x7f, 0x00, 0x00 }, // 7c |
|
||||
{ 0x00, 0x41, 0x36, 0x08, 0x00 }, // 7d }
|
||||
{ 0x10, 0x08, 0x08, 0x10, 0x08 }, // 7e ~
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 } // 7f
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* ---------------------------------------------------------------+
|
||||
* @desc FONTs
|
||||
* ---------------------------------------------------------------+
|
||||
* Copyright (C) 2020 Marian Hrinko.
|
||||
* Written by Marian Hrinko (mato.hrinko@gmail.com)
|
||||
*
|
||||
* @author Marian Hrinko
|
||||
* @datum 07.10.2020
|
||||
* @file font.h
|
||||
* @tested AVR Atmega16
|
||||
*
|
||||
* @depend
|
||||
* ---------------------------------------------------------------+
|
||||
*/
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#ifndef __FONT_H__
|
||||
#define __FONT_H__
|
||||
|
||||
// Characters definition
|
||||
// -----------------------------------
|
||||
// number of columns for chars
|
||||
#define CHARS_COLS_LENGTH 5
|
||||
// @const Characters
|
||||
extern const uint8_t FONTS[][CHARS_COLS_LENGTH];
|
||||
|
||||
#endif
|
18
src/gympal.c
18
src/gympal.c
|
@ -2,22 +2,16 @@
|
|||
#include <util/delay.h>
|
||||
|
||||
#include "control.h"
|
||||
#include "display.h"
|
||||
|
||||
int main() {
|
||||
display_init();
|
||||
ctl_init();
|
||||
// Just for testing the interrupts, we're setting up B4 as an indicator LED.
|
||||
DDRB |= 1 << PORTB4;
|
||||
PORTB &= ~(1 << PORTB4);
|
||||
uint8_t led = 0;
|
||||
while(1) {
|
||||
uint8_t v = ctl_isButtonAPressed();
|
||||
if (led != v) {
|
||||
led = v;
|
||||
if (led) {
|
||||
PORTB |= 1 << PORTB4;
|
||||
while (1) {
|
||||
if (ctl_isButtonAPressed()) {
|
||||
display_show_str("button A");
|
||||
} else {
|
||||
PORTB &= ~(1 << PORTB4);
|
||||
}
|
||||
display_show_str("Not button A");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,817 @@
|
|||
/**
|
||||
* --------------------------------------------------------------------------------------------+
|
||||
* @name ST773 1.8" LCD Driver
|
||||
* --------------------------------------------------------------------------------------------+
|
||||
* Copyright (C) 2020 Marian Hrinko.
|
||||
* Written by Marian Hrinko (mato.hrinko@gmail.com)
|
||||
*
|
||||
* @author Marian Hrinko
|
||||
* @datum 13.10.2020
|
||||
* @update 01.07.2021
|
||||
* @file st7735.c
|
||||
* @version 2.0
|
||||
* @tested AVR Atmega328
|
||||
*
|
||||
* @depend font.h
|
||||
* --------------------------------------------------------------------------------------------+
|
||||
* @descr Version 1.0 -> applicable for 1 display
|
||||
* Version 2.0 -> applicable for more than 1 display
|
||||
* --------------------------------------------------------------------------------------------+
|
||||
* @inspir http://www.displayfuture.com/Display/datasheet/controller/ST7735.pdf
|
||||
* https://github.com/adafruit/Adafruit-ST7735-Library
|
||||
* http://w8bh.net/avr/AvrTFT.pdf
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
#include "font.h"
|
||||
#include "st7735.h"
|
||||
|
||||
/** @array Init command */
|
||||
const uint8_t INIT_ST7735B[] PROGMEM = {
|
||||
// number of initializers
|
||||
5,
|
||||
// ---------------------------------------
|
||||
// Software reset - no arguments, delay
|
||||
0, 150, SWRESET,
|
||||
// Out of sleep mode, no arguments, delay
|
||||
0, 200, SLPOUT,
|
||||
// Set color mode, 1 argument delay
|
||||
1, 10, COLMOD, 0x05,
|
||||
// D7 D6 D5 D4 D3 D2 D1 D0
|
||||
// MY MX MV ML RGB MH - -
|
||||
// ------------------------------
|
||||
// ------------------------------
|
||||
// MV MX MY -> {MV (row / column exchange) MX (column address order), MY (row address order)}
|
||||
// ------------------------------
|
||||
// 0 0 0 -> begin left-up corner, end right-down corner
|
||||
// left-right (normal view)
|
||||
// 0 0 1 -> begin left-down corner, end right-up corner
|
||||
// left-right (Y-mirror)
|
||||
// 0 1 0 -> begin right-up corner, end left-down corner
|
||||
// right-left (X-mirror)
|
||||
// 0 1 1 -> begin right-down corner, end left-up corner
|
||||
// right-left (X-mirror, Y-mirror)
|
||||
// 1 0 0 -> begin left-up corner, end right-down corner
|
||||
// up-down (X-Y exchange)
|
||||
// 1 0 1 -> begin left-down corner, end right-up corner
|
||||
// down-up (X-Y exchange, Y-mirror)
|
||||
// 1 1 0 -> begin right-up corner, end left-down corner
|
||||
// up-down (X-Y exchange, X-mirror)
|
||||
// 1 1 1 -> begin right-down corner, end left-up corner
|
||||
// down-up (X-Y exchange, X-mirror, Y-mirror)
|
||||
// ------------------------------
|
||||
// ML: vertical refresh order
|
||||
// 0 -> refresh top to bottom
|
||||
// 1 -> refresh bottom to top
|
||||
// ------------------------------
|
||||
// RGB: filter panel
|
||||
// 0 -> RGB
|
||||
// 1 -> BGR
|
||||
// ------------------------------
|
||||
// MH: horizontal refresh order
|
||||
// 0 -> refresh left to right
|
||||
// 1 -> refresh right to left
|
||||
// 0xA0 = 1010 0000
|
||||
1, 0, MADCTL, 0xA0,
|
||||
// Main screen turn on
|
||||
0, 200, DISPON
|
||||
// ---------------------------------------
|
||||
};
|
||||
|
||||
/** @var array Chache memory char index row */
|
||||
unsigned short int cacheMemIndexRow = 0;
|
||||
/** @var array Chache memory char index column */
|
||||
unsigned short int cacheMemIndexCol = 0;
|
||||
|
||||
/**
|
||||
* @desc Hardware Reset
|
||||
*
|
||||
* @param struct signal *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_Reset (struct signal * reset)
|
||||
{
|
||||
// Actiavte pull-up resistor logical high on pin RST
|
||||
// posible write: SET_BIT (*(*reset).port, reset->pin)
|
||||
SET_BIT (*(reset->port), reset->pin);
|
||||
// DDR as output
|
||||
SET_BIT (*(reset->ddr), reset->pin);
|
||||
// delay 200 ms
|
||||
_delay_ms(200);
|
||||
// Reset Low
|
||||
CLR_BIT (*(reset->port), reset->pin);
|
||||
// delay 200 ms
|
||||
_delay_ms(200);
|
||||
// Reset High
|
||||
SET_BIT (*(reset->port), reset->pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Init SPI
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_SPI_Init (void)
|
||||
{
|
||||
// Output: SCK, MOSI
|
||||
SET_BIT (DDR, ST7735_SCK);
|
||||
SET_BIT (DDR, ST7735_MOSI);
|
||||
/*
|
||||
// Input: MISO with pullup
|
||||
CLR_BIT (DDR, ST7735_MOSI);
|
||||
PORT_BIT (PORT, ST7735_MOSI);
|
||||
*/
|
||||
// SPE - SPI Enale
|
||||
// MSTR - Master device
|
||||
SET_BIT (SPCR, SPE);
|
||||
SET_BIT (SPCR, MSTR);
|
||||
// SPI2X - Prescaler fclk/2 = 8MHz
|
||||
SET_BIT (SPSR, SPI2X);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Init Pins
|
||||
*
|
||||
* @param struct st7735 *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_Pins_Init (struct st7735 * lcd)
|
||||
{
|
||||
// DDR
|
||||
// --------------------------------------
|
||||
SET_BIT (*(lcd->cs->ddr), lcd->cs->pin);
|
||||
SET_BIT (*(lcd->bl->ddr), lcd->bl->pin);
|
||||
SET_BIT (*(lcd->dc->ddr), lcd->dc->pin);
|
||||
// PORT
|
||||
// --------------------------------------
|
||||
SET_BIT (*(lcd->cs->port), lcd->cs->pin); // Chip Select H
|
||||
SET_BIT (*(lcd->bl->port), lcd->bl->pin); // BackLigt ON
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Init st7735 driver
|
||||
*
|
||||
* @param struct st7735 *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_Init (struct st7735 * lcd)
|
||||
{
|
||||
// init pins
|
||||
ST7735_Pins_Init (lcd);
|
||||
// init SPI
|
||||
ST7735_SPI_Init ();
|
||||
// hardware reset
|
||||
ST7735_Reset (lcd->rs);
|
||||
// load list of commands
|
||||
ST7735_Commands (lcd, INIT_ST7735B);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Send list commands
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param const uint8_t *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_Commands (struct st7735 * lcd, const uint8_t * initializers)
|
||||
{
|
||||
uint8_t args;
|
||||
uint8_t cmnd;
|
||||
uint8_t time;
|
||||
uint8_t loop = pgm_read_byte (initializers++);
|
||||
|
||||
// loop through whole initializer list
|
||||
while (loop--) {
|
||||
|
||||
// 1st arg - number of command arguments
|
||||
args = pgm_read_byte (initializers++);
|
||||
// 2nd arg - delay time
|
||||
time = pgm_read_byte (initializers++);
|
||||
// 3th arg - command
|
||||
cmnd = pgm_read_byte (initializers++);
|
||||
|
||||
// send command
|
||||
ST7735_CommandSend (lcd, cmnd);
|
||||
// send arguments
|
||||
while (args--) {
|
||||
// send argument
|
||||
ST7735_Data8BitsSend (lcd, pgm_read_byte (initializers++));
|
||||
}
|
||||
// delay
|
||||
ST7735_DelayMs (time);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Command send
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
uint8_t ST7735_CommandSend (struct st7735 * lcd, uint8_t data)
|
||||
{
|
||||
// chip enable - active low
|
||||
CLR_BIT (*(lcd->cs->port), lcd->cs->pin);
|
||||
// command (active low)
|
||||
CLR_BIT (*(lcd->dc->port), lcd->dc->pin);
|
||||
// transmitting data
|
||||
SPDR = data;
|
||||
// wait till data transmit
|
||||
WAIT_UNTIL_BIT_IS_SET (SPSR, SPIF);
|
||||
// chip disable - idle high
|
||||
SET_BIT (*(lcd->cs->port), lcd->cs->pin);
|
||||
// return received data
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 8bits data send
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
uint8_t ST7735_Data8BitsSend (struct st7735 * lcd, uint8_t data)
|
||||
{
|
||||
// chip enable - active low
|
||||
CLR_BIT (*(lcd->cs->port), lcd->cs->pin);
|
||||
// data (active high)
|
||||
SET_BIT (*(lcd->dc->port), lcd->dc->pin);
|
||||
// transmitting data
|
||||
SPDR = data;
|
||||
// wait till data transmit
|
||||
WAIT_UNTIL_BIT_IS_SET (SPSR, SPIF);
|
||||
// chip disable - idle high
|
||||
SET_BIT (*(lcd->cs->port), lcd->cs->pin);
|
||||
// return received data
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 16bits data send
|
||||
*
|
||||
* @param struct st7735 * lcd
|
||||
* @param uint16_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
uint8_t ST7735_Data16BitsSend (struct st7735 * lcd, uint16_t data)
|
||||
{
|
||||
// chip enable - active low
|
||||
CLR_BIT (*(lcd->cs->port), lcd->cs->pin);
|
||||
// data (active high)
|
||||
SET_BIT (*(lcd->dc->port), lcd->dc->pin);
|
||||
// transmitting data high byte
|
||||
SPDR = (uint8_t) (data >> 8);
|
||||
// wait till high byte transmit
|
||||
WAIT_UNTIL_BIT_IS_SET (SPSR, SPIF);
|
||||
// transmitting data low byte
|
||||
SPDR = (uint8_t) (data);
|
||||
// wait till low byte transmit
|
||||
WAIT_UNTIL_BIT_IS_SET (SPSR, SPIF);
|
||||
// chip disable - idle high
|
||||
SET_BIT (*(lcd->cs->port), lcd->cs->pin);
|
||||
// return received data
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Set window
|
||||
*
|
||||
* @param struct st7735 * lcd
|
||||
* @param uint8_t x - start position
|
||||
* @param uint8_t x - end position
|
||||
* @param uint8_t y - start position
|
||||
* @param uint8_t y - end position
|
||||
*
|
||||
* @return uint8_t
|
||||
*/
|
||||
uint8_t ST7735_SetWindow (struct st7735 * lcd, uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1)
|
||||
{
|
||||
// check if coordinates is out of range
|
||||
if ((x0 > x1) ||
|
||||
(x1 > SIZE_X) ||
|
||||
(y0 > y1) ||
|
||||
(y1 > SIZE_Y)) {
|
||||
// out of range
|
||||
return ST7735_ERROR;
|
||||
}
|
||||
// column address set
|
||||
ST7735_CommandSend (lcd, CASET);
|
||||
// send start x position
|
||||
ST7735_Data16BitsSend (lcd, 0x0000 | x0);
|
||||
// send end x position
|
||||
ST7735_Data16BitsSend (lcd, 0x0000 | x1);
|
||||
|
||||
// row address set
|
||||
ST7735_CommandSend (lcd, RASET);
|
||||
// send start y position
|
||||
ST7735_Data16BitsSend (lcd, 0x0000 | y0);
|
||||
// send end y position
|
||||
ST7735_Data16BitsSend (lcd, 0x0000 | y1);
|
||||
|
||||
// success
|
||||
return ST7735_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Write color pixels
|
||||
*
|
||||
* @param struct st7735 * lcd
|
||||
* @param uint16_t color
|
||||
* @param uint16_t counter
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_SendColor565 (struct st7735 * lcd, uint16_t color, uint16_t count)
|
||||
{
|
||||
// access to RAM
|
||||
ST7735_CommandSend (lcd, RAMWR);
|
||||
// counter
|
||||
while (count--) {
|
||||
// write color
|
||||
ST7735_Data16BitsSend (lcd, color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Draw pixel
|
||||
*
|
||||
* @param struct st7735 * lcd
|
||||
* @param uint8_t x position / 0 <= cols <= MAX_X-1
|
||||
* @param uint8_t y position / 0 <= rows <= MAX_Y-1
|
||||
* @param uint16_t color
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawPixel (struct st7735 * lcd, uint8_t x, uint8_t y, uint16_t color)
|
||||
{
|
||||
// set window
|
||||
ST7735_SetWindow (lcd, x, x, y, y);
|
||||
// draw pixel by 565 mode
|
||||
ST7735_SendColor565 (lcd, color, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc RAM Content Show
|
||||
*
|
||||
* @param struct st7735 * lcd
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_RAM_Content_Show (struct st7735 * lcd)
|
||||
{
|
||||
// display content on
|
||||
ST7735_CommandSend (lcd, DISPON);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc RAM Content Hide
|
||||
*
|
||||
* @param struct st7735 * lcd
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_RAM_Content_Hide (struct st7735 * lcd)
|
||||
{
|
||||
// display content off
|
||||
ST7735_CommandSend (lcd, DISPOFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Clear screen
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint16_t color
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_ClearScreen (struct st7735 * lcd, uint16_t color)
|
||||
{
|
||||
// set whole window
|
||||
ST7735_SetWindow (lcd, 0, SIZE_X, 0, SIZE_Y);
|
||||
// draw individual pixels
|
||||
ST7735_SendColor565 (lcd, color, CACHE_SIZE_MEM);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Draw character
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param char character
|
||||
* @param uint16_t color
|
||||
* @param enum Size (X1, X2, X3)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
char ST7735_DrawChar (struct st7735 * lcd, char character, uint16_t color, enum Size size)
|
||||
{
|
||||
// variables
|
||||
uint8_t letter, idxCol, idxRow;
|
||||
// check if character is out of range
|
||||
if ((character < 0x20) &&
|
||||
(character > 0x7f)) {
|
||||
// out of range
|
||||
return 0;
|
||||
}
|
||||
// last column of character array - 5 columns
|
||||
idxCol = CHARS_COLS_LEN;
|
||||
// last row of character array - 8 rows / bits
|
||||
idxRow = CHARS_ROWS_LEN;
|
||||
|
||||
// --------------------------------------
|
||||
// SIZE X1 - normal font 1x high, 1x wide
|
||||
// --------------------------------------
|
||||
if (size == X1) {
|
||||
// loop through 5 bits
|
||||
while (idxCol--) {
|
||||
// read from ROM memory
|
||||
letter = pgm_read_byte (&FONTS[character - 32][idxCol]);
|
||||
// loop through 8 bits
|
||||
while (idxRow--) {
|
||||
// check if bit set
|
||||
if (letter & (1 << idxRow)) {
|
||||
// draw pixel
|
||||
ST7735_DrawPixel (lcd, cacheMemIndexCol + idxCol, cacheMemIndexRow + idxRow, color);
|
||||
}
|
||||
}
|
||||
// fill index row again
|
||||
idxRow = CHARS_ROWS_LEN;
|
||||
}
|
||||
// update x position
|
||||
cacheMemIndexCol = cacheMemIndexCol + CHARS_COLS_LEN + 1;
|
||||
|
||||
// --------------------------------------
|
||||
// SIZE X2 - font 2x higher, normal wide
|
||||
// --------------------------------------
|
||||
} else if (size == X2) {
|
||||
// loop through 5 bytes
|
||||
while (idxCol--) {
|
||||
// read from ROM memory
|
||||
letter = pgm_read_byte (&FONTS[character - 32][idxCol]);
|
||||
// loop through 8 bits
|
||||
while (idxRow--) {
|
||||
// check if bit set
|
||||
if (letter & (1 << idxRow)) {
|
||||
// draw first left up pixel;
|
||||
// (idxRow << 1) - 2x multiplied
|
||||
ST7735_DrawPixel (lcd, cacheMemIndexCol + idxCol, cacheMemIndexRow + (idxRow << 1), color);
|
||||
// draw second left down pixel
|
||||
ST7735_DrawPixel (lcd, cacheMemIndexCol + idxCol, cacheMemIndexRow + (idxRow << 1) + 1, color);
|
||||
}
|
||||
}
|
||||
// fill index row again
|
||||
idxRow = CHARS_ROWS_LEN;
|
||||
}
|
||||
// update x position
|
||||
cacheMemIndexCol = cacheMemIndexCol + CHARS_COLS_LEN + 1;
|
||||
|
||||
// --------------------------------------
|
||||
// SIZE X3 - font 2x higher, 2x wider
|
||||
// --------------------------------------
|
||||
} else if (size == X3) {
|
||||
// loop through 5 bytes
|
||||
while (idxCol--) {
|
||||
// read from ROM memory
|
||||
letter = pgm_read_byte (&FONTS[character - 32][idxCol]);
|
||||
// loop through 8 bits
|
||||
while (idxRow--) {
|
||||
// check if bit set
|
||||
if (letter & (1 << idxRow)) {
|
||||
// draw first left up pixel;
|
||||
// (idxRow << 1) - 2x multiplied
|
||||
ST7735_DrawPixel (lcd, cacheMemIndexCol + (idxCol << 1), cacheMemIndexRow + (idxRow << 1), color);
|
||||
// draw second left down pixel
|
||||
ST7735_DrawPixel (lcd, cacheMemIndexCol + (idxCol << 1), cacheMemIndexRow + (idxRow << 1) + 1, color);
|
||||
// draw third right up pixel
|
||||
ST7735_DrawPixel (lcd, cacheMemIndexCol + (idxCol << 1) + 1, cacheMemIndexRow + (idxRow << 1), color);
|
||||
// draw fourth right down pixel
|
||||
ST7735_DrawPixel (lcd, cacheMemIndexCol + (idxCol << 1) + 1, cacheMemIndexRow + (idxRow << 1) + 1, color);
|
||||
}
|
||||
}
|
||||
// fill index row again
|
||||
idxRow = CHARS_ROWS_LEN;
|
||||
}
|
||||
|
||||
// update x position
|
||||
cacheMemIndexCol = cacheMemIndexCol + CHARS_COLS_LEN + CHARS_COLS_LEN + 1;
|
||||
}
|
||||
|
||||
// return exit
|
||||
return ST7735_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Set text position x, y
|
||||
*
|
||||
* @param uint8_t x - position
|
||||
* @param uint8_t y - position
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
char ST7735_SetPosition (uint8_t x, uint8_t y)
|
||||
{
|
||||
// check if coordinates is out of range
|
||||
if ((x > MAX_X) && (y > MAX_Y)) {
|
||||
// error
|
||||
return ST7735_ERROR;
|
||||
|
||||
} else if ((x > MAX_X) && (y <= MAX_Y)) {
|
||||
// set position y
|
||||
cacheMemIndexRow = y;
|
||||
// set position x
|
||||
cacheMemIndexCol = 2;
|
||||
} else {
|
||||
// set position y
|
||||
cacheMemIndexRow = y;
|
||||
// set position x
|
||||
cacheMemIndexCol = x;
|
||||
}
|
||||
// success
|
||||
return ST7735_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Check text position x, y
|
||||
*
|
||||
* @param unsigned char x - position
|
||||
* @param unsigned char y - position
|
||||
* @param unsigned char
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
char ST7735_CheckPosition (unsigned char x, unsigned char y, unsigned char max_y, enum Size size)
|
||||
{
|
||||
// check if coordinates is out of range
|
||||
if ((x > MAX_X) && (y > max_y)) {
|
||||
// out of range
|
||||
return ST7735_ERROR;
|
||||
|
||||
}
|
||||
// if next line
|
||||
if ((x > MAX_X) && (y <= max_y)) {
|
||||
// set position y
|
||||
cacheMemIndexRow = y;
|
||||
// set position x
|
||||
cacheMemIndexCol = 2;
|
||||
}
|
||||
|
||||
// success
|
||||
return ST7735_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Draw string
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param char * string
|
||||
* @param uint16_t color
|
||||
* @param enum Size (X1, X2, X3)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawString (struct st7735 * lcd, char *str, uint16_t color, enum Size size)
|
||||
{
|
||||
// variables
|
||||
unsigned int i = 0;
|
||||
unsigned char check;
|
||||
unsigned char delta_y;
|
||||
unsigned char max_y_pos;
|
||||
unsigned char new_x_pos;
|
||||
unsigned char new_y_pos;
|
||||
|
||||
// loop through character of string
|
||||
while (str[i] != '\0') {
|
||||
// max x position character
|
||||
new_x_pos = cacheMemIndexCol + CHARS_COLS_LEN + (size & 0x0F);
|
||||
// delta y
|
||||
delta_y = CHARS_ROWS_LEN + (size >> 4);
|
||||
// max y position character
|
||||
new_y_pos = cacheMemIndexRow + delta_y;
|
||||
// max y pos
|
||||
max_y_pos = MAX_Y - delta_y;
|
||||
// control if will be in range
|
||||
check = ST7735_CheckPosition (new_x_pos, new_y_pos, max_y_pos, size);
|
||||
// update position
|
||||
if (ST7735_SUCCESS == check) {
|
||||
// read characters and increment index
|
||||
ST7735_DrawChar (lcd, str[i++], color, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Draw line by Bresenham algoritm
|
||||
* @surce https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t x start position / 0 <= cols <= MAX_X-1
|
||||
* @param uint8_t x end position / 0 <= cols <= MAX_X-1
|
||||
* @param uint8_t y start position / 0 <= rows <= MAX_Y-1
|
||||
* @param uint8_t y end position / 0 <= rows <= MAX_Y-1
|
||||
* @param uint16_t color
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
char ST7735_DrawLine (struct st7735 * lcd, uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2, uint16_t color)
|
||||
{
|
||||
// determinant
|
||||
int16_t D;
|
||||
// deltas
|
||||
int16_t delta_x, delta_y;
|
||||
// steps
|
||||
int16_t trace_x = 1, trace_y = 1;
|
||||
|
||||
// delta x
|
||||
delta_x = x2 - x1;
|
||||
// delta y
|
||||
delta_y = y2 - y1;
|
||||
|
||||
// check if x2 > x1
|
||||
if (delta_x < 0) {
|
||||
// negate delta x
|
||||
delta_x = -delta_x;
|
||||
// negate step x
|
||||
trace_x = -trace_x;
|
||||
}
|
||||
|
||||
// check if y2 > y1
|
||||
if (delta_y < 0) {
|
||||
// negate detla y
|
||||
delta_y = -delta_y;
|
||||
// negate step y
|
||||
trace_y = -trace_y;
|
||||
}
|
||||
|
||||
// Bresenham condition for m < 1 (dy < dx)
|
||||
if (delta_y < delta_x) {
|
||||
// calculate determinant
|
||||
D = (delta_y << 1) - delta_x;
|
||||
// draw first pixel
|
||||
ST7735_DrawPixel (lcd, x1, y1, color);
|
||||
// check if x1 equal x2
|
||||
while (x1 != x2) {
|
||||
// update x1
|
||||
x1 += trace_x;
|
||||
// check if determinant is positive
|
||||
if (D >= 0) {
|
||||
// update y1
|
||||
y1 += trace_y;
|
||||
// update determinant
|
||||
D -= 2*delta_x;
|
||||
}
|
||||
// update deteminant
|
||||
D += 2*delta_y;
|
||||
// draw next pixel
|
||||
ST7735_DrawPixel (lcd, x1, y1, color);
|
||||
}
|
||||
// for m > 1 (dy > dx)
|
||||
} else {
|
||||
// calculate determinant
|
||||
D = delta_y - (delta_x << 1);
|
||||
// draw first pixel
|
||||
ST7735_DrawPixel (lcd, x1, y1, color);
|
||||
// check if y2 equal y1
|
||||
while (y1 != y2) {
|
||||
// update y1
|
||||
y1 += trace_y;
|
||||
// check if determinant is positive
|
||||
if (D <= 0) {
|
||||
// update y1
|
||||
x1 += trace_x;
|
||||
// update determinant
|
||||
D += 2*delta_y;
|
||||
}
|
||||
// update deteminant
|
||||
D -= 2*delta_x;
|
||||
// draw next pixel
|
||||
ST7735_DrawPixel (lcd, x1, y1, color);
|
||||
}
|
||||
}
|
||||
// success return
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Fast draw line horizontal
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t xs - start position
|
||||
* @param uint8_t xe - end position
|
||||
* @param uint8_t y - position
|
||||
* @param uint16_t color
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawLineHorizontal (struct st7735 * lcd, uint8_t xs, uint8_t xe, uint8_t y, uint16_t color)
|
||||
{
|
||||
uint8_t temp;
|
||||
// check if start is > as end
|
||||
if (xs > xe) {
|
||||
// temporary safe
|
||||
temp = xs;
|
||||
// start change for end
|
||||
xe = xs;
|
||||
// end change for start
|
||||
xs = temp;
|
||||
}
|
||||
// set window
|
||||
ST7735_SetWindow (lcd, xs, xe, y, y);
|
||||
// draw pixel by 565 mode
|
||||
ST7735_SendColor565 (lcd, color, xe - xs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Fast draw line vertical
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t x - position
|
||||
* @param uint8_t ys - start position
|
||||
* @param uint8_t ye - end position
|
||||
* @param uint16_t color
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawLineVertical (struct st7735 * lcd, uint8_t x, uint8_t ys, uint8_t ye, uint16_t color)
|
||||
{
|
||||
uint8_t temp;
|
||||
// check if start is > as end
|
||||
if (ys > ye) {
|
||||
// temporary safe
|
||||
temp = ys;
|
||||
// start change for end
|
||||
ye = ys;
|
||||
// end change for start
|
||||
ys = temp;
|
||||
}
|
||||
// set window
|
||||
ST7735_SetWindow (lcd, x, x, ys, ye);
|
||||
// draw pixel by 565 mode
|
||||
ST7735_SendColor565 (lcd, color, ye - ys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Draw rectangle
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t x start position
|
||||
* @param uint8_t x end position
|
||||
* @param uint8_t y start position
|
||||
* @param uint8_t y end position
|
||||
* @param uint16_t color
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawRectangle (struct st7735 * lcd, uint8_t xs, uint8_t xe, uint8_t ys, uint8_t ye, uint16_t color)
|
||||
{
|
||||
uint8_t temp;
|
||||
// check if start is > as end
|
||||
if (xs > xe) {
|
||||
// temporary safe
|
||||
temp = xe;
|
||||
// start change for end
|
||||
xe = xs;
|
||||
// end change for start
|
||||
xs = temp;
|
||||
}
|
||||
// check if start is > as end
|
||||
if (ys > ye) {
|
||||
// temporary safe
|
||||
temp = ye;
|
||||
// start change for end
|
||||
ye = ys;
|
||||
// end change for start
|
||||
ys = temp;
|
||||
}
|
||||
// set window
|
||||
ST7735_SetWindow (lcd, xs, xe, ys, ye);
|
||||
// send color
|
||||
ST7735_SendColor565 (lcd, color, (xe-xs+1)*(ye-ys+1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Delay
|
||||
*
|
||||
* @param uint8_t time in milliseconds / max 256ms
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DelayMs (uint8_t time)
|
||||
{
|
||||
// loop through real time
|
||||
while (time--) {
|
||||
// 1 s delay
|
||||
_delay_ms(1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,423 @@
|
|||
/**
|
||||
* --------------------------------------------------------------------------------------------+
|
||||
* @name ST773 1.8" LCD Driver
|
||||
* --------------------------------------------------------------------------------------------+
|
||||
* Copyright (C) 2020 Marian Hrinko.
|
||||
* Written by Marian Hrinko (mato.hrinko@gmail.com)
|
||||
*
|
||||
* @author Marian Hrinko
|
||||
* @datum 13.10.2020
|
||||
* @update 01.07.2021
|
||||
* @file st7735.h
|
||||
* @version 2.0
|
||||
* @tested AVR Atmega328
|
||||
*
|
||||
* @depend font.h
|
||||
* --------------------------------------------------------------------------------------------+
|
||||
* @descr Version 1.0 -> applicable for 1 display
|
||||
* Version 2.0 -> applicable for more than 1 display
|
||||
* --------------------------------------------------------------------------------------------+
|
||||
* @inspir http://www.displayfuture.com/Display/datasheet/controller/ST7735.pdf
|
||||
* https://github.com/adafruit/Adafruit-ST7735-Library
|
||||
* http://w8bh.net/avr/AvrTFT.pdf
|
||||
*/
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#ifndef __ST7735_H__
|
||||
#define __ST7735_H__
|
||||
|
||||
// Success / Error
|
||||
// -----------------------------------
|
||||
#define ST7735_SUCCESS 0
|
||||
#define ST7735_ERROR 1
|
||||
|
||||
// PORT/PIN definition
|
||||
// -----------------------------------
|
||||
#define PORT PORTB
|
||||
#define DDR DDRB
|
||||
#define ST7735_MOSI 3 // SDA
|
||||
#define ST7735_MISO 4
|
||||
#define ST7735_SCK 5 // SCL
|
||||
|
||||
// Command definition
|
||||
// -----------------------------------
|
||||
#define DELAY 0x80
|
||||
|
||||
#define NOP 0x00
|
||||
#define SWRESET 0x01
|
||||
#define RDDID 0x04
|
||||
#define RDDST 0x09
|
||||
|
||||
#define SLPIN 0x10
|
||||
#define SLPOUT 0x11
|
||||
#define PTLON 0x12
|
||||
#define NORON 0x13
|
||||
|
||||
#define INVOFF 0x20
|
||||
#define INVON 0x21
|
||||
#define DISPOFF 0x28
|
||||
#define DISPON 0x29
|
||||
#define RAMRD 0x2E
|
||||
#define CASET 0x2A
|
||||
#define RASET 0x2B
|
||||
#define RAMWR 0x2C
|
||||
|
||||
#define PTLAR 0x30
|
||||
#define MADCTL 0x36
|
||||
#define COLMOD 0x3A
|
||||
|
||||
#define FRMCTR1 0xB1
|
||||
#define FRMCTR2 0xB2
|
||||
#define FRMCTR3 0xB3
|
||||
#define INVCTR 0xB4
|
||||
#define DISSET5 0xB6
|
||||
|
||||
#define PWCTR1 0xC0
|
||||
#define PWCTR2 0xC1
|
||||
#define PWCTR3 0xC2
|
||||
#define PWCTR4 0xC3
|
||||
#define PWCTR5 0xC4
|
||||
#define VMCTR1 0xC5
|
||||
|
||||
#define RDID1 0xDA
|
||||
#define RDID2 0xDB
|
||||
#define RDID3 0xDC
|
||||
#define RDID4 0xDD
|
||||
|
||||
#define GMCTRP1 0xE0
|
||||
#define GMCTRN1 0xE1
|
||||
|
||||
#define PWCTR6 0xFC
|
||||
|
||||
// Colors
|
||||
// -----------------------------------
|
||||
#define BLACK 0x0000
|
||||
#define WHITE 0xFFFF
|
||||
#define RED 0xF000
|
||||
#define GREEN 0x0F00
|
||||
#define BLUE 0x00F0
|
||||
|
||||
// AREA definition
|
||||
// -----------------------------------
|
||||
#define MAX_X 161 // max columns / MV = 0 in MADCTL
|
||||
#define MAX_Y 130 // max rows / MV = 0 in MADCTL
|
||||
#define SIZE_X MAX_X - 1 // columns max counter
|
||||
#define SIZE_Y MAX_Y - 1 // rows max counter
|
||||
#define CACHE_SIZE_MEM (MAX_X * MAX_Y) // whole pixels
|
||||
#define CHARS_COLS_LEN 5 // number of columns for chars
|
||||
#define CHARS_ROWS_LEN 8 // number of rows for chars
|
||||
|
||||
|
||||
// FUNCTION macros
|
||||
// -----------------------------------
|
||||
// clear bit
|
||||
#define CLR_BIT(port, bit) ( ((port) &= ~(1 << (bit))) )
|
||||
// set bit
|
||||
#define SET_BIT(port, bit) ( ((port) |= (1 << (bit))) )
|
||||
// bit is clear?
|
||||
#define IS_BIT_CLR(port, bit) ( IS_BIT_SET(port, bit) ? 0 : 1 )
|
||||
// bit is set?
|
||||
#define IS_BIT_SET(port, bit) ( ((port) & (1 << (bit))) ? 1 : 0 )
|
||||
// wait until bit is set
|
||||
#define WAIT_UNTIL_BIT_IS_SET(port, bit) { while (IS_BIT_CLR(port, bit)); }
|
||||
|
||||
/** @const Command list ST7735B */
|
||||
extern const uint8_t INIT_ST7735B[];
|
||||
/** @var array Chache memory char index row */
|
||||
unsigned short int cacheMemIndexRow;
|
||||
/** @var array Chache memory char index column */
|
||||
unsigned short int cacheMemIndexCol;
|
||||
|
||||
/** @enum Font sizes */
|
||||
enum Size {
|
||||
// 1x high & 1x wide size
|
||||
X1 = 0x00,
|
||||
// 2x high & 1x wide size
|
||||
X2 = 0x80,
|
||||
// 2x high & 2x wider size
|
||||
// 0x0A is set because need to offset 5 position to right
|
||||
// when draw the characters of string
|
||||
X3 = 0x81
|
||||
};
|
||||
|
||||
/** @struct Signal */
|
||||
struct signal {
|
||||
// ddr
|
||||
volatile uint8_t * ddr;
|
||||
// port
|
||||
volatile uint8_t * port;
|
||||
// pin
|
||||
uint8_t pin;
|
||||
};
|
||||
|
||||
/** @struct Lcd */
|
||||
struct st7735 {
|
||||
// Chip Select
|
||||
struct signal * cs;
|
||||
// Back Light
|
||||
struct signal * bl;
|
||||
// Data / Command
|
||||
struct signal * dc;
|
||||
// Reset
|
||||
struct signal * rs;
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc Init st7735 driver
|
||||
*
|
||||
* @param struct st7735 *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_Init (struct st7735 *);
|
||||
|
||||
/**
|
||||
* @desc Hardware Reset
|
||||
*
|
||||
* @param struct signal *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_Reset (struct signal *);
|
||||
|
||||
/**
|
||||
* @desc Init SPI
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_SPI_Init (void);
|
||||
|
||||
/**
|
||||
* @desc Init PINS
|
||||
*
|
||||
* @param struct st7735 *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_Pins_Init (struct st7735 *);
|
||||
|
||||
/**
|
||||
* @desc Send list commands
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param const uint8_t *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_Commands (struct st7735 *, const uint8_t *commands);
|
||||
|
||||
/**
|
||||
* @desc Command send
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
*
|
||||
* @return uint8_t
|
||||
*/
|
||||
uint8_t ST7735_CommandSend (struct st7735 *, uint8_t);
|
||||
|
||||
/**
|
||||
* @desc 8bits data send
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
*
|
||||
* @return uint8_t
|
||||
*/
|
||||
uint8_t ST7735_Data8BitsSend (struct st7735 *, uint8_t);
|
||||
|
||||
/**
|
||||
* @desc 16bits data send
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint16_t
|
||||
*
|
||||
* @return uint8_t
|
||||
*/
|
||||
uint8_t ST7735_Data16BitsSend (struct st7735 *, uint16_t);
|
||||
|
||||
/**
|
||||
* @desc Set window
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
*
|
||||
* @return uint8_t
|
||||
*/
|
||||
uint8_t ST7735_SetWindow (struct st7735 *, uint8_t, uint8_t, uint8_t, uint8_t);
|
||||
|
||||
/**
|
||||
* @desc Write color pixels
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint16_t
|
||||
* @param uint16_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_SendColor565 (struct st7735 *, uint16_t, uint16_t);
|
||||
|
||||
/**
|
||||
* @desc Draw pixel
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint16_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawPixel (struct st7735 *, uint8_t, uint8_t, uint16_t);
|
||||
|
||||
/**
|
||||
* @desc Clear screen
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint16_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_ClearScreen (struct st7735 *, uint16_t);
|
||||
|
||||
/**
|
||||
* @desc RAM Content Show
|
||||
*
|
||||
* @param struct st7735 *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_RAM_Content_Show (struct st7735 *);
|
||||
|
||||
/**
|
||||
* @desc RAM Content Hide
|
||||
*
|
||||
* @param struct st7735 *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_RAM_Content_Hide (struct st7735 *);
|
||||
|
||||
/**
|
||||
* @desc Display ON
|
||||
*
|
||||
* @param struct st7735 * lcd
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DisplayOn (struct st7735 *);
|
||||
|
||||
/**
|
||||
* @desc Check text position x, y
|
||||
*
|
||||
* @param unsigned char
|
||||
* @param unsigned char
|
||||
* @param unsigned char
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
char ST7735_CheckPosition (unsigned char, unsigned char, unsigned char, enum Size);
|
||||
|
||||
/**
|
||||
* @desc Set text position x, y
|
||||
*
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
char ST7735_SetPosition (uint8_t, uint8_t);
|
||||
|
||||
/**
|
||||
* @desc Draw character
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param char
|
||||
* @param uint16_t
|
||||
* @param enum Size (X1, X2, X3)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
char ST7735_DrawChar (struct st7735 *, char, uint16_t, enum Size);
|
||||
|
||||
/**
|
||||
* @desc Draw string
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param char *
|
||||
* @param uint16_t
|
||||
* @param enum Size (X1, X2, X3)
|
||||
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawString (struct st7735 *, char *, uint16_t, enum Size);
|
||||
|
||||
/**
|
||||
* @desc Draw line
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint16_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
char ST7735_DrawLine (struct st7735 *, uint8_t, uint8_t, uint8_t, uint8_t, uint16_t);
|
||||
|
||||
/**
|
||||
* @desc Fast draw line horizontal
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint16_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawLineHorizontal (struct st7735 *, uint8_t, uint8_t, uint8_t, uint16_t);
|
||||
|
||||
/**
|
||||
* @desc Fast draw line vertical
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint16_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawLineVertical (struct st7735 *, uint8_t, uint8_t, uint8_t, uint16_t);
|
||||
|
||||
/**
|
||||
* @desc Draw rectangle
|
||||
*
|
||||
* @param struct st7735 *
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint8_t
|
||||
* @param uint16_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DrawRectangle (struct st7735 *, uint8_t, uint8_t, uint8_t, uint8_t, uint16_t);
|
||||
|
||||
/**
|
||||
* @desc Delay
|
||||
*
|
||||
* @param uint8_t
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void ST7735_DelayMs (uint8_t);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue