-
A new gadget arrived today, and a bugfix
01/09/2017 at 22:37 • 0 commentsToday I received the first XH-W1401 specimen (mine has yellow instead of green 7S-LED displays).
Observations:
- The copper area that serves as a heat sink for the "AMS1117 5.0" linear regulator is too small (yes, it gets hot!)
- The 74HC164 unbuffered shift register that drives the LED columns is clocked by PD1/SWIM (of all pins). Let's see what we can do with this.
I didn't start experimenting with it because I had to fix a bug in the number conversion routine first. I added two features (more address words for peripheral devices, and lowercase numbers for base > 10) while I was at it. The new binary is at the usual location.
-
What's the difference between STM8S003F3P and STM8S103F3P6?
01/06/2017 at 20:28 • 14 commentsToday I worked a little on a more complete hardware register map. I copied the map data from the STM8S003 datasheet and converted it into a new stm8s003f3.inc file with a simple AWK script. Make failed because "PC_IDR" was rendered as "PB_IDR". Great, a human touch! After correcting the typo I got the same results as with my original register map file (that doesn't mean that all the map addresses I didn't use before are correct ;-)).
In my little project I always had difficulties telling the "Value Line" STM8S003F3P6 and the "Access Line" STM8S103F3P6 apart. According to the front page of the datasheets the differences are :
STM8S003F3P6 STM8S103F3P6 Flash 8 Kbyte Flash memory; data retention 20 years at 55 °C after 100 cycles
8 Kbyte Flash; data retention 20 years at 55 °C after 10 kcycle
EEPROM 128 bytes true data EEPROM; endurance up to 100 k write/erase cycles
640 byte true data EEPROM; endurance 300 kcycle
Unique ID - 96-bit unique key for each device Shouldn't I have a different include file for the STM8S103F3P6 for the sake of consistency?
Besides the wildly different specs for Flash, the different size of the EEPROM, and the guaranteed write cycles (what does "up to" mean in a datasheet?) there is that one "unique selling point" for an "Access Line" device: the "Unique ID".
What's the "Unique ID" anyway? Using the Forth console on a STM8S103F3P6 I made a dump of the "Unique ID" address range :
$4865 $F dump 4865 0 7 0 3A 2 47 36 30 32 35 36 35 1F 0 0 1F ___:_G602565__ ok
According to the datasheet the numbers mean "xWafer=1792, yWafer=14600, wafer#=2, lot#=higherthanthereareatomsintheuniverse". Quite obviously the datasheet is wrong: ID = [ 7, 58, 2, "G602565" ] is more like it.
Wafer number, lot number, position: all that sounds much more like the data the fab's QA is after. It would be a shame if such critical quality assurance data were not available for "Value Line" devices, wouldn't it?
Let's run the same test on a STM8S003F3P6:
$4865 $F dump 4865 0 1C 0 46 6 47 35 34 37 36 37 37 1F 0 0 1F ___F_G547677____ ok
This looks familiar. Of course, it makes no sense to tailor QA process just for removing a feature that's not listed!
Now I got curious: what about the 640 vs. 128 bytes EEPROM?
hex ulock ok 4000 &640 + . 4280 ok 77EE 427E ! ok 427E ? 77EE ok
Guess what: the STM8S003F3P6 also has 640 bytes of EEPROM!
Be advised: there is no easy way to tell a STM8S003F3P6 and a STM8S103F3P6 apart, and there is a very high risk that you receive fake STM8S103F3 chips when you source from the gray market!
On the bright side, for hobby use you can put your trust in the outstanding quality record of ST, and simply ignore the intimidating reference to "100 cycles" in the Flash characterization. It's probably more like 10k, and then only if you have data retention requirements of "20 years@55 °C". Otherwise I'm, quite sure, the trusty device on the breadboard will tolerate 20k erase/write cycles (and if not, dump it).
Ah yes, and you can use the additional 512 bytes EEPROM, too. Other than the QA guarantees, the front page of the data sheet, and the missing description of the "Unique ID" the devices are the same. The STM8103F3 datasheet even has the same error as that of it's cheaper twin: the symbol PC_IDR is missing in the port mapping. too ;-)
EDIT: Paul found a STM8S003F3 chip with considerably less EEPROM memory than 640 bytes (but still more than 3x the size specified in the datasheet). So please be aware that you might "get what you paid" for & "YMMV". -
Bump to v2.2.4: adding the SWIMCOM target, and more
01/05/2017 at 19:58 • 0 commentsThis release has been almost 10 days in the making.
The most important changes are:
- improved console communication options, e.g. through a single port D GPIO pin (like PD1/SWIM)
- simultaneous communication in console and background task is possible
- configurable character I/O code is now part of the core (no more merging into board code)
- board I/O code (board key input, 7S-LED output) was split into core and board code
- a new target SWIMCOM with console communication through PD1/SWIM was added for exploring unknown boards.
With these changes it's much easier to support new boards without needing to merge core changes into board configurations all the time. I actually sacrificed 15 (fifteen) bytes in the W1209 target for avoiding another configuration tree bifurcation.
The software serial I/O code is interrupt driven and rather fast (the overhead compared to using the UART is about 10µs). It's also possible to have two independent serial interfaces: the ESP-14 uses the STM8 UART for the ESP8266 but you can have RxD/TxD on one or two port pins for the Forth console. Through vectored I/O it's even possible to change the console I/O during operation! (@Elliot Williams, we discussed this some times ago)
One of the most important functional changes the GPIO console support that was announced in a log. Basically any STM8003F3P6 based board with a Port D pin that's not always required for operation of the board can be reverse engineered and programmed with eForth now: any STM8S003F3P6 board with an ICP connector is now fair game, not just the 5% with broken out UART port pins!
To make the threshold for exploring new cheap boards really, really low, I added the SWIMCOM target to the binary release (I assume that anybody here has an 1N4148 diode and some patch wires for an improvised half-duplex "console bus" handy).
Before you do anything that you'd regret later (like breaking some stuff), please make sure to read the warnings in the README.md!
-
Refectoring for better hardware support
01/03/2017 at 21:38 • 0 commentsI worked a bit on robust configurable serial I/O (UART, GPIO with interrupt, mixed, full/half duplex), and there will be some more work to do until I'm satisfied with the result. Currently I'm testing the W1209 with the new code.
Many boards have a 7S-LED display and I doubt that many will have the same GPIO configuration. On Taobao and on AliExpress there are dozens, and I ordered a bunch in the lower single digit $ range to play with.
My goal is to have a generic I/O module for the console, with little dependencies to board specific initialization and driver code. Serial I/O should be the first thing that works, and the last thing you should be required to change the code for supporting a new board.
-
More details on "LM2596 with voltmeter"
01/01/2017 at 16:31 • 0 commentsI toyed a bit with the "LM2596 with voltmeter" module. In case you're interested in the details of the voltmeter part, here is how the STM8 pins are connected:
Pin STM8 Connected to (LED pin # in brackets) -------------------------------------------------- 1 PD4 F (10) 2 PD5 A (11), LED "in" 3 PD6 V1 (12) cathode digit 1 4 NRST (6), manually wired 5 PA1 E (1) 6 PA2 D (2) 7 VSS GND 8 Vcap Cap 9 VDD +3.15V (LM317) 10 PA3 DP (3) 11 PB5 (nc) 12 PB4 (LM2596 pin5 "/enable", pull-up, manually wired) 13 PC3 LED MPX, key "out" 14 PC4 C (4) 15 PC5 B (7), LED "out" 16 PC6 V3 (8) cathode digit 3 17 PC7 V2 (9) cathode digit 2 18 PD1 G (5), key "in", SWIM 19 PD2 Ain "out" 20 PD3 Ain "in"
Here are details about the LED MPX and the key scan:
LED MPX: rate 20ms
- Duty PC6, PC7, PD7 (digit 1 .. 3): 2.285ms (low)
- Duty PC3 MPX LED in/out: 0.844ms (low)
Key scan after LED MPX active (low):
- 4µs PD1 G high (input, low while key "in" is pressed))
- 1µs PC3 MPX high (input, low while key "out" is pressed)
Key scan while the display is off:
- scan rate 8.165ms
- 4µs PD1 G high (input, low while key "in" pressed)
- All LEDs are dark and MPX is off while any key is pressed
Please note that the duty cycle of each 7-S LED digit is about 11%, and just 4% percent for the LEDs "in" and "out". The reason is simple: there are no current limiting resistors, and the supply voltage of 3.15V is much too high for a red LED. Part of why the LEDs don't overheat is that the STM8S output stages limit the current, and that's also visible at GPIOs that are in not connected. In awareness of that I ran the MPX with a duty cycle of 25%.
The LEDs aren't that much brighter than with the previous firmware:
The board clearly has some potential, but I'll wait until I know the details of some other variants before I add any code to the master repository.
-
A DC/DC Converter with a Voltmeter?
12/31/2016 at 12:22 • 4 commentsDigital voltmeters are popular: they give the user the feeling of getting an accurate measurement. However, accuracy has a price (e.g components with stable parameters, temperature compensation, reference voltage...). They say "you get what you pay for".
Different sellers at Chinese outlets offer LM2596 DC/DC converters with a voltmeter that, depending on a key press, shows the input or the output voltage. The price for such a module starts at $1.55 (including shipping halfway around the globe).
This has a smell of cheap µC although there is no ICP connector to be seen. I ordered one out of curiosity.
Of course, the only place where a µC could be hidden is below the display. I put it aside because removing it with a suction pump didn't work. Yesterday I played with a LED torch and in the bright light I spotted a TSSOP 20 package. Bingo! This time, it didn't take long to remove the LED display :-)
As expected the µC is a cheap STM8S003F3P6.I traced the wires and noticed the following:
- The NRST pin isn't connected (hence no ICP connector)
- PD1/SWIM drives segment G
- key "in" uses PD1/SWIM, too (I had noticed that when you press a key the display goes blank, now I know why)
- the LEDs "in" and "out" are segments A and B of a 4th digit (MPX PC3)
- key "out" uses PC3 (same as key "in" on PD1)
- PD2 and PD3 are the voltage inputs (or general GPIO)
- PB4 and PB5 (pins 11 and 12) are unused
Pin 5 of the LM2596 (/ENABLE) is connected to ground. It would have been easy to connect it to one of the unused µC pins. With thev ability to controll the converter key "in" wouldn't be useless (right now, it switches the voltmeter on or off while the output voltage is remains on).
Actually, that's is worse than useless - it's ridiculous!
You get what you pay for: assembled components without the engineering. I reckon that either the software was copied from some other circuit, or the SW-engineer isn't on the payroll anymore!
It goes without saying that I heated my soldering iron a second time: now PB5 controls pin 5 (/ENABLE) of the LM2596, and NRST is connected to the free pin 6 of the LED display socket. It turned out that the STM8S003F3P6 is read protected - but who cares?
Now what do we have? A bunch of assembled components that can be hacked into something useful!
- a relatively decent buck converter (even if the caps are of poor quality)
- a µC that can run Forth
- with an LM317 as a linear power supply
- with a 3 digit LED display
- with two keys (OK, pressing one of them will short-circuit the G segment)
- with two analog inputs (after removal of two resistors handily accessible on pads)
Possible applications (with more or less soldering effort) :
- a thermostat ;-)
- a battery charge controller
- on/off CV motor or solenoid control
- ...
For hacking the boards are just right. I ordered two more.
-
Working code for "Half-Duplex Serial through PD1/SWIM"
12/29/2016 at 09:57 • 0 commentsI've been working on interrupt driven half-duplex console communication through one pin, especiially PD1/SWIM on the ICP header, like this:
STM8 device . .----o serial TxD "TTL" . | . --- . / \ 1N4148 . --- ICP header . | . *----o serial RxD "TTL . | STM8 PD1/SWIM-->>-----*----o ST-LINK SWIM . NRST----------->>----------o ST-LINK NRST . GND------------>>-----*----o ST-LINK GND . | ................ .----o serial GND
Code for receive and transmit is fully interrupt driven and buffered. A synchronized timer is used to sample in the middle of a bit time, and it works with any PD port pin (it would work with a different port, too, but that requires using a different external interrupt). Unlike bit-banging the performance impact is negligible (1-2 µs per bit sent or received, well below 2% CPU load at 9600 baud with 100% communication rate). I guess that the code could be used up to 115 kBaud with minor modifications.
If you can live with some garbage on the screen while flashing a new image it isn't necessary to disconnect the serial adapter (I use a cheap CH340) or close the terminal program when transferring a new binary with ICP (I use a cheap ST-Link clone):
ok ���������D�������������i��?��������&�?���� ��������r'��n����1��������������� #�����������t�������G������b��҃^�������;����������� ����[����?����v��:d���w�����7�x�O��g�'��3���2������� ������+�_������Z��1����/��x���������V���������'����� �/�������>������=,�� stm8eForth v2.2
The terminal log above comes from this specimen of severe CPU underemployment:
The next complication that needs to be solved is when PD1/SWIM is also used for e.g. LED multiplexing, but I planned to experiment with synchronized LIN-style networks anyway.
-
​Bump to v2.2.3: important non-functional changes
12/27/2016 at 21:53 • 0 commentsMost of the changes in v2.2.3 are non-functional, but some is nevertheless important:
- I/O code in board folders: This change concentrates most of the board dependent code, i.e. initialization, interrupts, RX!, ?TX and OUT!, into the configuration folders. There is some risk of some future code repetition for very similar boards but this can be addressed as it arises. Future work will add more abstraction code (like BKEYCHAR for keyboard translation).
- improved vocabulary options The vocabulary options were reviewed and aligned with certain use cases: "Forth as a Scripting Language", "Self-hosted µC Development", and "Forth Interpreter Lab". Most users won't have the third use case, but if they need it the words the interpreter consists of can be linked.
- fix off-by-one in DEPTH and rp!: In both DEPTH and rp! were bugs that canceled each other out, but that left the number 0x3FF (1023) on the floor of the stack. This became visible when rp! was re-implemented in in-line assembly to save space.
- binary size reduction: Due to re-write of many routines in assembly, frequent use of short addressing modes, more factoring, and several optimized eForth core words the size of CORE including "Compile to Flash memory" is now below 4KiB (3800 bytes without this option). Further improvements would require abandoning STC in favor of DTC or even ITC.
- Retab: Unfortunately different authors left a mix of different tab width in the code. There was a retab-only commit to facilitate comparing code changes.
Did I mention that MINDEV is still below 5000 bytes even if I linked or added 22 words more to the vocabulary than in the last release?
stm8eForth v2.2 words RESET RAM NVM LOCKF ULOCKF LOCK ULOCK ADC@ ADC! 2C@ 2C! BITSR WORDS .S DUMP VARIABLE DOES> CREATE IMMEDIATE : CALL, ] ; ." $" ABORT" AFT REPEAT WHILE AHEAD ELSE THEN IF AGAIN UNTIL BEGIN +LOOP LOOP DO NEXT FOR $," LITERAL COMPILE [COMPILE] C, , ALLOT ' [ \ ( .( ? . U. TYPE U.R .R CR SPACES SPACE NUF? KEY DECIMAL HEX str #> SIGN #S # HOLD <# DIGIT PACK$ ERASE FILL CMOVE @EXECUTE PAD HERE COUNT 2@ 2! +! DEPTH PICK 0= ABS NEGATE NOT 2/ 1- 1+ 2* 2- 2+ */ */MOD M* * UM* / MOD /MOD M/MOD UM/MOD WITHIN MIN MAX < U< = DNEGATE 2DUP ROT ?DUP FILE HAND BG TIM -1 1 0 BL OUT '?KEY 'EMIT hld BASE UM+ - 0< OR AND XOR + OVER SWAP DUP >R R@ 2DROP DROP I R> C! C@ ! @ EXIT EXECUTE LEAVE EMIT ?KEY hi 'BOOT OUT! TX! ?RX COLD ok
Now I did :-)
As usual, the binary release is on GitHub. -
More cheap boards
12/27/2016 at 18:23 • 0 commentsAs you may know, code and docs for this project are on GitHub, and GitHub provides a lot of statistics about a repository. One of the statistics shows visitors and referrers, and since this project appeared as a "Featured Project" on HaD most referrers are from this site. Thanks guys, you're awesome :-)
A notable exception was visitors from the threat "Why build when you can buy" in the PICAXE forum, where some forum users discussed the virtues of home-made vs. off-the-shelf. Some embraced the idea of tinkering with ready-made boards, others were not so enthusiastic about it.
Of course, there are a lot of reasons for "home-brew", but it's also fun to work with "building blocks" (a.k.a. "modules"), especially when there is a competitive marked and they're highly standardized (a commodity). I took this as an incentive to make a list of STM8 based commodity module names. Collector's items, if you will ;-)
I've yet to understand how "module names", like "XH-M194" or "B3606", come into existence. My hypothesis is that it has a lot to do with Shanzhai: what others copy is worth copying! Better compete on commodities than try to sell a product which nobody knows it exists. Apparently this also applies to naming schemes.
-
A place for hardware drivers, and no more 0x3FF
12/26/2016 at 22:13 • 0 commentsThe code In the development branch on GitHub has some interesting changes:
- hardware driver code is now in the board folders (file boardcore.inc). Adding code for new boards, especially I/0-drivers, is now much easier
- the code is now again a bit leaner, for a simple reason: I wanted a complete CORE development system to fit into 4KiB.
- when you get data from th empty stack the first word you get isn't 0x3FF but it's random. The reason for this is that I fixed two off-by-one bugs that canceled each other out, but that left the number 0x3FF (1023) on the floor of the stack.
The first point became a priority when I realized that most Cheap China Gadgets won't provide simple access to RS23. With "most" I mean 9 out of 10. Since giving up isn't what I'm best known for, I decided to tackle diversity through clean configuration options.
The second point was important to me because I wanted this Forth implementation for tiny µCs to be, well, tiny. Also I wouldn't call it complete if your work vanishes when you cut the power (my VIC=20 did that and I didn't like it). Also there's no point in a fancy self-contained development environment when there is no space left for your application code. Call it my "4K challenge" ;-)
Here is a small demo of the new CORE image:
RESET ok NVM ok : test WORDS ; ok RAM ok COLD ok test test RESET RAM NVM WORDS .S DUMP CREATE IMMEDIATE : ] ; ." ABORT" AFT REPEAT WHILE ELSE THEN IF AGAIN UNTIL BEGIN NEXT FOR $," LITERAL C, , ALLOT ' [ \ ( .( ? . U. TYPE U.R CR SPACE KEY DECIMAL HEX FILL CMOVE 2@ 2! +! PICK ABS NEGATE NOT 2/ 1- 1+ 2* 2- 2+ */ */MOD M* * UM* / MOD /MOD M/MOD UM/MOD WITHIN MIN MAX < U< = DNEGATE 2DUP ROT ?DUP FILE HAND -1 1 0 BL BASE UM+ - 0< OR AND XOR + OVER SWAP DUP >R R@ 2DROP DROP R> C! C@ ! @ EXECUTE EMIT ?KEY 'BOOT COLD ok HEX ' test . 8FF8 ok
RESET removes any vocabulary in the Flash (and resets the initialization constants in the 'BOOT array. NVM switches to Flash compile mode. For the demo test is an alias for WORDS. RAM makes the configuration persistent. COLD does a cold-start. Running test shows that the word is still there, and a lookup of the code address with ' (tick) shows it to be below 0x9000, and this means that there is 4 KiB left for application code!
The CORE vocabulary was trimmed for usage as a scripting language, but I didn't select the background task option (this would have taken about 230 bytes more). A plain REPL now requires about 3800 bytes (down from the 5500 bytes of the original STM8EF code).
The 3rd point (0x3FF as the value when reading from an empty stack) indicates that I've turned most bytes of Dr. C.H. Ting's implementation upside-down by now. Some dark spots got cleaned up in the process.