ESP32forth étendu

publication: 9 janvier 2023 / mis à jour 18 avril 2023

Read this page in english

 


Appel à collaboration

Vous développez des montages, simples ou complexes avec ESP32 et ESP32forth.

Partagez-les ici sur ce site.

ESP32forth ne pourra se développer qu'avec la collaboration active de toutes les bonnes volontés.

Vos montages peuvent aider d'autres développeurs.

Les montages des autres développeurs peuvent vous aider.

Pour proposer un article ou un montage, cliquez ici


Cette implémentation a été réalisée dans ESP32Forth version 7.0.7.5 et 7.0.7.10

Pour récupérer cette version de ESP32forth:

Pour d'autres versions de ESP32forth, suivre les étapes décrites dans la suite de cet article.

Implémentation du code SPI

Dans le code source du fichier ESP32forthV70710-extended.ino, voici, en couleur rouge, les parties de code à implémenter:

# define ENABLE_CAMERA_SUPPORT
#define VOCABULARY_LIST \
  V(forth) V(internals) \
  V(rtos) V(SPIFFS) V(serial) V(SD) V(SD_MMC) V(SPI) V(ESP) \
  V(ledc) V(Wire) V(WiFi) V(bluetooth) V(sockets) V(oled) \
  V(rmt) V(interrupts) V(spi_flash) V(camera) V(timers)
// Default on several options.
// .......
#define ENABLE_MDNS_SUPPORT
#define ENABLE_I2C_SUPPORT
#define ENABLE_SPI_SUPPORT
#define ENABLE_SOCKETS_SUPPORT
#define ENABLE_FREERTOS_SUPPORT
// .......
#define PLATFORM_OPCODE_LIST \
// .........
  OPTIONAL_SD_SUPPORT \
  OPTIONAL_SD_MMC_SUPPORT \
  OPTIONAL_I2C_SUPPORT \
  OPTIONAL_SPI_SUPPORT \
  OPTIONAL_SERIAL_BLUETOOTH_SUPPORT \
  OPTIONAL_CAMERA_SUPPORT \
// ......
#ifndef ENABLE_SD_SUPPORT
// .......
#endif

// *** Support SPI ***
#ifndef ENABLE_SPI_SUPPORT
# define OPTIONAL_SPI_SUPPORT
#else
# include <SPI.h>
# define OPTIONAL_SPI_SUPPORT \
  XV(SPI, "SPI.begin", SPI_BEGIN, SPI.begin((int8_t) n3, (int8_t) n2, (int8_t) n1, (int8_t) n0); DROPn(4)) \
  XV(SPI, "SPI.end", SPI_END, SPI.end();) \
  XV(SPI, "SPI.setHwCs", SPI_SETHWCS, SPI.setHwCs((boolean) n0); DROP) \
  XV(SPI, "SPI.setBitOrder", SPI_SETBITORDER, SPI.setBitOrder((uint8_t) n0); DROP) \
  XV(SPI, "SPI.setDataMode", SPI_SETDATAMODE, SPI.setDataMode((uint8_t) n0); DROP) \
  XV(SPI, "SPI.setFrequency", SPI_SETFREQUENCY, SPI.setFrequency((uint32_t) n0); DROP) \
  XV(SPI, "SPI.setClockDivider", SPI_SETCLOCKDIVIDER, SPI.setClockDivider((uint32_t) n0); DROP) \
  XV(SPI, "SPI.getClockDivider", SPI_GETCLOCKDIVIDER, PUSH SPI.getClockDivider();) \
  XV(SPI, "SPI.transfer",   SPI_TRANSFER, SPI.transfer((uint8_t *) n1, (uint32_t) n0); DROPn(2)) \
  XV(SPI, "SPI.transfer8",  SPI_TRANSFER_8,  PUSH (uint8_t)  SPI.transfer((uint8_t) n0); NIP) \
  XV(SPI, "SPI.transfer16", SPI_TRANSFER_16, PUSH (uint16_t) SPI.transfer16((uint16_t) n0); NIP) \
  XV(SPI, "SPI.transfer32", SPI_TRANSFER_32, PUSH (uint32_t) SPI.transfer32((uint32_t) n0); NIP) \
  XV(SPI, "SPI.transferBytes", SPI_TRANSFER_BYTES, SPI.transferBytes((const uint8_t *) n2, (uint8_t *) n1, (uint32_t) n0); DROPn(3)) \
  XV(SPI, "SPI.transferBits", SPI_TRANSFER_BITES, SPI.transferBits((uint32_t) n2, (uint32_t *) n1, (uint8_t) n0); DROPn(3)) \
  XV(SPI, "SPI.write", SPI_WRITE, SPI.write((uint8_t) n0); DROP) \
  XV(SPI, "SPI.write16", SPI_WRITE16, SPI.write16((uint16_t) n0); DROP) \
  XV(SPI, "SPI.write32", SPI_WRITE32, SPI.write32((uint32_t) n0); DROP) \
  XV(SPI, "SPI.writeBytes", SPI_WRITE_BYTES, SPI.writeBytes((const uint8_t *) n1, (uint32_t) n0); DROPn(2)) \
  XV(SPI, "SPI.writePixels", SPI_WRITE_PIXELS, SPI.writePixels((const void *) n1, (uint32_t) n0); DROPn(2)) \
  XV(SPI, "SPI.writePattern", SPI_WRITE_PATTERN, SPI.writePattern((const uint8_t *) n2, (uint8_t) n1, (uint32_t) n0); DROPn(3))
#endif

#ifndef ENABLE_SD_MMC_SUPPORT
// .......
# endif
vocabulary SD_MMC   SD_MMC definitions
transfer SD_MMC-builtins
forth definitions

vocabulary SPI   SPI definitions
transfer SPI-builtins
forth definitions

vocabulary spi_flash   spi_flash definitions
transfer spi_flash-builtins

Une fois ce code implémenté, on passe à une compilation de contrôle avec ARDUINO IDE. Si cette compilation ne produit pas d'erreur, on effectue un upload du code vers la carte ESP32.

On contrôle la dispobilité du vocabulaire SPI en démarrant le terminal pour communiquer avec la carte ESP32 et lancer ESP32Forth:

ESP32-D0WDQ6   240 MHz   2 cores   4194304 bytes flash
     System Heap: 201092 free + 345808 used = 546900 total (36% free)
                  97964 bytes max contiguous
Forth dictionary: 77164 free + 30492 used = 107656 total (71% free)
3 x Forth stacks: 2048 bytes each
 ok
--> SPI
 ok
--> vlist
SPI.begin SPI.end SPI.setHwCs SPI.setBitOrder SPI.setDataMode SPI.setFrequency
SPI.setClockDivider SPI.getClockDivider SPI.transfer SPI.transfer8 SPI.transfer16
SPI.transfer32 SPI.transferBytes SPI.transferBits SPI.write SPI.write16
SPI.write32 SPI.writeBytes SPI.writePixels SPI.writePattern SPI-builtins
 ok
 -->

Autres extensions / modifications

: aft   drop ['] branch , here 0 , here swap ; immediate

( More Misc CAL words )
: between? ( n min-inc max-inc -- f ) rot >r r@ >= swap r> <= and ;
: autoexec
   300 for key? if rdrop exit then 10 ms next
   s\" /spiffs/autoexec.fs\" ['] included catch 2drop drop
   ['] revive catch drop ;
' autoexec ( leave on the stack for fini.fs )

forth definitions

: $= ( addr1 len1 addr2 len2 --- fl )
    str= ;
: string  ( n --- names_strvar )
    create  dup ,  0 ,  allot does>  cell+ cell+ dup cell - @  ;
: maxlen$  ( strvar --- strvar maxlen )
    over cell - cell - @ ;
: $!  ( str strvar --- )
    maxlen$  nip rot min 2dup swap cell - ! cmove  ;
: left$  ( str1 n --- str2 )
    0 max min  ;
: 0$! ( addr len -- )
    drop 0 swap cell - ! ;
: right$  ( str1 n --- str2 )
    0 max over min >r + r@ - r> ;
: mid$  ( str1 pos len --- str2 )
    >r over swap - right$ r> left$ ;
: c+$!  ( c str1 -- )
    over >r + c! r> cell - dup @ 1+ swap ! ;
: input$ ( addr len -- )
    over swap maxlen$ nip accept
    swap cell - !  ;

\ locals variables in DUMP:
\ START_ADDR      \ first address to dump
\ END_ADDR        \ latest address to dump
\ 0START_ADDR     \ first address for dump loop
\ LINES           \ number of lines for dump loop
\ myBASE          \ current numeric base
internals
: dump ( start len -- )
    cr cr ." --addr---  "
    ." 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  ------chars-----"
    2dup + { END_ADDR }             \ store latest address to dump
    swap { START_ADDR }             \ store START address to dump
    START_ADDR 16 / 16 * { 0START_ADDR } \ calc. addr for loop start
    16 / 1+ { LINES }
    base @ { myBASE }               \ save current base
    hex
    \ outer loop
    LINES 0 do
        0START_ADDR i 16 * +        \ calc start address for current line
        cr <# # # # #  [char] - hold # # # # #> type
        space space     \ and display address
        \ first inner loop, display bytes
        16 0 do
            \ calculate real address
            0START_ADDR j 16 * i + +
            ca@ <# # # #> type space \ display byte in format: NN
        loop 
        space
        \ second inner loop, display chars
        16 0 do
            \ calculate real address
            0START_ADDR j 16 * i + +
            \ display char if code in interval 32-127
            ca@     dup 32 < over 127 > or
            if      drop [char] . emit
            else    emit
            then
        loop 
    loop
    myBASE base !               \ restore current base
    cr cr
  ;
forth

Legal: site web personnel sans commerce / personal site without seling