diff --git a/driver/CMakeLists.txt b/driver/CMakeLists.txt index 2849181..dd02389 100644 --- a/driver/CMakeLists.txt +++ b/driver/CMakeLists.txt @@ -2,7 +2,7 @@ file(GLOB FILELIST start.S src/common.c src/system.c -src/reset.c +src/resets.c src/clock.c src/sio.c src/gpio.c diff --git a/driver/inc/reg/reg.h b/driver/inc/reg/reg.h index b77f2ae..624e7ca 100644 --- a/driver/inc/reg/reg.h +++ b/driver/inc/reg/reg.h @@ -16,12 +16,38 @@ #define getreg32(a) (*(volatile uint32_t *)(uintptr_t)(a)) #define putreg32(v, a) (*(volatile uint32_t *)(uintptr_t)(a) = (v)) -// Register address offsets for atomic RMW aliases +typedef volatile uint32_t io_rw_32; +typedef const volatile uint32_t io_ro_32; +typedef volatile uint32_t io_wo_32; +typedef volatile uint16_t io_rw_16; +typedef const volatile uint16_t io_ro_16; +typedef volatile uint16_t io_wo_16; +typedef volatile uint8_t io_rw_8; +typedef const volatile uint8_t io_ro_8; +typedef volatile uint8_t io_wo_8; + #define REG_ALIAS_RW_BITS (0x0u << 12u) #define REG_ALIAS_XOR_BITS (0x1u << 12u) #define REG_ALIAS_SET_BITS (0x2u << 12u) #define REG_ALIAS_CLR_BITS (0x3u << 12u) +// Untyped conversion alias pointer generation macros +#define hw_set_alias_untyped(addr) ((void *)(REG_ALIAS_SET_BITS | (uintptr_t)(addr))) +#define hw_clear_alias_untyped(addr) ((void *)(REG_ALIAS_CLR_BITS | (uintptr_t)(addr))) +#define hw_xor_alias_untyped(addr) ((void *)(REG_ALIAS_XOR_BITS | (uintptr_t)(addr))) + +inline static void hw_set_bits(io_rw_32 *addr, uint32_t mask) { + *(io_rw_32 *) hw_set_alias_untyped((volatile void *) addr) = mask; +} + +inline static void hw_clear_bits(io_rw_32 *addr, uint32_t mask) { + *(io_rw_32 *) hw_clear_alias_untyped((volatile void *) addr) = mask; +} + +inline static void hw_xor_bits(io_rw_32 *addr, uint32_t mask) { + *(io_rw_32 *) hw_xor_alias_untyped((volatile void *) addr) = mask; +} + #define ROM_BASE (0x00000000) #define XIP_BASE (0x10000000) #define XIP_MAIN_BASE (0x10000000) diff --git a/driver/inc/reg/reset_reg.h b/driver/inc/reg/resets_reg.h similarity index 51% rename from driver/inc/reg/reset_reg.h rename to driver/inc/reg/resets_reg.h index 1742704..6354e80 100644 --- a/driver/inc/reg/reset_reg.h +++ b/driver/inc/reg/resets_reg.h @@ -1,9 +1,15 @@ #ifndef __HARDWARE_RESET_REG_H__ #define __HARDWARE_RESET_REG_H__ -#define RESET_RESET_OFFSET (0x000) -#define RESET_WDSEL_OFFSET (0x004) -#define RESET_RESET_DONE_OFFSET (0x008) +#include "reg.h" + +typedef struct { + io_rw_32 reset; + io_rw_32 wdsel; + io_rw_32 reset_done; +} resets_hw_t; + +#define resets_hw ((resets_hw_t *const)RESETS_BASE) #ifdef __cplusplus extern "C" { diff --git a/driver/inc/reset.h b/driver/inc/reset.h deleted file mode 100644 index 557ea7e..0000000 --- a/driver/inc/reset.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __HARDWARE_RESET_H__ -#define __HARDWARE_RESET_H__ - -#include "reg.h" -#include "reset_reg.h" - -#define RESET_ADC (1 << 0) -#define RESET_BUSCTRL (1 << 1) -#define RESET_DMA (1 << 2) -#define RESET_I2C0 (1 << 3) -#define RESET_I2C1 (1 << 4) -#define RESET_IO_BANK0 (1 << 5) -#define RESET_IO_QSPI (1 << 6) -#define RESET_JTAG (1 << 7) -#define RESET_PADS_BANK0 (1 << 8) -#define RESET_PADS_QSPI (1 << 9) -#define RESET_PIO0 (1 << 10) -#define RESET_PIO1 (1 << 11) -#define RESET_SYSPLL (1 << 12) -#define RESET_USBPLL (1 << 13) -#define RESET_PWM (1 << 14) -#define RESET_RTC (1 << 15) -#define RESET_SPI0 (1 << 16) -#define RESET_SPI1 (1 << 17) -#define RESET_SYSCFG (1 << 18) -#define RESET_SYSINFO (1 << 19) -#define RESET_TBMAN (1 << 20) -#define RESET_TIMER (1 << 21) -#define RESET_UART0 (1 << 22) -#define RESET_UART1 (1 << 23) -#define RESET_USBCTRL (1 << 24) -#define RESET_ALL ((1 << 25) - 1) - -#ifdef __cplusplus -extern "C" { -#endif - -void reset_enable(uint32_t reset); -void reset_disable(uint32_t reset); -void reset(uint32_t reset); -uint32_t reset_get_state(uint32_t reset); -void reset_wdg_bound(uint32_t reset); -void reset_wdg_unbound(uint32_t reset); -uint32_t reset_get_wdg_bound_state(uint32_t reset); - -#ifdef __cplusplus -} -#endif - -#endif /* __HARDWARE_RESET_H__ */ diff --git a/driver/inc/resets.h b/driver/inc/resets.h new file mode 100644 index 0000000..f5979ef --- /dev/null +++ b/driver/inc/resets.h @@ -0,0 +1,72 @@ +#ifndef __HARDWARE_RESET_H__ +#define __HARDWARE_RESET_H__ + +#include "reg.h" +#include "resets_reg.h" + +#define RESETS_RESET_ADC (1 << 0) +#define RESETS_RESET_BUSCTRL (1 << 1) +#define RESETS_RESET_DMA (1 << 2) +#define RESETS_RESET_I2C0 (1 << 3) +#define RESETS_RESET_I2C1 (1 << 4) +#define RESETS_RESET_IO_BANK0 (1 << 5) +#define RESETS_RESET_IO_QSPI (1 << 6) +#define RESETS_RESET_JTAG (1 << 7) +#define RESETS_RESET_PADS_BANK0 (1 << 8) +#define RESETS_RESET_PADS_QSPI (1 << 9) +#define RESETS_RESET_PIO0 (1 << 10) +#define RESETS_RESET_PIO1 (1 << 11) +#define RESETS_RESET_SYSPLL (1 << 12) +#define RESETS_RESET_USBPLL (1 << 13) +#define RESETS_RESET_PWM (1 << 14) +#define RESETS_RESET_RTC (1 << 15) +#define RESETS_RESET_SPI0 (1 << 16) +#define RESETS_RESET_SPI1 (1 << 17) +#define RESETS_RESET_SYSCFG (1 << 18) +#define RESETS_RESET_SYSINFO (1 << 19) +#define RESETS_RESET_TBMAN (1 << 20) +#define RESETS_RESET_TIMER (1 << 21) +#define RESETS_RESET_UART0 (1 << 22) +#define RESETS_RESET_UART1 (1 << 23) +#define RESETS_RESET_USBCTRL (1 << 24) +#define RESETS_RESET_ALL ((1 << 25) - 1) + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void reset_blocks(uint32_t bits) { + hw_set_bits(&resets_hw->reset, bits); +} + +static inline void unreset_blocks(uint32_t bits) { + hw_clear_bits(&resets_hw->reset, bits); +} + +static inline void unreset_blocks_wait(uint32_t bits) { + hw_clear_bits(&resets_hw->reset, bits); + while (!(resets_hw->reset_done & bits)); +} + +static inline void reset_unreset_blocks_wait(uint32_t bits) { + reset_blocks(bits); + unreset_blocks_wait(bits); +} + +static inline void reset_watchdog_bound(uint32_t bits) { + hw_set_bits(&resets_hw->wdsel, bits); +} + +static inline void reset_watchdog_unbound(uint32_t bits) { + hw_clear_bits(&resets_hw->wdsel, bits); +} + +static inline uint32_t reset_watchdog_get_bound_state(void) { + return resets_hw->wdsel; +} + +#ifdef __cplusplus +} +#endif + +#endif /* __HARDWARE_RESET_H__ */ diff --git a/driver/src/clock.c b/driver/src/clock.c index a966dc0..c475fba 100644 --- a/driver/src/clock.c +++ b/driver/src/clock.c @@ -1,5 +1,5 @@ #include "clock.h" -#include "reset.h" +#include "resets.h" void clock_rosc_enable(void) { @@ -279,12 +279,10 @@ void clock_pll_init(uint8_t pll, uint8_t refdiv, uint8_t fbdiv, uint8_t postdiv1 uint32_t val; if (pll == CLOCK_PLL_SYSPLL) { - reset_enable(RESET_SYSPLL); - reset_disable(RESET_SYSPLL); + reset_unreset_blocks_wait(RESETS_RESET_SYSPLL); addr = PLL_SYS_BASE; } else if (pll == CLOCK_PLL_USBPLL) { - reset_enable(RESET_USBPLL); - reset_disable(RESET_USBPLL); + reset_unreset_blocks_wait(RESETS_RESET_USBPLL); addr = PLL_USB_BASE; } else { return; @@ -313,12 +311,10 @@ void clock_pll_init(uint8_t pll, uint8_t refdiv, uint8_t fbdiv, uint8_t postdiv1 void clock_pll_deinit(uint8_t pll) { if (pll == CLOCK_PLL_SYSPLL) { - reset_enable(RESET_SYSPLL); - reset_disable(RESET_SYSPLL); + reset_unreset_blocks_wait(RESETS_RESET_SYSPLL); putreg32(CLOCK_PLL_PWR_MASK, PLL_SYS_BASE + CLOCK_PLL_PWR_OFFSET); } else if (pll == CLOCK_PLL_USBPLL) { - reset_enable(RESET_USBPLL); - reset_disable(RESET_USBPLL); + reset_unreset_blocks_wait(RESETS_RESET_USBPLL); putreg32(CLOCK_PLL_PWR_MASK, PLL_USB_BASE + CLOCK_PLL_PWR_OFFSET); } } diff --git a/driver/src/reset.c b/driver/src/reset.c deleted file mode 100644 index 8793b77..0000000 --- a/driver/src/reset.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "reset.h" - -void reset_enable(uint32_t reset) -{ - uint32_t reg_base; - - reg_base = RESETS_BASE + REG_ALIAS_SET_BITS; - putreg32(reset, reg_base + RESET_RESET_OFFSET); -} - -void reset_disable(uint32_t reset) -{ - uint32_t reg_base; - - reg_base = RESETS_BASE + REG_ALIAS_CLR_BITS; - putreg32(reset, reg_base + RESET_RESET_OFFSET); -} - -void reset(uint32_t reset) -{ - reset_enable(reset); - reset_disable(reset); -} - -uint32_t reset_get_state(uint32_t reset) -{ - uint32_t reg_base; - uint32_t regval; - - reg_base = RESETS_BASE; - regval = getreg32(reg_base + RESET_RESET_DONE_OFFSET); - regval = regval & reset; - - return regval; -} - -void reset_wdg_bound(uint32_t reset) -{ - uint32_t reg_base; - - reg_base = RESETS_BASE + REG_ALIAS_SET_BITS; - putreg32(reset, reg_base + RESET_WDSEL_OFFSET); -} - -void reset_wdg_unbound(uint32_t reset) -{ - uint32_t reg_base; - - reg_base = RESETS_BASE + REG_ALIAS_CLR_BITS; - putreg32(reset, reg_base + RESET_WDSEL_OFFSET); -} - -uint32_t reset_get_wdg_bound_state(uint32_t reset) -{ - uint32_t reg_base; - uint32_t regval; - - reg_base = RESETS_BASE; - regval = getreg32(reg_base + RESET_WDSEL_OFFSET); - regval = regval & reset; - - return regval; -} diff --git a/driver/src/resets.c b/driver/src/resets.c new file mode 100644 index 0000000..e69de29 diff --git a/project.build b/project.build index e1d02ba..b5581a1 100644 --- a/project.build +++ b/project.build @@ -48,12 +48,15 @@ cmake_definition+= -DCONFIG_COMX=$(COMX) cmake_definition+= -DSDK_BASE_DIR=$(SDK_BASE_DIR) cmake_definition+= -DEXAMPLE_NAME=$(EXAMPLE_NAME) +FINAL_NAME_PRE := $(EXAMPLE_BASE_DIR)/build/$(EXAMPLE_NAME) + build:Makefile $(CMAKE) -S . -B build -G "Unix Makefiles" $(cmake_definition) $(MAKE) -C build -j - $(CROSS_COMPILE)objcopy -O binary $(EXAMPLE_BASE_DIR)/build/$(EXAMPLE_NAME).elf $(EXAMPLE_BASE_DIR)/build/$(EXAMPLE_NAME).bin - $(CROSS_COMPILE)objdump -d -S $(EXAMPLE_BASE_DIR)/build/$(EXAMPLE_NAME).elf > $(EXAMPLE_BASE_DIR)/build/$(EXAMPLE_NAME).asm - size $(EXAMPLE_BASE_DIR)/build/$(EXAMPLE_NAME).elf + $(CROSS_COMPILE)objcopy -O binary $(FINAL_NAME_PRE).elf $(FINAL_NAME_PRE).bin + $(CROSS_COMPILE)objdump -d -S $(FINAL_NAME_PRE).elf > $(FINAL_NAME_PRE).asm + size $(FINAL_NAME_PRE).elf + sha256sum $(FINAL_NAME_PRE).elf clean:: $(RM) build