How do i program an ESP32 or an ESP8266 module using assembly? I don't want to use arduino ide. I figured a way to program atmel chips with assembly. I wanted to learn how to program esp32 and esp8266 in assembly.
The tools can be easily found. I installed a pre-built tarball.
This is a mix of C and asm but you can do this all asm.
This is for an esp8266.
vectors.s
.section .init
.globl _start
_start:
call0 notmain
ill
.balign 0x100
.globl dummy
dummy:
ret.n
.balign 0x10
.globl PUT32
PUT32:
memw
s32i.n a3,a2,0
ret.n
.balign 0x10
.globl GET32
GET32:
memw
l32i.n a2,a2,0
ret.n
so.c
#define GPIO_ENSET 0x60000310
#define GPIO_OUTSET 0x60000304
#define GPIO_OUTCLR 0x60000308
#define IOMUX_GPIO2 0x60000838
void dummy ( unsigned int );
void PUT32 ( unsigned int, unsigned int );
unsigned GET32 ( unsigned int );
void notmain ( void )
{
unsigned int ra;
unsigned int rx;
ra=GET32(IOMUX_GPIO2);
ra&=(~0x130);
PUT32(IOMUX_GPIO2,ra);
PUT32(GPIO_ENSET,1<<2);
while(1)
{
PUT32(GPIO_OUTSET,1<<2);
for(rx=0;rx<800000;rx++) dummy(rx);
PUT32(GPIO_OUTCLR,1<<2);
for(rx=0;rx<800000;rx++) dummy(rx);
}
}
so.ld
MEMORY
{
bob : ORIGIN = 0x40100000, LENGTH = 0x1000
ted : ORIGIN = 0x3FFE8000, LENGTH = 0x1000
}
SECTIONS
{
.init : { *(.init*) } > bob
.literal : { *(.literal*) } > bob
.text : { *(.text*) } > bob
.rodata : { *(.rodata*) } > bob
.data : { *(.data*) } > ted
.bss : { *(.bss*) } > ted
}
build
xtensa-lx106-elf-as --warn --fatal-warnings vectors.s -o vectors.o
xtensa-lx106-elf-gcc -Wall -O2 -ffreestanding -c so.c -o so.o
xtensa-lx106-elf-ld -nostdlib -nostartfiles -T so.ld vectors.o so.o -o so.elf
xtensa-lx106-elf-objdump -D so.elf > so.list
xtensa-lx106-elf-objcopy so.elf so.bin -O binary
disassembly
Disassembly of section .init:
40100000 <_start>:
40100000: 001385 call0 4010013c <notmain>
...
40100100 <dummy>:
40100100: f00d ret.n
...
40100110 <PUT32>:
40100110: 0020c0 memw
40100113: 0239 s32i.n a3, a2, 0
40100115: f00d ret.n
...
40100120 <GET32>:
40100120: 0020c0 memw
40100123: 0228 l32i.n a2, a2, 0
40100125: f00d ret.n
Disassembly of section .literal:
40100128 <.literal>:
40100128: 0838 l32i.n a3, a8, 0
4010012a: 106000 and a6, a0, a0
4010012d: 03 .byte 0x3
4010012e: 046000 extui a6, a0, 0, 1
40100131: 03 .byte 0x3
40100132: 006000 rsil a0, 0
40100135: 35 .byte 0x35
40100136: 000c movi.n a0, 0
40100138: 0308 l32i.n a0, a3, 0
4010013a: 00 .byte 00
4010013b: 60 .byte 0x60
Disassembly of section .text:
4010013c <notmain>:
4010013c: e0c112 addi a1, a1, -32
4010013f: 61c9 s32i.n a12, a1, 24
40100141: fff9c1 l32r a12, 40100128 <GET32+0x8>
40100144: 7109 s32i.n a0, a1, 28
40100146: 0c2d mov.n a2, a12
40100148: 51d9 s32i.n a13, a1, 20
4010014a: 41e9 s32i.n a14, a1, 16
4010014c: 31f9 s32i.n a15, a1, 12
4010014e: fffd05 call0 40100120 <GET32>
40100151: cfae32 movi a3, 0xfffffecf
40100154: 103230 and a3, a2, a3
40100157: 0c2d mov.n a2, a12
40100159: fffb45 call0 40100110 <PUT32>
4010015c: fff421 l32r a2, 4010012c <GET32+0xc>
4010015f: 430c movi.n a3, 4
40100161: fffac5 call0 40100110 <PUT32>
40100164: fff3f1 l32r a15, 40100130 <GET32+0x10>
40100167: fff3d1 l32r a13, 40100134 <GET32+0x14>
4010016a: fff3e1 l32r a14, 40100138 <GET32+0x18>
4010016d: 430c movi.n a3, 4
4010016f: 0f2d mov.n a2, a15
40100171: fff9c5 call0 40100110 <PUT32>
40100174: 0c0c movi.n a12, 0
40100176: 0c2d mov.n a2, a12
40100178: cc1b addi.n a12, a12, 1
4010017a: fff845 call0 40100100 <dummy>
4010017d: f59cd7 bne a12, a13, 40100176 <notmain+0x3a>
40100180: 430c movi.n a3, 4
40100182: 202ee0 or a2, a14, a14
40100185: fff885 call0 40100110 <PUT32>
40100188: 0c0c movi.n a12, 0
4010018a: 0c2d mov.n a2, a12
4010018c: cc1b addi.n a12, a12, 1
4010018e: fff705 call0 40100100 <dummy>
40100191: f59cd7 bne a12, a13, 4010018a <notmain+0x4e>
40100194: fff546 j 4010016d <notmain+0x31>
And then due to how this was done, you can't use esptool.py to prep the file, so I made my own, taking the output here:
hexdump -C so.bin
00000000 85 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000100 0d f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000110 c0 20 00 39 02 0d f0 00 00 00 00 00 00 00 00 00 |. .9............|
00000120 c0 20 00 28 02 0d f0 00 38 08 00 60 10 03 00 60 |. .(....8..`...`|
00000130 04 03 00 60 00 35 0c 00 08 03 00 60 12 c1 e0 c9 |...`.5.....`....|
00000140 61 c1 f9 ff 09 71 2d 0c d9 51 e9 41 f9 31 05 fd |a....q-..Q.A.1..|
00000150 ff 32 ae cf 30 32 10 2d 0c 45 fb ff 21 f4 ff 0c |.2..02.-.E..!...|
00000160 43 c5 fa ff f1 f3 ff d1 f3 ff e1 f3 ff 0c 43 2d |C.............C-|
00000170 0f c5 f9 ff 0c 0c 2d 0c 1b cc 45 f8 ff d7 9c f5 |......-...E.....|
00000180 0c 43 e0 2e 20 85 f8 ff 0c 0c 2d 0c 1b cc 05 f7 |.C.. .....-.....|
00000190 ff d7 9c f5 46 f5 ff |....F..|
00000197
turning it into this
hexdump -C so.esp.bin
00000000 e9 01 00 00 00 00 10 40 00 00 10 40 98 01 00 00 |.......@...@....|
00000010 85 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000110 0d f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000120 c0 20 00 39 02 0d f0 00 00 00 00 00 00 00 00 00 |. .9............|
00000130 c0 20 00 28 02 0d f0 00 38 08 00 60 10 03 00 60 |. .(....8..`...`|
00000140 04 03 00 60 00 35 0c 00 08 03 00 60 12 c1 e0 c9 |...`.5.....`....|
00000150 61 c1 f9 ff 09 71 2d 0c d9 51 e9 41 f9 31 05 fd |a....q-..Q.A.1..|
00000160 ff 32 ae cf 30 32 10 2d 0c 45 fb ff 21 f4 ff 0c |.2..02.-.E..!...|
00000170 43 c5 fa ff f1 f3 ff d1 f3 ff e1 f3 ff 0c 43 2d |C.............C-|
00000180 0f c5 f9 ff 0c 0c 2d 0c 1b cc 45 f8 ff d7 9c f5 |......-...E.....|
00000190 0c 43 e0 2e 20 85 f8 ff 0c 0c 2d 0c 1b cc 05 f7 |.C.. .....-.....|
000001a0 ff d7 9c f5 46 f5 ff 00 00 00 00 00 00 00 00 ae |....F...........|
000001b0
I will let you figure that out, tool sources are available.
https://github.com/espressif/esptool
If this link stops working then search for "esptool.py" to hopefully find one.
Then flash it:
esptool.py --port /dev/ttyUSB5 write_flash -fm qio 0x00000 so.esp.bin
I am using a cheap nodemcu clone. I bought 5 of them for $15 on Amazon. Don't need extra wires/usb-uart, etc.
Changing these
for(rx=0;rx<800000;rx++)
to/from
for(rx=0;rx<400000;rx++)
and see the led blink rate change.
You can easily write this in only assembly by poking the few registers yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With