-
Notifications
You must be signed in to change notification settings - Fork 13
/
README
1962 lines (1546 loc) · 76.5 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
@
@ Mecrisp-Stellaris - A native code Forth implementation for ARM-Cortex M microcontrollers
@ Copyright (C) 2013 Matthias Koch
@
@ This program is free software: you can redistribute it and/or modify
@ it under the terms of the GNU General Public License as published by
@ the Free Software Foundation, either version 3 of the License, or
@ (at your option) any later version.
@
@ This program is distributed in the hope that it will be useful,
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ GNU General Public License for more details.
@
@ You should have received a copy of the GNU General Public License
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
@
;------------------------------------------------------------------------------
This is the stable release of Mecrisp-Stellaris,
a port of Mecrisp to the ARM Cortex M architecture.
It runs out of the box on:
- TI Stellaris/Tiva Launchpad with LM4F120H5QR / TM4C123GH6PM
- TI Tiva Connected Launchpad with TM4C1294NCPDT
- TI MSP432 Launchpad with MSP432P401R
- STM L053 Discovery with STM32L053C8T6
- STM Nucleo L152RE with STM32L152RE
- STM Nucleo 401RE with STM32F401RE
- STM Nucleo 411RE with STM32F411RET6
- STM F0 Discovery with STM32F051R8
- STM VL Discovery with STM32F100RB
- Shenzhen LC Technology board with STM32F103C8T6
- STM F3 Discovery with STM32F303VCT6
- STM F4 Discovery with STM32F407VGT6
- STM F429 Discovery with STM32F429ZIT6
- Freescale Freedom FRDM-KL25Z with KL25Z128VLK4
- Freescale Freedom FRDM-KL46Z with KL46Z256VLL4
- Freescale Freedom FRDM-K64F with MK64FN1M0VLL12
- Infineon XMC2GO with XMC1100Q024F0064
- EFM32 Giant Gecko with EFM32GG990F1024
- EFM32 Happy Gecko with EFM32HG322F64
- Breadboard friendly, DIP packaged LPC1114FN28
- LPC1114FBD48
- LPC1115FBD48
- Very small TSSOP20 packaged STM32F030F4
Contributions:
- Teensy 3.1 with MK20DX256VLH7
- Chinese QF-LM4F232 with LM4F232H5QC
- nRFgo Starter Kit & Microbit with nRF51822
- STM L152 Discovery with STM32L152RBT6
- STM Nucleo F207ZG with STM32F207ZG
- STM Nucleo F303K8 with STM32F303K8
- STM L476 Discovery with STM32L476VG
- STM F746 Discovery with STM32F746NG
- Atmel SAME70 X-plained with ATSAME70Q21
http://mecrisp.sourceforge.net/
;------------------------------------------------------------------------------
Mecrisp finally got a younger sister and mastered the jump
to the ARM Cortex M instruction set.
They share most of the design ideas, so Mecrisp-Stellaris can compile
directly into Flash, generates native code with constant folding and
inlining of short words.
Communication is via serial 115200 baud 8N1 over
- UART0 in LM4F120 (connected to USB-serial bridge on Stellaris Launchpad)
- UART0 in TM4C1294 (connected to USB-serial bridge on Tiva Connected Launchpad)
- USCI0 in MSP432P401R (TX on P1.3, RX on P1.2, connected to USB-serial bridge)
- UART in LPC1114FN28 (TX on P1.7, RX on P1.6)
- UART in LPC1114FBD48 (TX on P1.7, RX on P1.6)
- UART in LPC1115FBD48 (TX on P1.7, RX on P1.6)
- USART1 in STM32F051 (TX on PA9, RX on PA10)
- USART1 in STM32F030F4 (TX on PA9, RX on PA10)
- USART1 in STM32F100 (TX on PA9, RX on PA10)
- USART1 in STM32F103 (TX on PA9, RX on PA10)
- USART1 in STM32F303 (TX on PA9, RX on PA10)
- USART1 in STM32F429 (TX on PA9, RX on PA10)
- USART1 in STM32L053C8 (TX on PA9, RX on PA10)
- USART2 in STM32F401 (TX on PA2, RX on PA3 connected to USB-serial bridge on Nucleo board)
- USART2 in STM32F407 (TX on PA2, RX on PA3)
- USART2 in STM32F411 (TX on PA2, RX on PA3 connected to USB-serial bridge on Nucleo board)
- USART2 in STM32L152 (TX on PA2, RX on PA3 connected to USB-serial bridge on Nucleo board)
- USART2 in STM32L476 (TX on PD5, RX on PD6 connected to USB-serial bridge on Discovery board)
- UART0 in KL25Z128 (connected to USB-serial bridge on Freedom board)
- UART0 in KL46Z256 (connected to USB-serial bridge on Freedom board)
- UART5 in LM4F232
- UART0 in MK20DX256 (RX1/TX1 on Teensy 3.1. Physical pins #2/#3 (these are also Digital IO 0/1 lines)
Digital IO pins 18/19 are setup for CTS/RTS respectively
;------------------------------------------------------------------------------
Hardware and configuration for LM4F120 and TM4C123:
;------------------------------------------------------------------------------
Connect your cable to the Debug-USB-Port,
set "PWR SELECT" switch to DEBUG and
close VDD jumper.
Flashing is possible with lm4flash:
https://github.com/utzig/lm4tools
On startup, this runs with internal PIOSC at 16 MHz,
which is specified +-3% over whole temperature range.
;------------------------------------------------------------------------------
Hardware and configuration for TM4C1294:
;------------------------------------------------------------------------------
Connect your cable to the Debug-USB-Port,
set "POWER SELECT" jumpers (JP1) to "ICDI",
close both "MCU 3V3" (JP2) and "+3v3" (JP3) jumpers and
set communication jumper blocks (JP4 and JP5) both to UART mode.
Flashing is possible with lm4flash:
https://github.com/utzig/lm4tools
On startup, this runs with internal PIOSC at 16 MHz,
which is specified +-3% over whole temperature range.
;------------------------------------------------------------------------------
Hardware and configuration for MSP432P401R:
;------------------------------------------------------------------------------
Connect your cable to the USB-Port,
set "JTAG switch" to XDS position,
close 5V, 3V3, RXD, TXD jumpers.
Flashing is possible with DSLite, which is part of Energia 15:
DSLite -c MSP432P401R.ccxml -f mecrisp-stellaris-msp432p401r.bin -l 0
On startup, this runs with DCO on 12 MHz.
;------------------------------------------------------------------------------
Hardware and configuration for LPC1114FN28 on breadboard:
;------------------------------------------------------------------------------
Connect 3.3 V power across
+ Vdd (Pin 21) and Vdda (Pin 7)
- Vss (Pin 22) and Vssa (Pin 8)
Connect TTL serial to
TXD on P1.7 (Pin 16) and
RXD on P1.6 (Pin 15)
Connect two push buttons between
/Reset (Pin 23) and GND
Bootloader enable on P0.1 (Pin 24) and GND
The chip enters serial bootloader in ROM
if Reset button is released while
the bootloader button is hold down.
Flashing is possible with LPC21ISP:
http://sourceforge.net/projects/lpc21isp/
lpc21isp -wipe mecrisp-stellaris-lpc1114fn28.hex /dev/ttyUSB0 9600 12000
On startup, this runs with internal RC oscillator at 12 MHz
which is specified +-1% over whole temperature range.
;------------------------------------------------------------------------------
Hardware and configuration for STM32L053C8:
;------------------------------------------------------------------------------
Connect USB cable to ST-Link USB port.
Terminal is included into the debug section and can be used
if you close solder bridges SB2 and SB3.
Flashing is possible with st-flash:
https://github.com/texane/stlink
Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
the low address range to generate short opcodes for calling core words, but
for flashing the binary, you have to use the "true address" $08000000.
st-flash erase
st-flash write mecrisp-stellaris-stm32l053c8.bin 0x08000000
On startup, this runs with internal 16 MHz HSI clock.
;------------------------------------------------------------------------------
Hardware and configuration for STM32L152:
;------------------------------------------------------------------------------
Connect USB cable to ST-Link USB port.
Terminal is included into the debug section on Nucleo boards.
Flashing is possible with st-flash:
https://github.com/texane/stlink
Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
the low address range to generate short opcodes for calling core words, but
for flashing the binary, you have to use the "true address" $08000000.
st-flash erase
st-flash write mecrisp-stellaris-stm32l152.bin 0x08000000
On startup, this runs with internal 16 MHz HSI clock.
;------------------------------------------------------------------------------
Hardware and configuration for STM32L476:
;------------------------------------------------------------------------------
Connect USB cable to ST-Link USB port.
Terminal is included into the debug section on Discovery boards.
Flashing is possible with st-flash:
https://github.com/texane/stlink
on Windows using STLINK Tools from ST website:
http://www.st.com/web/en/catalog/tools/PF258168#
Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
the low address range to generate short opcodes for calling core words, but
for flashing the binary, you have to use the "true address" $08000000.
st-flash erase
st-flash write mecrisp-stellaris-stm32l476.bin 0x08000000
On startup, this runs with internal 48 MHz MSI clock. Currently flash ECC is
supported. (JJ:O)
;------------------------------------------------------------------------------
Hardware and configuration for STM32F401 and STM32F411:
;------------------------------------------------------------------------------
Connect USB cable to ST-Link USB port.
Terminal is included into the debug section on Nucleo boards.
Flashing is possible with st-flash:
https://github.com/texane/stlink
Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
the low address range to generate short opcodes for calling core words, but
for flashing the binary, you have to use the "true address" $08000000.
st-flash erase
st-flash write mecrisp-stellaris-stm32f401.bin 0x08000000
st-flash write mecrisp-stellaris-stm32f411.bin 0x08000000
On startup, this runs with internal 16 MHz HSI clock.
;------------------------------------------------------------------------------
Hardware and configuration for STM32F407:
;------------------------------------------------------------------------------
Connect USB cable to ST-Link USB port,
connect your favourite serial link to PA2 (TX) and PA3 (RX),
keep logic voltage levels in mind !
Flashing is possible with st-flash:
https://github.com/texane/stlink
Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
the low address range to generate short opcodes for calling core words, but
for flashing the binary, you have to use the "true address" $08000000.
st-flash erase
st-flash write mecrisp-stellaris-stm32f407.bin 0x08000000
On startup, this runs with external 8 MHz crystal HSE clock,
as internal oscillator is specified -8% + 4.5% over whole temp range.
;------------------------------------------------------------------------------
Hardware and configuration for STM32F429:
;------------------------------------------------------------------------------
Similiar to STM32F407.
Connect USB cable to ST-Link USB port,
connect your favourite serial link to PA9 (TX) and PA10 (RX),
keep logic voltage levels in mind !
st-flash erase
st-flash write mecrisp-stellaris-stm32f429.bin 0x08000000
On startup, this runs with external 8 MHz crystal HSE clock.
;------------------------------------------------------------------------------
Hardware and configuration for STM32F030F4:
;------------------------------------------------------------------------------
Connect everything necessary to power up and flash the chip.
Connect your favourite serial link to PA9 (TX) and PA10 (RX),
keep logic voltage levels in mind !
st-flash erase
st-flash write mecrisp-stellaris-stm32f030f4.bin 0x08000000
On startup, this runs with internal 8 MHz HSI clock.
;------------------------------------------------------------------------------
Hardware and configuration for STM32F051:
;------------------------------------------------------------------------------
Similiar to STM32F407.
Connect USB cable to ST-Link USB port,
connect your favourite serial link to PA9 (TX) and PA10 (RX),
keep logic voltage levels in mind !
st-flash erase
st-flash write mecrisp-stellaris-stm32f051.bin 0x08000000
On startup, this runs with internal 8 MHz HSI clock.
;------------------------------------------------------------------------------
Hardware and configuration for STM32F100:
;------------------------------------------------------------------------------
Similiar to STM32F407.
Connect USB cable to ST-Link USB port,
connect your favourite serial link to PA9 (TX) and PA10 (RX),
keep logic voltage levels in mind !
st-flash erase
st-flash write mecrisp-stellaris-stm32f100.bin 0x08000000
On startup, this runs with internal 8 MHz HSI clock.
;------------------------------------------------------------------------------
Hardware and configuration for STM32F303:
;------------------------------------------------------------------------------
Similiar to STM32F407.
Connect USB cable to ST-Link USB port,
connect your favourite serial link to PA9 (TX) and PA10 (RX),
keep logic voltage levels in mind !
st-flash erase
st-flash write mecrisp-stellaris-stm32f303.bin 0x08000000
On startup, this runs with internal 8 MHz HSI clock.
;------------------------------------------------------------------------------
Hardware and configuration for KL25Z128, KL46Z256, MK64FN1M0:
;------------------------------------------------------------------------------
Connect USB cable to SDA-USB-PORT
Flashing is via mass storage interface -
the board will appear as Flash Disk, just copy .bin file in.
Maybe you have to do an OpenSDA firmware update before.
On startup, this runs with internal FLL at 20.97 MHz.
If you wish to try Mecrisp-Stellaris without target hardware,
there is a Cortex M0 instruction set emulator prepared for use with
Freescale Freedom binary images. Go into kl25z128/thumbulator
directory, type "make", copy the binary and then type
"thumbulator mecrisp-stellaris-kl25z128.bin" to run.
;------------------------------------------------------------------------------
Hardware and configuration for XMC1100:
;------------------------------------------------------------------------------
Connect USB cable for flashing and terminal.
Flashing is possible with JLinkExe from Segger, which is available for Linux:
https://www.segger.com/jlink-software.html
"Software and documentation pack", 32 Bit TGZ archive is fine.
JLink_Linux_V510c_i386# ./JLinkExe -device XMC1100-0064 -if SWD -speed 4000
erase
loadfile mecrisp-stellaris-xmc1100.hex
r
g
OpenOCD 0.9 has support for the XMC2GO, but it failed with the firmware version
of my board. The command line would be something like this:
openocd -f board/xmc-2go.cfg
openocd -f board/xmc-2go.cfg -c "program mecrisp-stellaris-xmc1100.hex verify reset exit"
If you have issues with broken characters in the terminal,
try changing the UART_FDR_STEP value in terminal.s a bit.
To circumvent a bug in the XMC2GO serial bridge, the baudrate is set a bit
off the nominal value. If you connect your own terminal, make sure to change
it to the correct value.
See mecrisp-stellaris-source/xmc1100/terminal.s for hints.
On startup, this runs with internal MCLK = PCKL = 8 MHz clock.
;------------------------------------------------------------------------------
Hardware and configuration for EFM32GG990 and EFM32HG322:
;------------------------------------------------------------------------------
Connect USB cable to DBG connector for flashing and terminal.
To get the mass storage flashing interface and USB-serial bridge,
a firmware update of the on board debugger might be necessary.
See instructions on MBED:
https://developer.mbed.org/teams/SiliconLabs/wiki/Silicon-Labs-Firmware
Flashing is done by copying the binary into the USB drive.
Unfortunately, flashing this way doesn't not perform a proper mass erase.
If you cannot get it up and running this way, you need use a proper debugger
and erase the whole flash properly.
On startup, this runs with internal HFCLK = HFRCO = 14 MHz clock.
;------------------------------------------------------------------------------
Hardware and configuration for MK20DX256VLH7 on a Teensy 3.1 board:
;------------------------------------------------------------------------------
( Contributed by Mark Schweizer )
Connect USB cable to USB port
Open Teensy Loader Application (https://www.pjrc.com/teensy/loader.html) on your PC
Select the "mecrisp-stellaris-mk20dx256.hex" file in the mk20dx256 directory
Select the "Auto" button (this automatically loads the coad and resets the Teensy when the programming button is pushed)
Press the button on the Teensy 3.1 board to initite the bootloader
Connect a serial cable to TX1/RX1 (physical pins #2/#3 (these are also Digital IO 0/1 lines)
Optionally connect CTS/RTS to physical pins #25/26 (these are also Digital IO 18/18 lines)
R C
T T
S S
o o o o o o o o o o o o o o
|--------------------------o
| o
USB| Teensy 3.1 o
| o
|--------------------------o
o o o o o o o o o o o o o o
G R T
N X X
D
On startup, this runs with internal FLL at 20.97 MHz. See MCG.txt for how to switch to 96MHz
;------------------------------------------------------------------------------
Hardware and configuration for nRF51822:
;------------------------------------------------------------------------------
( Contributed by John Huberts )
I have been using the nRFgo Motherboard fitted with a nRF51822 module
to do the development and testing. Programming is done using nRFStudio
and the Segger J-LINK LITE that comes with the dev kit.
I was also able to debug using GDB in the nRF51 Eclipse IDE
The motherboard has a DB9 for serial port connection but jumpers need to
be placed between P15 (RXD, TXD) and P9 (P2.0, P2.1). If you don't have a
serial port on your PC then you will need a USB-serial cable.
The UART can be configured to use other pins on the SOC by changing these
lines in in terminal.s:
.equ RX_PIN_NUMBER, 16
.equ TX_PIN_NUMBER, 17
;------------------------------------------------------------------------------
Hardware and configuration for Microbit:
;------------------------------------------------------------------------------
Flashing can be done by just copying mecrisp-stellaris-microbit.hex
into the Microbit which comes with a mass storage interface.
Communication is done over P0.24 TX and P0.25 RX, connected
to USB-serial-bridge on debugger section.
;------------------------------------------------------------------------------
Mecrisp-Stellaris itself is sending LF for line ending,
but recognizes both LF and CR. Invoke Picocom with something like
picocom -b 115200 /dev/ttyACM0 --imap lfcrlf,crcrlf --omap delbs,crlf
For changing line ending to CR-LF or whatever else you like,
look at the beginning of mecrisp-stellaris-....s.
Assembling is done with the GCC-Arm-Embedded toolchain:
https://launchpad.net/gcc-arm-embedded/
;------------------------------------------------------------------------------
* Fetch-Modify-Store operations like +! or bic! are not atomic.
* You can contribute your favourite hardware handling routines
to be included in upcoming releases !
* Chip specific sources have added English comments and hints included
for simplify porting to other ARM Cortex-M chips.
* For design ideas, have a look into Mecrisp for MSP430, too !
;------------------------------------------------------------------------------
; Turnkey applications
;------------------------------------------------------------------------------
If you define a word with name "init" - its latest definition is called every
startup ! You you can redefine init if you like to add e.g. additional hardware
setup; don't forget to give your old definition of init a call if you have one.
;------------------------------------------------------------------------------
; Porting
;------------------------------------------------------------------------------
Mecrisp-Stellaris can assemble without change for M0, M3 and M4 cores.
M0 cores lack conditional execution "ite eq...", which has to be circumvented
by conditional branches. stmdb psp!, {tos} is missing, which I use to push to
data stack and they have no division in hardware.
There is an assembler switch "m0core" to assemble the core with replacement
code for ARM Cortex-M0 chips. Depending on your flash capabilities, there are
two useful switches:
"charkommaavailable" which is self-explaining and
"emulated16bitflashwrites" if your particular Flash controller
cannot write data in separate 16-Bit chunks.
Core needs about 14 kb flash at the moment, but reserves 16 kb for upcoming
additions, and needs 1.5 kb RAM for stacks and buffers plus variables for
interrupt handlers plus RAM dictionary space. Bare minimum for ARM to get it
running will be around 16kb/2kb, but to have fun with it and leave space for
real applications, go with at least of 32 kb flash and 4 kb RAM.
Look at the flash specification for your particular chip.
The compiler only depends on 2-aligned 16-Bit flash writes
one time per location, you can remove c, and halign without issues
from the compiler, but 8-Bit flash writes are nice to have
for compatibility with standard code.
For special cases having only 4-aligned 32-bit one-time writes to Flash,
there is a hflash! emulation layer.
Flash erasing is only available for the user, it doesn't need erase cycles
while compiling.
Keep these criteria in mind, pick your favourite chip and add it as your
contribution. It won't be too difficult, start with an UART echo written
in assembly without libraries, and I will be there for your help.
You have to change memory map, hardware initialisation and interrupt vectors,
write key?, key, emit?, emit for a first reaction and flash write access
for final success. There is a common mimimum set of handlers across
ARM Cortex CPUs, which will help you to get it running for the first time.
Unfortunately, there is a lot of bit twiddling necessary for peripherial
modules, as they differ a lot across manufacturers. ARMs seem to only share
core components like CPU, interrupt controler and a very basic systick timer.
I don't have the time to support a lot of different chips with examples.
TI ADCs have a sequencer FIFO buffer, ST ADCs need a DMA channel configured.
TI Flash controller offers 32 bit aligned writes only, but as many as you
wish per location until all bits are zero;
ST-M3 have 16 bit aligned Flash write only,
ST-M4 have 8 bit, 16 bit and 32 bit Flash writes available,
but only once per location.
I would like to focus on core development, support porting to other chips and
families with adaptions in core, but leave writing initialisation code,
testing and writing Forth examples to "family maintainers" which are deep
into their chip of choice.
;------------------------------------------------------------------------------
; Register allocator
;------------------------------------------------------------------------------
It should look and feel like the classic Mecrisp-Stellaris,
but with a very important difference:
It contains an analytical compiler which keeps track
of the top five stack elements and maps them to registers
whenever possible.
To dive in, you should load the disassembler and see
definitions you have just compiled.
Two examples, on M0:
: >gray ( u -- x ) dup 1 rshift xor ; ok.
see >gray
00006B38: 0873 lsrs r3 r6 #1
00006B3A: 405E eors r6 r3
00006B3C: 4770 bx lr
ok.
: bitexp ( u -- u ) ok.
ok.
\ Returns an integer value equivalent to ok.
\ the exponential. For numbers > 16, ok.
\ bitexp(x) approx = 2^(x/8 + 1) ok.
ok.
\ B(E(x)) = x for 16 <= x <= 247. ok.
ok.
dup 247 u> \ Overflow ? ok.
if drop $F0000000 ok.
else ok.
ok.
dup 16 u<= if 1 rshift ok.
else ok.
dup ( u u ) ok.
7 and 8 or ( u b ) ok.
swap ( b u ) ok.
3 rshift 2 - lshift ok.
then ok.
ok.
then ok.
ok.
1-foldable ; ok.
ok.
see bitexp
00006BA2: 2EF7 cmp r6 #F7
00006BA4: B500 push { lr }
00006BA6: D902 bls 00006BAE
00006BA8: 26F0 movs r6 #F0
00006BAA: 0636 lsls r6 r6 #18
00006BAC: E00C b 00006BC8
00006BAE: 2E10 cmp r6 #10
00006BB0: D801 bhi 00006BB6
00006BB2: 0876 lsrs r6 r6 #1
00006BB4: E008 b 00006BC8
00006BB6: 0033 lsls r3 r6 #0
00006BB8: 2007 movs r0 #7
00006BBA: 4003 ands r3 r0
00006BBC: 2008 movs r0 #8
00006BBE: 4303 orrs r3 r0
00006BC0: 08F6 lsrs r6 r6 #3
00006BC2: 3E02 subs r6 #2
00006BC4: 40B3 lsls r3 r6
00006BC6: 461E mov r6 r3
00006BC8: BD00 pop { pc }
Note that it compiles bitexp without any stack movements at all.
;------------------------------------------------------------------------------
; Hacking
;------------------------------------------------------------------------------
If you wish to dive into the assembly sources, here comes a register map:
r0: Free scratch register ( Saved on interrupt entry by hardware )
r1: Free scratch register ( Saved on interrupt entry by hardware )
r2: Free scratch register ( Saved on interrupt entry by hardware )
r3: Free scratch register ( Saved on interrupt entry by hardware )
r4: Inner loop count ( Needs Push and Pop when used otherwise )
r5: Inner loop limit ( Needs Push and Pop when used otherwise )
r6=TOS: Top-Of-Stack ( Stack design is interrupt safe )
r7=PSP: Parameter Stack Pointer ( Stack design is interrupt safe )
r8: Unused
r9: Unused
r10: Unused
r11: Unused
r12: Unused ( Saved on interrupt entry by hardware )
r13=SP: Return Stack Pointer
r14=LR: Link Register
r15=PC: Program Counter, always odd
;------------------------------------------------------------------------------
Here comes a word list,
with short descriptions of all currently included words:
View it with fixed-width font !
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Terminal-IO (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------
emit? ( -- Flag ) Ready to send a character ?
key? ( -- Flag ) Checks if a key is waiting
key ( -- Char ) Waits for and fetches the pressed key
emit ( Char -- ) Emits a character.
hook-emit? ( -- a-addr ) Hooks for redirecting
hook-key? ( -- a-addr ) terminal IO
hook-key ( -- a-addr ) on the fly
hook-emit ( -- a-addr )
serial-emit? ( -- Flag ) Serial interface
serial-key? ( -- Flag ) terminal routines
serial-key ( -- Char ) as default communications
serial-emit ( Char -- )
hook-pause ( -- a-addr ) Hook for a multitasker
pause ( -- ) Task switch, none for default
;------------------------------------------------------------------------------
; Stack Jugglers (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------
Single-Jugglers:
depth ( -- +n ) Gives number of single-cell stack items.
nip ( x1 x2 -- x2 )
drop ( x -- )
rot ( x1 x2 x3 -- x2 x3 x1 )
-rot ( x1 x2 x3 -- x3 x1 x2 )
swap ( x1 x2 -- x2 x1 )
tuck ( x1 x2 -- x2 x1 x2 )
over ( x1 x2 -- x1 x2 x1 )
?dup ( x -- 0 | x x )
dup ( x -- x x )
pick ( ... xi+1 xi ... x1 x0 i -- ... x1 x0 xi )
Picks one element from deep below
>r ( x -- ) (R: -- x )
r> ( -- x ) (R: x -- )
r@ ( -- x ) (R: x -- x )
rdrop ( -- ) (R: x -- )
rdepth ( -- +n ) Gives number of return stack items.
rpick ( i -- xi ) R: ( ... xi ... x0 -- ... xi ... x0 )
Double-Jugglers: They perform the same for double numbers.
2nip ( x1 x2 x3 x4 -- x3 x4 )
2drop ( x1 x2 -- )
2rot ( x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2 )
2-rot ( x1 x2 x3 x4 x5 x6 -- x5 x6 x1 x2 x3 x4 )
2swap ( x1 x2 x3 x4 -- x3 x4 x1 x2 )
2tuck ( x1 x2 x3 x4 -- x3 x4 x1 x2 x3 x4 )
2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 )
2dup ( x1 x2 -- x1 x2 x1 x2 )
2>r ( x1 x2 -- ) (R: -- x1 x2 )
2r> ( -- x1 x2 ) (R: x1 x2 -- )
2r@ ( -- x1 x2 ) (R: x1 x2 -- x1 x2 )
2rdrop ( -- ) (R: x1 x2 -- )
Stack pointers:
sp@ ( -- a-addr ) Fetch data stack pointer
sp! ( a-addr -- ) Store data stack pointer
rp@ ( -- a-addr ) Fetch return stack pointer
rp! ( a-addr -- ) Store return stack pointer
;------------------------------------------------------------------------------
; Logic (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------
arshift ( x1 u -- x2 ) Arithmetric right-shift of u bit-places
rshift ( x1 u -- x2 ) Logical right-shift of u bit-places
lshift ( x1 u -- x2 ) Logical left-shift of u bit-places
shr ( x1 -- x2 ) Logical right-shift of one bit-place
shl ( x1 -- x2 ) Logical left-shift of one bit-place
ror ( x1 -- x2 ) Logical right-rotation of one bit-place
rol ( x1 -- x2 ) Logical left-rotation of one bit-place
bic ( x1 x2 -- x3 ) Bit clear, identical to "not and"
not ( x1 -- x2 ) Invert all bits
xor ( x1 x2 -- x3 ) Bitwise Exclusive-OR
or ( x1 x2 -- x3 ) Bitwise OR
and ( x1 x2 -- x3 ) Bitwise AND
false ( -- 0 ) False-Flag
true ( -- -1 ) True-Flag
clz ( x1 -- u ) Count leading zeros
;------------------------------------------------------------------------------
; Calculus for single numbers (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------
u/mod ( u1 u2 -- u3 u4 ) 32/32 = 32 rem 32 Division
u1 / u2 = u4 remainder u3
/mod ( n1 n2 -- n3 n4 ) n1 / n2 = n4 rem n3
mod ( n1 n2 -- n3 ) n1 / n2 = remainder n3
/ ( n1 n2 -- n3 ) n1 / n2 = n3
* ( u1|n1 u2|n2 -- u3|n3 ) 32*32 = 32 Multiplication
min ( n1 n2 -- n1|n2 ) Keeps smaller of top two items
max ( n1 n2 -- n1|n2 ) Keeps greater of top two items
umin ( u1 u2 -- u1|u2 ) Keeps unsigned smaller
umax ( u1 u2 -- u1|u2 ) Keeps unsigned greater
2- ( u1|n1 -- u2|n2 ) Subtracts two, optimized
1- ( u1|n1 -- u2|n2 ) Subtracts one, optimized
2+ ( u1|n1 -- u2|n2 ) Adds two, optimized
1+ ( u1|n1 -- u2|n2 ) Adds one, optimized
even ( u1|n1 -- u2|n2 ) Makes even. Adds one if uneven.
2* ( n1 -- n2 ) Arithmetric left-shift
2/ ( n1 -- n2 ) Arithmetric right-shift
abs ( n -- u ) Absolute value
negate ( n1 -- n2 ) Negate
- ( u1|n1 u2|n2 -- u3|n3 ) Subtraction
+ ( u1|n1 u2|n2 -- u3|n3 ) Addition
;------------------------------------------------------------------------------
; Calculus involving double numbers (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------
um* ( u1 u2 -- ud ) 32*32 = 64 Multiplication
ud* ( ud1 ud2 -- ud3 ) 64*64 = 64 Multiplication
udm* ( ud1 ud2 -- ud3-Low ud4-High ) 64*64=128 Multiplication
um/mod ( ud u1 -- u2 u3 ) ud / u1 = u3 remainder u2
ud/mod ( ud1 ud2 -- ud3 ud4 ) 64/64 = 64 rem 64 Division
ud1 / ud2 = ud4 remainder ud3
m* ( n1 n2 -- d ) n1 * n2 = d
m/mod ( d n1 -- n2 n3 ) d / n1 = n3 remainder r2
d/mod ( d1 d2 -- d3 d4 ) d1 / d2 = d4 remainder d3
d/ ( d1 d2 -- d3 ) d1 / d2 = d3
*/ ( n1 n2 n3 -- n4 ) n1 * n2 / n3 = n4
u*/ ( u1 u2 u3 -- u4 ) u1 * u2 / u3 = u4
*/mod ( n1 n2 n3 -- n4 n5 ) n1 * n2 / n3 = n5 remainder n4
u*/mod ( u1 u2 u3 -- u4 u5 ) u1 * u2 / u3 = u5 remainder u4
d2* ( d1 -- d2 ) Arithmetric left-shift
d2/ ( d1 -- d2 ) Arithmetric right-shift
dshl ( ud1 -- ud2 ) Logical left-shift, same as d2*
dshr ( ud1 -- ud2 ) Logical right-shift
dabs ( d -- ud ) Absolute value
dnegate ( d1 -- d2 ) Negate
d- ( ud1|d1 ud2|d2 -- ud3|d3 ) Subtraction
d+ ( ud1|d1 ud2|d2 -- ud3|d3 ) Addition
s>d ( n -- d ) Makes a signed single number double length
;------------------------------------------------------------------------------
; Comparisions (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------
Single-Comparisions:
u<= ( u1 u2 -- flag ) Unsigned comparisions
u>= ( u1 u2 -- flag )
u> ( u1 u2 -- flag )
u< ( u1 u2 -- flag )
<= ( n1 n2 -- flag ) Signed comparisions
>= ( n1 n2 -- flag )
> ( n1 n2 -- flag )
< ( n1 n2 -- flag )
0< ( n - flag ) Negative ?
0<> ( x -- flag )
0= ( x -- flag )
<> ( x1 x2 -- flag )
= ( x1 x2 -- flag )
Double-Comparisions: They perform the same for double numbers.
du> ( ud1 ud2 -- flag )
du< ( ud1 ud2 -- flag )
d> ( d1 d2 -- flag )
d< ( d1 d2 -- flag )
d0< ( d -- flag )
d0= ( d -- flag )
d<> ( d1 d2 -- flag )
d= ( d1 d2 -- flag )
;------------------------------------------------------------------------------
; Tools (not only) for s31.32 fixed point numbers (speciality!)
;------------------------------------------------------------------------------
Fixpoint numbers are stored ( n-comma n-whole ) and can be handled
like signed double numbers.
f/ ( df1 df2 -- df3 ) Division of two fixpoint numbers
f* ( df1 df2 -- df3 ) Multiplication
hold< ( char -- )
Adds character to pictured number output buffer
from behind.
f#S ( n-comma1 -- n-comma2 )
Adds 32 comma-digits to number output
f# ( n-comma1 -- n-comma2 )
Adds one comma-digit to number output
f. ( df -- )
Prints a fixpoint number with 32 fractional digits
f.n ( df n -- )
Prints a fixpoint number with n fractional digits
number ( Counted-String-Address -- 0 )
cstr-addr -- n 1 )
-- n-low n-high 2 )
Tries to convert a string to a number.
;------------------------------------------------------------------------------
; Number base (exactly ANS)
;------------------------------------------------------------------------------
binary ( -- ) Sets base to 2
decimal ( -- ) Sets base to 10
hex ( -- ) Sets base to 16
base ( -- a-addr ) Base variable address
;------------------------------------------------------------------------------
; Memory access (subtle differences to ANS, special cpu-specific extensions)
;------------------------------------------------------------------------------
move ( c-addr1 c-addr2 u -- ) Moves u Bytes in Memory
fill ( c-addr u c ) Fill u Bytes of Memory with value c
cbit@ ( mask c-addr -- flag ) Test BIts in byte-location
hbit@ ( mask a-addr -- flag ) Test BIts in halfword-location
bit@ ( mask a-addr -- flag ) Test BIts in word-location
cxor! ( mask c-addr -- ) Toggle bits in byte-location
hxor! ( mask a-addr -- ) Toggle bits in halfword-location
xor! ( mask a-addr -- ) Toggle bits in word-location
cbic! ( mask c-addr -- ) Clear BIts in byte-location
hbic! ( mask a-addr -- ) Clear BIts in halfword-location
bic! ( mask a-addr -- ) Clear BIts in word-location
cbis! ( mask c-addr -- ) Set BIts in byte-location
hbis! ( mask a-addr -- ) Set BIts in halfword-location
bis! ( mask a-addr -- ) Set BIts in word-location
2constant name ( ud|d -- ) Makes a double constant.
constant name ( u|n -- ) Makes a single constant.
2variable name ( ud|d -- ) Makes an initialized double variable
variable name ( n|n -- ) Makes an initialized single variable
nvariable name ( n1*u|n n1 -- ) Makes an initialized variable with
specified size of n1 words
Maximum is 15 words
buffer: name ( u -- ) Creates a buffer in RAM with u bytes length
2@ ( a-addr -- ud|d ) Fetches double number from memory
2! ( ud|d a-addr -- ) Stores double number in memory
@ ( a-addr -- u|n ) Fetches single number from memory
! ( u|n a-addr -- ) Stores single number in memory
+! ( u|n a-addr -- ) Add to memory location
h@ ( c-addr -- char ) Fetches halfword from memory
h! ( char c-addr ) Stores halfword in memory
h+! ( u|n a-addr -- ) Add to halfword memory location
c@ ( c-addr -- char ) Fetches byte from memory
c! ( char c-addr ) Stores byte in memory
c+! ( u|n a-addr -- ) Add to byte memory location
;------------------------------------------------------------------------------
; Strings and beautiful output (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------
String routines:
type ( c-addr length -- )
Prints a string.
s" Hello" Compiles a string and
( -- c-addr length )
gives back its address and length when executed.
." Hello" Compiles a string and
( -- )
prints it when executed.
( Comment ) Ignore Comment
\ Comment Comment to end of line
cr ( -- ) Emits line feed
bl ( -- 32 ) ASCII code for Space
space ( -- ) Emits space
spaces ( n -- ) Emits n spaces if n is positive
compare ( caddr-1 len-1 c-addr-2 len-2 -- flag )
Compares two strings
accept ( c-addr maxlength -- length ) Read input into a string.
Counted string routines:
ctype ( cstr-addr -- )
Prints a counted string.
c" Hello" Compiles a counted string and
( -- cstr-addr )
gives back its address when executed.
cexpect ( cstr-addr maxlength -- ) Read input into a counted string.
count ( cstr-addr -- c-addr length )
Convert counted string into addr-length string
skipstring ( cstr-addr -- a-addr )
Increases the pointer to the aligned end of the string.
Pictured numerical output:
.digit ( u -- char ) Converts a digit to a char
digit ( char -- u true | false ) Converts a char to a digit
[char] * Compiles code of following char
( -- char ) when executed
char * ( -- char ) gives code of following char
hold ( char -- ) Adds character to pictured number
output buffer from the front.
sign ( n -- ) Add a minus sign to pictured number
output buffer, if n is negative
#S ( ud1|d1 -- 0 0 ) Add all remaining digits
from the double length number to output buffer
# ( ud1|d1 -- ud2|d2 ) Add one digit from the
double length number to output buffer
#> ( ud|d -- c-addr len )
Drops double-length number and finishes
pictured numeric output ready for type
<# ( -- ) Prepare pictured number output buffer
u. ( u -- ) Print unsigned single number
. ( n -- ) Print single number
ud. ( ud -- ) Print unsigned double number
d. ( d -- ) Print double number
Deep insights:
words ( -- ) Prints list of defined words.
.s ( many -- many ) Prints stack contents, signed
u.s ( many -- many ) Prints stack contents, unsigned
h.s ( many -- many ) Prints stack contents, unsigned, hex
hex. ( u -- ) Prints 32 bit unsigned in hex base,
needs emit only.
This is independent of number subsystem.
;------------------------------------------------------------------------------
; User input and its interpretation (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------