diff --git a/examples/optionbytes/Makefile b/examples/optionbytes/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..967b1fb14448928b5b09d24c68d325c5c9a41a31 --- /dev/null +++ b/examples/optionbytes/Makefile @@ -0,0 +1,55 @@ +TARGET:=optionbytes + +all : flash + +PREFIX:=riscv64-unknown-elf + +GPIO_Toggle:=EXAM/GPIO/GPIO_Toggle/User + +EVT:=../../ch32v003evt + +MINICHLINK:=../../minichlink + +ifeq ($(OS),Windows_NT) +# On Windows, all the major RISC-V GCC installs are missing the -ec libgcc. +LIB_GCC=../../misc/libgcc.a +else +LIB_GCC=-lgcc +endif + +CH32V003FUN:=../../ch32v003fun + +CFLAGS:= \ + -g -Os -flto -ffunction-sections \ + -static-libgcc $(LIB_GCC) \ + -march=rv32ec \ + -mabi=ilp32e \ + -I/usr/include/newlib \ + -I$(CH32V003FUN) \ + -nostdlib \ + -I. -DTINYVECTOR + +LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections + +SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c + +$(TARGET).elf : $(SYSTEM_C) $(TARGET).c + $(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS) + +$(TARGET).bin : $(TARGET).elf + $(PREFIX)-size $^ + $(PREFIX)-objdump -S $^ > $(TARGET).lst + $(PREFIX)-objdump -t $^ > $(TARGET).map + $(PREFIX)-objcopy -O binary $< $(TARGET).bin + $(PREFIX)-objcopy -O ihex $< $(TARGET).hex + +flash : $(TARGET).bin + $(MINICHLINK)/minichlink -w $< flash -b + +monitor : flash + $(MINICHLINK)/minichlink -T + + +clean : + rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex + diff --git a/examples/optionbytes/optionbytes.c b/examples/optionbytes/optionbytes.c new file mode 100644 index 0000000000000000000000000000000000000000..25aaf5c9178eeae2dd395a1380a329ddb888d42d --- /dev/null +++ b/examples/optionbytes/optionbytes.c @@ -0,0 +1,147 @@ +// Really basic self-contained demo for the ch32v003 +// Doesn't rely on any of the weird HAL stuff from CH +// Final executable is ~1/4th the size. + +// Could be defined here, or in the processor defines. +#define SYSTEM_CORE_CLOCK 48000000 + +#include "ch32v003fun.h" +#include <stdio.h> + +uint32_t count; + +int FLASH_WaitForLastOperation(uint32_t Timeout); + +int main() +{ + SystemInit48HSI(); + SetupDebugPrintf(); + + FLASH->OBKEYR = FLASH_KEY1; + FLASH->OBKEYR = FLASH_KEY2; + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; + FLASH->MODEKEYR = FLASH_KEY1; + FLASH->MODEKEYR = FLASH_KEY2; + + printf( "Option bytes started as:%04x\n", OB->USER ); + + uint16_t rdptmp = RDP_Key; + + + int status = FLASH_WaitForLastOperation(EraseTimeout); + if(status == FLASH_COMPLETE) + { + FLASH->OBKEYR = FLASH_KEY1; + FLASH->OBKEYR = FLASH_KEY2; + + FLASH->CTLR |= CR_OPTER_Set; + FLASH->CTLR |= CR_STRT_Set; + status = FLASH_WaitForLastOperation(EraseTimeout); + + if(status == FLASH_COMPLETE) + { + FLASH->CTLR &= CR_OPTER_Reset; + FLASH->CTLR |= CR_OPTPG_Set; + OB->RDPR = (uint16_t)rdptmp; + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status != FLASH_TIMEOUT) + { + FLASH->CTLR &= CR_OPTPG_Reset; + } + } + else + { + if(status != FLASH_TIMEOUT) + { + FLASH->CTLR &= CR_OPTPG_Reset; + } + } + } + + + printf( "After Clear:%04x\n", OB->USER ); +/* Notes from flash document: + * @param OB_IWDG - Selects the IWDG mode + * OB_IWDG_SW - Software IWDG selected + * OB_IWDG_HW - Hardware IWDG selected + * OB_STOP - Reset event when entering STOP mode. + * OB_STOP_NoRST - No reset generated when entering in STOP + * OB_STOP_RST - Reset generated when entering in STOP + * OB_STDBY - Reset event when entering Standby mode. + * OB_STDBY_NoRST - No reset generated when entering in STANDBY + * OB_STDBY_RST - Reset generated when entering in STANDBY + * OB_RST - Selects the reset IO mode and Ignore delay time + * OB_RST_NoEN - Reset IO disable (PD7) + * OB_RST_EN_DT12ms - Reset IO enable (PD7) and Ignore delay time 12ms + * OB_RST_EN_DT1ms - Reset IO enable (PD7) and Ignore delay time 1ms + * OB_RST_EN_DT128ms - Reset IO enable (PD7) and Ignore delay time 128ms +*/ + uint16_t OB_IWDG = OB_STOP_NoRST; + uint16_t OB_STOP = OB_IWDG_SW; + uint16_t OB_STDBY = OB_STDBY_NoRST; + uint16_t OB_RST = OB_RST_EN_DT1ms; + + FLASH->OBKEYR = FLASH_KEY1; + FLASH->OBKEYR = FLASH_KEY2; + status = FLASH_WaitForLastOperation(10000); + + if(status == FLASH_COMPLETE) + { + FLASH->CTLR |= CR_OPTPG_Set; + OB->USER = OB_IWDG | (uint16_t)(OB_STOP | (uint16_t)(OB_STDBY | (uint16_t)(OB_RST | (uint16_t)0xE0))); + + status = FLASH_WaitForLastOperation(10000); + if(status != FLASH_TIMEOUT) + { + FLASH->CTLR &= CR_OPTPG_Reset; + } + } + + printf( "After Write:%04x\n", OB->USER ); + + while(1); +} + + +int FLASH_GetBank1Status(void) +{ + int flashstatus = FLASH_COMPLETE; + + if((FLASH->STATR & FLASH_FLAG_BANK1_BSY) == FLASH_FLAG_BSY) + { + flashstatus = FLASH_BUSY; + } + else + { + if((FLASH->STATR & FLASH_FLAG_BANK1_WRPRTERR) != 0) + { + flashstatus = FLASH_ERROR_WRP; + } + else + { + flashstatus = FLASH_COMPLETE; + } + } + return flashstatus; +} + + +int FLASH_WaitForLastOperation(uint32_t Timeout) +{ + int status = FLASH_COMPLETE; + + status = FLASH_GetBank1Status(); + while((status == FLASH_BUSY) && (Timeout != 0x00)) + { + status = FLASH_GetBank1Status(); + Timeout--; + } + if(Timeout == 0x00) + { + status = FLASH_TIMEOUT; + } + return status; +} +