aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--02-usart/include/common.h3
-rw-r--r--02-usart/include/isr_vector.h8
-rw-r--r--02-usart/include/isrs.i112
-rw-r--r--02-usart/src/init.c45
-rw-r--r--02-usart/src/isr_vector.c216
-rw-r--r--02-usart/src/main.c115
6 files changed, 263 insertions, 236 deletions
diff --git a/02-usart/include/common.h b/02-usart/include/common.h
index 8e0cb06..f9cbe06 100644
--- a/02-usart/include/common.h
+++ b/02-usart/include/common.h
@@ -5,6 +5,9 @@
#include <stddef.h>
#include <assert.h>
+#define WEAK __attribute__((weak))
+#define NORETURN __attribute__((noreturn))
+
#ifndef static_assert
#define static_assert(a, b)
#endif
diff --git a/02-usart/include/isr_vector.h b/02-usart/include/isr_vector.h
index 3e55f52..7cb4596 100644
--- a/02-usart/include/isr_vector.h
+++ b/02-usart/include/isr_vector.h
@@ -1,6 +1,8 @@
#ifndef h__ISR_VECTOR_H__
#define h__ISR_VECTOR_H__
+#include <stdint.h>
+
/*
* Include file for interrupt service routines.
*/
@@ -9,12 +11,14 @@
* The interrupt service routines. These link in the function `main` as the
* main function.
*/
-extern const void* isr_vector[];
+extern const void* vectors[];
/*
* Defines an error state. This loops forever and defines a distinct flashing
* pattern to let the user know an unhandled ISR happened.
*/
-void unhandled_isr();
+void unhandled_isr(uint8_t val);
+
+void isr_simple_pin_on();
#endif /* h___ISR_VECTOR_H__ */
diff --git a/02-usart/include/isrs.i b/02-usart/include/isrs.i
new file mode 100644
index 0000000..cdb3889
--- /dev/null
+++ b/02-usart/include/isrs.i
@@ -0,0 +1,112 @@
+/*
+ * The following is a list of interrupts listed in a way
+ * that makes it easy to macro-process them by defining
+ * macro definitions for IRQ and IRQ_RESERVED alike followed
+ * by including this file.
+ */
+IRQ(on_reset, 1)
+IRQ(on_nmi, 2)
+IRQ(on_hard_fault, 3)
+IRQ(on_mem_manage, 4)
+IRQ(on_bus_fault, 5)
+IRQ(on_usage_fault, 6)
+IRQ_RESERVED(7)
+IRQ_RESERVED(8)
+IRQ_RESERVED(9)
+IRQ_RESERVED(10)
+IRQ(on_svc, 11)
+IRQ(on_debug_mon, 12)
+IRQ_RESERVED(13)
+IRQ(on_pendsv, 14)
+IRQ(on_systick, 15)
+IRQ(on_wwdg_irq, 16)
+IRQ(on_pvd_irq, 17)
+IRQ(on_tamper_stamp_irq, 18)
+IRQ(on_rtc_wkup_irq, 19)
+IRQ(on_flash_irq, 20)
+IRQ(on_rcc_irq, 21)
+IRQ(on_exti0_irq, 22)
+IRQ(on_exti1_irq, 23)
+IRQ(on_exti2_irq, 24)
+IRQ(on_exti3_irq, 25)
+IRQ(on_exti4_irq, 26)
+IRQ(on_dma1_channel1_irq, 27)
+IRQ(on_dma1_channel2_irq, 28)
+IRQ(on_dma1_channel3_irq, 29)
+IRQ(on_dma1_channel4_irq, 30)
+IRQ(on_dma1_channel5_irq, 31)
+IRQ(on_dma1_channel6_irq, 32)
+IRQ(on_dma1_channel7_irq, 33)
+IRQ(on_adc1_irq, 34)
+IRQ(on_can1_tx, 35)
+IRQ(on_can1_rx0, 36)
+IRQ(on_can1_rx1, 37)
+IRQ(on_can1_sce, 38)
+IRQ(on_exti9_5, 39)
+IRQ(on_tim1_brk, 40)
+IRQ(on_tim1_up, 41)
+IRQ(on_tim1_trg_com, 42)
+IRQ(on_tim1_cc, 43)
+IRQ(on_tim2, 44)
+IRQ(on_tim3, 45)
+IRQ(on_tim4, 46)
+IRQ(on_i2c1_ev, 47)
+IRQ(on_i2c1_er, 48)
+IRQ(on_i2c2_ev, 49)
+IRQ(on_i2c2_er, 50)
+IRQ(on_spi1, 51)
+IRQ(on_spi2, 52)
+IRQ(on_usart1, 53)
+IRQ(on_usart2, 54)
+IRQ(on_usart3, 55)
+IRQ(on_exti15_10, 56)
+IRQ(on_rtc_alarm, 57)
+IRQ(on_dfsdm1_flt3, 58)
+IRQ(on_tim8_brk, 59)
+IRQ(on_tim8_up, 60)
+IRQ(on_tim8_trg_com, 61)
+IRQ(on_tim8_cc, 62)
+IRQ(on_adc3, 63)
+IRQ(on_fmc, 64)
+IRQ(on_sdmmc1, 65)
+IRQ(on_tim5, 66)
+IRQ(on_spi3, 67)
+IRQ(on_uart4, 68)
+IRQ(on_uart5, 69)
+IRQ(on_tim6_dacunder, 70)
+IRQ(on_tim7, 71)
+IRQ(on_dma2_channel1, 72)
+IRQ(on_dma2_channel2, 73)
+IRQ(on_dma2_channel3, 74)
+IRQ(on_dma2_channel4, 75)
+IRQ(on_dma2_channel5, 76)
+IRQ(on_dfsdm1_flt0, 77)
+IRQ(on_dfsdm1_flt1, 78)
+IRQ(on_dfsdm1_flt2, 79)
+IRQ(on_comp, 80)
+IRQ(on_lptim1, 81)
+IRQ(on_lptim2, 82)
+IRQ(on_otg_fs, 83)
+IRQ(on_dma2_channel6, 84)
+IRQ(on_dma2_channel7, 85)
+IRQ(on_lpuart1, 86)
+IRQ(on_quadspi, 87)
+IRQ(on_i2c3_ev, 88)
+IRQ(on_i2c3_er, 89)
+IRQ(on_sai1, 90)
+IRQ(on_sai2, 91)
+IRQ(on_swpmi1, 92)
+IRQ(on_tsc, 93)
+IRQ(on_lcd, 94)
+IRQ(on_aes, 95)
+IRQ(on_rng, 96)
+IRQ(on_fpu, 97)
+IRQ(on_hash, 98)
+IRQ(on_i2c4_ev, 99)
+IRQ(on_i2c4_er, 100)
+IRQ(on_dcmi, 101)
+IRQ(on_can2_tx, 102)
+IRQ(on_can2_rx0, 103)
+IRQ(on_can2_rx1, 104)
+IRQ(on_can2_sce, 105)
+IRQ(on_dma2d, 106)
diff --git a/02-usart/src/init.c b/02-usart/src/init.c
new file mode 100644
index 0000000..70703aa
--- /dev/null
+++ b/02-usart/src/init.c
@@ -0,0 +1,45 @@
+#include "arch.h"
+#include "system.h"
+
+/* Forward-declare the main function. This is implemented in main.c. */
+void main();
+
+/* These are defined in the linker script. */
+extern uint32_t INIT_DATA_VALUES;
+extern uint32_t DATA_SEGMENT_START;
+extern uint32_t DATA_SEGMENT_STOP;
+extern uint32_t BSS_START;
+extern uint32_t BSS_END;
+
+/*
+ * Runs before main. Initializes the data and bss segments by loading them
+ * into memory.
+ */
+_Noreturn void on_reset()
+{
+ uint32_t* src;
+ uint32_t* dest;
+
+ src = &INIT_DATA_VALUES;
+ dest = &DATA_SEGMENT_START;
+
+ /* Copy the values from flash into the data segment. */
+ while (dest != &DATA_SEGMENT_STOP) {
+ *(dest++) = *(src++);
+ }
+
+ /* Everything in the BSS segment is set to zero. */
+ dest = &BSS_START;
+ while (dest != &BSS_END) {
+ *(dest++) = 0;
+ }
+
+ /* Set the vector offset table to be at the start
+ * of FLASH memory. */
+ SCB.vto_r = 0x08000000;
+
+ /* Jump to main. */
+ main();
+
+ for(;;);
+}
diff --git a/02-usart/src/isr_vector.c b/02-usart/src/isr_vector.c
index 6d5128c..484f3c5 100644
--- a/02-usart/src/isr_vector.c
+++ b/02-usart/src/isr_vector.c
@@ -6,165 +6,101 @@
#ifdef ARCH_STM32L4
-/* Forward-declare the main function. This is implemented in main.c. */
-void main();
-
-/* These are defined in the linker script. */
-extern uint32_t INIT_DATA_VALUES;
-extern uint32_t DATA_SEGMENT_START;
-extern uint32_t DATA_SEGMENT_STOP;
-extern uint32_t BSS_START;
-extern uint32_t BSS_END;
-
-/*
- * Runs before main. Initializes the data and bss segments by loading them
- * into memory.
- */
-void init()
+#define IRQ_RESERVED(n)
+#define IRQ(name, n) \
+ void WEAK name () { \
+ unhandled_isr(n); \
+ }
+#include "isrs.i"
+#undef IRQ_RESERVED
+#undef IRQ
+
+
+void isr_simple_pin_on()
{
- uint32_t* src;
- uint32_t* dest;
+ __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B);
+ gpio_output_pin_t pin3 = set_gpio_pin_output(port_b, PIN_3);
- src = &INIT_DATA_VALUES;
- dest = &DATA_SEGMENT_START;
+ pin_on(pin3);
+}
- /* Copy the values from flash into the data segment. */
- while (dest != &DATA_SEGMENT_STOP) {
- *(dest++) = *(src++);
+#define DEFINE_UNHANDLED_ISR(n) \
+ int unhandled_isr_##n() \
+ { \
+ unhandled_isr(n); \
}
- /* Everything in the BSS segment is set to zero. */
- dest = &BSS_START;
- while (dest != &BSS_END) {
- *(dest++) = 0;
+
+/* Flashes wildly. */
+void super_flash()
+{
+ static int pin_on = 0;
+ __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B);
+ gpio_output_pin_t pin3 = set_gpio_pin_output(port_b, PIN_3);
+
+ if (pin_on) {
+ pin_off(pin3);
+ } else {
+ pin_on(pin3);
}
- /* Jump to main. */
- main();
+ pin_on = !pin_on;
}
+#define IRQ_RESERVED(n) 0,
+#define IRQ(name, n) name,
const void* vectors[] __attribute__((section(".vectors"))) = {
(void*)0x2000c000, /* Top of stack at top of sram1. 48k */
- init, /* Reset handler */
- unhandled_isr, /* NMI */
- unhandled_isr, /* Hard Fault */
- unhandled_isr, /* MemManage */
- unhandled_isr, /* BusFault */
- unhandled_isr, /* UsageFault */
- unhandled_isr, /* Reserved */
- unhandled_isr, /* Reserved */
- unhandled_isr, /* Reserved */
- unhandled_isr, /* Reserved */
- unhandled_isr, /* SVCall */
- unhandled_isr, /* Debug */
- unhandled_isr, /* Reserved */
- unhandled_isr, /* PendSV */
- unhandled_isr, /* SysTick */
-
- /* External interrupt handlers follow */
- unhandled_isr, /* 0 WWDG */
- unhandled_isr, /* 1 PVD */
- unhandled_isr, /* 2 TAMP_SAMP */
- unhandled_isr, /* 3 RTC_WKUP */
- unhandled_isr, /* 4 FLASH */
- unhandled_isr, /* 5 RCC */
- unhandled_isr, /* 6 EXTI0 */
- unhandled_isr, /* 7 EXTI1 */
- unhandled_isr, /* 8 EXTI2 */
- unhandled_isr, /* 9 EXTI3 */
- unhandled_isr, /* 10 EXTI4 */
- unhandled_isr, /* 11 DMA_CH1 */
- unhandled_isr, /* 12 DMA_CH2 */
- unhandled_isr, /* 13 DMA_CH3 */
- unhandled_isr, /* 14 DMA_CH4 */
- unhandled_isr, /* 15 DMA_CH5 */
- unhandled_isr, /* 16 DMA_CH6 */
- unhandled_isr, /* 17 DMA_CH7 */
- unhandled_isr, /* 18 ADC1 */
- unhandled_isr, /* 19 CAN_TX */
- unhandled_isr, /* 20 CAN_RX0 */
- unhandled_isr, /* 21 CAN_RX1 */
- unhandled_isr, /* 22 CAN_SCE */
- unhandled_isr, /* 23 EXTI9_5 */
- unhandled_isr, /* 24 TIM1_BRK/TIM15 */
- unhandled_isr, /* 25 TIM1_UP/TIM16 */
- unhandled_isr, /* 26 TIM1_TRG_COM */
- unhandled_isr, /* 27 TIM1_CC */
- unhandled_isr, /* 28 TIM2 */
- unhandled_isr, /* 29 Reserved */
- unhandled_isr, /* 30 Reserved */
- unhandled_isr, /* 31 I2C1_EV */
- unhandled_isr, /* 32 I2C1_ER */
- unhandled_isr, /* 33 I2C2_EV */
- unhandled_isr, /* 34 I2C2_ER */
- unhandled_isr, /* 35 SPI1 */
- unhandled_isr, /* 36 SPI2 */
- unhandled_isr, /* 37 USART1 */
- unhandled_isr, /* 38 USART2 */
- unhandled_isr, /* 39 USART3 */
- unhandled_isr, /* 40 EXTI15_10 */
- unhandled_isr, /* 41 RTCAlarm */
- unhandled_isr, /* 42 Reserved */
- unhandled_isr, /* 43 Reserved */
- unhandled_isr, /* 44 Reserved */
- unhandled_isr, /* 45 Reserved */
- unhandled_isr, /* 46 Reserved */
- unhandled_isr, /* 47 Reserved */
- unhandled_isr, /* 48 Reserved */
- unhandled_isr, /* 49 SDMMC1 */
- unhandled_isr, /* 50 Reserved */
- unhandled_isr, /* 51 SPI3 */
- unhandled_isr, /* 52 Reserved */
- unhandled_isr, /* 53 Reserved */
- unhandled_isr, /* 54 TIM6_DACUNDER */
- unhandled_isr, /* 55 TIM7 */
- unhandled_isr, /* 56 DMA2_CH1 */
- unhandled_isr, /* 57 DMA2_CH2 */
- unhandled_isr, /* 58 DMA2_CH3 */
- unhandled_isr, /* 59 DMA2_CH4 */
- unhandled_isr, /* 60 DMA2_CH5 */
- unhandled_isr, /* 61 Reserved */
- unhandled_isr, /* 62 Reserved */
- unhandled_isr, /* 63 Reserved*/
- unhandled_isr, /* 64 COMP */
- unhandled_isr, /* 65 LPTIM1 */
- unhandled_isr, /* 66 LPTIM2 */
- unhandled_isr, /* 67 USB_FS */
- unhandled_isr, /* 68 DMA_CH6 */
- unhandled_isr, /* 69 DMA_CH7 */
- unhandled_isr, /* 70 LPUART1 */
- unhandled_isr, /* 71 QUADSPI */
- unhandled_isr, /* 72 I2C3_EV */
- unhandled_isr, /* 73 I2C3_ER */
- unhandled_isr, /* 74 SAI1 */
- unhandled_isr, /* 75 Reserved */
- unhandled_isr, /* 76 SWPMI1 */
- unhandled_isr, /* 77 TSC */
- unhandled_isr, /* 78 Reserved */
- unhandled_isr, /* 79 AES */
- unhandled_isr, /* 80 RNG */
- unhandled_isr, /* 81 FPU */
- unhandled_isr /* 82 CRS */
+#include "isrs.i"
};
+#undef IRQ_RESERVED
+#undef IRQ
-/*
- * Does nothing ... forever.
+/* Encodes the provided number as a series of flashes on the on-board
+ * LED. The flashes follow as such:
+ *
+ * Before the bits of the code are flashed, a rapid succession of 20 flashes
+ * followed by a pause will occur indicating that the next 8 flashes indicate
+ * the bits of the provided code.
+ *
+ * The next eight flashes are indicate either a 1 or 0 depending on the length
+ * of the light being on. The first flash is the least-significant bit, the next
+ * the second least, the third third least, etc.
+ *
+ * - A quick flash followed by a long pause indicates a 0 bit.
+ * - A "long" flash followed by a equally long pause indicates a 1 bit.
*/
-void unhandled_isr()
+void unhandled_isr(uint8_t number)
{
__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. */
+ for (int i = 0; i < 20; ++ i) {
+ pin_on(pin3);
+ delay(1000000);
+ pin_off(pin3);
+ delay(1000000);
+ }
+ delay(50000000);
- pin_off(pin3);
- delay(1000000);
- pin_on(pin3);
- delay(1000000);
- pin_off(pin3);
- delay(1000000);
- pin_on(pin3);
- delay(5000000);
+ int n = number;
+ for (int i = 0; i < 8; ++ i) {
+ if (n & 1) {
+ // LSB is a 1
+ pin_on(pin3);
+ delay(15000000);
+ pin_off(pin3);
+ delay(15000000);
+ } else {
+ // LSB is a 0
+ pin_on(pin3);
+ delay(1000000);
+ pin_off(pin3);
+ delay(29000000);
+ }
+
+ n >>= 1;
+ }
}
}
diff --git a/02-usart/src/main.c b/02-usart/src/main.c
index b4f7dd7..b293202 100644
--- a/02-usart/src/main.c
+++ b/02-usart/src/main.c
@@ -1,4 +1,6 @@
+#include "isr_vector.h"
+#include "lib.h"
#include "string.h"
#include "mem.h"
#include "dma.h"
@@ -8,117 +10,42 @@
#include "gpio.h"
#include "spin.h"
#include "usart.h"
+#include "system.h"
-volatile uint32_t delay_amt = 20000000 / 4;
-int setup_usart2(uint32_t baud_rate)
-{
- __IO gpio_port_t* port_a = enable_gpio(GPIO_PORT_A);
- enable_hsi(&RCC, true);
-
- // Turn on the clock for the USART2 peripheral
- set_usart2_clock_src(&RCC, USART_CLK_SRC_HSI16);
- set_usart2_clock_enabled(&RCC, true);
-
- // Configure the I/O pins. Will use PA2 as TX and PA15 as RX so setup for
- // alternate function
- set_gpio_pin_mode(port_a, PIN_2, MODE_ALTERNATE);
- set_gpio_pin_mode(port_a, PIN_15, MODE_ALTERNATE);
- set_gpio_alternate_function(port_a, PIN_2, AFN_7);
- set_gpio_alternate_function(port_a, PIN_15, AFN_3);
-
- // De-assert reset of USART2
- RCC.apb1rst1_r &= ~BIT(17);
-
- // Configure the USART
- // disable USART first to allow setting of other control bits
- // This also disables parity checking and enables 16 times oversampling
-
- USART2.c_r1 = 0;
- USART2.c_r2 = 0;
- USART2.c_r3 = 0;
-
- usart_set_divisor(&USART2, 16000000 / baud_rate);
-}
+#ifdef ARCH_STM32L4
-int enable_usart1(uint32_t baud_rate)
+/** Overrides the default systick irq handler. */
+void on_systick()
{
- /* Enable the GPIO bus. */
- __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B);
-
- /* Enable the USART clock. */
- RCC.apb2en_r |= BIT(14);
-
- /* == Configure the IO Pins. == */
-
- /* GPIO D5 (Port B pin 6) is USART1 Tx,
- * GPIO D6 (Port B pin 7) is USART1 Rx. */
- set_gpio_pin_mode(port_b, PIN_6, MODE_ALTERNATE);
- set_gpio_pin_mode(port_b, PIN_7, MODE_ALTERNATE);
-
- /* Set the GPIO pins to use the USART alternate function. */
- set_gpio_alternate_function(port_b, PIN_6, AFN_7);
- set_gpio_alternate_function(port_b, PIN_7, AFN_7);
+ static int is_on = 0;
- RCC.apb2rst_r &= ~BIT(14); /* De-assert reset of USART1 */
-
- uint32_t baud_rate_div = 80000000 / baud_rate;
- USART1.c_r1 = 0;
- USART1.c_r2 = 0;
- USART1.c_r3 = 0;
- USART1.br_r = baud_rate_div;
+ __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B);
+ gpio_output_pin_t pin3 = set_gpio_pin_output(port_b, PIN_3);
- USART1.c_r1 |= BIT(3) | BIT(2);
- USART1.c_r1 |= BIT(0);
+ if (is_on) {
+ pin_off(pin3);
+ } else {
+ pin_on(pin3);
+ }
- /* Enable the transmitter and the receiver. */
- usart_set_enabled(&USART1, USART_ENABLE_TX);
- enable_interrupts();
+ is_on = ! is_on;
}
-#ifdef ARCH_STM32L4
-
/* 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);
-
/* Enable a higher clock frequency. */
set_system_clock_MHz(80);
- setup_usart2(115200);
-
-
- char* into = (char*) (SRAM1_BASE + 50);
- const char* hello = "Hello, Chester Cheeto!\r\n";
- int len = strlen(hello);
- memcpy(into, hello, len + 1);
-
- usart_enable_dma(&USART2, USART_ENABLE_TX);
- usart_set_enabled(&USART2, USART_ENABLE_TX | USART_ENABLE_RX);
-
- pin_on(pin3);
-
- RCC.ahb1en_bf.dma1en = 1; /* Enable DMA1 Clock. */
- DMA1.csel_bf.c7s = 0x2; /* Select USART2_TX for the sel. */
- DMA1.channel_config[6].cc_r = 0;
- DMA1.channel_config[6].cc_bf.dir = READ_FROM_MEMORY;
- DMA1.channel_config[6].cc_bf.minc = 1;
- DMA1.channel_config[6].cc_bf.pl = DMA_PRIORITY_LEVEL_VERY_HIGH;
- DMA1.channel_config[6].cndt_bf.ndt = len;
- DMA1.channel_config[6].cpa_r = ptr2reg(&USART2.td_r);
- DMA1.channel_config[6].cma_r = ptr2reg(into);
+ /* Set the countdown to start from 1,000,0000. */
+ SCB.strv_r = 10000000;
- USART2.ic_bf.tccf = 1;
- DMA1.channel_config[6].cc_bf.en = 1;
+ /* Enable interrupts. */
+ SCB.stcs_bf.tickint = 1;
- pin_on(pin3);
- // usart_transmit_str_sync(&USART2, into);
- for(;;);
+ /* Start the systick. */
+ SCB.stcs_bf.enable = 1;
}
#endif