SpinSemi FV-1 - WiFi enabled remote EEPROM emulator/programmer

Started by free electron, January 21, 2021, 05:30:42 AM

Previous topic - Next topic

free electron

The idea for this project sparked in this thread:
https://www.diystompboxes.com/smfforum/index.php?topic=126087.0

In short words, what it does is instead of having to write the new hex file to the onboard EEPROM everytime something has changed in the code you can just plug in a remote emulator/programmer having the following features:
- web interface for uploading the hex files and switching between the patches with 3MB disk space
- for even faster upload - access through an FTP server
- clicking on "Enable" parses the hex file and makes it available for the FV-1
- once the hex enabled, clicking on any of the 8 buttons will upload corresponding patch to the FV-1
- if the work on the code is done you can burn that firmware to the EEPROM
- as final test you can enable the onboard EEPROM to test if everything works fine
- works up to 44.1kHz sample rate (i2c clock depends on the sample rate).



Schematic, code and instructions are on github:

https://github.com/hexeguitar/FV-1_devRemote

Project is written using Platformio + VScode.

pruttelherrie

#1
You're a hero!

[edit]

Question! You state that one might have to update platformio.ini:


    ; change accordingly to your operating system (ie COMx for Windows)
    upload_port = /dev/ttyUSB0
    upload_speed = 230400

    ; change accordingly to your operating system (ie COMx for Windows)
    monitor_port = /dev/ttyUSB0
    monitor_speed = 115200


Normally, I only set the monitor_speed line to match whatever the serial port is opened with, I never have to set the port nor the upload speed. Have you tried without?

free electron

Yes, i tried. This is only necessary if you have more USB/UART dongles plugged in or boards that use them.
Normally platformio attemps to probe and detect the esp8266 board by looking at the serial port list.
In my case i have other similar dongles plugged, platformio decided the other one is the esp8266. Hence i hardcoded the correct upload port in the ini file.
If there is only one board at a time in the system you can comment out that line.
If the upload starts, but can't connect to the esp - that is usually indicates a wrong upload serial port.

Btw, i tried to use curlftpfs to mount the disk a directory, but it won't work. The problem is in the ESP's ftp implementation and the limit of one connection only.
The mount and listing works, but any file operation failed. Apparently curlftpfs tries to open up a new connection for file operations, something that the ESP will not handle.
Filezilla works fine.

potul

You are the boss!!

I see that at the end you are using T0 to trigger the program reload, right? So switching to internal and then external memory again?

I will scroll through your code and reuse some of it if you don't mind. I'm planning to build something similar but slightly different as I want to have the ESP included in the pedal.
I already have part of the code done, but I might want to optimize it if yours looks better. :)

Thanks!




free electron

Yes, i used the T0 as it's separate from whatever might be switching the programs on the target board. Otherwise some kind of ORing would have to be added. I think this way it will be easier to adapt existing builds.

Sure, use the code.
It should be fairly easy to adapt it for the ESP32 in case you need more IOs, pheripherals or to make it use less power.
An SD card for the filesystem could be another possible option.

I have managed to replace the Flash on a few esp8266 boards installing an 8MB one. The partitioning is set in the platformio.ini file:
; 4MB Flash chip, 1MB for firmware, 3MB disk partition
board_build.ldscript = eagle.flash.4m3m.ld

The list of available options (linker scripts) is here:
https://github.com/esp8266/Arduino/tree/master/tools/sdk/ld

IE, for an 8MB flash chip with 1MB reserved for the firmware and almost 7MB for the filesystem that line would look  like this:
board_build.ldscript = eagle.flash.8m7m.ld

potul

I was just peeking at the code. May I ask why you used the inline NOPs as delay routine instead of the standard delay()?


free electron

Interrupts are turned off for the time of sending the data over to the FV-1 to ensure lowest latency. Delay uses timer/interrupts, so it can't be used here.
I was also getting a watchdog triggered occasionally, hence i'm resetting it inside that function.
The fact that FV1 always requests 512 bytes + we do not have to care about the initial EEPROM address decoding simplifies the i2c slave handling to the point it can do the 250-300KHz clock rate.
Within limits of course, clocking the FV-1 with 48KHz will not work with the ESP board.

potul

I see, I didn't notice you were disabling interrupts BEFORE toggling T0. Makes sense.

pruttelherrie

Quote from: free electron on January 22, 2021, 03:24:33 AM
Btw, i tried to use curlftpfs to mount the disk a directory, but it won't work. The problem is in the ESP's ftp implementation and the limit of one connection only.
The mount and listing works, but any file operation failed. Apparently curlftpfs tries to open up a new connection for file operations, something that the ESP will not handle.
Filezilla works fine.

I wanted to try this FUSE ftpfs: https://github.com/rr-/ftpfs to see if it would work with one connection, but I'm running into problems compiling.
I didn't have the SparkFun External EEPROM Arduino Library, so I put this in the platformio.ini:


lib_deps =
     sparkfun/SparkFun External EEPROM Arduino Library @ ^1.0.3


however now I get the following error:


.pio/libdeps/esp12e/SparkFun External EEPROM Arduino Library/src/SparkFun_External_EEPROM.h:59:19: error: This platform doesn't have a wire buffer size defined. Please contribute to this library!
#pragma GCC error "This platform doesn't have a wire buffer size defined. Please contribute to this library!"


