0
votes

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.

1
there is no documentation how to use wifi on low level. the manufacturer provides a closed source C SDK to interface the MCU peripherals and a great part of WiFi is software. the CPU of esp MCUs is Tensilica XtensaJuraj
I strongly recommend against programming these chips in assembler. WiFi and Bluetooth require software stack of considerable size, are written in C/C++ and not readily available in assembler. If you want to avoid the Arduino IDE or the Arduino framework, there are many choices: There is the ESP-IDF framework for ESP32, there is the PlatformIO build system with IDE integrations etc.Codo
If you want wifi then see above with respect to those libraries. Otherwise gnu tools are easily available and documentation (no IDEs/SDKs required). The chips offer a relatively simple download solution (from my notes on baremetal for this platform looks like there is a bootloader in there that comes before your code). C or assembly you can still link and call (wifi) libraries...old_timer
@old_timer which are those tools? like i use avr-gcc or avra to compile my code and avrdude to upload it to atmel chips. Is it the same way? Which c compiler should i use to program esp32 and esp8266?vishnu joshi
yup got your point. thanks guys.vishnu joshi

1 Answers

3
votes

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 cant 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 google 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.