diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2020-12-09 20:29:31 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2020-12-09 20:29:31 -0700 |
commit | a5923b21e48fcfe660c1e7d586fe0c6a5b79e421 (patch) | |
tree | 8477e2e5088847b5c5e93257681ee19d43394bbd | |
parent | 1710871aa1958c2cac38e4b372964ef22032ed4a (diff) | |
download | stm32l4-a5923b21e48fcfe660c1e7d586fe0c6a5b79e421.tar.gz stm32l4-a5923b21e48fcfe660c1e7d586fe0c6a5b79e421.tar.bz2 stm32l4-a5923b21e48fcfe660c1e7d586fe0c6a5b79e421.zip |
Got a basic timer to work.
-rw-r--r-- | Makefile.preamble | 2 | ||||
-rw-r--r-- | include/arch/arm/arch.h | 2 | ||||
-rw-r--r-- | include/arch/stm32l4xxx/peripherals/tim.h | 175 | ||||
-rw-r--r-- | include/arch/x86_64/arch.h | 2 | ||||
-rw-r--r-- | src/kern/main.c | 34 | ||||
-rw-r--r-- | test_harness/fake_env.c | 2 | ||||
-rw-r--r-- | test_harness/fake_env.h | 1 |
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(); |