aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--system-clock/Makefile.preamble21
-rw-r--r--system-clock/clock.c149
-rw-r--r--system-clock/clock.h61
-rw-r--r--system-clock/common.h13
-rwxr-xr-xsystem-clock/genmake.pl52
-rw-r--r--system-clock/gpio.c48
-rw-r--r--system-clock/gpio.h128
-rw-r--r--system-clock/linker_script.ld14
-rw-r--r--system-clock/main.c183
9 files changed, 669 insertions, 0 deletions
diff --git a/system-clock/Makefile.preamble b/system-clock/Makefile.preamble
new file mode 100644
index 0000000..2a66399
--- /dev/null
+++ b/system-clock/Makefile.preamble
@@ -0,0 +1,21 @@
+OPT?=-O
+PREFIX?=arm-unknown-eabi-
+CC=$(PREFIX)gcc
+LD=$(PREFIX)ld
+CFLAGS?=$(OPT) -mcpu=cortex-m4 -mthumb -g -lgcc -static -nostartfiles
+LD_FLAGS?=-T linker_script.ld -nostdlib --cref -Map main.map -static
+
+
+all: main.elf
+
+main.bin: main.elf
+ $(PREFIX)objcopy -O binary main.elf main.bin
+
+flash: main.bin
+ st-flash write main.bin 0x8000000
+
+clean:
+ rm -f *.o *.elf *.bin
+
+genmake:
+ ./genmake.pl > Makefile
diff --git a/system-clock/clock.c b/system-clock/clock.c
new file mode 100644
index 0000000..b846ceb
--- /dev/null
+++ b/system-clock/clock.c
@@ -0,0 +1,149 @@
+/*
+ * This file sets the system clock to its full glory of 80Mhz
+ */
+
+#include "clock.h"
+#include <stdint.h>
+
+#define RCC_CR_HSERDY ((uint32_t)0x00020000) /* High-speed clock ready? */
+#define RCC_CR_HSEON ((uint32_t)0x00020000) /*!< External High Speed clock ready flag */
+
+#define FLASH_ACR_LATENCY ((uint32_t)0x00000001) /*!< Latency */
+#define FLASH_ACR_PRFTEN ((uint32_t)0x00000002) /*!< Prefetch Buffer Enable */
+#define FLASH_ACR_ACC64 ((uint32_t)0x00000004) /*!< Access 64 bits */
+
+#define RCC_APB1ENR_PWREN ((uint32_t)0x10000000) /*!< Power interface clock enable */
+#define PWR_CR_VOS_0 ((uint16_t)0x0800) /*!< Bit 0 */
+
+/*!< HPRE configuration */
+#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< SYSCLK not divided */
+#define RCC_CFGR_HPRE_DIV2 ((uint32_t)0x00000080) /*!< SYSCLK divided by 2 */
+#define RCC_CFGR_HPRE_DIV4 ((uint32_t)0x00000090) /*!< SYSCLK divided by 4 */
+#define RCC_CFGR_HPRE_DIV8 ((uint32_t)0x000000A0) /*!< SYSCLK divided by 8 */
+#define RCC_CFGR_HPRE_DIV16 ((uint32_t)0x000000B0) /*!< SYSCLK divided by 16 */
+#define RCC_CFGR_HPRE_DIV64 ((uint32_t)0x000000C0) /*!< SYSCLK divided by 64 */
+#define RCC_CFGR_HPRE_DIV128 ((uint32_t)0x000000D0) /*!< SYSCLK divided by 128 */
+#define RCC_CFGR_HPRE_DIV256 ((uint32_t)0x000000E0) /*!< SYSCLK divided by 256 */
+#define RCC_CFGR_HPRE_DIV512 ((uint32_t)0x000000F0) /*!< SYSCLK divided by 512 */
+
+#define RCC_CFGR_PPRE1 ((uint32_t)0x00000700) /*!< PRE1[2:0] bits (APB1 prescaler) */
+#define RCC_CFGR_PPRE1_0 ((uint32_t)0x00000100) /*!< Bit 0 */
+#define RCC_CFGR_PPRE1_1 ((uint32_t)0x00000200) /*!< Bit 1 */
+#define RCC_CFGR_PPRE1_2 ((uint32_t)0x00000400) /*!< Bit 2 */
+
+/*!< PPRE1 configuration */
+#define RCC_CFGR_PPRE1_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */
+#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400) /*!< HCLK divided by 2 */
+#define RCC_CFGR_PPRE1_DIV4 ((uint32_t)0x00000500) /*!< HCLK divided by 4 */
+#define RCC_CFGR_PPRE1_DIV8 ((uint32_t)0x00000600) /*!< HCLK divided by 8 */
+#define RCC_CFGR_PPRE1_DIV16 ((uint32_t)0x00000700) /*!< HCLK divided by 16 */
+
+#define RCC_CFGR_PPRE2 ((uint32_t)0x00003800) /*!< PRE2[2:0] bits (APB2 prescaler) */
+#define RCC_CFGR_PPRE2_0 ((uint32_t)0x00000800) /*!< Bit 0 */
+#define RCC_CFGR_PPRE2_1 ((uint32_t)0x00001000) /*!< Bit 1 */
+#define RCC_CFGR_PPRE2_2 ((uint32_t)0x00002000) /*!< Bit 2 */
+
+/*!< PPRE2 configuration */
+#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */
+#define RCC_CFGR_PPRE2_DIV2 ((uint32_t)0x00002000) /*!< HCLK divided by 2 */
+#define RCC_CFGR_PPRE2_DIV4 ((uint32_t)0x00002800) /*!< HCLK divided by 4 */
+#define RCC_CFGR_PPRE2_DIV8 ((uint32_t)0x00003000) /*!< HCLK divided by 8 */
+#define RCC_CFGR_PPRE2_DIV16 ((uint32_t)0x00003800) /*!< HCLK divided by 16 */
+#define RCC_CFGR_PLLMUL ((uint32_t)0x003C0000) /*!< PLLMUL[3:0] bits (PLL multiplication factor) */
+#define RCC_CFGR_PLLDIV ((uint32_t)0x00C00000) /*!< PLLDIV[1:0] bits (PLL Output Division) */
+
+#define RCC_CFGR_PLLSRC ((uint32_t)0x00010000) /*!< PLL entry clock source */
+#define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000) /*!< HSE as PLL entry clock source */
+#define RCC_CFGR_PLLMUL8 ((uint32_t)0x000C0000) /*!< PLL input clock * 8 */
+#define RCC_CFGR_PLLDIV2 ((uint32_t)0x00400000) /*!< PLL clock output = CKVCO / 2 */
+#define RCC_CR_PLLON ((uint32_t)0x01000000) /*!< PLL enable */
+#define RCC_CR_PLLRDY ((uint32_t)0x02000000) /*!< PLL clock ready flag */
+#define RCC_CFGR_SW ((uint32_t)0x00000003) /*!< SW[1:0] bits (System clock Switch) */
+#define RCC_CFGR_SW_PLL ((uint32_t)0x00000003) /*!< PLL selected as system clock */
+#define RCC_CFGR_SWS ((uint32_t)0x0000000C) /*!< SWS[1:0] bits (System Clock Switch Status) */
+#define RCC_CFGR_SWS_PLL ((uint32_t)0x0000000C) /*!< PLL used as system clock */
+
+inline int is_hse_ready()
+{
+ return RCC.cr & RCC_CR_HSERDY;
+}
+
+inline void hse_on()
+{
+ RCC.cr |= RCC_CR_HSEON;
+}
+
+#define TIMER 1000000
+int set_sys_clock()
+{
+ uint32_t c = 0; /* Time the PLL startup. */
+
+ /* Turn on the HSE */
+ hse_on();
+
+ /* Wait 'til ready, or if it takes tool long, (c == TIMER). */
+ for (c = 0; !is_hse_ready() && c < TIMER; ++ c);
+
+ if (c == TIMER) {
+ /* The HSE never came up. That's not cool! */
+ return -1;
+ }
+
+ /* The HSE came up, now we just need to set it to be the main clock. */
+
+ /* Don't really know why we're touching the flash registers ... */
+ FLASH.acr |= FLASH_ACR_ACC64; /* Enable 64-bit access. */
+ FLASH.acr |= FLASH_ACR_PRFTEN; /* Enable prefetch buffer. */
+ FLASH.acr |= FLASH_ACR_LATENCY; /* Flash 1 wait state. */
+
+ RCC.apb1enr |= RCC_APB1ENR_PWREN; /* Enable power. */
+ PWR.cr = PWR_CR_VOS_0; /* Set voltage to 1.8v. */
+
+ /* Wait for the vwoltage regulator to turn on. */
+ for (c = 0; (PWR.csr & PWR_CSR_VOSF) && c < TIMER; ++ c);
+
+ if (c == TIMER) {
+ /* Timeout occurred. */
+ return -2;
+ }
+
+ RCC.cfgr |= RCC_CFGR_HPRE_DIV1; /* HCLK = SYSCLK/1. */
+ RCC.cfgr |= RCC_CFGR_PPRE2_DIV1; /* PCLK2 = HCLK/1 */
+ RCC.cfgr |= RCC_CFGR_PPRE1_DIV1; /* PCLK1 = HCLK/1 */
+
+ /* PLL Configuration */
+ RCC.cfgr &= ~(
+ RCC_CFGR_PLLSRC |
+ RCC_CFGR_PLLMUL |
+ RCC_CFGR_PLLDIV );
+
+ RCC.cfgr |=
+ RCC_CFGR_PLLSRC_HSE |
+ RCC_CFGR_PLLMUL8 |
+ RCC_CFGR_PLLDIV2;
+
+ /* Enable the PLL. */
+ RCC.cr |= RCC_CR_PLLON;
+
+ /* Wait for PLL to become ready. */
+ for(c = 0; !(RCC.cr & RCC_CR_PLLRDY) && c < TIMER; ++ c);
+
+ if (c == TIMER) {
+ /* Timeout occurred. */
+ return -3;
+ }
+
+ /* Set PLL as the system clock. */
+ RCC.cfgr &= ~RCC_CFGR_SW;
+ RCC.cfgr |= RCC_CFGR_SW_PLL;
+
+ /* Wait for PLL to be used as system clock. */
+ for (c = 0; (RCC.cfgr & RCC_CFGR_SWS) != RCC_CFGR_SW_PLL && c < TIMER; ++ c);
+
+ if (c == TIMER) {
+ /* Timeout occurred. */
+ return -4;
+ }
+
+ return 0;
+}
diff --git a/system-clock/clock.h b/system-clock/clock.h
new file mode 100644
index 0000000..2ba6880
--- /dev/null
+++ b/system-clock/clock.h
@@ -0,0 +1,61 @@
+#ifndef CLOCK_H__
+#define CLOCK_H__
+
+#include <stdint.h>
+
+#define PERIPH_BASE ((uint32_t) 0x40000000)
+#define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000)
+#define RCC_BASE (AHBPERIPH_BASE + 0x00001000)
+#define FLASH_R_BASE (AHBPERIPH_BASE + 0x00003C00)
+#define PWR_BASE (PERIPH_BASE + 0x7000)
+#define PWR_CSR_VOSF ((uint16_t)0x0010) /*!< Voltage Scaling select flag */
+
+
+#ifndef __IO
+#define __IO volatile
+#endif
+
+typedef struct {
+ __IO uint32_t cr;
+ __IO uint32_t csr;
+} pwr_t;
+
+typedef struct {
+ __IO uint32_t acr;
+ __IO uint32_t pecr;
+ __IO uint32_t pdkeyr;
+ __IO uint32_t pekeyr;
+ __IO uint32_t prgkeyr;
+ __IO uint32_t optkeyr;
+ __IO uint32_t sr;
+ __IO uint32_t obr;
+ __IO uint32_t wrpr;
+} flash_t;
+
+typedef struct {
+ __IO uint32_t cr;
+ __IO uint32_t icscr;
+ __IO uint32_t cfgr;
+ __IO uint32_t cir;
+ __IO uint32_t ahbrstr;
+ __IO uint32_t apb2rstr;
+ __IO uint32_t apb1rstr;
+ __IO uint32_t ahbenr;
+ __IO uint32_t apb2enr;
+ __IO uint32_t apb1enr;
+ __IO uint32_t ahblpenr;
+ __IO uint32_t apb2lpenr;
+ __IO uint32_t apb1lpenr;
+ __IO uint32_t csr;
+} rcc_t;
+
+#define RCC (*(rcc_t*) (RCC_BASE))
+#define FLASH (*(flash_t*) (FLASH_R_BASE))
+#define PWR (*(pwr_t*) (PWR_BASE))
+
+/*
+ * Sets the system clock to a full 80Mhz.
+ */
+int set_sys_clock();
+
+#endif /* CLOCK_H__ */
diff --git a/system-clock/common.h b/system-clock/common.h
new file mode 100644
index 0000000..f58f179
--- /dev/null
+++ b/system-clock/common.h
@@ -0,0 +1,13 @@
+#ifndef COMMON__H
+#define COMMON__H
+
+/* Define __IO to be volatile if it's not already. */
+#ifndef __IO
+#define __IO volatile
+#endif
+
+#define bool int
+
+#define PACKED __attribute__((packed))
+
+#endif /* COMMON_H */
diff --git a/system-clock/genmake.pl b/system-clock/genmake.pl
new file mode 100755
index 0000000..3403759
--- /dev/null
+++ b/system-clock/genmake.pl
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+
+# This script is designed to introspect C files and generate a makefile to use.
+
+sub header_deps {
+ my $file = @_[0];
+ my @headers;
+
+ if (open(my $fh, '<:encoding(UTF-8)', $file)) {
+ print STDERR "\x1b[35m[Trace] - Reading file $file\x1b[00m\n";
+ push(@headers, $file);
+
+ while (<$fh>) {
+ /#include\s+"(.*)"\s*$/ && push(@headers, header_deps($1));
+ }
+ }
+
+ return @headers;
+}
+
+my @files = glob('./*.c');
+my @obj_files;
+
+open(my $fh, '<:encoding(UTF-8)', "Makefile.preamble") or die "Missing Makefile.preamble";
+while (<$fh>) {
+ print "$_";
+}
+
+foreach $file (@files) {
+ (my $file_no_ext = $file) =~ s/^\.\/(.*)\.c$/\1/g;
+
+ my $obj_file = "${file_no_ext}.o";
+ my $c_file = "${file_no_ext}.c";
+ my $s_file = "${file_no_ext}.s";
+
+ push(@obj_files, $obj_file);
+ my @deps = header_deps($c_file);
+
+ my $deps_as_join = join(" ", @deps);
+
+ # Emit the rule to make the object file.
+ print "$obj_file: $deps_as_join\n\t";
+ print '$(CC) -c ' . $c_file . ' -o ' . $obj_file . ' $(CFLAGS)' . "\n\n";
+
+ # Emit the rule to make the assembly file.
+ print "$s_file: $deps_as_join\n\t";
+ print '$(CC) -S ' . $c_file . ' -o ' . $s_file . ' $(CFLAGS)' . "\n\n";
+}
+
+my $obj_files_deps = join(' ', @obj_files);
+print "main.elf: $obj_files_deps linker_script.ld\n\t";
+print '$(LD) -o main.elf $(LD_FLAGS) ' . "$obj_files_deps\n\n";
diff --git a/system-clock/gpio.c b/system-clock/gpio.c
new file mode 100644
index 0000000..ab3606d
--- /dev/null
+++ b/system-clock/gpio.c
@@ -0,0 +1,48 @@
+#include "gpio.h"
+
+/*
+ * Sets the mode of a pin on a gpio por.
+ */
+void set_gpio_pin_mode(
+ __IO gpio_port_t* gpio_port,
+ gpio_pin_t pin,
+ gpio_pin_mode_t mode)
+{
+ /* Each pin has a 2-bit mode provided at bits pin#*2 and pin#*2+1 */
+ gpio_port->mode_r &= ~(0x03 << pin * 2);
+ gpio_port->mode_r |= mode << pin * 2;
+}
+
+
+gpio_output_pin_t set_gpio_pin_output(
+ __IO gpio_port_t* gpio_port,
+ gpio_pin_t pin)
+{
+ set_gpio_pin_mode(gpio_port, pin, MODE_OUTPUT);
+
+ return (gpio_output_pin_t) {
+ .gpio_port = gpio_port,
+ .pin = pin
+ };
+}
+
+void set_gpio_output_pin(
+ gpio_output_pin_t pin,
+ bool onoff)
+{
+ if (onoff) {
+ pin.gpio_port->output_r |= 1 << pin.pin;
+ } else {
+ pin.gpio_port->output_r &= ~(1 << pin.pin);
+ }
+}
+
+#define GPIO_PORTS_BASE_ADDR ((uint32_t)0x48000000)
+#define RCC_BASE ((uint32_t)0x40021000)
+#define RCC_AHB2ENR (*((__IO uint32_t*) (RCC_BASE + 0x4c)))
+__IO gpio_port_t* enable_gpio(gpio_port_number_t gpio_port_number)
+{
+ RCC_AHB2ENR |= 1 << gpio_port_number; /* Enable the port. */
+ return
+ (__IO gpio_port_t*) (GPIO_PORTS_BASE_ADDR + (gpio_port_number * 0x400));
+}
diff --git a/system-clock/gpio.h b/system-clock/gpio.h
new file mode 100644
index 0000000..53ece32
--- /dev/null
+++ b/system-clock/gpio.h
@@ -0,0 +1,128 @@
+#ifndef GPIO_H__
+#define GPIO_H__
+
+#include "common.h"
+
+#include <stdint.h>
+
+/*
+ * Possible GPIO ports.
+ */
+typedef enum {
+ GPIO_PORT_A = 0,
+ GPIO_PORT_B = 1,
+ GPIO_PORT_C = 2,
+ GPIO_PORT_D = 3
+} gpio_port_number_t;
+
+/*
+ * Structure defining the layout of the layout of the GPIO registers on the
+ * stm32l432 development board.
+ */
+typedef struct GPIO_PORT_STR {
+ __IO uint32_t mode_r; /* Mode register */
+ __IO uint32_t pupd_r; /* Pull up/pull down/none register */
+ __IO uint32_t speed_r; /* Speed register */
+ __IO uint32_t type_r; /* Type register */
+ __IO uint32_t input_r; /* Input data register */
+ __IO uint32_t output_r; /* Output data register */
+ __IO uint32_t bsr_r; /* Bit set/reset register */
+ __IO uint32_t lock_r; /* Lock register */
+ __IO uint32_t altfn_r; /* Alternate function register */
+} PACKED gpio_port_t;
+
+/*
+ * Enum defining the PINs in a GPIO port. Each port has 16 pins to use in
+ * the stm32l432.
+ */
+typedef enum GPIO_PIN_ENUM {
+ PIN_0 = 0,
+ PIN_1 = 1,
+ PIN_2 = 2,
+ PIN_3 = 3,
+ PIN_4 = 4,
+ PIN_5 = 5,
+ PIN_6 = 6,
+ PIN_7 = 7,
+ PIN_8 = 8,
+ PIN_9 = 9,
+ PIN_10 = 10,
+ PIN_11 = 11,
+ PIN_12 = 12,
+ PIN_13 = 13,
+ PIN_14 = 14,
+ PIN_15 = 15
+} gpio_pin_t;
+
+/*
+ * Enum defining the pin modes that are possible.
+ */
+typedef enum {
+ MODE_INPUT = 0,
+ MODE_OUTPUT = 1,
+ MODE_ALTERNATE = 2,
+ MODE_ANALOG = 3
+} gpio_pin_mode_t;
+
+/*
+ * Enum defining the pin speeds that are possible.
+ */
+typedef enum {
+ SPEED_2MHZ = 0,
+ SPEED_10MHZ = 1,
+ SPEED_50MHZ = 3,
+} speed_t;
+
+/*
+ * Structure defining an OUTPUT pin. Structurally equivalent to the input pin,
+ * but can be used in a slightly type-safe manner.
+ */
+typedef struct {
+ __IO gpio_port_t* gpio_port;
+ gpio_pin_t pin;
+} gpio_output_pin_t;
+
+/*
+ * Sets the mode on a GPIO pin.
+ *
+ * gpio_port: the gpio port to use.
+ * pin: the pin number to set.
+ * pin_mode: the mode to set the pin to.
+ */
+void set_gpio_pin_mode(
+ __IO gpio_port_t* gpio_port,
+ gpio_pin_t pin,
+ gpio_pin_mode_t pin_mode);
+
+/*
+ * Sets the given GPIO pin to be an output pin. Returns an output_pin struct
+ * corresponding to
+ */
+gpio_output_pin_t set_gpio_pin_output(
+ __IO gpio_port_t* gpio_port,
+ gpio_pin_t pin);
+
+/*
+ * Sets an output pin on or off.
+ *
+ * pin: the pin to toggle.
+ * onoff: 0 for off, non-zero of on.
+ */
+void set_gpio_output_pin(
+ gpio_output_pin_t pin,
+ bool onoff);
+
+#define pin_on(p) \
+ set_gpio_output_pin(p, 1)
+
+#define pin_off(p) \
+ set_gpio_output_pin(p, 0)
+
+/*
+ * Enables a GPIO port and returns a reference to the register definition
+ * of that GPIO port.
+ */
+__IO gpio_port_t* enable_gpio(gpio_port_number_t number);
+
+
+#endif /* GPIO_H__ */
diff --git a/system-clock/linker_script.ld b/system-clock/linker_script.ld
new file mode 100644
index 0000000..fe0c14b
--- /dev/null
+++ b/system-clock/linker_script.ld
@@ -0,0 +1,14 @@
+MEMORY
+{
+ flash : org = 0x08000000, len = 256k
+}
+
+SECTIONS
+{
+ /* This is where the code goes. */
+ . = ORIGIN(flash);
+ .text : {
+ *(.vectors); /* All .vector sections go here. */
+ *(.text); /* All .text sections go here. */
+ } >flash
+}
diff --git a/system-clock/main.c b/system-clock/main.c
new file mode 100644
index 0000000..f7a30e8
--- /dev/null
+++ b/system-clock/main.c
@@ -0,0 +1,183 @@
+#include "gpio.h"
+
+int main();
+
+void spin();
+
+/*
+ * Interrupt service routine handlers.
+ */
+const void* vectors[] __attribute__((section(".vectors"))) = {
+ (void *) 0x2000c000, /* Top of stack at top of sram1. 48k */
+ main, /* Reset handler */
+ spin, /* NMI */
+ spin, /* Hard Fault */
+ spin, /* MemManage */
+ spin, /* BusFault */
+ spin, /* UsageFault */
+ spin, /* Reserved */
+ spin, /* Reserved */
+ spin, /* Reserved */
+ spin, /* Reserved */
+ spin, /* SVCall */
+ spin, /* Debug */
+ spin, /* Reserved */
+ spin, /* PendSV */
+ spin, /* SysTick */
+
+/* External interrupt handlers follow */
+ spin, /* 0 WWDG */
+ spin, /* 1 PVD */
+ spin, /* 2 TAMP_SAMP */
+ spin, /* 3 RTC_WKUP */
+ spin, /* 4 FLASH */
+ spin, /* 5 RCC */
+ spin, /* 6 EXTI0 */
+ spin, /* 7 EXTI1 */
+ spin, /* 8 EXTI2 */
+ spin, /* 9 EXTI3 */
+ spin, /* 10 EXTI4 */
+ spin, /* 11 DMA_CH1 */
+ spin, /* 12 DMA_CH2 */
+ spin, /* 13 DMA_CH3 */
+ spin, /* 14 DMA_CH4 */
+ spin, /* 15 DMA_CH5 */
+ spin, /* 16 DMA_CH6 */
+ spin, /* 17 DMA_CH7 */
+ spin, /* 18 ADC1 */
+ spin, /* 19 CAN_TX */
+ spin, /* 20 CAN_RX0 */
+ spin, /* 21 CAN_RX1 */
+ spin, /* 22 CAN_SCE */
+ spin, /* 23 EXTI9_5 */
+ spin, /* 24 TIM1_BRK/TIM15 */
+ spin, /* 25 TIM1_UP/TIM16 */
+ spin, /* 26 TIM1_TRG_COM */
+ spin, /* 27 TIM1_CC */
+ spin, /* 28 TIM2 */
+ spin, /* 29 Reserved */
+ spin, /* 30 Reserved */
+ spin, /* 31 I2C1_EV */
+ spin, /* 32 I2C1_ER */
+ spin, /* 33 I2C2_EV */
+ spin, /* 34 I2C2_ER */
+ spin, /* 35 SPI1 */
+ spin, /* 36 SPI2 */
+ spin, /* 37 USART1 */
+ spin, /* 38 USART2 */
+ spin, /* 39 USART3 */
+ spin, /* 40 EXTI15_10 */
+ spin, /* 41 RTCAlarm */
+ spin, /* 42 Reserved */
+ spin, /* 43 Reserved */
+ spin, /* 44 Reserved */
+ spin, /* 45 Reserved */
+ spin, /* 46 Reserved */
+ spin, /* 47 Reserved */
+ spin, /* 48 Reserved */
+ spin, /* 49 SDMMC1 */
+ spin, /* 50 Reserved */
+ spin, /* 51 SPI3 */
+ spin, /* 52 Reserved */
+ spin, /* 53 Reserved */
+ spin, /* 54 TIM6_DACUNDER */
+ spin, /* 55 TIM7 */
+ spin, /* 56 DMA2_CH1 */
+ spin, /* 57 DMA2_CH2 */
+ spin, /* 58 DMA2_CH3 */
+ spin, /* 59 DMA2_CH4 */
+ spin, /* 60 DMA2_CH5 */
+ spin, /* 61 Reserved */
+ spin, /* 62 Reserved */
+ spin, /* 63 Reserved*/
+ spin, /* 64 COMP */
+ spin, /* 65 LPTIM1 */
+ spin, /* 66 LPTIM2 */
+ spin, /* 67 USB_FS */
+ spin, /* 68 DMA_CH6 */
+ spin, /* 69 DMA_CH7 */
+ spin, /* 70 LPUART1 */
+ spin, /* 71 QUADSPI */
+ spin, /* 72 I2C3_EV */
+ spin, /* 73 I2C3_ER */
+ spin, /* 74 SAI1 */
+ spin, /* 75 Reserved */
+ spin, /* 76 SWPMI1 */
+ spin, /* 77 TSC */
+ spin, /* 78 Reserved */
+ spin, /* 79 AES */
+ spin, /* 80 RNG */
+ spin, /* 81 FPU */
+ spin /* 82 CRS */
+};
+
+/* Delay for some number of iterations. */
+void delay(uint32_t itrs)
+{
+ /* Need to keep the compiler from optimizing this loop out entirely. */
+ while(itrs --) {
+ asm volatile ("");
+ }
+}
+
+/* Main function. This gets executed from the interrupt vector defined above. */
+int main()
+{
+ /* Enable the GPIO port B. */
+
+ __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B);
+ gpio_output_pin_t pin3 = set_gpio_pin_output(port_b, PIN_3);
+ gpio_output_pin_t pin1 = set_gpio_pin_output(port_b, PIN_1);
+
+ while(1) {
+ /* Set the GPIO pin to high. */
+ pin_on(pin3);
+ pin_off(pin1);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+
+ /* Set the GPIO pin to low. */
+ pin_off(pin3);
+ pin_on(pin1);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ delay(65535);
+ }
+}
+
+/*
+ * Does nothing ... forever.
+ */
+void spin()
+{
+ __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B);
+ gpio_output_pin_t pin3 = set_gpio_pin_output(port_b, PIN_3);
+ for(;;) {
+
+ /* Flash in a distinct pattern to know that something went wrong. */
+
+ pin_off(pin3);
+ delay(100000);
+ pin_on(pin3);
+ delay(100000);
+ pin_off(pin3);
+ delay(100000);
+ pin_on(pin3);
+ delay(500000);
+ }
+}