[Sipeed LicheeRV 86 Panel Review] D1 as a single-chip computer naked programming light - LED-Blinky
[Copy link]
A great person on the Internet has developed a baremetal programming for D1, which makes D1 a real single-chip microcomputer. The open source project is here: https://github.com/bigmagic123/d1-nezha-baremeta
Learn from this and learn how to program the registers of the various components inside D1.
There is no JTAG debugging environment yet, so you can only compile-download-run and check whether it works properly by the running effect. Download using the xfel tool: https://github.com/xboot/xfel/, just download the Windows version.
You need to remove the SD card, or press and hold the FEL button on the core board when powering on to enter the FEL download mode.
After entering FEL mode, the computer detects the USB device and installs the USB universal driver through Zadig. Then you can use xfel to check whether the connection is correct and whether it has entered FEL mode:
xfel version
AWUSBFEX ID=0x00185900(D1/F133) dflag=0x44 dlength=0x08 scratchpad=0x00045000
xfel sid
d20011005c00481448000505093f760b
The prerequisite is to make sure that the riscv64 toolchain has been installed. You can use elf or linux-gnu toolchain. (I installed it in WSL environment, which should be the same as virtual machine or Linux host)
By looking at D1-H_User Manual.pdf, we can find the GPIO document, and then compare it with the development board schematic diagram. We can find that the LED of Lichee RV 86Panel is connected to PC1 (the BT_WAKE_AP signal of the 86Panel baseboard is also connected to PC1, but in the bare metal programming environment, BT is not enabled and can be ignored. If you are not sure, you can unplug it and run the core board alone);
First, use XFEL's read and write commands to test the read and write GPIO registers to see if the LED can flash:
First, read the PC configuration register PC_CFG0 (0x02000060), where PC1 should be changed from the default Disable mode at power-on to the OUTPUT mode.
// led-blinky: PC1 to output
xfel hexdump 0x02000060 100
xfel write32 0x02000060 0xFFFFFF1F
// Toggle PC1
xfel write32 0x02000070 0x00000002
xfel write32 0x02000070 0x00000000
Each time 0/1 is written to the position corresponding to PC1 of the PC_DAT register, the LED turns off/on accordingly. Therefore, the LED-Blinky program can be implemented by following the same steps.
led-blinky.c
void delay(int);
static int k = 23;
int main(int argc, char argv) {
int GPIO_BASE_ADDR = 0x02000000;
int PC_CFG0 = 0x0060;
int PC_DAT = 0x0070;
unsigned int *PC_CFG0_Addr = (unsigned int *)(GPIO_BASE_ADDR + PC_CFG0);
unsigned int *PC_DAT_Addr = (unsigned int *)(GPIO_BASE_ADDR + PC_DAT);
unsigned int PC_CFG0_Value = *PC_CFG0_Addr;
PC_CFG0_Value &= 0xFFFFFF0F;
PC_CFG0_Value |= 0x00000010;
*PC_CFG0_Addr = PC_CFG0_Value;
while(1) {
delay(1000);
*PC_DAT_Addr ^= 0x00000002;
}
k++;
return k;
}
void delay(int count)
{
volatile int x = count;
while(1) {
volatile int y = 2000;
for(; y >0; y--)
__asm__("nop");
if(x > 0) x--;
else break;
}
return ;
}
led-blinky.ld
OUTPUT_ARCH( "riscv" )
OUTPUT_FORMAT("elf64-littleriscv")
ENTRY( main )
SECTIONS
{
/* text: test code section */
. = 0x00020000;
.text : { *(.text) }
/* data: Initialized data segment */
.gnu_build_id : { *(.note.gnu.build-id) }
.data : { *(.data) }
.rodata : { *(.rodata) }
.sdata : { *(.sdata) }
.debug : { *(.debug) }
. += 0x8000;
stack_top = .;
/* End of uninitalized data segement */
_end = .;
}
Makefile
PROJECT ?= led-blinky
CROSS_COMPILE ?= riscv64-unknown-linux-gnu
CFLAGS += -fPIC
.PHONY: ${PROJECT}.bin
${PROJECT}.bin: ${PROJECT}.elf
${CROSS_COMPILE}-objcopy -O binary $< $@
${PROJECT}.elf: ${PROJECT}.o
${CROSS_COMPILE}-ld -T ${PROJECT}.ld -o $@ $<
${PROJECT}.o: ${PROJECT}.c
${CROSS_COMPILE}-gcc ${CFLAGS} -c -o $@ $<
clean:
rm *.o *.elf *.bin
It should be noted that in the link file, 0x00020000 is specified as the starting address, which is the address of the SRAM inside the D1 chip. Later tests found that when the PIC (position-independent code) flag of gcc is used, the code can be executed correctly no matter where it is placed.
After the code, .ld and Makefile are written, make can complete the compilation, linking, and convert elf to bin file (make sure riscv64-unknown-linux-gnu-gcc is in PATH)
Then use xfel to download the generated bin file to the SRAM of the D1 chip, as shown in the figure;
At this time, the LED on the core board flashes normally.
|