#include #include "ch573/gpio.h" #define GPIO_PORT_A ch573_gpio__gpio_port_a #define GPIO_PORT CH573_GPIO__GPIO_PORT_T_INTF static void start(void); /* * Function (or really pointer to code) for the reset interrupt handler. */ void on_reset(void); /* * Function which delays for a bit. */ void delay(void); /* Type def to a void function to make things mor ereadable. */ typedef void (*isr_routine)(void); /** The ISR Vector structure. This is linked to starting at address 0. */ // __attribute((__section__(".isr_vector"))) volatile struct { // // What NULL points to. nothing useful. // uint32_t reserved__; // // Called when the device boots or reset is pressed. // isr_routine reset_cb; // isr_routine nmi_cb; // isr_routine exc_cb; // } isr_vectors = {.reset_cb = on_reset}; /* * The reset callback.This has to be a naked function because the stack pointer * may not be initialized!!. */ __attribute((naked)) void on_reset(void) { // Set up the stack pointer to point to the end of SRAM. asm volatile( "li sp,0x20008000\n" "addi sp,sp,-4\n" "jalr %0\n" "spin:\n" "j spin\n" : : "r"(start)); } uint32_t collatz(uint32_t n) { uint32_t c = 0; while (n > 1) { if (n % 2 == 0) { n /= 2; } else { n = n * 3 + 1; } c++; } return c; } void blink_n(int n) { uint32_t bit = 1 << 8; while (n > 0) { GPIO_PORT.out.set(GPIO_PORT_A, OFF, 8); delay(); GPIO_PORT.out.set(GPIO_PORT_A, ON, 8); delay(); --n; } } void delay(void) { for (volatile uint32_t i = 0; i < 10000; ++i); } /* Main routine. This is called on_reset once everything else has been set up. */ static void start(void) { GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, 8); GPIO_PORT.pd_drv.set(GPIO_PORT_A, PD_DRV_OPEN_DRAIN, 8); for (;;) { GPIO_PORT.out.set(GPIO_PORT_A, ON, 8); delay(); delay(); delay(); GPIO_PORT.out.set(GPIO_PORT_A, OFF, 8); delay(); } // uint32_t i; // for (i = 1;; ++i) { // uint32_t c = collatz(i); // blink_n(c); // delay(); // delay(); // delay(); // delay(); // delay(); // delay(); // delay(); // delay(); // delay(); // } }