aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.preamble2
-rw-r--r--include/arch/arm/arch.h2
-rw-r--r--include/arch/stm32l4xxx/peripherals/tim.h175
-rw-r--r--include/arch/x86_64/arch.h2
-rw-r--r--src/kern/main.c34
-rw-r--r--test_harness/fake_env.c2
-rw-r--r--test_harness/fake_env.h1
7 files changed, 217 insertions, 1 deletions
diff --git a/Makefile.preamble b/Makefile.preamble
index 62b221a..75f3afb 100644
--- a/Makefile.preamble
+++ b/Makefile.preamble
@@ -6,7 +6,7 @@ CFLAGS?=$(OPT) -mcpu=cortex-m4 -mthumb -g -lgcc -static -nostartfiles -Iinclude
LD_FLAGS?=-T linker/linker_script.ld -nostdlib --cref -Map linker/main.map -static
TEST_PREFIX=x86_64-pc-linux-gnu-
-TEST_CFLAGS=-Iinclude -Iinclude/arch/x86_64 -Itest_harness -g3 -ggdb -DFOR_TESTING -Wall
+TEST_CFLAGS=-Iinclude -Iinclude/arch/x86_64 -Itest_harness -g3 -ggdb -gdwarf-2 -DFOR_TESTING -Wall
all: _$(PREFIX)_obs/main.elf
diff --git a/include/arch/arm/arch.h b/include/arch/arm/arch.h
index 267621f..7dfc343 100644
--- a/include/arch/arm/arch.h
+++ b/include/arch/arm/arch.h
@@ -47,6 +47,8 @@
#define SYSCFG_BASE (0x40010000)
#define EXTI_BASE (0x40010400)
+#define TIM2_BASE (0x40000000)
+
#include <stdint.h>
#ifndef DRY_RUN
_Static_assert(sizeof(void*) == sizeof(uint32_t), "Pointers must be 32 bits");
diff --git a/include/arch/stm32l4xxx/peripherals/tim.h b/include/arch/stm32l4xxx/peripherals/tim.h
new file mode 100644
index 0000000..145622a
--- /dev/null
+++ b/include/arch/stm32l4xxx/peripherals/tim.h
@@ -0,0 +1,175 @@
+#ifndef ARCH_STM32L4XXX_PERIPHERALS_TIM_H_
+#define ARCH_STM32L4XXX_PERIPHERALS_TIM_H_
+
+#include "arch.h"
+#include "kern/common.h"
+
+#define TIM2 (*((tim_regs_t*)TIM2_BASE))
+
+typedef __IO struct {
+#define tim_uifremap (1 << 11) /* UIF status bit remapping */
+#define tim_ckd (3 << 8) /* Clock Divisor */
+#define tim_arpe (1 << 7) /* Auto-reload preload enable */
+#define tim_cms (3 << 5) /* Center align mode selection */
+#define tim_dir (1 << 4) /* Direction */
+#define tim_opm (1 << 3) /* One-pulse mode */
+#define tim_urs (1 << 2) /* Update request source */
+#define tim_udis (1 << 1) /* Update disable */
+#define tim_cen (1 << 0) /* Counter enable */
+ uint32_t c_r1;
+
+#define tim_ti1s (1 << 7)
+#define tim_mms (7 << 4)
+#define tim_ccds (1 << 3)
+ uint32_t c_r2;
+
+#define tim_sms_3 (1 << 16)
+#define tim_etp (1 << 15)
+#define tim_ece (1 << 14)
+#define tim_etps (3 << 12)
+#define tim_etf (0xF << 8)
+#define tim_msm (1 << 7)
+#define tim_ts (7 << 4)
+#define tim_occs (1 << 3)
+#define tim_sms_0_2 (7 << 0)
+ uint32_t smc_r;
+
+#define tim_tde (1 << 14) /* Trigger DMA request enable */
+#define tim_cc4de (1 << 12) /* Capture/Compare 4 DMA request enable */
+#define tim_cc3de (1 << 11) /* Capture/Compare 3 DMA request enable */
+#define tim_cc2de (1 << 10) /* Capture/Compare 2 DMA request enable */
+#define tim_cc1de (1 << 9) /* Capture/Compare 1 DMA request enable */
+#define tim_ude (1 << 8) /* Update DMA request enable */
+#define tim_tie (1 << 6) /* Trigger interrupt enable */
+#define tim_cc4ie (1 << 4) /* Capture/Compare 4 interrupt enable */
+#define tim_cc3ie (1 << 3) /* Capture/Compare 3 interrupt enable */
+#define tim_cc2ie (1 << 2) /* Capture/Compare 2 interrupt enable */
+#define tim_cc1ie (1 << 1) /* Capture/Compare 1 interrupt enable */
+#define tim_uie (1 << 0) /* Update interrupt enable */
+ uint32_t die_r; /* Dma interrupt/enable register */
+
+#define tim_cc4of (1 << 12) /* Capture/Compare 4 overcapture flag */
+#define tim_cc3of (1 << 11) /* Capture/Compare 3 overcapture flag */
+#define tim_cc2of (1 << 10) /* Capture/compare 2 overcapture flag */
+#define tim_cc1of (1 << 9) /* Capture/Compare 1 overcapture flag */
+#define tim_tif (1 << 6) /* Trigger interrupt flag */
+#define tim_cc4if (1 << 4) /* Capture/Compare 4 interrupt flag */
+#define tim_cc3if (1 << 3) /* Capture/Compare 3 interrupt flag */
+#define tim_cc2if (1 << 2) /* Capture/Compare 2 interrupt flag */
+#define tim_cc1if (1 << 1) /* Capture/compare 1 interrupt flag */
+#define tim_uif (1 << 0) /* Update interrupt flag */
+ uint32_t s_r; /* Status register */
+
+#define tim_tg (1 << 6) /* Trigger generation */
+#define tim_cc4g (1 << 4) /* Capture/compare 4 generation */
+#define tim_cc3g (1 << 3) /* Capture/compare 3 generation */
+#define tim_cc2g (1 << 2) /* Capture/compare 2 generation */
+#define tim_cc1g (1 << 1) /* Capture/compare 1 generation */
+#define tim_ug (1 << 0) /* Update generation */
+ uint32_t eg_r; /* Event generation register. */
+
+#define tim_ic2f (15 << 12) /* Input capture 2 filter */
+#define tim_ic2psc (3 << 10) /* Input capture 2 prescaler */
+#define tim_cc2s (3 << 8) /* Capture/compare 2 selection */
+#define tim_ic1f (15 << 4) /* Input capture 1 filter */
+#define tim_ic1psc (3 << 2) /* Input capture 1 prescaler */
+#define tim_cc1s (3 << 0) /* Capture/Compare 1 selection */
+ /* Alternate */
+#define tim_oc2ce (1 << 15) /* Output compare 2 clear enable */
+#define tim_oc2m_3 (1 << 24) /* Output compare 2 mode, bit 3. */
+#define tim_oc2m_0_2 (7 << 12) /* Output compare 2 mode, bits 0-2 */
+#define tim_oc2pe (1 << 11) /* Output compare 2 preload enable */
+#define tim_oc2fe (1 << 10) /* Output compare 2 fast enable */
+#define tim_cc2s (3 << 8) /* Capture/Compare 2 selection */
+#define tim_oc1ce (1 << 7) /* Output compare 1 clear enable */
+#define tim_oc1m_3 (1 << 16) /* Output compare 1 mode, bit 3. */
+#define tim_oc1m_0_2 (7 << 4) /* Output compare 1 mode, bits 0-2. */
+#define tim_oc1pe (1 << 3) /* Output compare 1 preload enable */
+#define tim_oc1fe (1 << 2) /* Output compare 1 fast enable */
+#define tim_cc1s (3 << 0) /* Capture/Compare 1 selection */
+ uint32_t ccm_r1; /* Capture/compare mode register 1. */
+
+#define tim_ic4f (15 << 12) /* Input capture 4 filter */
+#define tim_ic4psc (3 << 10) /* Input capture 4 prescaler */
+#define tim_cc4s (3 << 8) /* Capture/Compare 4 selection */
+#define tim_ic3f (15 << 4) /* Input capture 3 filter */
+#define tim_ic3psc (3 << 2) /* Input capture 3 prescaler */
+#define tim_cc3s (3 << 0) /* Capture/Compare 3 selection */
+ /* Alternate */
+#define tim_oc4ce (1 << 15) /* Output compare 4 clear enable */
+#define tim_oc4m_3 (1 << 24) /* Output compare 4 mode, bit 3. */
+#define tim_oc4m_0_2 (7 << 12) /* Output compare 4 mode, bits 0-2 */
+#define tim_oc4pe (1 << 11) /* Output compare 4 preload enable */
+#define tim_oc4fe (1 << 10) /* Output compare 4 fast enable */
+#define tim_cc4s (3 << 8) /* Capture/Compare 4 selection */
+#define tim_oc3ce (1 << 7) /* Output compare 3 clear enable */
+#define tim_oc3m_3 (1 << 16) /* Output compare 3 mode, bit 3. */
+#define tim_oc3m_0_2 (7 << 4) /* Output compare 3 mode, bits 0-2. */
+#define tim_oc3pe (1 << 3) /* Output compare 3 preload enable */
+#define tim_oc3fe (1 << 2) /* Output compare 3 fast enable */
+#define tim_cc3s (3 << 0) /* Capture/Compare 3 selection */
+ uint32_t ccm_r2; /* Capture/compare mode register 2. */
+
+#define tim_cc4np (1 << 15) /* Capture/Compare 4 output Polarity. */
+#define tim_cc4p (1 << 13) /* Capture/Compare 4 output Polarity. */
+#define tim_cc4e (1 << 12) /* Capture/Compare 4 output enable. */
+#define tim_cc3np (1 << 11) /* Capture/Compare 3 output Polarity. */
+#define tim_cc3p (1 << 9) /* Capture/Compare 3 output Polarity. */
+#define tim_cc3e (1 << 8) /* Capture/Compare 3 output enable. */
+#define tim_cc2np (1 << 7) /* Capture/Compare 2 output Polarity. */
+#define tim_cc2p (1 << 5) /* Capture/Compare 2 output Polarity. */
+#define tim_cc2e (1 << 4) /* Capture/Compare 2 output enable. */
+#define tim_cc1np (1 << 3) /* Capture/Compare 1 output Polarity. */
+#define tim_cc1p (1 << 1) /* Capture/Compare 1 output Polarity. */
+#define tim_cc1e (1 << 0) /* Capture/Compare 1 output enable. */
+ uint32_t cce_r; /* Copture/compare enable register. */
+
+ /* Mapping depends on UIFREMAP. */
+#define tim_cnt (0x7fffffff << 0) /* Counter value */
+#define tim_uifcpy (1 << 31)
+ uint32_t cnt;
+
+ uint16_t psc; /* Prescaler. */
+ uint16_t reserved0;
+
+ uint32_t ar_r; /* Auto reload register. */
+
+ uint32_t reserved1;
+
+ uint32_t cc_r1; /* Capture compare register 1. */
+ uint32_t cc_r2; /* Capture compare register 2. */
+ uint32_t cc_r3; /* Capture compare register 3. */
+ uint32_t cc_r4; /* Capture compare register 4. */
+
+ uint32_t reserved2;
+
+#define tim_dbl (31 << 8) /* DMA burst length */
+#define tim_dba (31 << 0) /* DMA base address */
+ uint32_t dc_r; /* dma control register. */
+
+ uint16_t dma_r; /* dma address for full transfer. */
+ uint16_t reserved3; /* dma address for full transfer. */
+
+ union {
+#define tim_ti4_rmp (3 << 2) /* Input Capture 4 remap */
+#define tim_etr_rmp (1 << 1) /* External trigger remap */
+#define tim_itr1_rmp (1 << 0) /* Internal trigger 1 remap */
+ uint32_t tim2_o_r1;
+#define tim_ti1_rmp (3 << 0)
+ uint32_t tim3_o_r1;
+ };
+
+ uint32_t reserved4[3];
+
+#define tim_etrsel (7 << 14) /* ETR source selection */
+ union {
+ uint32_t tim2_o_r2;
+ uint32_t tim3_o_r2;
+ };
+} tim_regs_t;
+
+static_assert(offsetof(tim_regs_t, ar_r) == 0x2c, "Offset check failed");
+static_assert(offsetof(tim_regs_t, dc_r) == 0x48, "Offset check failed");
+static_assert(offsetof(tim_regs_t, tim3_o_r2) == 0x60, "Offset check failed");
+
+#endif /* ARCH_STM32L4XXX_PERIPHERALS_TIM_H_ */
diff --git a/include/arch/x86_64/arch.h b/include/arch/x86_64/arch.h
index 15ebd6d..8bd3468 100644
--- a/include/arch/x86_64/arch.h
+++ b/include/arch/x86_64/arch.h
@@ -37,6 +37,8 @@
#define SYSCFG_BASE (load_fake_syscfg__())
#define EXTI_BASE (load_fake_exti__())
+#define TIM2_BASE (load_fake_exti__())
+
// Pretend there's a data segement at the start of SRAM1 for more accurate
// testing.
#define GHOST_DATA_SEGMENT_SIZE 1200
diff --git a/src/kern/main.c b/src/kern/main.c
index 2b97197..082d450 100644
--- a/src/kern/main.c
+++ b/src/kern/main.c
@@ -2,6 +2,7 @@
#include "arch/arm/cortex-m4/mpu.h"
#include "arch/stm32l4xxx/peripherals/clock.h"
#include "arch/stm32l4xxx/peripherals/dma.h"
+#include "arch/stm32l4xxx/peripherals/tim.h"
#include "arch/stm32l4xxx/peripherals/exti.h"
#include "arch/stm32l4xxx/peripherals/irq.h"
#include "arch/stm32l4xxx/peripherals/rcc.h"
@@ -23,6 +24,15 @@
#include "kern/systick/systick_manager.h"
#include "user/syscall.h"
+void on_exti9_5()
+{
+ klogf("Exit Interrupt!\n");
+ klogf("Pending Reg_again: %p\n", EXTI.p_r1);
+ klogf("Write: %p\n", (1 << 6));
+ EXTI.p_r1 |= 1 << 6;
+ klogf("Pending Reg_again: %p\n", EXTI.p_r1);
+}
+
void on_hard_fault()
{
panic("Hard fault encountered!\n");
@@ -81,6 +91,15 @@ static uint32_t bytescale(uint32_t n, uint32_t sc)
return n * sc / 255;
}
+void on_tim2()
+{
+ if (regget(TIM2.s_r, tim_uif)) {
+ regset(TIM2.s_r, tim_uif, 0);
+ }
+
+ klogf("Tim2 Update\n");
+}
+
/* Main function. This gets executed from the interrupt vector defined above. */
int main()
{
@@ -88,6 +107,21 @@ int main()
klogf("Entering main\n");
+ klogf("Enable ir\n");
+ enable_interrupt(IRQ_TIM2);
+ klogf("Enable clock\n");
+ regset(RCC.apb1en1_r, rcc_tim2en, 1);
+ klogf("psc\n");
+ TIM2.psc = 39999; /* Counts every half millisecond. */
+ klogf("ar_r\n");
+ TIM2.ar_r = 1000;
+ klogf("die_r\n");
+ regset(TIM2.die_r, tim_uie, 1);
+ klogf("eg_r\n");
+ regset(TIM2.eg_r, tim_ug, 1);
+ klogf("c_r1\n");
+ regset(TIM2.c_r1, tim_cen, 1);
+
int ec;
gpio_reserved_pin_t sysled = get_sysled();
diff --git a/test_harness/fake_env.c b/test_harness/fake_env.c
index cee7246..bae6298 100644
--- a/test_harness/fake_env.c
+++ b/test_harness/fake_env.c
@@ -65,3 +65,5 @@ DEFINE_MEMORY_SEGMENT(spi3, 0x40003C00, 0x40003FFF)
DEFINE_MEMORY_SEGMENT(syscfg, 0x40010000, 0x4001002F)
DEFINE_MEMORY_SEGMENT(exti, 0x40010400, 0x40010800)
+
+DEFINE_MEMORY_SEGMENT(tim2, 0x40000000, 0x400003FF)
diff --git a/test_harness/fake_env.h b/test_harness/fake_env.h
index 43097ae..83ac702 100644
--- a/test_harness/fake_env.h
+++ b/test_harness/fake_env.h
@@ -17,6 +17,7 @@ void* load_fake_spi3__();
void* load_fake_mpu__();
void* load_fake_syscfg__();
void* load_fake_exti__();
+void* load_fake_tim2__();
void wipeout_fake_env();