-
Goal:
I want to accurately update the STM32F4 RTC:- using a GPS pulse per second (PPS) signal or
- using the GPS RTC as external reference clock
Some background:
I am using the following hardware
- STM32F4 Discovery board
- MikroElektronika STM32F4 Discovery shield
- MikroElektronika GPS click board (ublox LEA-6S receiver)
which pretty much looks like this:
So far I have integrated the GPS receiver into my project pretty well and have extended the basic GPS module to include configuration commands and a few other features.
The STM32F407 has a highly capable, built-in RTC which I would like to make use of within the Espruino JavaScript environment.
For the inquisitive, the ST manual on how to use the RTC can be found here.
From what I can see I have the following options to synchronise the STM32F4 RTC:
- The RTC calendar can be synchronized to a more precise, remote clock using the RTC shift feature (see page 19 of the ST RTC manual for more details).
- Use the "zero on write" method as described in the "Clock Synchronisation Methods" link below.
- Figure out RFC2783 and RFC1589 and hack something using the PPS signal (as used in the gpsd Linux project).
- Hack something according to the IEEE1588 Precision Time Protocol.
Questions:
- I'd appreciate some guidance on how to expose the functionality contained in stm32f4xx_rtc.c to the Espruino JavaScript interpreter.
- Has anybody tried to synchronise the RTC to a more precise, external time source and is willing to share some tips?
References:
Here are a few interesting links that have edified me somewhat: - using a GPS pulse per second (PPS) signal or
-
Edit: My apologies. I found it :)
=========================
@user6350 thanks so much for this wonderful code base to learn from!I have one question concerning your code. On lines 38 and 39 you have the following function calls:
tracking("RMC"); tracking("GGA");
However I don't see where this tracking function is defined. Could you please clarify?
Many thanks.
Roy -
Not sure what is going on but there must be something more at play here. I have also just tested all the above cases again, making sure to remove the card completely from the slot, and still no joy :(
Out of desperation I even removed and replaced the whole microSD click board from the mikroBUS slot while powered up and I still got the same errors!
The only difference I can think of is the card detect (CD) pin going low upon card extraction and going high upon re-insertion. I wonder whether that change isn't causing some confusion in the code somewhere?
I'm off visiting a friend for the next few days so my involvement here could be a bit sporadic.
-
@Gordon thanks for this addition. I cloned the latest from Git, compiled it and am testing it out. This is what I see:
Case 1.1
A small change to case 1. Instead ofDISK_ERR
errors I'm gettingNOT_READY
errors_____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |_____|___| _|_| |___|_|_|_|___| |_| http://espruino.com 1v70 Copyright 2014 G.Williams >var f = require("fs").readFile("test.txt"); ="hello\n\n" >E.unmountSD(); =undefined // removed card >var f = require("fs").readFile("test.txt"); ERROR: Unable to mount SD card : NOT_READY =undefined // re-inserted card >var f = require("fs").readFile("test.txt"); ERROR: Unable to mount SD card : NOT_READY =undefined >reset(); =undefined _____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |_____|___| _|_| |___|_|_|_|___| |_| http://espruino.com 1v70 Copyright 2014 G.Williams >var f = require("fs").readFile("test.txt"); ERROR: Unable to mount SD card : NOT_READY =undefined
Case 2.1
A slight change to case 2. This time aNOT_READY
error instead of aDISK_ERR
error.// fresh restart >var f = require("fs").readFile("test.txt"); ="hello\n\n" >E.unmountSD(); =undefined //Removed card and re-inserted without file operation >var f = require("fs").readFile("test.txt"); ERROR: Unable to mount SD card : NOT_READY =undefined
Conclusion
Just to check, I just tried 'Case 1' here on the Espruino Board and it works fine - so I'm pretty surprised that yours is different as it's using the same code.
I guess it may be possible that you didn't do a make clean before building with the filesystem enabled, and that meant that somehow reset() didn't reinitialise the SD card?
I did forget to do
make clean
last time but not this time. For me callingreset()
still isn't workingThe problem is that jswrap_fs_kill is actually called from reset(), so if that doesn't solve the problem then there's something else...
I think there has to be something else. Using the very latest Github version, calling
E.unmountSD()
has only managed to changeDISK_ERR
errors intoNOT_READY
errors. -
Unfortunately a soft reset doesn't do the trick @Gordon. This is what happens:
Case 1:
// fresh restart _____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |_____|___| _|_| |___|_|_|_|___| |_| http://espruino.com 1v70 Copyright 2014 G.Williams >var f = require("fs").readFile("test.txt"); ="hello\n\n" // remove card >var f = require("fs").readFile("test.txt"); ERROR: Unable to read file : DISK_ERR =undefined // re-insert card >var f = require("fs").readFile("test.txt"); ERROR: Unable to read file : DISK_ERR =undefined >reset(); =undefined _____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |_____|___| _|_| |___|_|_|_|___| |_| http://espruino.com 1v70 Copyright 2014 G.Williams >var f = require("fs").readFile("test.txt"); ERROR: Unable to mount SD card : NOT_READY =undefined
However if I hit the reset button on the board or cycle the power then everything comes back to life.
Case 2:
Does the error happen if you pull the card out and re-insert it, without doing any file operations when it is removed?
Yes, the
DISK_ERR
also occurs in this case:>var f = require("fs").readFile("test.txt"); ="hello\n\n" //Removed card and re-inserted without file operation >var f = require("fs").readFile("test.txt"); ERROR: Unable to read file : DISK_ERR =undefined
Case 3:
I thought out another situation that could occur:
- Fresh restart.
- Card removed and re-inserted.
- Attempt to read from card.
This still works. So it seems a problem arises only once you have already performed a previous card read/write and then remove/re-insert the card, with or without doing any file operations while removed.
If the error only happens if you read when the card is removed, I'd just explicitly check the value of the card detect pin, and not do anything when it's disconnected.
Yes, that is what I thought I'd do. Hardware wise however, as you pointed out, this isn't possible with the Espruino board as the card detect pin is not wired up. Also, it seems from the second case illustrated above, that if you have already performed a file operation, then remove and re-insert the card without any further file operations (blocked by not detecting a card) and then attempt a file operation post re-insertion, you still have a problem.
think something needs to be reset, but the filesystem code we have just doesn't do so yet.
Yes, this is my suspicion too @DrAzzy. It probably has to be looked at in the C code. Not exactly my strength...yet :).
I would have it a guess that upon detecting the card removal (assuming this hardware functionality is available), that the
jswrap_fs_kill()
function in jswrap_fs.c should be called.I don't suppose it absolutely must happen in the C code. The main thing is the handle to the FATFS needs to be renewed...I think :)
- Fresh restart.
-
This is a follow on from my previous discussion concerning the microSD card.
With all my bits and pieces connected up and working, when I run the following command, assuming a text file called
test.txt
is already on the microSD card which contains the word hello followed by an empty line:>var f = require("fs").readFile("test.txt"); ="hello\n\n"
If, while my system is running, I remove the microSD card and re-run the above I get the following response:
>var f = require("fs").readFile("test.txt"); ERROR: Unable to read file : DISK_ERR =undefined
replacing the card and re-running the same command still produces the
DISK_ERR
.My questions:
- Is this expected behaviour?
- Should I implement error checking to prevent getting this error upon re-inserting the microSD card while the system is live?
- If so, any suggestions how?
Temporary solution
The only way I can get the read to work again is to reset everything. - Is this expected behaviour?
-
-
Well what do you know, it is working! :)
Wandering in the wilderness
Since my last post I delved right down into the SD specification to try and figure out what should be happening. I found a few particularly helpful posts and documents that I'd like to share here for others having similar problems:
- SD Specifications - Part 1 - Physical Layer - Simplified Specification - Version 4.10
- Reading SD cards with the STM32F4-Discovery
- Micro SD Data Sheet
- Secure Digital Card Interface for the MSP430 - Dept. of Electrical and Computer Engineering, Michigan State University
and it even got me ferreting through the C code ;)
Thanks to reference #2 above I found out what should be happening with the card detect (CD) pin when the card is put into the slot. Everything was in order.
Still no joy!
For some reason I decided to use another set of pins and see what happened. This is the current standing of the SD definition block in
boards/STM32F4DISCOVERY.py
:'SD' : { 'pin_cs' : 'D7', 'pin_di' : 'B5', 'pin_do' : 'B4', 'pin_clk' : 'B3' },
I connected her up, ran my command and this is what I got:
>var f = require("fs").readFile("test.txt"); ="hello\n\n"
followed by a write just to make sure it really was working:
>var f = require("fs").writeFile("blah.txt","hello"); =true
So I'm not quite sure what is wrong with the other set of pins but at least it is now working and I have learnt a bunch of stuff I never thought I'd have to!
Thanks again for all your help @Gordon.
- SD Specifications - Part 1 - Physical Layer - Simplified Specification - Version 4.10
-
-
Thanks for the suggestion @Frida. Unfortunately it still gives the same error:
This is what I saw in my two attempts, this time monitoring the CS and DI pins. **First attempt** I started by executing the following command to set the CS pin low:
B12.write(false);
I then followed this up with the file read command:
var f = require("fs").readFile("test.txt");
```and saw the following on the scope:
Second attempt
This time I just ran the file read command and saw the following on the scope:
Conclusion
From this it seems the chip select pin is being set correctly.
Any other ideas?
-
Unfortunately still not working.
So I did the following:
- double and triple checked my pinout in
boards/STM32F4DISCOVERY.py
. No problem there. I reformatted both of my microSD cards as follows:
sudo mkdosfs /dev/sdg1 -F 32 -I
I connected up my oscilloscope to pins PB15 (DI) and PB14 (DO) as suggested, ran the following command:
var f = require("fs").readFile("test.txt");
and captured this image where channel 2 (blue) is PB15 (DI):
Figure 1: Oscilloscope image showing the DI (blue) and DO (yellow) pin states while attempting to read from the SD card.So it seems it is at least addressing the correct pins.
Pinout differences:
I then remembered comparing the pinouts of the Espruino board SD card holder schematic with those of the MikroElektronika microSD click board. Below is a side by side image of the two.My observations:
- pin 9 (CD) is connected up on the MikroElektronika board. Initially I didn't know what this pin was for but after reading the Adafruit microSD breakout board tutorial I see it is the card detect pin which shorts to ground when a card is inserted. This pin is not connected on the Espruino schematic. No idea what the consequences are of this difference.
- there are a number of differences with the ground connections (G2, G3, G4) on the Espruino board which the MikroElektronika doesn't show in as much detail.
Any tips @Gordon?
Once again many thanks.
Roy
- double and triple checked my pinout in
-
Sweet! So that solved the
Uncaught Error: Function "log" not found!
problem however the issue with the SD card is still there.This is what I did:
- Created a text file on my Linux system (using vim) called,
test.txt
in the root of the microSD card which contains a single line of text, namelyhello
. I then connect my hardware setup, as explained in my previous post, to the Web IDE and run the following line of code with the associated response:
>var f = require("fs").readFile("test.txt"); ERROR: Unable to mount SD card : NOT_READY
Any ideas @Gordon?
- Created a text file on my Linux system (using vim) called,
-
Okay @Gordon I went through the process and everything goes fine until I connect to the board in the webIDE. I get the following message in the console:
>echo(0); Uncaught Error: Function "log" not found! at line 1 col 9 console.log("<<"+"<<<"+JSON.stringify(process.env)+">>>"+">>... ^
I swear I didn't delete the log function :)
Running something simple like
1+2
returns the correct answer.I put a simple text file on the SD card (
text.txt
) and then tried to read it out (it simply contains the word 'hello') like this:>var f = require("fs").readFile("test.txt"); ERROR: Unable to mount SD card : NOT_READY
Any tips?
This is exactly what I did to get to this point:
git clone -b RELEASE_1V69 https://github.com/espruino/Espruino.git espruino_1v69
The relevant sections of my
Makefile
look like this:STM32F4DISCOVERY=1 ... RELEASE=1 ... else ifdef STM32F4DISCOVERY ... USE_FILESYSTEM=1
and the
boards/STM32F4DISCOVERY.py
:devices = { ... 'SD' : { 'pin_cs' : 'B12', 'pin_di' : 'B15', 'pin_do' : 'B14', 'pin_clk': 'B13' }, };
I then just ran the command
make
and out poppedespruino_1v70_stm32f4discovery.bin
(I was expecting a file with a1v69
version).I must say I can't figure out how to use
stm32loader.py
. With both USB cables plugged into the Discovery board, without jumpers on theGND-PB2
andBOOT0-VDD
pin pairs the board is mounted on/dev/ttyACM2
.Running the following command:
python scripts/stm32loader.py -k -p /dev/ttyACM2 -evw espruino_1v70_stm32f4discovery.bin
I end up with the following error:
Reading data from espruino_1v70_stm32f4discovery.bin Can't init. Ensure BOOT0=1, BOOT1=0, and reset device Traceback (most recent call last): File "scripts/stm32loader.py", line 554, in <module> bootversion = cmd.cmdGet() File "scripts/stm32loader.py", line 140, in cmdGet if self.cmdGeneric(0x00): File "scripts/stm32loader.py", line 137, in cmdGeneric return self._wait_for_ack(hex(cmd)) File "scripts/stm32loader.py", line 101, in _wait_for_ack raise CmdException("Unrecognised response 0x%x to %s" % (ask, info)) __main__.CmdException: Unrecognised response 0xff to 0x0
So instead I use the
stlink
application as follows:- Disconnect power and put jumpers across the
GND-PB2
andBOOT0-VDD
pin pairs. - Connect up the USB ST-Link cable.
Run the following command:
sudo ./st-flash write espruino_1v70_stm32f4discovery.bin 0x08000000
Everything flashes fine and I can remove the jumpers and restart the board.
- Disconnect power and put jumpers across the
-
That means that you may have to look at another system anyway - or maybe MikroElektronika makes their own F4 board
This is just the prototyping platform. The final product will have a different backplane board with more mikroBUS sockets and will have a processor board something like the MINI-M4 for STM32.
-
Thanks for the help @Gordon. Super snappy response :)
Also, if you want something that 'just works', is cheaper than buying all that, and also helps to pay for all the time I spend on improving and supporting Espruino, you can always buy an Espruino board ;)
I would love to support you but at the moment I am in the process of evaluating Espruino for much larger things. I'm starting my own company and have spent a lot of time looking for a hardware platform to base it on.
So if things work out between Espruino and myself, you and I should talk some more about future collaboration ;)
-
I am trying to get my head around connecting up a microSD card using SPI and wouldn't mind a bit of guidance, especially since I am new to Espruino.
Some background:
I am using the following hardware
- STM32F4 Discovery board
- MikroElektronika STM32F4 Discovery shield
- MikroElektronika microSD click board
which pretty much looks like this:
I have the microSD click board (bottom left in the image above) in the mikroBUS port 1 on the Discovery shield which translates to the following pinout:
mikroBUS port 1:
SD card pin -----------> STM32F4 Pin
2 (CS) -------------------> B12 (CS)
3 (DI) -------------------> B15 (SPI2 MOSI)
5 (SCK) -----------------> B13 (SPI2 SCK)
7 (DO) ------------------> B14 (SPI2 MISO)Goal:
Is obviously to read from and write to the SD card.
I found the following conversation on the Espruino forum where @Gordon alludes how to go about using SPI to get this working but I am still a bit lost.
I see that the filesystem module is only supported on boards with a SD card slot
@Gordon says in his comment above to, "just stick with normal SPI"
Getting the SPI setup seems very straight forward:
SPI2.setup({mosi:B15, miso:B14, sck:B13, baud:?});
SPI setup comments:
- About the baud rate. Should it be half the clock speed, which is 168 MHz (max)?
- Where does the chip select pin (CS, B12) come into play?
Once the SPI is taken care of how does one deal with reading and writing files with normal SPI?
Any help greatly appreciated!
- STM32F4 Discovery board
-
Busy establishing a one-man-band company at http://www.infinitefingers.com. The aim is to create a general purpose, modular, open source, IoT data logging platform and base various products on this platform.
Maybe I didn't explain myself properly @Gordon. As far as I understand things, the crystal is there to prevent the clock drifting by making sure the frequency is exactly 2^15 cycles per second. That doesn't help much if the micro RTC is off by an hour to start with or has a completely incorrect date/time (e.g. after losing power).
What I am aiming to achieve is to have a datalogger, that is installed in some remote place, automatically update its RTC on start up and then once a day (or more frequently if desired) during long term operation from the GPS timestamp (via serial) and the time pulse pin.
As I have applications in the scientific research and energy domains, I'd like to make it autonomous and as accurate as I can to ensure that data collected from a geographically distributed network of my devices can be reliably compared.