ESP32forth étendu
publication: 9 janvier 2023 / mis à jour 18 avril 2023
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:
- version 7.0710 ZIP file (41 K)
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