Looking at SparkFun_External_EEPROM.h, it turns out it cannot be used on ESP8266? Did you modify the library (add a wire buffer size definition I guess) to get it to compile?

pruttelherrie

Followup. I added the following to SparkFun_External_EEPROM.h, according to some shady websites 64 should be the correct size.


#elif defined(ESP8266)
#define I2C_BUFFER_LENGTH_RX 64
#define I2C_BUFFER_LENGTH_TX 64


Compiled & uploaded, wrote the data/ folder to the ESP and it seems it works (I can access the webpage, haven't connected it to any FV-1 pedal yet).
Installed that Python ftpfs but I cannot get it to work. However, testing with a public ftp server (ftp.freebsd.org) it doesn't work either *sigh*

Would be awesome to get the filesystem mounted so that SpinCAD hex files can be written directly to the ESP!

free electron

#10
I see i forgot to copy the eeprom library when i was setting up the repo. Yes, i did some changes to it.
Updated, clone it again and it should work.

The FTP lib has this "limitations" section:
Quote
Server only allows one ftp control and one data connection at a time. You need to setup Filezilla (or other clients) to respect that, i.e. only allow **1** connection.
(In FileZilla go to File/Site Manager then select your site. In Transfer Settings, check "Limit number of simultaneous connections" and set the maximum to 1.)
This limitation is also the reason why FuseFS based clients (e.g. curlftpfs) seem to work (i.e. listing directories) but will fail on file operations as they try to open a second control connection for that.

potul

I don't know what the hell I'm doing wrong but I'm getting an error

"expected class-name before '{' token class WiFiServer : public Server {"

when trying to compile. It's like it cannot recognize Server as a class.

I've traced all the includes, and it looks ok... Server.h is there as part of the core arduino libraries.

free electron

Are you on Windows?
Windows file names are not case sensitive, unix/linux are.
I named the file server.h, but apparently there is a Server.h in the Arduino core.
On Linux these are two different files, on windows not.
Solution:
change the name of the server.h + server.cpp (the ones in my repo)  to something else, like fv1_server.h, fv1_server.cpp + all the includes.
I've just updated the repo, please try the most recent commit.


potul

oh shit, this might be the issue.... I did not think on the file name. I was aware of the server vs Server, but I was thinking on the definitions, not the files.
I'll be back in 10 minutes....

potul

ok, that was it... changing names of server.h and server.cpp fixed the error.

Thanks!


Have you JUST changed the repo? I downloaded it 3 hours ago...

potul

Nevermind, I just checked and see you modified the names. That was a fast reaction  :icon_mrgreen:

free electron

Yes, that was a small and quick change :)
Glad it worked out!

I've run into similar problems a few times in the past. Usually working on customized local for project libraries in platformio.

Btw, have you tried the WinSCP for the FTP/mount as disk thing? Apparently it does what we need, can sync folders over ftp.

pruttelherrie

Quote from: pruttelherrie on January 24, 2021, 03:00:08 PM
Would be awesome to get the filesystem mounted so that SpinCAD hex files can be written directly to the ESP!

Since I'm on Linux (Debian), WinSCP won't do, but I found another convoluted way to get this to work:

  • populate ~/.netrc with the hostname/username/passwd of the ftp server (192.168.4.1/fv1/fv1)
  • make a systemd unit file that watches a folder for changes, then call this:
  • echo 'put path/filename.hex' | ftp 192.168.4.1
I tried it 'by hand' and it works, it uploads the hexfile to the ESP. So when the unitfile works, a hex-export to that folder from within SpinCAD should be enough to get in onto the ESP.

pruttelherrie

Hey Piotr,

I was playing with the code on a NodeMCU D1 mini I had lying around, on my Linux laptop. I noticed the following: the hexfiles that SpinCAD generated in the past has lines which were only 0x0A terminated. The FV1-devRemote would not enable these files, complaining it's not a valid FV1 fle. After using unix2dos <filename>, evrything would work fine. Could you modify the function FV1::load_file(path) so that it accepts all possible line-terminations? (I believe it is Windows=CRLF, Unix=LF, Mac=CR). I believe the code checks for \n which is an LF so my story above does not make sense?!?  :icon_confused:

free electron

Hey,
i'll look into this. Generally it's a mess with OS dependant line endings.
\n is 0x0A and it's a standard line ending on Linux, we have three options:
  \n - linux
\r\n - windows
\r   - mac

\n should work for both linux and windows, since the data length is encoded in the record. The \r will be ignored.
Mac will fail. I'll try to implement a check for the used line ending before the file is processed. First look for '\n' and if found use it as the line ending. If failed - look for '\r'.
However in your case the problem might be somewhere else. What is the file size in bytes generates by the SpinCad?
The program checks for the length of a file generated by the SpinAsm (21517 bytes) even before it starts to read the lines.
It happens here:
    if (hexfile.size() != FV1_HEXFILE_SIZE)
    {
        hexfile.close();
        boot_complete = 1;
        return FV1_INPUT_FILE_WRONG;
    }

FV1_HEXFILE_SIZE is defined at the top of the fv1.cpp file. Try to put the length of the SpinCad hex output and see if it works.
Length matching will have to be also updated, depending on the detected OS.
Actually, i have been thinking about changing that part of the code to allow writing shorter files (minimum 1 patch of 512 bytes).