Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spi code #9

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Spi code #9

wants to merge 2 commits into from

Conversation

jkbits1
Copy link
Contributor

@jkbits1 jkbits1 commented Aug 12, 2016

This PR relates mainly to SPI functionality created to support the 8 character, 7-segment MAX7219 display. Other changes and additions are mostly in support of this functionality. It works very well for my own projects (some examples are included) and may have some wider benefit for the esp-lisp project generally.

MAX7219_font.h - added

There are a few projects on the web that define letters for the 8 character, 7-segment MAX7219 display. It wouldn’t be so hard to create this data from scratch, but this file makes for a good starting point. I’ve made a few changes to it but left the original developer’s copyright details in.

Makefile – changed

The underlying esp-open-rtos project now creates a single binary (rather than two). The linking has changed, so it’s easier to go along with this for now. The firmware binary takes its name from the PROGRAM defined here.

Lisp.c – changed

Minor items – new prims, delay, random, random_basic

delay - exposes vTaskDelay() (used by the spi code) to the lisp environment. It’s not an especially elegant approach, but this primitive comes in handy for my changing lights program.

random, random_basic – created these but not used now. Left in, as a straightforward way to build them from the lisp environment isn’t obvious.

Main items – new primitives, led_data, led_show

led_data – this supports storing a variable length list in spiData[], at a specified offset.

NOTE the MAX7219 display has two modes – in decode mode (default, value == 1), 1 displays the digit 1 etc. Otherwise a value is treated as a binary number, where each bit represents one of the seven led segments.

This primitive supports hex numbers in non-decode mode, by adjusting the value to point to the numbers/letters in the font file.

See the auto-loaded numbers defines for examples of this in use.

led_show – this exposes spi_led()

Main items – spi_led() and the functions it calls

spi_led() interacts with the MAX7219 display in two ways, depending on the init parameter. If init > 0, the display is initialised is a variety of necessary ways. See the auto-loaded numbers defines for examples of this in use. The lights auto-loaded defines show a sensible order for init methods, although sometimes it seems to need a few resets for the display to start up, after which point it operates without problems. That may be related to a power supply issue rather than the software.

If init == 0, the data in spiData[] is sent to the display via SPI. The value sent is adjusted by sendChar() if decodeMode == 0.

The SPI works with data in 16-bit chunks. One set of 8 bits inform the display which character to change, and the other 8 bits determine the led segments to switch on.

The clock, cs and data pins are set high and low according to the MAX7219 display documentation, which seems to be the standard SPI pattern.

Main item – auto-load of defines in readeval()

pDefines is set to point to an array of strings, currently either pLightsDefines and pNumbersDefines. These are left in as examples, and pNumbersDefines documents the use of the MAX7219 display.

The flag libLoaded is initially set to zero, which causes readeval () to execute one define from the array of strings at a time, until the currentDefine counter matches defineCount. A small delay is placed between the execution of each define.

For my projects, this is a useful alternative to manual typing. It’s very handy during development, as even if defines can be stored in the flash ram, this is usually completely overwritten.

@jkbits1
Copy link
Contributor Author

jkbits1 commented Aug 12, 2016

Something not mentioned in the PR description above. I experimented with the SPI API provided by the RTOS project. This looks promising but work on this was stopped due to time constraints. Various commented out pieces of code in the PR relate to this.

@yesco
Copy link
Owner

yesco commented Aug 13, 2016

@yesco
Copy link
Owner

yesco commented Aug 13, 2016

I've added 2 new functions for both unix and esp8266

  • (random) => -seed
  • (random -seed) => -seed
  • (random N) => [0, N[
  • (random S E) => [S, E]
  • (delay ms) => ms

SPI... looked at it but will have to check how to support a new screen I just bought. Will then add, or try to use the one which is part of esp-open-rtos.

thanks
Jonas

PS: Going to think about how to support incorporating lisp code in a nicer way.
There is a load function that takes a file. Maybe with the new spiffs support for files on flash we can use that. Haven't played with it yet, or do like you do and compile in it in the binary... Could also allow the load to load from an URL ;-) maybe.

@jkbits1
Copy link
Contributor Author

jkbits1 commented Aug 13, 2016

Yes, the commented out code is from https://github.com/SuperHouse/esp-open-rtos/blob/master/core/include/esp/spi.h

It looks ideal, and seems likely to provide the fastest SPI method. spi.h includes some example code for using the API. That seems to be a common pattern with the RTOS code, to put examples/documentation in the header. However, in the short time I tested it, it didn't work. Ad I needed something to work for a deadline, I kept with the hand-coded SPI method in this PR.

@jkbits1
Copy link
Contributor Author

jkbits1 commented Aug 13, 2016

It will be great to have your random and delay functions in the library. When I was building some game/puzzle widgets, various ideas needed a random function. My delay() felt a bit like I was going against the grain of using a timer function, but a synchronous function made my lisp code easier to write and debug, so I viewed it as a common coding trade-off.

@jkbits1
Copy link
Contributor Author

jkbits1 commented Aug 13, 2016

I'm very interested in any possible ways to load lisp code automatically. The solution in this PR enabled me to create game/puzzle widgets that would work immediately when connected to any power supply, with no set-up needed.

In an earlier attempt, I put defines into init_library() using DE macros etc. The method here is an improvement on that because the syntax is exactly the same as used in the interpreter.

In some earlier code (not in this PR), I created new interpreter commands, which allowed decisions on loading specific functions only. That was handy for debugging, but not essential for the main purpose of a widget being ready on power up (or just to have a more efficient coding process).

As ever, time constraints stopped me from looking at a RTOS file access method. What most appealed to me about a method like that was making the project even more useful to a wider audience. My method is fine for me, as I can code in C. So adding/deleting new array items, changing the array size variable and so on is straightforward. However, for others it adds another obstacle to get past. However, if there was a blank file in the project, and any defines typed into that file were auto-loaded, someone only needs to type 'make all' and know how to use esptool to create a widget.

Loading from a url sounds a great idea - my own widgets aren't always connected to wifi though, especially if taken out and about to show to people. But still, it's a way of making the project accessible.

@yesco
Copy link
Owner

yesco commented Aug 21, 2016

Have now added SPIFFS support!

Initial disk size 128K. Files are stored in the SPIFFS directory. The Makefile will build the directory snapshot each time you do make flash. The file "init.lsp" loads automatically on start, it loads env.lsp with some debugging functions. There is a scheme.lsp compatibility module that defines long scheme names.

Added info in the wiki. There is a function (cat "lisp.hlp") to display files. More file functions can be added, scheme/common lisp style...

Hope it will work well!

Btw, there is also a trace function that takes invididual functions
try
(trace fibo)
(fibo 10)

it's different from the "trace on" command, that traces all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants