]> Devi Nivas Git - 4dulcd-nolibrary.git/commitdiff
Modify code to work with Arduino Arduino_Code_Lab2Starter
authorAdvaith Menon <noreply-git@bp4k.net>
Wed, 4 Feb 2026 18:22:12 +0000 (13:22 -0500)
committerAdvaith Menon <noreply-git@bp4k.net>
Wed, 4 Feb 2026 18:22:12 +0000 (13:22 -0500)
Arduino_Starter.ino [new file with mode: 0644]
CMakeLists.txt [deleted file]
GUIDE.adoc [deleted file]
LICENSE [deleted file]
README.adoc [deleted file]
main/CMakeLists.txt [deleted file]
main/main.c [deleted file]
pytest_hello_world.py [deleted file]
sdkconfig.ci [deleted file]

diff --git a/Arduino_Starter.ino b/Arduino_Starter.ino
new file mode 100644 (file)
index 0000000..15fd861
--- /dev/null
@@ -0,0 +1,407 @@
+#include <Arduino.h>
+#include <HardwareSerial.h>
+#include <time.h>
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdint.h>
+
+#define PIN_ULCD_RESET 4
+#define PIN_UART_RXD 5
+#define PIN_UART_TXD 6
+
+#define ULCD_DEFAULT_BAUD_RATE 9600
+#define ULCD_DEFAULT_DATA_BITS UART_DATA_8_BITS
+#define ULCD_DEFAULT_PARITY    UART_PARITY_DISABLE
+#define ULCD_DEFAULT_STOP_BITS UART_STOP_BITS_1
+#define TIME_LIMIT 2000
+
+/* screen width and height */
+#define SCR_W   128
+#define SCR_H   128
+
+
+HardwareSerial LCDSer(1);
+
+
+/* Helper functions to make things easier for Arduino users */
+/* DO NOT CALL UNTIL UART IS INITIALIZED */
+int write_tx(const void *data, size_t bufsz);
+int read_rx(void *data, size_t bufsz, uint32_t timeout);
+int flush_rx();
+int flush_tx(uint32_t timeout);
+void update_baud(int baud);
+
+
+void ulcd_init(void);
+void ulcd_cls(void);
+void ulcd_txt_demo(void);
+void ulcd_moving_circle(void);
+void ulcd_faster_baud(void);
+void ulcd_default_baud(void);
+void ulcd_baud(int, int);
+void ulcd_lab2(void);
+
+
+void setup(void)
+{
+    Serial.begin(9600);
+    Serial.println("Starting program");
+    Serial.println("Initializing GPIO...");
+    pinMode(PIN_ULCD_RESET, OUTPUT);
+    Serial.println("Initializing UART...");
+
+    /* Install Drivers */
+    LCDSer.begin(9600, SERIAL_8N1, PIN_UART_RXD, PIN_UART_TXD);
+
+    /* Reset the ULCD manually */
+    Serial.println("Reset the ULCD...");
+    digitalWrite(PIN_ULCD_RESET, 0);
+    delay(1000);
+    digitalWrite(PIN_ULCD_RESET, 1);
+    delay(1000);
+
+    /* UART is initialized. We can now work on initializing the uLCD. */
+    Serial.println("Wait 3 Seconds for ULCD to be Initialized");
+    delay(3000);
+
+
+    Serial.println("Initializing ULCD...");
+    /* This is not mentioned in the code. */
+    ulcd_init();
+
+    ulcd_cls();
+    ulcd_txt_demo();
+    delay(3000); /* wait for a bit */
+
+}
+
+
+void loop() {
+    ulcd_cls();
+    ulcd_moving_circle();
+}
+
+
+void ulcd_init(void) {
+    /* TODO port ported library without helpers */
+}
+
+
+void ulcd_cls(void) {
+    unsigned char instr[2];
+    unsigned char ack;
+    int written;
+
+    /* 1: move cursor to 0, 0 */
+    Serial.println("Clearing screen (gfx_Cls)");
+
+    /* opcode (big-endian) */
+    instr[0] = 0xFF;
+    instr[1] = 0xD7;
+
+    written = write_tx(instr, 2);
+    flush_tx(TIME_LIMIT);
+
+    if (written != 2) Serial.println("Failed to write gfx_Cls!");
+
+    written = read_rx(&ack, 1, TIME_LIMIT);
+    if (written != 1 || ack != 6)
+        Serial.println("Failed to get acknowledge");
+}
+
+
+void ulcd_txt_demo(void) {
+    unsigned char instr[16];
+    unsigned char ack;
+    int written; /* or read */
+
+    /* 1: move cursor to 0, 0 */
+    Serial.println("Moving cursor to 0, 0");
+
+    /* opcode (big-endian) */
+    instr[0] = 0xFF;
+    instr[1] = 0xE4;
+
+    /* Line value is 2 bytes */
+    instr[2] = 0;
+    instr[3] = 0;
+
+    /* Column is again 2 bytes */
+    instr[4] = 0;
+    instr[5] = 0;
+
+    /* Since this is a demo, we do not use helpers. */
+    /* START the below code can be made into a helper */
+    written = write_tx(instr, 6);
+    flush_tx(TIME_LIMIT);
+
+    if (written != 6) Serial.println("Failed to write txt_MoveCursor!");
+
+    written = read_rx(&ack, 1, TIME_LIMIT);
+    if (written != 1 || ack != 6)
+        Serial.println("Failed to get acknowledge");
+    /* END the below code can be made into a helper */
+
+    /* write Hello, World (12) to the display */
+    /* see putstr on Goldelox */
+
+    instr[0] = 0x00;
+    instr[1] = 0x06;
+
+    instr[2] = 'H';
+    instr[3] = 'e';
+    instr[4] = 'l';
+    instr[5] = 'l';
+    instr[6] = 'o';
+    instr[7] = ',';
+    instr[8] = ' ';
+    instr[9] = 'W';
+    instr[10] = 'o';
+    instr[11] = 'r';
+    instr[12] = 'l';
+    instr[13] = 'd';
+
+    instr[14] = '\0';
+
+    written = write_tx(instr, 15);
+    flush_tx(TIME_LIMIT);
+
+    if (written != 15) Serial.println("Failed to write putstr!");
+
+    written = read_rx(&ack, 1, TIME_LIMIT);
+    if (written != 1 || ack != 6)
+        Serial.println("Failed to get acknowledge");
+}
+
+
+void ulcd_lab2(void) {
+    uint16_t current_x = 64;
+    uint16_t current_y = 64;
+    uint16_t prev_x = 64;
+    uint16_t prev_y = 64;
+    uint16_t step_x = 2;
+    uint16_t step_y = 2;
+    const uint16_t rad = 15;
+    int written;
+    unsigned char ack;
+    unsigned char instr[10];
+    /* using gfx_CircleFilled */
+    instr[0] = 0xFF;
+    instr[1] = 0xCC;
+
+    while (1) {
+        /* we draw a circle as long as it is in bounds */
+
+        /* draw a black circle to cover our tracks */
+
+        /* x coord */
+        instr[2] = (prev_x >> 8);
+        instr[3] = prev_x & 0xFF;
+        /* y coord */
+        instr[4] = (prev_y >> 8);
+        instr[5] = prev_y & 0xFF;
+
+        /* rad */
+        instr[6] = (rad >> 8);
+        instr[7] = rad;
+
+        /* color (British spelling used in docs) */
+        instr[8] = 0x00;
+        instr[9] = 0x00;
+
+        written = write_tx(instr, 10);
+        flush_tx(TIME_LIMIT);
+
+        if (written != 10) Serial.println("Failed to write gfx_CircleFilled!");
+
+        written = read_rx(&ack, 1, TIME_LIMIT);
+        if (written != 1 || ack != 6)
+            Serial.println("Failed to get acknowledge");
+
+
+        /* draw blue circle */
+        instr[2] = (current_x >> 8);
+        instr[3] = current_x & 0xFF;
+        /* y coord */
+        instr[4] = (current_y >> 8);
+        instr[5] = current_y & 0xFF;
+
+        /* rad */
+        instr[6] = (rad >> 8);
+        instr[7] = rad;
+
+        /* 5 bits for red, 6 for green and 5 for blue */
+        instr[8] = 0x00;
+        instr[9] = 0x1F;
+
+        written = write_tx(instr, 10);
+        flush_tx(TIME_LIMIT);
+
+        if (written != 10) Serial.println("Failed to write gfx_CircleFilled!");
+
+        written = read_rx(&ack, 1, TIME_LIMIT);
+        if (written != 1 || ack != 6)
+            Serial.println("Failed to get acknowledge");
+
+
+        /* increment motion counters */
+        prev_x = current_x;
+        prev_y = current_y;
+        current_x += step_x;
+        current_y += step_y;
+    }
+}
+void ulcd_moving_circle(void) {
+    /* This demo generates a circle that moves from left to right of the screen.
+     * It is supposed to show that having a higher baud rate makes a difference.
+     */
+    uint16_t current_x = 0;
+    uint16_t current_y = 0;
+    uint16_t step_x = 2;
+    uint16_t step_y = 2;
+    const uint16_t rad = 15;
+    int written;
+    unsigned char ack;
+    unsigned char instr[10];
+    /* using gfx_CircleFilled */
+    instr[0] = 0xFF;
+    instr[1] = 0xCC;
+
+    while (current_x < SCR_W && current_y < SCR_H) {
+        /* we draw a moving circle as long as it is in bounds */
+        uint16_t prev_x = (current_x - step_x) % SCR_W;
+        uint16_t prev_y = (current_y - step_y) % SCR_H;
+
+        /* draw a black circle to cover our tracks */
+
+        /* x coord */
+        instr[2] = (prev_x >> 8);
+        instr[3] = prev_x & 0xFF;
+        /* y coord */
+        instr[4] = (prev_y >> 8);
+        instr[5] = prev_y & 0xFF;
+
+        /* rad */
+        instr[6] = (rad >> 8);
+        instr[7] = rad;
+
+        /* color (British spelling used in docs) */
+        instr[8] = 0x00;
+        instr[9] = 0x00;
+
+        written = write_tx(instr, 10);
+        flush_tx(TIME_LIMIT);
+
+        if (written != 10) Serial.println("Failed to write gfx_CircleFilled!");
+
+        written = read_rx(&ack, 1, TIME_LIMIT);
+        if (written != 1 || ack != 6)
+            Serial.println("Failed to get acknowledge");
+
+
+        /* draw blue circle */
+        instr[2] = (current_x >> 8);
+        instr[3] = current_x & 0xFF;
+        /* y coord */
+        instr[4] = (current_y >> 8);
+        instr[5] = current_y & 0xFF;
+
+        /* rad */
+        instr[6] = (rad >> 8);
+        instr[7] = rad;
+
+        /* 5 bits for red, 6 for green and 5 for blue */
+        instr[8] = 0x00;
+        instr[9] = 0x1F;
+
+        written = write_tx(instr, 10);
+        flush_tx(TIME_LIMIT);
+
+        if (written != 10) Serial.println("Failed to write gfx_CircleFilled!");
+
+        written = read_rx(&ack, 1, TIME_LIMIT);
+        if (written != 1 || ack != 6)
+            Serial.println("Failed to get acknowledge");
+
+
+        /* increment motion counters */
+        current_x += step_x;
+        current_y += step_y;
+    }
+}
+
+
+void ulcd_faster_baud(void) {
+    /* this makes the baud rate the max possible */
+    ulcd_baud(4, 600000);
+}
+
+
+void ulcd_default_baud(void) {
+    /* this makes the baud rate the max possible */
+    ulcd_baud(312, 9600);
+}
+
+
+void ulcd_baud(int baud_table_idx, int actual_baud) {
+    unsigned char instr[4], ack;
+    int written;
+
+    /* see the setbaudWait function */
+    instr[0] = 0x00;
+    instr[1] = 0x0B;
+    instr[2] = (baud_table_idx >> 8);
+    instr[3] = baud_table_idx;
+
+    written = write_tx(instr, 4);
+    flush_tx(TIME_LIMIT);
+
+    if (written != 4) Serial.println("Failed to write setbaudWait!");
+
+    update_baud(actual_baud);
+
+    /* wait 100 ms for the acknowledge in the new baud rate */
+    delay(100);
+
+    written = read_rx(&ack, 1, TIME_LIMIT);
+    if (written != 1 || ack != 6)
+        Serial.println("Failed to get acknowledge");
+}
+
+/* ================================================================= */
+/* for arduino */
+
+int write_tx(const void *data, size_t sz) {
+    return LCDSer.write((char *) data, sz);
+}
+
+
+int read_rx(void *data, size_t sz, uint32_t wait_ms) {
+    if (sizeof(size_t) > sizeof(uint32_t) && sz > UINT32_MAX)
+        return -1;
+    time_t tm = time(NULL);
+    while (time(NULL) - tm < wait_ms / 1000) {
+        if (LCDSer.available() >= sz)
+            return LCDSer.readBytes((char *) data, sz);
+    }
+    return 0;
+}
+
+
+int flush_rx() {
+    LCDSer.flush();
+    return 1;
+}
+
+
+int flush_tx(uint32_t wait_ms) {
+    return 1;
+}
+
+void update_baud(int baud) {
+    LCDSer.end();
+    LCDSer.begin(baud, SERIAL_8N1, PIN_UART_RXD, PIN_UART_TXD);
+}
+
+/* ================================================================= */
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644 (file)
index 75a2178..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# The following lines of boilerplate have to be in your project's
-# CMakeLists in this exact order for cmake to work correctly
-cmake_minimum_required(VERSION 3.16)
-
-include($ENV{IDF_PATH}/tools/cmake/project.cmake)
-# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
-idf_build_set_property(MINIMAL_BUILD ON)
-project(ulcd_nolib)
diff --git a/GUIDE.adoc b/GUIDE.adoc
deleted file mode 100644 (file)
index 8cf918f..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-= Writing to the uLCD without a library: Student Guide
-Advaith Menon <advaith@gatech.edu>; Diego Fratta <dfratta3@gatech.edu>
-v0.1.0, 2026-01-20
-:toc:
-:link-goldelox: https://github.com/4dsystems/Goldelox-Serial-Linux-Library
-:link-spe: https://resources.4dsystems.com.au/manuals/workshop4/serial/goldelox/#text-and-string-commands
-:link-repository: https://git.devinivas.org/?p=4dulcd-nolibrary.git;a=summary
-
-== Abstract
-This document details the necessary steps to write to the uLCD without using the
-libraries provided by 4D Systems.
-
-NOTE: Some of this code was written by
-reverse-engineering the {link-goldelox}[Linux library] provided by 4D Systems.
-This is not necessary - 4D provides {link-spe}[comprehensive
-documentation] on the opcodes and how to use them.
-
-== Copyright
-The code is licensed under the MIT License. Students should legally be able to
-copy code from this demo into their assignments, as long as the copyright notice
-is retained.
-
-The authors of this document discourage copying code. Instead, they encourage
-understanding what the code does and then attempting to rewrite it on their own.
-
-== Approach
-The code uses ESP-IDF as its platform. Since all other platforms, such as
-Arduino, run on top of ESP-IDF, this code should be portable. The wiring for the
-reset is also done directly to the ESP's reset line, hence there is no code to
-reset the uLCD.
-
-NOTE: To get the code to work with Arduino, rename the `app_main` function to
-`setup` and add a new line: `void loop(void) {}`.
-
-== Code
-Code can be found at Advaith's personal Git server. The link is as follows:
-{link-repository}. To clone the repository, run `git clone
-git://git.devinivas.org/4dulcd-nolibrary.git`.
-
-== Basic Steps
-The steps to initialize UART are not covered here since these depend on the
-platform that the user chooses to use. The UART interface has been abstracted to
-four functions:
-
-* `write_tx(const void *data, size_t bufsz)`: Send `bufsz` data from the `data`
-  buffer via the TX line. Returns number of bytes sent.
-* `read_rx(void *data, size_t bufsz, uint32_t tout)`: Read `bufsz` data into the
-  `data` buffer, and limit to `tout` seconds. If it takes longer, this function
-  fails. Returns number of bytes read.
-* `flush_rx()`: Flush the receiving buffer.
-* `flush_tx(uint32_t timeout)`: Flush the transmit buffers. The operation times
-  out if it exceeds `timeout` seconds.
-
-By abstracting the UART interface into these four functions, it should be
-possible to use this code with any microcontroller that supports UART - these
-functions will simply have to be implemented for that specific architecture.
-
-=== Initialization
-The EVE (Extensible Virtual Engine) takes 3 seconds to boot up. This is the
-most reliable way to perform the
-boot wait - alternate methods will not work.
-
-NOTE: The official uLCD libraries work by sending a bunch of 'X's until a `0x15`
-is received. At least, that is how it's supposed to work in theory, but actually
-the read just times out, basically having the same effect as above.
-
-=== uLCD Default Parameters
-By default, the ULCD uses `8N1` UART at a baud rate of 9600. This baud rate can
-be changed via a special opcode.
-
-The uLCD can be treated as a "big-endian" device. This means most significant
-bits are sent first. For instance, if you wish to send the data `0xDEADBEEF`,
-you would send it as `0xDE`, `0xAD`, `0xBE`, `0xEF`.
-
-=== uLCD opcodes
-uLCD opcodes are 16 bits in length. These opcodes can be found at {link-spe}[the
-4D Systems documentation]. For example, the opcode for clearing the screen is
-`0xFFD7`, which means you send `0xFF`, then `0xD7`.
-
-Some opcodes take arguments. Argument values are sent in a big-endian
-fashion.
-
-=== uLCD Acknowledge
-After every instruction is set, an acknowledge can be obtained from the uLCD by
-reading 1 byte from it. This byte should be `0x06`. Any other value indicates an
-error code.
-
-TIP: The reader is encouraged to create a helper function to perform this
-acknowledge since it is a
-very commonly used operation. The demo code does not do so to promote learning.
-
-== Demos
-
-TIP: The reader is encouraged to attempt writing the code without looking at the
-aforementioed repository. Doing so will train one on how to read documentation.
-
-IMPORTANT: The code must be pulled from the actual repository, and is not
-provided here.
-
-=== Clearing the screen
-Per the uLCD documentation, if there is no serial activity after 5 seconds from
-EVE initialization, the "flash" screen will be written. To prevent writing on
-top of this screen in the event the uLCD has not been reset, the screen must be
-cleared. To perform this action, there is the `gfx_Cls` command in GOLDELOX.
-This has an opcode of `0xFFD7` and takes no arguments.
-
-=== Hello, World!
-The function `ulcd_txt_demo` demonstrates this process by writing a Hello World
-string to the first line and column. This code is in the function
-`ulcd_txt_demo`.
-
-The text cursor first has to be placed at the desired location.
-This is done with the `txt_MoveCursor`
-function with an opcode of `0xFFE4`. It takes two arguments, the line number and
-the column number, both which are 16-bit unsigned integers. Since the uLCD's
-number of pixels don't even exceed one byte, it can easily be fit within the
-lower byte. The code goes to (0,0).
-
-Now, the `putstr` command can be used to print a string to the current location
-on the LCD. In standard C convention, the string must end with a `0x00` byte to
-denote its end. The string "Hello, World" is sent here.
-
-**Exercise to the reader:** (Not for credit)
-
-. Make the text bold and change its color to white.
-  The `txt_Bold` and `txt_FGcolour` commands might help.
-. Center the text horizontally and vertically to the screen.
-  Avoid using trial-and-error, and use the
-  `charwidth`, `charheight` and `gfx_MoveTo` functions instead.
-. Display the text inside a sufficiently big semicircle.
-
-
-=== Changing the baud rate
-Unlike other instructions which basically follow the same process, the baud rate
-instruction is a bit tricky to implement. It works in three steps:
-
-. Call the `setBaudWait` command
-. Change the baud rate
-. With the new baud rate, perform the acknowledge procedure.
-
-To ease understanding of the code, we have abstracted the process of changing
-the baud rate to a function called `update_baud`.
-
-Note that `setBaudWait` doesn't take a baud rate as its argument! It instead
-takes a mapping to a number indicating a baud rate. The mapping table can be
-found at 4D's website.
-
-The function `ulcd_baud` performs the baud rate change. It takes two arguments,
-the first being the index from the table, and the second the actual baud rate.
-The below table lists a few of the possible values.
-
-[cols="1,1"]
-|===
-|Index |Baud Rate
-
-|312
-|9600 (default)
-
-|207
-|14400
-
-|155
-|19200
-
-|77
-|38400
-
-|25
-|115200
-
-|4
-|600000 (fastest)
-|===
-
-The baud rate change happens in 100ms. We wait while the hardware gets the
-acknowledge and stores it, and then we check for the acknowledge afterwards.
-
-To demonstrate the difference in using a faster baud rate, a demo program
-showing a moving circle has been made. Note that the circle moves faster and is
-more clear with a higher baud rate.
diff --git a/LICENSE b/LICENSE
deleted file mode 100644 (file)
index 9e6b0e6..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2026 Advaith Menon
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the “Software”), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
diff --git a/README.adoc b/README.adoc
deleted file mode 100644 (file)
index 109f2cd..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-= Writing to the uLCD without a library
-Advaith Menon <advaith@gatech.edu>; Diego Fratta <dfratta3@gatech.edu>
-v0.1.0, 2026-01-20
-:toc:
-:link-goldelox: https://github.com/4dsystems/Goldelox-Serial-Linux-Library
-:link-spe: https://resources.4dsystems.com.au/manuals/workshop4/serial/goldelox/#text-and-string-commands
-:link-repository: https://git.devinivas.org/?p=4dulcd-nolibrary.git;a=summary
-
-== Abstract
-This document details the necessary steps to write to the uLCD without using the
-libraries provided by 4D Systems. Most of this code was written by
-reverse-engineering the {link-goldelox}[Linux library] provided by 4D Systems.
-This is not necessary - 4D provides {link-spe}[comprehensive
-documentation] on the opcodes and how to use them. It is left as an exercise to
-the reader to replicate the same without referring to library code.
-
-== Approach
-The code uses ESP-IDF as its platform. Since all other platforms, such as
-Arduino, run on top of ESP-IDF, this code should be portable. The wiring for the
-reset is also done directly to the ESP's reset line, hence there is no code to
-reset the uLCD.
-
-== Code
-Code can be found at Advaith's personal Git server. The link is as follows:
-{link-repository}. To clone the repository, run `git clone
-git://git.devinivas.org/4dulcd-nolibrary.git`.
-
-== Basic Steps
-We do not cover the steps to initialize UART here, since these depend on the
-platform that the user chooses to use. We have abstracted the UART interface to
-four functions:
-
-* `write_tx(const void *data, size_t bufsz)`: Send `bufsz` data from the `data`
-  buffer via the TX line. Returns number of bytes sent.
-* `read_rx(void *data, size_t bufsz, uint32_t tout)`: Read `bufsz` data into the
-  `data` buffer, and limit to `tout` seconds. If it takes longer, this function
-  fails. Returns number of bytes read.
-* `flush_rx()`: Flush the receiving buffer.
-* `flush_tx(uint32_t timeout)`: Flush the transmit buffers. The operation times
-  out if it exceeds `timeout` seconds.
-
-The uLCD is a "big-endian" device. This means we send the most significant bit
-over UART.
-
-=== Initialization
-The EVE takes 3 seconds to boot up. This is the most reliable way to perform the
-boot wait - alternate methods, like sending a bunch of 'K's until we get an
-acknowledge are not reliable and can even cause irrepairable harm to the uLCDs
-in some cases.
-
-=== uLCD opcodes
-uLCD opcodes are 8 bits in length. These opcodes can be found at {link-spe}[the
-4D Systems documentation]. For example, the opcode for clearing the screen is
-`0xFFD7`, which means you send `0xFF`, then `0xD7`.
-
-Most opcodes (except the baud rate switch) return an acknowledge. This
-acknowledge can be obtained by reading one byte of data from the UART device,
-and this byte should be `0x06`.
-
-=== Demos
-The function `ulcd_txt_demo` demonstrates this process by writing a Hello World
-string to the first line and column. More demo functions will come soon.
diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt
deleted file mode 100644 (file)
index 6ee2157..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-idf_component_register(SRCS "main.c"
-                       PRIV_REQUIRES spi_flash
-                            esp_driver_uart
-                            esp_driver_gpio
-                       INCLUDE_DIRS "")
diff --git a/main/main.c b/main/main.c
deleted file mode 100644 (file)
index 19285b2..0000000
+++ /dev/null
@@ -1,351 +0,0 @@
-#include <stdio.h>
-#include <inttypes.h>
-#include "freertos/FreeRTOS.h"
-#include "esp_log.h"
-#include "esp_system.h"
-#include <stdint.h>
-#include "driver/uart.h"
-
-#define PIN_UART_RXD 4
-#define PIN_UART_TXD 5
-
-#define ULCD_DEFAULT_BAUD_RATE 9600
-#define ULCD_DEFAULT_DATA_BITS UART_DATA_8_BITS
-#define ULCD_DEFAULT_PARITY    UART_PARITY_DISABLE
-#define ULCD_DEFAULT_STOP_BITS UART_STOP_BITS_1
-#define TIME_LIMIT 2000
-
-/* screen width and height */
-#define SCR_W   128
-#define SCR_H   128
-
-
-static const char *TAG = "main";
-static const uart_port_t uart_port = UART_NUM_1;
-
-/* UART config. This is handy as some sort of default. */
-static const uart_config_t uart_cfg = {
-    .baud_rate = ULCD_DEFAULT_BAUD_RATE,
-    .data_bits = ULCD_DEFAULT_DATA_BITS,
-    .parity    = ULCD_DEFAULT_PARITY,
-    .stop_bits = ULCD_DEFAULT_STOP_BITS,
-    .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
-    .rx_flow_ctrl_thresh = 10
-};
-
-
-/* Helper functions to make things easier for Arduino users */
-/* DO NOT CALL UNTIL UART IS INITIALIZED */
-int write_tx(const void *data, size_t bufsz);
-int read_rx(void *data, size_t bufsz, uint32_t timeout);
-int flush_rx();
-int flush_tx(uint32_t timeout);
-void update_baud(int baud);
-
-
-void ulcd_init(void);
-void ulcd_cls(void);
-void ulcd_txt_demo(void);
-void ulcd_moving_circle(void);
-void ulcd_faster_baud(void);
-void ulcd_default_baud(void);
-void ulcd_baud(int, int);
-
-
-void app_main(void)
-{
-    ESP_LOGI(TAG, "Starting program");
-    ESP_LOGI(TAG, "Initializing UART...");
-
-    /* Install Drivers */
-    const int uart_bufsz = UART_HW_FIFO_LEN(uart_port) + 4;
-    QueueHandle_t uart_q;
-    ESP_ERROR_CHECK(uart_driver_install(uart_port,
-                uart_bufsz,
-                uart_bufsz,
-                10,
-                &uart_q,
-                0));
-
-    /* Set comms parameters */
-    ESP_ERROR_CHECK(uart_param_config(uart_port, &uart_cfg));
-
-    /* Set pins */
-    ESP_ERROR_CHECK(uart_set_pin(uart_port, PIN_UART_TXD, PIN_UART_RXD,
-                UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
-
-    /* UART is initialized. We can now work on initializing the uLCD. */
-    ESP_LOGI(TAG, "Wait 3 Seconds for ULCD to be Initialized");
-    vTaskDelay(pdMS_TO_TICKS(3000)); /* see "Power-Up and Reset" in 4D docs */
-
-
-    ESP_LOGI(TAG, "Initializing ULCD...");
-    /* This is not mentioned in the code. */
-    ulcd_init();
-
-    ulcd_cls();
-    ulcd_txt_demo();
-    vTaskDelay(pdMS_TO_TICKS(3000)); /* wait for a bit */
-
-    ulcd_cls();
-    ulcd_moving_circle();
-    vTaskDelay(pdMS_TO_TICKS(1000)); /* let the user digest how bad that was */
-
-    ulcd_faster_baud();
-    ulcd_cls();
-    ulcd_moving_circle();
-    /* Hey, it's Andy from LTT here and look at my crazy-fast 60fps gaming
-     * monitor! */
-    vTaskDelay(pdMS_TO_TICKS(1000));
-
-    /* Allows the program to loop w/o resetting uLCD */
-    ulcd_default_baud();
-
-
-    ESP_LOGI(TAG, "Work is done");
-    vTaskDelay(pdMS_TO_TICKS(1000));
-    esp_restart();
-}
-
-
-void ulcd_init(void) {
-    /* TODO port ported library without helpers */
-}
-
-
-void ulcd_cls(void) {
-    unsigned char instr[2];
-    unsigned char ack;
-    int written;
-
-    /* 1: move cursor to 0, 0 */
-    ESP_LOGI(TAG, "Clearing screen (gfx_Cls)");
-
-    /* opcode (big-endian) */
-    instr[0] = 0xFF;
-    instr[1] = 0xD7;
-
-    written = write_tx(instr, 2);
-    flush_tx(TIME_LIMIT);
-
-    if (written != 2) ESP_LOGE(TAG, "Failed to write gfx_Cls!");
-
-    written = read_rx(&ack, 1, TIME_LIMIT);
-    if (written != 1 || ack != 6)
-        ESP_LOGE(TAG, "Failed to get acknowledge");
-}
-
-
-void ulcd_txt_demo(void) {
-    unsigned char instr[16];
-    unsigned char ack;
-    int written; /* or read */
-
-    /* 1: move cursor to 0, 0 */
-    ESP_LOGI(TAG, "Moving cursor to 0, 0");
-
-    /* opcode (big-endian) */
-    instr[0] = 0xFF;
-    instr[1] = 0xE4;
-
-    /* Line value is 2 bytes */
-    instr[2] = 0;
-    instr[3] = 0;
-
-    /* Column is again 2 bytes */
-    instr[4] = 0;
-    instr[5] = 0;
-
-    /* Since this is a demo, we do not use helpers. */
-    /* START the below code can be made into a helper */
-    written = write_tx(instr, 6);
-    flush_tx(TIME_LIMIT);
-
-    if (written != 6) ESP_LOGE(TAG, "Failed to write txt_MoveCursor!");
-
-    written = read_rx(&ack, 1, TIME_LIMIT);
-    if (written != 1 || ack != 6)
-        ESP_LOGE(TAG, "Failed to get acknowledge");
-    /* END the below code can be made into a helper */
-
-    /* write Hello, World (12) to the display */
-    /* see putstr on Goldelox */
-
-    instr[0] = 0x00;
-    instr[1] = 0x06;
-
-    instr[2] = 'H';
-    instr[3] = 'e';
-    instr[4] = 'l';
-    instr[5] = 'l';
-    instr[6] = 'o';
-    instr[7] = ',';
-    instr[8] = ' ';
-    instr[9] = 'W';
-    instr[10] = 'o';
-    instr[11] = 'r';
-    instr[12] = 'l';
-    instr[13] = 'd';
-
-    instr[14] = '\0';
-
-    written = write_tx(instr, 15);
-    flush_tx(TIME_LIMIT);
-
-    if (written != 15) ESP_LOGE(TAG, "Failed to write putstr!");
-
-    written = read_rx(&ack, 1, TIME_LIMIT);
-    if (written != 1 || ack != 6)
-        ESP_LOGE(TAG, "Failed to get acknowledge");
-}
-
-
-void ulcd_moving_circle(void) {
-    /* This demo generates a circle that moves from left to right of the screen.
-     * It is supposed to show that having a higher baud rate makes a difference.
-     */
-    uint16_t current_x = 0;
-    uint16_t current_y = 0;
-    uint16_t step_x = 2;
-    uint16_t step_y = 2;
-    const uint16_t rad = 15;
-    int written;
-    unsigned char ack;
-    unsigned char instr[10];
-    /* using gfx_CircleFilled */
-    instr[0] = 0xFF;
-    instr[1] = 0xCC;
-
-    while (current_x < SCR_W && current_y < SCR_H) {
-        /* we draw a moving circle as long as it is in bounds */
-        uint16_t prev_x = (current_x - step_x) % SCR_W;
-        uint16_t prev_y = (current_y - step_y) % SCR_H;
-
-        /* draw a black circle to cover our tracks */
-
-        /* x coord */
-        instr[2] = (prev_x >> 8);
-        instr[3] = prev_x & 0xFF;
-        /* y coord */
-        instr[4] = (prev_y >> 8);
-        instr[5] = prev_y & 0xFF;
-
-        /* rad */
-        instr[6] = (rad >> 8);
-        instr[7] = rad;
-
-        /* color (British spelling used in docs) */
-        instr[8] = 0x00;
-        instr[9] = 0x00;
-
-        written = write_tx(instr, 10);
-        flush_tx(TIME_LIMIT);
-
-        if (written != 10) ESP_LOGE(TAG, "Failed to write gfx_CircleFilled!");
-
-        written = read_rx(&ack, 1, TIME_LIMIT);
-        if (written != 1 || ack != 6)
-            ESP_LOGE(TAG, "Failed to get acknowledge");
-
-
-        /* draw blue circle */
-        instr[2] = (current_x >> 8);
-        instr[3] = current_x & 0xFF;
-        /* y coord */
-        instr[4] = (current_y >> 8);
-        instr[5] = current_y & 0xFF;
-
-        /* rad */
-        instr[6] = (rad >> 8);
-        instr[7] = rad;
-
-        /* 5 bits for red, 6 for green and 5 for blue */
-        instr[8] = 0x00;
-        instr[9] = 0x1F;
-
-        written = write_tx(instr, 10);
-        flush_tx(TIME_LIMIT);
-
-        if (written != 10) ESP_LOGE(TAG, "Failed to write gfx_CircleFilled!");
-
-        written = read_rx(&ack, 1, TIME_LIMIT);
-        if (written != 1 || ack != 6)
-            ESP_LOGE(TAG, "Failed to get acknowledge");
-
-
-        /* increment motion counters */
-        current_x += step_x;
-        current_y += step_y;
-    }
-}
-
-
-void ulcd_faster_baud(void) {
-    /* this makes the baud rate the max possible */
-    ulcd_baud(4, 600000);
-}
-
-
-void ulcd_default_baud(void) {
-    /* this makes the baud rate the max possible */
-    ulcd_baud(312, 9600);
-}
-
-
-void ulcd_baud(int baud_table_idx, int actual_baud) {
-    unsigned char instr[4], ack;
-    int written;
-
-    /* see the setbaudWait function */
-    instr[0] = 0x00;
-    instr[1] = 0x0B;
-    instr[2] = (baud_table_idx >> 8);
-    instr[3] = baud_table_idx;
-
-    written = write_tx(instr, 4);
-    flush_tx(TIME_LIMIT);
-
-    if (written != 4) ESP_LOGE(TAG, "Failed to write setbaudWait!");
-
-    update_baud(actual_baud);
-
-    /* wait 100 ms for the acknowledge in the new baud rate */
-    vTaskDelay(pdMS_TO_TICKS(100));
-
-    written = read_rx(&ack, 1, TIME_LIMIT);
-    if (written != 1 || ack != 6)
-        ESP_LOGE(TAG, "Failed to get acknowledge");
-}
-
-/* ================================================================= */
-
-int write_tx(const void *data, size_t sz) {
-    return uart_write_bytes(uart_port, data, sz);
-}
-
-
-int read_rx(void *data, size_t sz, uint32_t wait_ms) {
-    if (sizeof(size_t) > sizeof(uint32_t) && sz > UINT32_MAX)
-        return -1;
-    return uart_read_bytes(uart_port, data, (uint32_t) sz,
-            (TickType_t) wait_ms / portTICK_PERIOD_MS);
-}
-
-
-int flush_rx() {
-    return (int) uart_flush(uart_port);
-}
-
-
-int flush_tx(uint32_t wait_ms) {
-    return (int) uart_wait_tx_done(uart_port,
-            (TickType_t) wait_ms / portTICK_PERIOD_MS);
-}
-
-void update_baud(int baud) {
-    uart_config_t ucfg2 = uart_cfg;
-    ucfg2.baud_rate = baud;
-    ESP_ERROR_CHECK(uart_param_config(uart_port, &ucfg2));
-}
-
-/* ================================================================= */
diff --git a/pytest_hello_world.py b/pytest_hello_world.py
deleted file mode 100644 (file)
index eb02bd7..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
-# SPDX-License-Identifier: CC0-1.0
-import hashlib
-import logging
-from typing import Callable
-
-import pytest
-from pytest_embedded_idf.dut import IdfDut
-from pytest_embedded_idf.utils import idf_parametrize
-from pytest_embedded_qemu.app import QemuApp
-from pytest_embedded_qemu.dut import QemuDut
-
-
-@pytest.mark.generic
-@idf_parametrize('target', ['supported_targets', 'preview_targets'], indirect=['target'])
-def test_hello_world(dut: IdfDut, log_minimum_free_heap_size: Callable[..., None]) -> None:
-    dut.expect('Hello world!')
-    log_minimum_free_heap_size()
-
-
-@pytest.mark.host_test
-@idf_parametrize('target', ['linux'], indirect=['target'])
-def test_hello_world_linux(dut: IdfDut) -> None:
-    dut.expect('Hello world!')
-
-
-@pytest.mark.host_test
-@pytest.mark.macos_shell
-@idf_parametrize('target', ['linux'], indirect=['target'])
-def test_hello_world_macos(dut: IdfDut) -> None:
-    dut.expect('Hello world!')
-
-
-def verify_elf_sha256_embedding(app: QemuApp, sha256_reported: str) -> None:
-    sha256 = hashlib.sha256()
-    with open(app.elf_file, 'rb') as f:
-        sha256.update(f.read())
-    sha256_expected = sha256.hexdigest()
-
-    logging.info(f'ELF file SHA256: {sha256_expected}')
-    logging.info(f'ELF file SHA256 (reported by the app): {sha256_reported}')
-
-    # the app reports only the first several hex characters of the SHA256, check that they match
-    if not sha256_expected.startswith(sha256_reported):
-        raise ValueError('ELF file SHA256 mismatch')
-
-
-@pytest.mark.host_test
-@pytest.mark.qemu
-@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
-def test_hello_world_host(app: QemuApp, dut: QemuDut) -> None:
-    sha256_reported = dut.expect(r'ELF file SHA256:\s+([a-f0-9]+)').group(1).decode('utf-8')
-    verify_elf_sha256_embedding(app, sha256_reported)
-
-    dut.expect('Hello world!')
diff --git a/sdkconfig.ci b/sdkconfig.ci
deleted file mode 100644 (file)
index e69de29..0000000