-
I uploaded the fork to our repository for review/use. Right now it's set to use the TerminusT2 hardware in the makefile, but a swap to the discovery the hardware will be correct. I also made some slight adjustments in the clock usage. Now you can define the clock in the makefile, just set the divider so that it matches (8Mhz w/ 8, 16Mhz w/ 16).
https://github.com/JanusRC/T2-Terminus/tree/master/espruinoT2
The main adjustments that pertain to the SD card are:
ifdef USE_FILESYSTEM_SDIO DEFINES += -DUSE_FILESYSTEM_SDIO ifeq ($(FAMILY), STM32F4) SOURCES += \ libs/filesystem/fat_sd/stm32f2_4_diskio.c \ libs/filesystem/fat_sd/stm32f2_4_sdio_sd.c else SOURCES += \ libs/filesystem/fat_sd/sdio_diskio.c \ libs/filesystem/fat_sd/sdio_sdcard.c endif else SOURCES += \ libs/filesystem/fat_sd/spi_diskio.c endif endif #!LINUX endif
And in the board.py file:
'SD' : { 'pin_cmd' : 'D2', 'pin_d0' : 'C8', 'pin_d1' : 'C9', 'pin_d2' : 'C10', 'pin_d3' : 'C11', 'pin_clk' : 'C12' },
If you want to use the bitbanged SPI, you'd have to remove the SDIO defines.
File additions that get called:
-stm32f2_4_diskio.c
-stm32f2_4_sdio_sd.c
-stm32f2_4_sdio_sd.hAs Clive1 mentioned, it'll work correctly if you boot the device up and initialize the library with the SD card in place. If you remove it and re-insert then it breaks, for now anyway.
-
Oh wow, that totally works. Quick test on a random sd card I have.
>var spi = new SPI(); ={ } >spi.setup({mosi:D2,miso:C8,sck:C12}); =undefined >E.connectSDCard(spi,C11); =undefined >console.log(require("fs").readdirSync()); [ "debug", "dtbs", "MLO", "u-boot.img", "zImage", "initrd.img", "uEnv.txt", "ID.txt", "SOC.sh", "flash-eMMC.txt", "App", "Drivers", "Docs", "scripts", "autorun.inf", "LICENSE.txt", "README.htm", "README.md", "START.htm", "uInitrd" ] =undefined Uncaught SyntaxError: Got ?[173] expected EOF at line 1 col 41 console.log(require("fs").readdirSync()); >console.log(require("fs").readFile("autorun.inf")); [Autorun] shellexecute=START.htm icon=Docs\beagle.ico label=BeagleBone Getting Started action=Open BeagleBone Getting Started Guide [DeviceInstall] DriverPath=Drivers\Windows\FTDI DriverPath=Drivers\Windows\RNDIS =undefined >
Not sure if that Syntaxerror is anything of note, but it does work. Just built it for the 32F4DISCOVERY since my other board isn't on hand.
'SD' : { 'pin_cs' : 'C11', 'pin_di' : 'D2', 'pin_do' : 'C8', 'pin_clk' : 'C12' },
It didn't like the USE_FILESYSTEM define without at least having the pins declared in the board.py
That's great though. I'm sure it'll help a lot of people out.
We're still bound and determined to get the SDIO library working. We have it at least compiling for the Discovery, whether it actually works I dunno yet, going to try that out next.
-
Otherwise as @DrAzzy says, I'll be including the ability to use the SD card on any pins. It won't be SDIO (in fact it'll just be software SPI if you haven't got the SD card connected to a hardware SPI port), but it should work well enough.
Bitbanged SPI is a nice workaround for pre-existing hardware, and would work pretty well I'd bet. I don't suppose there's any ETA on beta firmware for that is there? If it's remotely close I'll just move to the other peripherals and hang tight.
The issue is probably that the SDIO driver is designed for the STM32F1 parts, and you're trying to use in on an STM32F4. You could try and change the code so that it would handle STM32F4 too, but that might be quite hard work.
Yeah I spent quite a while looking at that today and trying to adjust the sdio_* files and various includes to use a discovery board SDIO example, but no real luck yet on that. I'd imagine with the DiscoveryBB using SDIO I won't be the only one to ask though. I should be able to mainly focus on these files for that, right?
diskio
sdio_diskio
sdio_sdcard
ff -
So I've gotten my project to a point where I can bring up the primary function and run some basic autonomous cellular demonstrations (I'll pop that code up into the projects section shortly here), and found what needed to be adjusted for 16Mhz operation. However, now that I've got that running I want to try and get my major peripherals up and usable. One of them is an SD card, which unfortunately is connected via SDIO, and I can't get a successful compile.
Adding this to my board file:
'SD' : { 'pin_cmd' : 'D2', 'pin_d0' : 'C8', 'pin_d1' : 'C9', 'pin_d2' : 'C10', 'pin_d3' : 'C11', 'pin_clk' : 'C12' },
It matches the HY, conveniently.
Makefile info:
else ifdef T2_STM32F4 EMBEDDED=1 USE_FILESYSTEM=1 USE_FILESYSTEM_SDIO=1 DEFINES += -DUSE_USB_OTG_FS=1 BOARD=T2_STM32F4 STLIB=STM32F40_41xxx PRECOMPILED_OBJS+=$(ROOT)/targetlibs/stm32f4/lib/startup_stm32f40_41xxx.o OPTIMIZEFLAGS+=-O3
I see this in the jsrap_fs.c file
It is currently only available on boards that contain an SD card slot, such as the Olimexino and the HY. It can not currently be added to boards that did not ship with a card slot.
But I know that it's possible to use the USE_FILESYSTEM=1 on the STM32F4DISCOVERY with added on SD card slot (saw the thread noting it), but I guess before I continue digging in the wrong areas of code I was just curious if this was even possible in the current build, or what I'd have to modify if it isn't.
Running a make with one or the other compiles, it's just not happy with both defines on an STM32F4 based build.
-
Okay, so I kinda followed what you have there, expounding on what I had started previously. Now I've written a small function to grab the incoming data and pop the information to a buffer that I can check at any time.
var mdmBuffer = ""; //Main storage buffer var mdmURCBuffer = ""; //URC Buffer var mdmParsedBuffer = ""; //AT Response buffer Serial6.on('data', function (data) { //This event grabs incoming data and concatenates it into a buffer //The buffer is scanned for identifiable modem AT responses and handles URCs. //This assumes a regular cleanup of the main buffer in your flow. var idx1 = -1; var idx2 = -1; mdmBuffer += data; //Scan for common AT responses, need to search for these as //sometimes you can get multiple CRLF and throw off other checks if (mdmBuffer.indexOf("#")>=0 || mdmBuffer.indexOf("+")>=0 || mdmBuffer.indexOf("$")>=0 || mdmBuffer.indexOf(">")>=0 || mdmBuffer.indexOf("ERROR")>=0 || mdmBuffer.indexOf("OK")>=0) { //Found one of these if (mdmBuffer === "\r\nOK\r\n") { //Straight up OK response, no other return mdmParsedBuffer = "OK"; } if (mdmBuffer === "\r\nERROR\r\n") { //Straight up ERROR response, no other return mdmParsedBuffer = "ERROR"; } if (mdmBuffer.indexOf("#")>=0 || mdmBuffer.indexOf("+")>=0 || mdmBuffer.indexOf("$")>=0) { //Found one of these //Could be a URC or an AT response //Put these to a buffer we can call upon at runtime or service through //a set interval. If we print these immediately they may not be read/full. if (mdmBuffer.indexOf("OK")>=0) { //If there's an OK in here, it's not a URC mdmParsedBuffer = mdmParseResponse(mdmBuffer); } else mdmURCBuffer = mdmParseResponse(mdmBuffer); } } }); function mdmParseResponse(inSTR) { //This function parses out the responses to readable format //It recognizes non-AT style responses by the \r\n and just returns them. if (inSTR !== -1 && inSTR.length > 0) { rtnSTR= inSTR; if (inSTR.indexOf('\r\n',0) !== -1) { splitList = inSTR.split('\r\n'); rtnSTR = splitList[1]; } } return rtnSTR; }
and some little helper functions
function mdmClearBuffer() { //Clears the main buffer mdmBuffer = ""; } function mdmPrintBuffers() { //Prints out the main buffers to console console.log("mdmBuffer = " + mdmBuffer); console.log("mdmURCBuffer = " + mdmURCBuffer); console.log("mdmParsedBuffer = " + mdmParsedBuffer); } function mdmSendAT(data) { Serial6.println(data); }
Output
mdmSendAT('AT+CREG?')
=undefined
mdmPrintBuffers()
mdmBuffer =
+CREG: 0,2
OK
mdmURCBuffer = +CRE
mdmParsedBuffer = +CREG: 0,2
=undefinedSo overall it's similar to what I had before, just done more automatic and doesn't require calling a receive/parsing function separately, which is nice.
Now the question is how do I actually take this further and if it's even possible, as in, is it possible to automate something that I want done. I'm trying to wrap my head around what normally gets done for this and it's getting a little muddy.
An example would be something simple like reading an I/O and sending an SMS upon a desired state. I feel like I'm going to be creating a bunch of little functions, and a larger function that gets an interval set and passed the desired small function to run, so that it can run the network checking and whatnot when required.
Hmm, I feel like this should be moved to the projects/JS area so it's not muddying up the General area.
-
Yeah I'd like to have a few options.
- A direct cross terminal, which is easily accomplished with the Serialx.on with a write to the oppositng port. I could also put them to a loopback too, I suppose. Right now I've got the xterminal going with USB as my kind of watch port.
- What you're suggesting, which is pretty great actually.
- A little more autonomous functionality that I could call a send so that higher level functions could be implemented for bigger things such as socket dials.
Having trouble with #3 right now. Any particular reason this wouldn't work? Right now it's like if I sent anything to the port I can't loop and read or check availability from that port in waiting, it needs to come back to the terminal or I need to utilize setTimeout.
function Test(inSTR, timeOut) { var TO=getTime() + timeOut; //set timeout in seconds Serial6.println(inSTR); while (getTime() < TO) { if (Serial6.available() > 0) { console.log("Success."); return 1; } } return -1; }
So Test('AT+CREG?',2) simply comes back with a timeout in this case.
This is probably something silly that I'm not taking into account.
I've tried implementing other options such as using a Serial6.on to just parse and put to a buffer, but I'm having trouble with what appears to be scoping (my JS is awful, kind of learning as I go).
- A direct cross terminal, which is easily accomplished with the Serialx.on with a write to the oppositng port. I could also put them to a loopback too, I suppose. Right now I've got the xterminal going with USB as my kind of watch port.
-
Hi Gordon,
I'm porting it over to this guy: http://www.janus-rc.com/T2Terminus.html
I wanted to see how Espruino would work for this device, since currently it's a pretty open platform, but it's certified for network usage.
I've been away from it for a few days, but back at it now and working on exploring Espruino and writing some modem controlling functions to start with.
Quick question since I can't seem to find it anywhere. Is there a way to grab data from the console itself or is that not possible? It seems like I need to have console as a dedicated port such as USB, and then do serial.read/serial.writes to the other ports if I want to manipulate information.
-
HI Gordon, thanks for the response.
Okay, so after playing with the ST libraries, I still couldn't get it to function. No LED flashing, no nothing.
I did the drastic thing and just cut the traces, hacking in an 8Mhz crystal. After putting things back to normal I'm happy to say that I see the nice greeting on the terminal.
Now that I have life I need to figure out what I didn't set to get the higher speed working, as well as start playing with the I/O and writing a library.
-
Hi,
I'm trying to utilize Espruino on the larger STM32F405 package, and having some trouble with getting it to even boot. I've been able to successfully compile and load espruino to an STM32F4DISOVERY on a ubuntu box, and I've also got an Espruino board coming from adafruit to play with directly (I want to see how it does as a nice little protocol tester for some of my devices), but the migration to the larger package for a design already in place is just leaving me puzzled.
I believe I've changed the basic required information to what's needed, and didn't see anything that was obvious in the target libraries (although I could be overlooking an HSE adjustment there?).
Main differences:- The larger package.
- The board uses a 16Mhz oscillator.
- Some things like the SD card have different connections so I've left them undefined for now.
I've taken a few bits and pieces from the smartwatch board configuration to account for the speed change, but it looks to need some heavy updating, so I don't know if that was the best move.
T2_STM32F4.py pertinent info
import pinutils; info = { 'name' : "T2 STM32F4", 'link' : [ "http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252138" ], 'default_console' : "EV_SERIAL3", # USART3 by default. USART6 goes to the embedded modem 'default_console_tx' : "B10", # USART3_TX on PB10 'default_console_rx' : "B11", # USART3_RX on PB11 'default_console_baudrate' : "115200", # Baudrate default 'variables' : 5450, [#Leaving](https://forum.espruino.com/search/?q=%23Leaving) it same as the discovery. 'binary_name' : 'espruino_%v_T2stm32f4.bin', }; chip = { 'part' : "STM32F405ZGT6", 'family' : "STM32F4", 'package' : "LQFP144", 'hse' : 16000000, # oscillator 'ram' : 192, 'flash' : 1024, 'speed' : 168, 'usart' : 6, 'spi' : 3, 'i2c' : 3, 'adc' : 3, 'dac' : 2, }; # left-right, or top-bottom order board = { }; devices = { 'OSC' : { 'pin_1' : 'H0', 'pin_2' : 'H1' }, 'OSC_RTC' : { 'pin_1' : 'C14', 'pin_2' : 'C15' }, 'LED1' : { 'pin' : 'E12' }, 'LED2' : { 'pin' : 'E13' }, 'LED3' : { 'pin' : 'E14' }, #'LED4' : { 'pin' : 'D15' }, #'BTN1' : { 'pin' : 'A0' }, 'USB' : { #'pin_otg_pwr' : 'E14', 'pin_dm' : 'A11', 'pin_dp' : 'A12', 'pin_vbus' : 'A9', 'pin_id' : 'A10', }, #'SD' : { 'pin_cs' : 'D2', # 'pin_di' : 'B15', # 'pin_do' : 'B14', # 'pin_clk' : 'B13' }, #'MEMS' : { 'device' : 'LIS302DL', # 'pin_cs' : 'E3', # 'pin_int1' : 'E0', # 'pin_int2' : 'E1', # 'pin_mosi' : 'A7', # 'pin_miso' : 'A6', # 'pin_sck' : 'A5' }, #'MIC' : { 'device' : 'MP45DT02', # 'pin_clk' : 'C3', # 'pin_dout' : 'B10', }, #'AUDIO' : { 'device' : 'CS43L22', # 'pin_sda' : 'B9', # 'pin_scl' : 'B6', # 'pin_mclk' : 'C7', # 'pin_sclk' : 'C10', # 'pin_sdin' : 'C12', # 'pin_lrck' : 'A4', # 'pin_nrst' : 'D4', # }, }; board_css = """ """; def get_pins(): pins = pinutils.scan_pin_file([], 'stm32f40x.csv', 6, 9, 10) return pinutils.only_from_package(pinutils.fill_gaps_in_pin_list(pins), chip["package"])
Makefile pertinent info
else ifdef T2_STM32F4 EMBEDDED=1 DEFINES += -DUSE_USB_OTG_FS=1 DEFINES+=-DHSE_VALUE=16000000UL BOARD=T2_STM32F4 STLIB=STM32F40_41xxx PRECOMPILED_OBJS+=$(ROOT)/targetlibs/stm32f4/lib/startup_stm32f40_41xxx.o OPTIMIZEFLAGS+=-O3
I checked the generated pin information and it appears to be okay. Some oddities are the pin labels like below though... although below it shows the define as pin 27 and 27? PB10/PB11 are pins 69 and 70. I see the LED defines are labeled as INDEX, so I'm guessing I'm just reading this wrong and these are offsets, not the actual pin numbers. I did a sanity check with the discovery board it's similar, but just in case her's the info:
DEFAULT_CONSOLE_DEVICE EV_SERIAL3 DEFAULT_CONSOLE_TX_PIN 26/* B10 */ DEFAULT_CONSOLE_RX_PIN 27/* B11 */ DEFAULT_CONSOLE_BAUDRATE 115200
Am I missing something obvious? After a reset I get nothing out of the USB at all. The USB connections are identical to the discovery. I was going to try and remove the 16Mhz oscillator and bump it down to an 8Mhz one just in case but I figured the above should cover that.
- The larger package.
After coming across Espruino and really liking what it had to offer, I was able to convince my team that a port to our hardware could be a really beneficial endeavor. I started work on doing the port, and roped in a team member who helped me get some of the more nuanced things working, such as the SDIO FS usage.
Bit of a primer
Janus RC is an M2M company that I work for, we offer fully certified devices for usage on various networks, through the use of Telit brand modems. While not always in the expense range of the maker type of project, we take care of the massive front end costs that accompany network certification, such as PTCRB. Our plug in devices are more akin to what users here would look for. This particular port is for our T2 Terminus, which is an STM32F4 powered device.
@Gordon - If you have any issues with my documentation/naming schemes of things, just let me know.
On to the fun stuff
Enough with the wordy preamble. You want code/examples, and you shall have them!
We've written some modules that can be used as building blocks for an M2M/cellular application, leaning on the modem's stack to handle basically everything you'd want. Although they are geared for Telit modems, you could simply tool the flow to fit your modem of choice... many basic AT commands overlap as standard (+CREG, for example). The primary goal is autonomous applications since that's what M2M is really all about.
This is my first Javascript based project, so I'm sure that I've done many things that many not be well executed, or take full advantage of what's available. Criticisms are of course welcome.
Our current repository for this fork:
https://github.com/JanusRC/T2-Terminus/tree/master/espruinoT2/Janus_JS
I won't re-write everything here, as I tried to document usage well in our github with a downloadable user guide. For those who don't want to use that .doc version, I tried to mirror it all in our forum, located here.
Our current modules and code include:
-Modem
4a. Socket Dial to remote host
4b. Socket Listen for a remote client
4c. Socket Listen for remote client, with remote control of the console.
-Other
A note about the AT handler:
AT Command handler, uses an iterative approach to commands since Espruino currently cannot do something like "send AT command, wait for response" in a single loop. It must return to idle state for backend processing of the received data. This will likely improve later with a more streamlined approach. For now, you simply send the command twice to fetch the response.
Example AT send/receive:
Example registration demo: