Most recent activity
-
- 3 comments
- 2,851 views
-
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.
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: