diff options
| -rw-r--r-- | .gitignore | 9 | ||||
| -rw-r--r-- | .gitmodules | 3 | ||||
| -rw-r--r-- | GenClangd.py | 6 | ||||
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | lib/colours.h | 7 | ||||
| -rw-r--r-- | lib/ili9341.c | 253 | ||||
| -rw-r--r-- | lib/ili9341.h | 73 | ||||
| -rw-r--r-- | lib/spi_sw.c | 32 | ||||
| -rw-r--r-- | lib/spi_sw.h | 22 | ||||
| -rw-r--r-- | rules.mk | 177 | ||||
| -rw-r--r-- | src/Makefile | 19 | ||||
| -rw-r--r-- | src/main.c | 37 |
13 files changed, 651 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a569521 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.clangd + +libopencm3 + +*.elf +*.bin +*.ld +*.o +*.d diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6bccd68 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libopencm3"] + path = libopencm3 + url = https://github.com/libopencm3/libopencm3 diff --git a/GenClangd.py b/GenClangd.py new file mode 100644 index 0000000..7616559 --- /dev/null +++ b/GenClangd.py @@ -0,0 +1,6 @@ +import os + +if __name__ == "__main__": + path = os.getcwd() + with open(".clangd", "w") as file: + file.write("CompileFlags:\n Add: -I"+path+"/libopencm3/include\n") diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..24ce9df --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +all: + make -C src + +flash: + make -C src + st-flash --reset write src/*.bin 0x8000000 + +init: + git submodule update --init + python3 GenClangd.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..e85ebad --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# STM32F103 libopencm3 ili9341 screen lib + +# Connection diff --git a/lib/colours.h b/lib/colours.h new file mode 100644 index 0000000..e7c637e --- /dev/null +++ b/lib/colours.h @@ -0,0 +1,7 @@ +#define PALET_16BIT + +#ifdef PALET_16BIT + +#define white 0xFFFF + +#endif //PALET_16BIT diff --git a/lib/ili9341.c b/lib/ili9341.c new file mode 100644 index 0000000..5aba148 --- /dev/null +++ b/lib/ili9341.c @@ -0,0 +1,253 @@ +#include "ili9341.h" +#include <libopencm3/stm32/f1/spi.h> +#include <stdint.h> +#include "libopencm3/stm32/f1/gpio.h" +#include "spi_sw.h" +#include "libopencm3/stm32/common/spi_common_v1.h" +#include "libopencm3/stm32/f1/rcc.h" + +#define SW_SPI_IMPL + +SPI_IMPL spi_sw; + +void spi_transmit(int spi, uint8_t pl) { +#ifdef SW_SPI_IMPL + SpiSend(&spi_sw, pl); +#else + spi_write(spi, pl); +#endif +} + +// Hard resets the screen +void ILI_hard_reset(void) { + gpio_clear(GPIOA, ILI9341_RES); + delayCycles(100000); + gpio_set(GPIOA, ILI9341_RES); + delayCycles(100000); +} + +// Sets up GPIO for peripherals +void ILI_SetupGPIO() { + // setting up DC and RES + gpio_set_mode(GPIOA, + GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, + ILI9341_DC | ILI9341_RES); + + // Setting up MOSI, SS and SCK + gpio_set_mode(GPIOA, + GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, + ILI9341_CS | ILI9341_CLK | ILI9341_MOSI ); + + // Setting up MISO + gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, ILI9341_MISO); + +#ifdef SW_SPI_IMPL + spi_sw = SpiInit(ILI9341_MOSI, ILI9341_CLK); +#else + // Setting up a SPI timer + rcc_periph_reset_pulse(RST_SPI1); + + spi_init_master(SPI_ADDR, SPI_CR1_BAUDRATE_FPCLK_DIV_4, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); + + spi_enable_software_slave_management(SPI_ADDR); + spi_set_nss_high(SPI_ADDR); + spi_enable(SPI_ADDR); + spi_set_clock_phase_1(SPI_ADDR); +#endif +} + +// Sends a comand to display +void ILI_sendComand(uint8_t cmd) { + gpio_set(GPIOA, ILI9341_CS); + gpio_clear(GPIOC, GPIO13); // Set the transmission LED + gpio_clear(GPIOA, ILI9341_DC); + spi_transmit(SPI_ADDR, cmd); + gpio_set(GPIOC, GPIO13); // Clear the reansmission LED + gpio_clear(GPIOA, ILI9341_CS); +} + +// Writes a bit to SPI +void ILI_sendData(uint8_t data) { + gpio_set(GPIOA, ILI9341_CS); + gpio_clear(GPIOC, GPIO13); // Set the transmission LED + gpio_set(GPIOA, ILI9341_DC); + spi_transmit(SPI_ADDR, data); + gpio_set(GPIOC, GPIO13); // Clear the reansmission LED + gpio_clear(GPIOA, ILI9341_CS); +} + +// Starts up an initialization sequence +void ILI_Setup(void) { + ILI_sendComand(ILI9341_SOFTRESET); + ILI_hard_reset(); + ILI_sendComand(ILI9341_SOFTRESET); + delayCycles(500000); + + ILI_sendComand(0xEF); + ILI_sendData(0x03); + ILI_sendData(0x80); + ILI_sendData(0x02); + + ILI_sendComand(0xCF); + ILI_sendData(0x00); + ILI_sendData(0XC1); + ILI_sendData(0X30); + + ILI_sendComand(0xED); + ILI_sendData(0x64); + ILI_sendData(0x03); + ILI_sendData(0X12); + ILI_sendData(0X81); + + ILI_sendComand(0xE8); + ILI_sendData(0x85); + ILI_sendData(0x00); + ILI_sendData(0x78); + + // Power control A + ILI_sendComand(ILI9341_POWERCONTROL_A); + ILI_sendData(0x39); + ILI_sendData(0x2C); + ILI_sendData(0x00); + ILI_sendData(0x34); + ILI_sendData(0x02); + + // Power control B + ILI_sendComand(ILI9341_POWERCONTROL_B); + ILI_sendData(0x00); + ILI_sendData(0xC1); + ILI_sendData(0x30); + + // Driver timings A + ILI_sendComand(ILI9341_DRIVER_TIMINGS_A); + ILI_sendData(0x85); + ILI_sendData(0x00); + ILI_sendData(0x78); + + // Driver timings B + ILI_sendComand(ILI9341_DRIVER_TIMINGS_B); + ILI_sendData(0x00); + ILI_sendData(0x00); + + // POS control + ILI_sendComand(ILI9341_POS_CONTROL); + ILI_sendData(0x64); + ILI_sendData(0x03); + ILI_sendData(0x12); + ILI_sendData(0x81); + + // Pump ratio + ILI_sendComand(ILI9341_PUMP_RATIO_CONTROL); + ILI_sendData(0x20); + + // Power control, VHR[5:0] + ILI_sendComand(ILI9341_POWERCONTROL1); + ILI_sendData(0x23); + + // Power control, SAP[2:0];BT[3:0] + ILI_sendComand(ILI9341_POWERCONTROL2); + ILI_sendData(0x10); + + // VCOM control 1 + ILI_sendComand(ILI9341_VCOM_CONTROL1); + ILI_sendData(0x3E); + ILI_sendData(0x28); + + // VCOM control 2 + ILI_sendComand(ILI9341_VCOM_CONTROL2); + ILI_sendData(0x86); + + // Memory access control + ILI_sendComand(ILI9341_MEM_ACCESS_CONTROL); + ILI_sendData(0x48); + + // Pixel format set + ILI_sendComand(ILI9341_PIXEL_FORMAT_CONTROL); + ILI_sendData(ILI9341_PIXEL_FORMAT_16BIT); + + // Frame ratio control + ILI_sendComand(ILI9341_FRAME_RATIO_CONTROL); + ILI_sendData(0x00); + ILI_sendData(0x18); + + // Display ratio control + ILI_sendComand(ILI9341_DISPLAY_RATIO_CONTROL); + ILI_sendData(0x08); + ILI_sendData(0x82); + ILI_sendData(0x27); + + // 3 gamma control + ILI_sendComand(ILI9341_3G_SETUP); + ILI_sendData(0x00); + + // Selected gamma + ILI_sendComand(ILI9341_GAMMA_CURVE_SELECTED); + ILI_sendData(0x01); + + // Positive gamma + ILI_sendComand(ILI9341_SET_POS_GAMMA); + ILI_sendData(0x0F); + ILI_sendData(0x31); + ILI_sendData(0x2B); + ILI_sendData(0x0C); + ILI_sendData(0x0E); + ILI_sendData(0x08); + ILI_sendData(0x4E); + ILI_sendData(0xF1); + ILI_sendData(0x37); + ILI_sendData(0x07); + ILI_sendData(0x10); + ILI_sendData(0x03); + ILI_sendData(0x0E); + ILI_sendData(0x09); + ILI_sendData(0x00); + + // Positive gamma + ILI_sendComand(ILI9341_SET_NEG_GAMMA); + ILI_sendData(0x00); + ILI_sendData(0x0E); + ILI_sendData(0x14); + ILI_sendData(0x03); + ILI_sendData(0x11); + ILI_sendData(0x07); + ILI_sendData(0x31); + ILI_sendData(0xC1); + ILI_sendData(0x48); + ILI_sendData(0x08); + ILI_sendData(0x0F); + ILI_sendData(0x0C); + ILI_sendData(0x31); + ILI_sendData(0x36); + ILI_sendData(0x0F); + + ILI_sendComand(ILI9341_SLEEPOUT); + delayCycles(500000); + ILI_sendComand(ILI9341_DISPLAYON); + delayCycles(500000); +} + +// Set position to write to +void ILI_setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { + ILI_sendComand(ILI9341_SET_COLUMN); + ILI_sendData((x0 >> 8) & 0xFF); + ILI_sendData(x0 & 0xFF); + ILI_sendData((x1 >> 8) & 0xFF); + ILI_sendData(x1 & 0xFF); + + ILI_sendComand(ILI9341_SET_ROW); + ILI_sendData((y0 >> 8) & 0xFF); + ILI_sendData(y0 & 0xFF); + ILI_sendData((y1 >> 8) & 0xFF); + ILI_sendData(y1 & 0xFF); + + ILI_sendComand(ILI9341_WRITE_TO_RAM); +} + +void delayCycles(uint32_t nops) { + for (uint32_t i = 0; i < nops; i++) { + __asm__("nop"); + } +} diff --git a/lib/ili9341.h b/lib/ili9341.h new file mode 100644 index 0000000..af1d3ee --- /dev/null +++ b/lib/ili9341.h @@ -0,0 +1,73 @@ +#include <stdint.h> +#define STM32F1 +#include <libopencm3/stm32/gpio.h> + +#ifndef ili9341 +#define ili9341 + +#define PALET_16BIT + +#define SCREEN_HEIGHT 240 +#define SCREEN_WIDTH 320 + +#define SPI_ADDR SPI1 + +#define ILI9341_DC GPIO2 +#define ILI9341_RES GPIO3 +#define ILI9341_CS GPIO1 +#define ILI9341_CLK GPIO5 +#define ILI9341_MISO GPIO6 +#define ILI9341_MOSI GPIO7 + +// Init comands +#define ILI9341_SOFTRESET 0x01 +#define ILI9341_POWERCONTROL_A 0xCB +#define ILI9341_POWERCONTROL_B 0xCF +#define ILI9341_DRIVER_TIMINGS_A 0xE8 +#define ILI9341_DRIVER_TIMINGS_B 0xEA +#define ILI9341_POS_CONTROL 0xEA +#define ILI9341_PUMP_RATIO_CONTROL 0xF7 +#define ILI9341_POWERCONTROL1 0xC0 +#define ILI9341_POWERCONTROL2 0xC1 +#define ILI9341_VCOM_CONTROL1 0xC5 +#define ILI9341_VCOM_CONTROL2 0xC7 +#define ILI9341_MEM_ACCESS_CONTROL 0x36 +#define ILI9341_PIXEL_FORMAT_CONTROL 0x3A +#define ILI9341_FRAME_RATIO_CONTROL 0xB1 +#define ILI9341_DISPLAY_RATIO_CONTROL 0xB6 +#define ILI9341_3G_SETUP 0xF2 +#define ILI9341_GAMMA_CURVE_SELECTED 0x26 +#define ILI9341_SET_POS_GAMMA 0x0F +#define ILI9341_SET_NEG_GAMMA 0xE1 + +#define ILI9341_DISPLAYOFF 0x28 +#define ILI9341_PIXELFORMAT 0x3A +#define ILI9341_MEMCONTROL 0x36 +#define ILI9341_SLEEPOUT 0x11 +#define ILI9341_DISPLAYON 0x29 + +#define ILI9341_SET_COLUMN 0x2A +#define ILI9341_SET_ROW 0x2B +#define ILI9341_WRITE_TO_RAM 0x2C + +#define ILI9341_PIXEL_FORMAT_16BIT 0x55 + +// Sets up GPIO for peripherals +void ILI_SetupGPIO(void); +// Starts up an initialization sequence +void ILI_Setup(void); +// Hard resets the screen +void ILI_hard_reset(void); + +// Sends a comand to display +void ILI_sendComand(uint8_t cmd); +// Writes a bit to SPI +void ILI_sendData(uint8_t data); + +// Set position to write to +void ILI_setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + +#endif // ili9341 + +// Performs a goven amount of NOPs +void delayCycles(uint32_t nops); diff --git a/lib/spi_sw.c b/lib/spi_sw.c new file mode 100644 index 0000000..1b5656d --- /dev/null +++ b/lib/spi_sw.c @@ -0,0 +1,32 @@ +#include "spi_sw.h" +#include <libopencm3/stm32/gpio.h> +#include <stdint.h> + +SPI_IMPL SpiInit(uint16_t MOSI_pin, uint16_t CLK_pin) { + SPI_IMPL outp = { + .MOSI_pin = MOSI_pin, + .CLK_pin = CLK_pin, + .delay = (uint16_t) 1000, + }; + return outp; +} + +void SpiSend(SPI_IMPL *spi, uint8_t playload) { + if (TRAILING_EDGE) { + gpio_clear(GPIOA, spi->CLK_pin); + } else { + gpio_set(GPIOA, spi->CLK_pin); + } + + for (int i = 0; i < 8; i++) { + gpio_toggle(GPIOA, spi->CLK_pin); + if ((playload >> i) & 1) { + gpio_clear(GPIOA, spi->MOSI_pin); + } else { + gpio_set(GPIOA, spi->MOSI_pin); + } + delayCycles(spi->delay); + gpio_toggle(GPIOA, spi->CLK_pin); + delayCycles(spi->delay); + } +} diff --git a/lib/spi_sw.h b/lib/spi_sw.h new file mode 100644 index 0000000..26af12d --- /dev/null +++ b/lib/spi_sw.h @@ -0,0 +1,22 @@ +#define STM32F1 +#include <stdint.h> +#include <stdbool.h> +#include <sys/types.h> +#include <libopencm3/stm32/gpio.h> +#include "ili9341.h" + +#ifndef SPI_SW +#define SPI_SW + +#define TRAILING_EDGE false + +typedef struct { + uint16_t MOSI_pin; + uint16_t CLK_pin; + uint16_t delay; +} SPI_IMPL; + +SPI_IMPL SpiInit(uint16_t MOSI_pin, uint16_t CLK_pin); +void SpiSend(SPI_IMPL *spi, uint8_t playload); + +#endif //SPI_SW diff --git a/rules.mk b/rules.mk new file mode 100644 index 0000000..e417d2f --- /dev/null +++ b/rules.mk @@ -0,0 +1,177 @@ +# This version of rules.mk expects the following to be defined before +# inclusion.. +### REQUIRED ### +# OPENCM3_DIR - duh +# PROJECT - will be the basename of the output elf, eg usb-gadget0-stm32f4disco +# CFILES - basenames only, eg main.c blah.c +# CXXFILES - same for C++ files. Must have cxx suffix! +# DEVICE - the full device name, eg stm32f405ret6 +# _or_ +# LDSCRIPT - full path, eg ../../examples/stm32/f4/stm32f4-discovery/stm32f4-discovery.ld +# OPENCM3_LIB - the basename, eg: opencm3_stm32f4 +# OPENCM3_DEFS - the target define eg: -DSTM32F4 +# ARCH_FLAGS - eg, -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 +# (ie, the full set of cpu arch flags, _none_ are defined in this file) +# +### OPTIONAL ### +# INCLUDES - fully formed -I paths, if you want extra, eg -I../shared +# BUILD_DIR - defaults to bin, should set this if you are building multiarch +# OPT - full -O flag, defaults to -Os +# CSTD - defaults -std=c99 +# CXXSTD - no default. +# OOCD_INTERFACE - eg stlink-v2 +# OOCD_TARGET - eg stm32f4x +# both only used if you use the "make flash" target. +# OOCD_FILE - eg my.openocd.cfg +# This overrides interface/target above, and is used as just -f FILE +### TODO/FIXME/notes ### +# No support for stylecheck. +# No support for BMP/texane/random flash methods, no plans either +# No support for magically finding the library. +# C++ hasn't been actually tested with this..... sorry bout that. ;) +# Second expansion/secondary not set, add this if you need them. + +BUILD_DIR ?= bin +OPT ?= -Os +CSTD ?= -std=c99 + +# Be silent per default, but 'make V=1' will show all compiler calls. +# If you're insane, V=99 will print out all sorts of things. +V?=0 +ifeq ($(V),0) +Q := @ +NULL := 2>/dev/null +endif + +# Tool paths. +PREFIX ?= arm-none-eabi- +CC = $(PREFIX)gcc +CXX = $(PREFIX)g++ +LD = $(PREFIX)gcc +OBJCOPY = $(PREFIX)objcopy +OBJDUMP = $(PREFIX)objdump +OOCD ?= openocd + +OPENCM3_INC = $(OPENCM3_DIR)/include + +# Inclusion of library header files +INCLUDES += $(patsubst %,-I%, . $(OPENCM3_INC) ) + +OBJS = $(CFILES:%.c=$(BUILD_DIR)/%.o) +OBJS += $(CXXFILES:%.cxx=$(BUILD_DIR)/%.o) +OBJS += $(AFILES:%.S=$(BUILD_DIR)/%.o) +GENERATED_BINS = $(PROJECT).elf $(PROJECT).bin $(PROJECT).map $(PROJECT).list $(PROJECT).lss + +TGT_CPPFLAGS += -MD +TGT_CPPFLAGS += -Wall -Wundef $(INCLUDES) +TGT_CPPFLAGS += $(INCLUDES) $(OPENCM3_DEFS) + +TGT_CFLAGS += $(OPT) $(CSTD) -ggdb3 +TGT_CFLAGS += $(ARCH_FLAGS) +TGT_CFLAGS += -fno-common +TGT_CFLAGS += -ffunction-sections -fdata-sections +TGT_CFLAGS += -Wextra -Wshadow -Wno-unused-variable -Wimplicit-function-declaration +TGT_CFLAGS += -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes + +TGT_CXXFLAGS += $(OPT) $(CXXSTD) -ggdb3 +TGT_CXXFLAGS += $(ARCH_FLAGS) +TGT_CXXFLAGS += -fno-common +TGT_CXXFLAGS += -ffunction-sections -fdata-sections +TGT_CXXFLAGS += -Wextra -Wshadow -Wredundant-decls -Weffc++ + +TGT_ASFLAGS += $(OPT) $(ARCH_FLAGS) -ggdb3 + +TGT_LDFLAGS += -T$(LDSCRIPT) -L$(OPENCM3_DIR)/lib -nostartfiles +TGT_LDFLAGS += $(ARCH_FLAGS) +TGT_LDFLAGS += -specs=nano.specs +TGT_LDFLAGS += -Wl,--gc-sections +# OPTIONAL +#TGT_LDFLAGS += -Wl,-Map=$(PROJECT).map +ifeq ($(V),99) +TGT_LDFLAGS += -Wl,--print-gc-sections +endif + +# Linker script generator fills this in for us. +ifeq (,$(DEVICE)) +LDLIBS += -l$(OPENCM3_LIB) +endif +# nosys is only in newer gcc-arm-embedded... +#LDLIBS += -specs=nosys.specs +LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group + +# Burn in legacy hell fortran modula pascal yacc idontevenwat +.SUFFIXES: +.SUFFIXES: .c .S .h .o .cxx .elf .bin .list .lss + +# Bad make, never *ever* try to get a file out of source control by yourself. +%: %,v +%: RCS/%,v +%: RCS/% +%: s.% +%: SCCS/s.% + +all: $(PROJECT).elf $(PROJECT).bin +flash: $(PROJECT).flash + +# error if not using linker script generator +ifeq (,$(DEVICE)) +$(LDSCRIPT): +ifeq (,$(wildcard $(LDSCRIPT))) + $(error Unable to find specified linker script: $(LDSCRIPT)) +endif +else +# if linker script generator was used, make sure it's cleaned. +GENERATED_BINS += $(LDSCRIPT) +endif + +# Need a special rule to have a bin dir +$(BUILD_DIR)/%.o: %.c + @printf " CC\t$<\n" + @mkdir -p $(dir $@) + $(Q)$(CC) $(TGT_CFLAGS) $(CFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $@ -c $< + +$(BUILD_DIR)/%.o: %.cxx + @printf " CXX\t$<\n" + @mkdir -p $(dir $@) + $(Q)$(CXX) $(TGT_CXXFLAGS) $(CXXFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $@ -c $< + +$(BUILD_DIR)/%.o: %.S + @printf " AS\t$<\n" + @mkdir -p $(dir $@) + $(Q)$(CC) $(TGT_ASFLAGS) $(ASFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $@ -c $< + +$(PROJECT).elf: $(OBJS) $(LDSCRIPT) $(LIBDEPS) + @printf " LD\t$@\n" + $(Q)$(LD) $(TGT_LDFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ + +%.bin: %.elf + @printf " OBJCOPY\t$@\n" + $(Q)$(OBJCOPY) -O binary $< $@ + +%.lss: %.elf + $(OBJDUMP) -h -S $< > $@ + +%.list: %.elf + $(OBJDUMP) -S $< > $@ + +%.flash: %.elf + @printf " FLASH\t$<\n" +ifeq (,$(OOCD_FILE)) + $(Q)(echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \ + $(OOCD) -f interface/$(OOCD_INTERFACE).cfg \ + -f target/$(OOCD_TARGET).cfg \ + -c "program $(realpath $(*).elf) verify reset exit" \ + $(NULL) +else + $(Q)(echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \ + $(OOCD) -f $(OOCD_FILE) \ + -c "program $(realpath $(*).elf) verify reset exit" \ + $(NULL) +endif + +clean: + rm -rf $(BUILD_DIR) $(GENERATED_BINS) + +.PHONY: all clean flash +-include $(OBJS:.o=.d) + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..a32c435 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,19 @@ +PROJECT = blink-led +BUILD_DIR = bin + +SHARED_DIR = ../lib +CFILES = main.c +CFILES += ili9341.c +CFILES += spi_sw.c + +# TODO - you will need to edit these two lines! +DEVICE=stm32f103c8 + +# You shouldn't have to edit anything below here. +VPATH += $(SHARED_DIR) +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) +OPENCM3_DIR=../libopencm3 + +include $(OPENCM3_DIR)/mk/genlink-config.mk +include ../rules.mk +include $(OPENCM3_DIR)/mk/genlink-rules.mk diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..b68eded --- /dev/null +++ b/src/main.c @@ -0,0 +1,37 @@ +#define STM32F1 +#include <stdint.h> +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/gpio.h> +#include <ili9341.h> + +#define LED_PIN GPIO13 + +int main(void) { + // Enabling peripheral clocks + rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_GPIOB); + rcc_periph_clock_enable(RCC_GPIOC); + rcc_periph_clock_enable(RCC_SPI1); + + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, LED_PIN); + gpio_set(GPIOC, GPIO13); + + ILI_SetupGPIO(); + ILI_Setup(); + + // gpio_set(GPIOC, GPIO13); + // for (uint32_t i = 0; i < 1000000; i++) { + // __asm__("nop"); + // } + + + uint16_t colour = 0x0000; + while (1) { + ILI_setAddrWindow(0, 0, 9, 9); + for (int i = 0; i < 100; i++) { + ILI_sendData((colour >> 8) & 0xFF); + ILI_sendData(colour & 0xFF); + } + colour++; + } +} |
