uLisp-ARM support for TCA8418 I/O expander with ILI9341 display


#1

Hello David,

I am working on adding support for the TCA8418 expander to uLisp, aiming to create a device with a full keyboard. Currently, I have a prototype with a 4x4 keypad, but my goal is to develop a device similar to the Lisp Badge, complete with a TFT display.

Following your suggestion, I used the T-Deck implementation by essentially copy-pasting it into the ulisp-arm version.

I managed to get the display working correctly, and the expander now seems to be functioning as expected. However, the overall system isn’t behaving properly.

I can send commands via PuTTY and use my keypad to enter commands. Unfortunately, no output is shown on the display. The results only appear in the terminal, followed by a new prompt. When I continue entering new commands, they simply accumulate on the display without any proper formatting.

When I send the (fill-screen) command from the terminal, the display correctly clears. However, text rendered afterwards starts from the middle of the line on the display. Despite this, expression evaluation works, and I can still use both the keypad and terminal. Highlighting works fine all the time.

I am curious about the differences between the T-Deck and the Raspberry Pi Pico which would cause this behaviour.

I would appreciate any hints on how to make it work.

Thank you!


#2

Please see my code here:
https://github.com/pogurek/ulisp-arm/blob/display_keypad/ulisp-arm/ulisp-arm.ino

And some pictures:
https://photos.app.goo.gl/Qs6DPb73mmESzSn36


#3

I think you need to call Display() from pserial(), like this:

void pserial (char c) {
  LastPrint = c;
  if (!tstflag(NOECHO)) Display(c);         // Don't display when paste in listing
  #if defined (serialmonitor)
  if (c == '\n') Serial.write('\r');
  Serial.write(c);
  #endif
}

#4

Thank you so much!

This seems to have solved the major problem. All the functions I have tried so far are working. However, there is an issue with (load-image). When I call it from the terminal, the device gets stuck. I cannot use my keyboard or the terminal. The last message in the terminal is: lfs_file_close: fd=0x20030c14.

Do you have any idea what might be going on?


#5

I suspect the problem may be the differences between how LittleFS is supported on the ESP32, as used in the T-Deck version of uLisp, and on the Raspberry Pi Pico in the ARM version of uLisp.

I think the first thing to check is that save-image and load-image work on your board using a standard ARM version of uLisp. You can then compare the LittleFS code between both versions and see whether you need to change anything.

Ask me again if you can’t solve it!
David


#6

You are right. This problem is unrelated. It was coused by different upload method. I was using Picoprobe (CMSIS-DAP) option. Now I switched back to Default (UF2) and everything works again.

Thanks once again!


#7

Unfortunately, I’ve encountered another issue, this time related to LispLibrary.

When I try to load a function from the library, such as (require 'count), it doesn’t display correctly the result and the following prompt. It appears that the display is only showing commands sent from the Arduino monitor and nothing else. However, the (fill-screen) command does successfully clear the screen.


#8

A command such as (require 'count) doesn’t print anything; it just returns nil and returns to the prompt. To see the function you’ve loaded you need to print it, with something like:

(pprint count)

I’m not sure what you mean by “it doesn’t display correctly the result”.


#9

The command (require 'count) prints “nil” if no library is loaded and “t” if it was succesfully loaded from the library. At least it does to the monitor.

When I enter the command (require 'count) from the monitor the display shows the particular command (monitor does not) and then it skip to the next line. From this moment on, the display shows only what I enter in the terminal. No results of any functions are being printed. For instance (count 1 '(1 1 1)) is being printed on display, but the result 3 is being printed in the monitor only. The same goes with (cls), only “nil” is being printed in monitor, but the display is not being cleared.

However, function (fill-screen) does make the display go black. And then, as previously, only commands I enter in the monitor are being printed on display one after each other. So the function performs the desired side-effect, but the result is not shown and also no new prompt is shown.

The behaviour is like before I added the Display() function to the pserial (char c) function. Now pserial() looks like this:

void pserial (char c) {
  LastPrint = c;
  if (!tstflag(NOECHO)) Display(c);
  if (c == '\n') Serial.write('\r');
  Serial.write(c);
}

Please, se my final code: https://github.com/pogurek/ulisp-arm/blob/display_keypad/ulisp-arm/ulisp-arm.ino

Lines 7138 to 7202 were copied from T-Deck. I cannot find any difference between T-Deck and Arm version which could be causing this.

Thank you for your kind assistance.


#10

Try changing:

if (!tstflag(NOECHO)) Display(c);

to:

Display(c);

If that works I’ll explain what it was for.


#11

It does work. Please explain :)

I would maybe open new thread to discuss this…

I have also some questions about how the interaction among keyboard/serial/display is supposed to work. In T-Deck FW you can turn off the serial monitor. In Arm FW you can turn on lineeditor and vt100 support. In T-Deck FW you cannot turn off the vt100 support. Some of my questions are:

  • Are you planning to have these two versions of fw in this regard the same? (It would be nice to have even the arm version prepared for easy keyboard integration)

  • It is not the problem to copy-paste code in vt100 mode? It is not better to have always the opportunity to turn off the vt100 mode?

  • If I write to monitor/terminal, do I want to see the same text on the display? (I think I cannot turn it off now)

  • When I write commands to terminal emulator (PuTTY), I don’t see any text being written into the teminal, only on the display. However, the result of the expressions will show up on both. (Possibly bug or my bad code caused by copy-paste from T-Deck?)

  • On the other hand, if I write on the keaboard, do I want to see it in the terminal? (This I can turn off by disabling serial monitor, I believe)

  • How can I suppress the result and the following prompt being shown on the display while rendering a graphics on the display? Is it just kind of a waiting for key press in the lisp program?

I’m sorry if I have missed any of these questions in the docs.


#12

First, to explain about NOECHO:

A convenient way to enter programs into uLisp is to paste them into the Arduino IDE Serial Monitor. However, the Arduino doesn’t implement handshaking on the Serial interface, so when the listing is echoed to the Serial Monitor it’s possible that subsequent characters being read could be missed. My solution was to turn off echoing to the Serial Monitor when pasting in a listing, by setting a NOECHO flag. A listing is recognised by having a comment, preceded by a ‘;’ at the start, because you wouldn’t include comments when typing into the REPL.

The NOECHO flag is turned off automatically after a delay when there’s no Serial input, with the lines:

unsigned long start = millis();
while (!Serial.available() && !KybdAvailable) if (millis() - start > 1000) clrflag(NOECHO);

Those lines should have been included in the T-Deck version of uLisp. I based the T-Deck version of the Lisp Badge LE code, so it might be good to look at that:

Lisp badge LE

In reply to your questions:

Are you planning to have these two versions of fw in this regard the same? (It would be nice to have even the arm version prepared for easy keyboard integration)

The T-Deck version is a one-off rather than an officially supported version of uLisp. It has some problems as described on the T-Deck page on the uLisp site, so I am reluctant to recommend it, at least until those are fixed by Espressif.

It is not the problem to copy-paste code in vt100 mode? It is not better to have always the opportunity to turn off the vt100 mode?
If I write to monitor/terminal, do I want to see the same text on the display? (I think I cannot turn it off now)

I agree that it should be possible to have either or both options.

How can I suppress the result and the following prompt being shown on the display while
rendering a graphics on the display? Is it just kind of a waiting for key press in the lisp program?

The simplest solution would be to hang up in a loop with the Lisp statement:

(loop (when nil (return)))

Then type ‘~’ Return when you want to escape.