diff options
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | cmake/fiddle.cmake | 10 | ||||
-rw-r--r-- | fdl/ch573/spi.fdl | 31 | ||||
-rw-r--r-- | include/spi.h | 5 | ||||
-rw-r--r-- | src/main.c | 41 | ||||
-rw-r--r-- | src/spi.c | 62 |
6 files changed, 130 insertions, 27 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e53af7f..d20fe90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,13 @@ set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) set(TC_PREFIX riscv32-picolibc-elf-) # Set compiler and tools set(CMAKE_C_COMPILER "${TC_PREFIX}gcc" CACHE INTERNAL "C Compiler") -set(CMAKE_OBJCOPY "${TC_PREFIX}objcopy" CACHE INTERNAL "Object Copier") +find_program(CMAKE_OBJCOPY "${TC_PREFIX}objcopy") + +if (CMAKE_OBJCOPY) + message(STATUS "Found objcopy at ${CMAKE_OBJCOPY}") +else() + message(FATAL_ERROR "Could not find ${TC_PREFIX}objcopy.") +endif() set(CMAKE_EXPORT_COMPILE_COMMANDS ON) file(REAL_PATH "stubs/libgloss_stub.c" LIBGLOSS_STUB) diff --git a/cmake/fiddle.cmake b/cmake/fiddle.cmake index 6b151a2..6830ce5 100644 --- a/cmake/fiddle.cmake +++ b/cmake/fiddle.cmake @@ -1,3 +1,11 @@ +find_program(FIDDLEC "fiddlec") + +if (FIDDLEC) + message (STATUS "Found fiddlec at ${FIDDLEC}") +else() + message (FATAL_ERROR "Could not find fiddlec. Please download and build it at git@git.josher.dev:fiddle.git") +endif() + function(add_fiddle_source header_out fdl_file) get_filename_component(dir_path ${fdl_file} DIRECTORY) get_filename_component(file_name_without_extension ${fdl_file} NAME_WE) @@ -13,7 +21,7 @@ function(add_fiddle_source header_out fdl_file) DEPENDS ${fdl_file} COMMENT "Fiddle compile ${fdl_file} -> ${output_header}" COMMAND ${CMAKE_COMMAND} -E make_directory "${output_dir}" - COMMAND fiddlec -Lc -h ${output_header} -I ${CMAKE_SOURCE_DIR}/fdl/ --intf-dir ${CMAKE_BINARY_DIR}/fdli/ ${CMAKE_SOURCE_DIR}/${fdl_file} + COMMAND ${FIDDLEC} -Lc -h ${output_header} -I ${CMAKE_SOURCE_DIR}/fdl/ --intf-dir ${CMAKE_BINARY_DIR}/fdli/ ${CMAKE_SOURCE_DIR}/${fdl_file} ) # Make the output header file available as a source file for the target diff --git a/fdl/ch573/spi.fdl b/fdl/ch573/spi.fdl index 855d17f..cec88f3 100644 --- a/fdl/ch573/spi.fdl +++ b/fdl/ch573/spi.fdl @@ -8,6 +8,7 @@ package ch573.spi { using ch573.common; type spi_t : struct { + assert_pos(0x0); /** SPI0 Control Mode Register */ reg ctrl_mod(8) : struct { /** SPI master/slave mode select */ @@ -18,18 +19,32 @@ package ch573.spi { wire_2_mod : bit_t; union { /** Clock idle mode select in master mode */ - mst_sck_mod : bit_t; + mst_sck_mod : enum(1) { + [[ c: unqualified ]] + CLOCK_IDLE_LOW = 0, + + [[ c: unqualified ]] + CLOCK_IDLE_HIGH = 1, + }; /** First byte command mode select in slave mode */ slv_cmd_mod : bit_t; }; /** FIFO direction setting bit */ - fifo_dir : bit_t; - /** SCK output enable bit */ - sck_oe : bit_t; - /** MOSI output enable bit */ - mosi_oe : bit_t; - /** MISO output enable bit */ - miso_oe : bit_t; + fifo_dir : enum(1) { + [[ c: unqualified ]] + FIFO_DIR_INPUT = 1, + + [[ c: unqualified ]] + FIFO_DIR_OUTPUT = 0, + }; + struct { + /** SCK output enable bit */ + sck_oe : enable_t; + /** MOSI output enable bit */ + mosi_oe : enable_t; + /** MISO output enable bit */ + miso_oe : enable_t; + } pin_enable; }; /** SPI0 Control Configuration Register */ diff --git a/include/spi.h b/include/spi.h new file mode 100644 index 0000000..65e3a9d --- /dev/null +++ b/include/spi.h @@ -0,0 +1,5 @@ +#pragma once + +void enable_spi(void); + +void run_spi(void); @@ -5,6 +5,7 @@ #include "ch573/pwr.h" #include "ch573/uart.h" #include "clock.h" +#include "spi.h" #include "system.h" #define GPIO_PORT_A ch573_gpio__gpio_port_a @@ -124,28 +125,34 @@ static void fast_delay() */ int main(void) { - GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, 8); - GPIO_PORT.pd_drv.set(GPIO_PORT_A, 0, 8); - GPIO_PORT.out.set(GPIO_PORT_A, OFF, 8); + printf("Running SPI.\n"); - GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, 11); - GPIO_PORT.pd_drv.set(GPIO_PORT_A, 0, 11); + enable_spi(); - GPIO_PORT.dir.set(GPIO_PORT_A, DIR_IN, 10); - GPIO_PORT.pd_drv.set(GPIO_PORT_A, PD_DRV_OPEN_DRAIN, 11); + run_spi(); - set_system_clock_6Mhz(); - uint32_t reg = (*(uint32_t*)0x40001008); - reg &= ~0x1f; - reg |= 10; - enter_safe_mode(); - (*(uint32_t*)0x40001008) = reg; + // GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, 8); + // GPIO_PORT.pd_drv.set(GPIO_PORT_A, 0, 8); + // GPIO_PORT.out.set(GPIO_PORT_A, OFF, 8); + // GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, 11); + // GPIO_PORT.pd_drv.set(GPIO_PORT_A, 0, 11); - for (int i = 0;; ++i) { - GPIO_PORT.out.set(GPIO_PORT_A, ON, 8); - GPIO_PORT.out.set(GPIO_PORT_A, OFF, 8); - } + // GPIO_PORT.dir.set(GPIO_PORT_A, DIR_IN, 10); + // GPIO_PORT.pd_drv.set(GPIO_PORT_A, PD_DRV_OPEN_DRAIN, 11); + + // set_system_clock_6Mhz(); + // uint32_t reg = (*(uint32_t*)0x40001008); + // reg &= ~0x1f; + // reg |= 10; + // enter_safe_mode(); + // (*(uint32_t*)0x40001008) = reg; + + + // for (int i = 0;; ++i) { + // GPIO_PORT.out.set(GPIO_PORT_A, ON, 8); + // GPIO_PORT.out.set(GPIO_PORT_A, OFF, 8); + // } // clock_cfg_t cfg; // for (int i = 0;; ++i) { diff --git a/src/spi.c b/src/spi.c new file mode 100644 index 0000000..3105f1b --- /dev/null +++ b/src/spi.c @@ -0,0 +1,62 @@ +#include "spi.h" + +#include <stdio.h> + +#include "ch573/gpio.h" +#include "ch573/spi.h" + +#define SPI CH573_SPI__SPI_T_INTF +#define SPI0 ch573_spi__spi0 + +#define GPIO_PORT_A ch573_gpio__gpio_port_a +#define GPIO_PORT_B ch573_gpio__gpio_port_b +#define GPIO_PORT CH573_GPIO__GPIO_PORT_T_INTF + +#define GPIO_I CH573_GPIO__GPIO_T_INTF +#define GPIO ch573_gpio__gpio + +void enable_spi(void) +{ + GPIO_I.pin_alternate.pin_spi0.set(GPIO, OFF); + + GPIO_PORT.out.set(GPIO_PORT_A, ON, 12); + GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, 12); + GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, 14); + GPIO_PORT.pd_drv.set(GPIO_PORT_A, 0, 12); + GPIO_PORT.pd_drv.set(GPIO_PORT_A, 0, 14); + + GPIO_PORT.dir.set(GPIO_PORT_B, DIR_OUT, 12); + GPIO_PORT.dir.set(GPIO_PORT_B, DIR_OUT, 14); + GPIO_PORT.pd_drv.set(GPIO_PORT_B, 0, 12); + GPIO_PORT.pd_drv.set(GPIO_PORT_B, 0, 14); + GPIO_PORT.out.set(GPIO_PORT_B, OFF, 14); + GPIO_PORT.out.set(GPIO_PORT_B, ON, 12); + + GPIO_PORT.dir.set(GPIO_PORT_B, DIR_IN, 13); + GPIO_PORT.dir.set(GPIO_PORT_B, DIR_IN, 15); + GPIO_PORT.dir.set(GPIO_PORT_A, DIR_IN, 13); + GPIO_PORT.dir.set(GPIO_PORT_A, DIR_IN, 15); + + SPI.clock_div.set(SPI0, 16); + SPI.ctrl_mod.all_clear.set(SPI0, 1); + // SPI.ctrl_mod.set(SPI0, 0xe0); // Set mosi and sck + + SPI.ctrl_mod.all_clear.set(SPI0, 0); + SPI.ctrl_mod.pin_enable.set(SPI0, 0x7); // Set mosi and sck + SPI.ctrl_cfg.auto_if.set(SPI0, 1); + SPI.ctrl_cfg.dma_enable.set(SPI0, OFF); +} + +void run_spi(void) +{ + GPIO_PORT.out.set(GPIO_PORT_A, ON, 12); + while (1) { + GPIO_PORT_A->clr |= 1 << 12; + SPI.ctrl_mod.fifo_dir.set(SPI0, FIFO_DIR_OUTPUT); + // R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; + SPI.data_buf.set(SPI0, 0xaa); + // R8_SPI0_BUFFER = 0xaa; + while (!SPI.int_flag.free.get(SPI0)); + GPIO_PORT.out.set(GPIO_PORT_A, ON, 12); + } +} |