diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/arch/arm/arch.h | 5 | ||||
| -rw-r--r-- | include/arch/stm32l4xxx/peripherals/exti.h | 35 | ||||
| -rw-r--r-- | include/arch/stm32l4xxx/peripherals/syscfg.h | 87 | ||||
| -rw-r--r-- | include/arch/stm32l4xxx/peripherals/tim.h | 175 | ||||
| -rw-r--r-- | include/arch/x86_64/arch.h | 6 | ||||
| -rw-r--r-- | include/drv/ir/control.h | 14 | ||||
| -rw-r--r-- | include/drv/ir/ir.h | 34 | ||||
| -rw-r--r-- | include/drv/ir/lg_remote_codes.h | 17 | ||||
| -rw-r--r-- | include/drv/ws2812B/ws2812b.h | 3 | ||||
| -rw-r--r-- | include/kern/common.h | 1 | ||||
| -rw-r--r-- | include/kern/exti/exti_manager.h | 32 | ||||
| -rw-r--r-- | include/kern/gpio/gpio_manager.h | 56 | ||||
| -rw-r--r-- | include/kern/mem.h | 2 | ||||
| -rw-r--r-- | include/shared/array_list.h | 105 | ||||
| -rw-r--r-- | include/shared/avl_tree.h | 270 | ||||
| -rw-r--r-- | include/shared/avl_tree.h.gch | bin | 0 -> 11451 bytes | |||
| -rw-r--r-- | include/shared/linked_list.h | 277 | ||||
| -rw-r--r-- | include/shared/map.h | 90 | ||||
| -rw-r--r-- | include/shared/math.h | 19 | ||||
| -rw-r--r-- | include/shared/stdmacro.h | 7 |
20 files changed, 1100 insertions, 135 deletions
diff --git a/include/arch/arm/arch.h b/include/arch/arm/arch.h index e4ebb8d..7dfc343 100644 --- a/include/arch/arm/arch.h +++ b/include/arch/arm/arch.h @@ -44,6 +44,11 @@ #define STACK_TOP (0x2000c000) #define MPU_BASE (0xE000ED90) +#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/exti.h b/include/arch/stm32l4xxx/peripherals/exti.h new file mode 100644 index 0000000..6776d10 --- /dev/null +++ b/include/arch/stm32l4xxx/peripherals/exti.h @@ -0,0 +1,35 @@ +#ifndef PERIPHERALS_EXTI_H_ +#define PERIPHERALS_EXTI_H_ + +#include "arch.h" + +#define EXTI (*(exti_regs_t*)(EXTI_BASE)) + +typedef struct { +#define exti_im_n(n) (1 << (n)) + uint32_t im_r1; /* Interrupt mask register 1. */ + +#define exti_em_n(n) (1 << (n)) + uint32_t em_r1; /* Event mask register 1. */ + +#define exti_rt_n(n) (1 << (n)) + uint32_t rts_r1; /* Rising trigger selection register 1. */ + +#define exti_ft_n(n) (1 << (n)) + uint32_t fts_r1; /* Falling trigger selection register 1. */ + +#define exti_swi_n(n) (1 << (n)) + uint32_t swie_r1; /* Software interrupt event register 1. */ + +#define exti_pif_n(n) (1 << (n)) + uint32_t p_r1; /* Pending register 1. */ + + uint32_t im_r2; /* Interrupt mask register 2. */ + uint32_t em_r2; /* Event mask register 2. */ + uint32_t rts_r2; /* Rising trigger selection register 2. */ + uint32_t fts_r2; /* Falling trigger selection register 2. */ + uint32_t swie_r2; /* Software interrupt event register 2. */ + uint32_t p_r2; /* Pending register 2. */ +} exti_regs_t; + +#endif /* PERIPHERALS_EXTI_H_ */ diff --git a/include/arch/stm32l4xxx/peripherals/syscfg.h b/include/arch/stm32l4xxx/peripherals/syscfg.h new file mode 100644 index 0000000..65290a0 --- /dev/null +++ b/include/arch/stm32l4xxx/peripherals/syscfg.h @@ -0,0 +1,87 @@ +#ifndef PERIPHERALS_SYSCFG_H_ +#define PERIPHERALS_SYSCFG_H_ + +#include "arch.h" +#include "kern/common.h" + +#define SYSCFG (*(syscfg_t*)SYSCFG_BASE) + +typedef __IO struct { +#define syscfg_memmode (7 << 0) /* Memory mapping selection. */ +#define syscfg_fbmode (1 << 8) /* Flash bank mode selection. */ + uint32_t memrmp_r; /* Configuration on memory map. */ + +#define syscfg_fwdis (1 << 0) /* Disable firewall. */ +#define syscfg_boosten (1 << 8) /* Enable analog boost. */ +#define syscfg_i2c4_fmp \ + (1 << 23) /* Fast-mode Plus driving capability activation (this bit is only \ + available on */ +#define syscfg_i2c3_fmp \ + (1 << 22) /* I2C3 Fast-mode Plus driving capability activation */ +#define syscfg_i2c2_fmp \ + (1 << 21) /* I2C2 Fast-mode Plus driving capability activation */ +#define syscfg_i2c1_fmp \ + (1 << 20) /* I2C1 Fast-mode Plus driving capability activation */ +#define syscfg_i2c_pb9_fmp \ + (1 << 19) /* Fast-mode Plus (Fm+) driving capability activation on PB9 */ +#define syscfg_i2c_pb8_fmp \ + (1 << 18) /* Fast-mode Plus (Fm+) driving capability activation on PB8 */ +#define syscfg_i2c_pb7_fmp \ + (1 << 17) /* Fast-mode Plus (Fm+) driving capability activation on PB7 */ +#define syscfg_i2c_pb6_fmp \ + (1 << 16) /* Fast-mode Plus (Fm+) driving capability activation on PB6 */ +#define syscfg_fpe_ie (0x3f << 26) /* Floating point interrupts enabled. */ + uint32_t cfg_r1; /* Configuration register 1. */ + +#define syscfg_exti0 (0xf << 0) +#define syscfg_exti1 (0xf << 4) +#define syscfg_exti2 (0xf << 8) +#define syscfg_exti3 (0xf << 12) + uint32_t extic_r1; /* External interrupt configuration register 1. */ + +#define syscfg_exti4 (0xf << 0) +#define syscfg_exti5 (0xf << 4) +#define syscfg_exti6 (0xf << 8) +#define syscfg_exti7 (0xf << 12) + uint32_t extic_r2; /* External interrupt configuration register 2. */ + +#define syscfg_exti8 (0xf << 0) +#define syscfg_exti9 (0xf << 4) +#define syscfg_exti10 (0xf << 8) +#define syscfg_exti11 (0xf << 12) + uint32_t extic_r3; /* External interrupt configuration register 3. */ + +#define syscfg_exti12 (0xf << 0) +#define syscfg_exti13 (0xf << 4) +#define syscfg_exti14 (0xf << 8) +#define syscfg_exti15 (0xf << 12) + uint32_t extic_r4; /* External interrupt configuration register 4. */ + +#define syscfg_sram2er (1 << 0) +#define syscfg_sram2bsy (1 << 1) + uint32_t scs_r; /* SRAM2 control & status register. */ + +#define syscfg_spf (1 << 8) /* SRAM2 parity error flag */ +#define syscfg_eccl (1 << 3) /* ECC Lock */ +#define syscfg_pvdl (1 << 2) /* PVD lock enable bit */ +#define syscfg_spl (1 << 1) /* SRAM2 parity lock bit */ +#define syscfg_cll (1 << 0) /* Cortex-M4 LOCKUP (Hardfault) output enable bit */ + uint32_t cfg_r2; /* Configuration register 2. */ + +#define syscfg_pnwp(n) (1 << (n)) /* Page n write protection on sram2. */ + uint32_t swp_r1; /* SRAM2 software protection register 1. */ + + union { + uint8_t sk_r; /* SRAM2 write protection key for software erase. */ + uint32_t reserved; + }; + + uint32_t swp_r2; /* SRAM2 software protection register 2. */ + + +} syscfg_t; + +static_assert( + offsetof(syscfg_t, swp_r2) == 0x28, "Offset check failed"); + +#endif /* PERIPHERALS_SYSCFG_H_ */ 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 ab26d1e..8bd3468 100644 --- a/include/arch/x86_64/arch.h +++ b/include/arch/x86_64/arch.h @@ -34,11 +34,15 @@ #define SPI3_BASE (load_fake_spi3__()) #define MPU_BASE (load_fake_mpu__()) +#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 #define HEAP_START (*(((unsigned char*)SRAM1_BASE) + GHOST_DATA_SEGMENT_SIZE)) -#define HEAP_STOP (*(&HEAP_START + 16384 - GHOST_DATA_SEGMENT_SIZE)) +#define HEAP_STOP (*(&HEAP_START + 49152 - GHOST_DATA_SEGMENT_SIZE)) #endif /* ARCH_H_ */ diff --git a/include/drv/ir/control.h b/include/drv/ir/control.h new file mode 100644 index 0000000..11e3604 --- /dev/null +++ b/include/drv/ir/control.h @@ -0,0 +1,14 @@ +#ifndef _DRV_IR_CONTROL_H_ +#define _DRV_IR_CONTROL_H_ + +#include "kern/common.h" + +#define add_ir_code_callback(code, fn, closure) \ + add_ir_code_callback_(code, (void (*)(uint32_t, void*))(fn), closure) + +void add_ir_code_callback_( + uint32_t code, void (*fn)(uint32_t code, void* closure), void* closure); + +void enable_ir_control(); + +#endif /* _DRV_IR_CONTROL_H_ */ diff --git a/include/drv/ir/ir.h b/include/drv/ir/ir.h new file mode 100644 index 0000000..0a747e8 --- /dev/null +++ b/include/drv/ir/ir.h @@ -0,0 +1,34 @@ +#ifndef _DRV_IR_IR_H_ +#define _DRV_IR_IR_H_ + +#include "kern/common.h" + +typedef struct { + uint16_t ts[64]; /* Timestamps. Microseconds. */ + uint8_t n; +} ir_code_t; + +typedef struct { + uint32_t c; +} decoded_ir; + +/* + * Attempt to decode the provided ir code. + * + * The generic ir is: + * + * The frame starts out as really-long, half(ish) as long, short. If + * this basic frame header does not exist decoding cannot continue. + * + * A short code followed by a short code = 0 + * A long code followed by a short code = 1 + * + * returns non-zero on successful decode. + */ +int ir_generic_decode(const ir_code_t* code, uint32_t* out); + +void add_ir_callback(void(*callback)(const ir_code_t*)); + +void ir_begin_listen(); + +#endif /* _DRV_IR_IR_H_ */ diff --git a/include/drv/ir/lg_remote_codes.h b/include/drv/ir/lg_remote_codes.h new file mode 100644 index 0000000..77cbb45 --- /dev/null +++ b/include/drv/ir/lg_remote_codes.h @@ -0,0 +1,17 @@ +#ifndef _DRV_IR_LG_REMOTE_CODES_H_ +#define _DRV_IR_LG_REMOTE_CODES_H_ + +#define RC_HIGH 0x08e76800 +#define RC_TEMP_UP 0x08e7a800 +#define RC_DRY 0x08e72800 +#define RC_LOW 0x08e77000 +#define RC_TEMP_DOWN 0x08e7b000 +#define RC_COOL 0x08e73000 +#define RC_CONTINUOUS 0x08e75000 +#define RC_FAN 0x08e71000 +#define RC_SLEEP 0x08e76000 +#define RC_UNITS 0x08e72000 +#define RC_TIMER 0x08e78000 +#define RC_POWER 0x08e70080 + +#endif /* _DRV_IR_LG_REMOTE_CODES_H_ */ diff --git a/include/drv/ws2812B/ws2812b.h b/include/drv/ws2812B/ws2812b.h index 3189907..d7137a1 100644 --- a/include/drv/ws2812B/ws2812b.h +++ b/include/drv/ws2812B/ws2812b.h @@ -30,7 +30,4 @@ void ws2812b_write_rgb_arr_sync(ws2812b_t* drv, rgb_t* arr, size_t arr_len); void ws2812b_delete(ws2812b_t* drv); -/* Returns round(sin(2πn / 256) * 127.5 + 127.5). */ -uint8_t byte_sin(uint8_t n); - #endif /* WS2812B_H_ */ diff --git a/include/kern/common.h b/include/kern/common.h index 021229b..0acc9d3 100644 --- a/include/kern/common.h +++ b/include/kern/common.h @@ -39,6 +39,7 @@ typedef enum { ENDIANNESS_LITTLE, ENDIANNESS_BIG } endianness_t; #define ptr2reg(ptr) ((uint32_t)(ptrdiff_t)(ptr)) typedef __IO uint32_t bits_t; +typedef uint16_t msize_t; #define regset(reg, mask, val) ((reg) = ((reg) & ~mask) | (val << CTZ(mask))) diff --git a/include/kern/exti/exti_manager.h b/include/kern/exti/exti_manager.h new file mode 100644 index 0000000..aa39b4f --- /dev/null +++ b/include/kern/exti/exti_manager.h @@ -0,0 +1,32 @@ +#ifndef _KERN_EXTI_EXTI_MANAGER_H_ +#define _KERN_EXTI_EXTI_MANAGER_H_ + +#include "kern/common.h" +#include "kern/gpio/gpio_manager.h" +#include "shared/linked_list.h" + +#define EXTI_ERROR_ALREADY_IN_USE 1 + +struct EXTI_HANDLE; + + +typedef struct { + void (*fn)(struct EXTI_HANDLE, void*); + void* closure; +} exti_callback_t; + +LINKED_LIST_DECL(exti_callback_t); +typedef struct EXTI_HANDLE { + uint8_t id; + linked_list_t(exti_callback_t)* callbacks; +} exti_handle_t; + +exti_handle_t* enable_exti_for_gpio(gpio_pin_t gpio_pin, int* ec); + +exti_handle_t* exti_add_callback(exti_handle_t*, exti_callback_t* callback); + +gpio_pin_t exti_gpio_pin(exti_handle_t* handle); + + + +#endif /* _KERN_EXTI_EXTI_MANAGER_H_ */ diff --git a/include/kern/gpio/gpio_manager.h b/include/kern/gpio/gpio_manager.h index 922a423..cb61059 100644 --- a/include/kern/gpio/gpio_manager.h +++ b/include/kern/gpio/gpio_manager.h @@ -1,8 +1,8 @@ #ifndef KERN_GPIO_GPIO_MANAGE_H_ #define KERN_GPIO_GPIO_MANAGE_H_ -#include "kern/common.h" #include "arch/stm32l4xxx/peripherals/gpio.h" +#include "kern/common.h" #define GPIO_ERROR_IN_USE 1 #define GPIO_ERROR_INVALID_PIN_FOR_ALTERNATE_FUNCTION 2 @@ -10,8 +10,7 @@ typedef enum { /* Creates vaules GPIO_PIN_<port><num> i.e. GPIO_PIN_A0 */ -#define PORT(p, pn) \ - GPIO_PIN_P ## p ## pn, +#define PORT(p, pn) GPIO_PIN_P##p##pn, #include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" #undef PORT @@ -20,16 +19,14 @@ typedef enum { /* Alternate functions. */ typedef enum { -#define AFN(fn, ...) \ - GPIO_ALTERNATE_FUNCTION_ ## fn, +#define AFN(fn, ...) GPIO_ALTERNATE_FUNCTION_##fn, #include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/afn_table.inc" #undef AFN GPIO_ALTERNATE_FUNCTION_EVENTOUT, } gpio_alternate_function_t; #define gpio_pin_for_alternate_function(af) ((af) / 16) -#define gpio_pin_out_of_range(pin) \ - ((pin) < 0 || (pin) >= N_GPIO_PINS) +#define gpio_pin_out_of_range(pin) ((pin) < 0 || (pin) >= N_GPIO_PINS) typedef enum { GPIO_PORT_A, @@ -83,41 +80,43 @@ typedef enum { inline static gpio_port_t get_port_for_pin(gpio_pin_t pin) { switch (pin) { -#define PORT(p, pn) \ - case GPIO_PIN_P ## p ## pn: return GPIO_PORT_ ## p; +#define PORT(p, pn) \ + case GPIO_PIN_P##p##pn: \ + return GPIO_PORT_##p; #include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" #undef PORT - case N_GPIO_PINS: return N_GPIO_PORTS; + case N_GPIO_PINS: + return N_GPIO_PORTS; } /* Should be unreachable. */ } -#define DEFAULT_GPIO_OPTS_OUTPUT \ - (gpio_pin_opts_t) { \ - .mode = GPIO_MODE_OUTPUT, \ - .pull_dir = GPIO_PULL_DIR_DOWN, \ - .output_opts.speed = GPIO_OUTPUT_SPEED_MEDIUM, \ - .output_opts.type = GPIO_OUTPUT_TYPE_PUSH_PULL, \ +#define DEFAULT_GPIO_OPTS_OUTPUT \ + (gpio_pin_opts_t) \ + { \ + .mode = GPIO_MODE_OUTPUT, .pull_dir = GPIO_PULL_DIR_DOWN, \ + .output_opts.speed = GPIO_OUTPUT_SPEED_MEDIUM, \ + .output_opts.type = GPIO_OUTPUT_TYPE_PUSH_PULL, \ } -#define DEFAULT_GPIO_OPTS_INPUT \ - (gpio_pin_opts_t) { \ - .mode = GPIO_MODE_OUTPUT, \ - .pull_dir = GPIO_PULL_DIR_DOWN, \ +#define DEFAULT_GPIO_OPTS_INPUT \ + (gpio_pin_opts_t) \ + { \ + .mode = GPIO_MODE_INPUT, .pull_dir = GPIO_PULL_DIR_DOWN, \ } typedef struct { - gpio_mode_t mode; - gpio_pull_dir_t pull_dir; + gpio_mode_t mode; + gpio_pull_dir_t pull_dir; union { struct { } input_opts; struct { - gpio_output_speed_t speed; - gpio_output_type_t type; + gpio_output_speed_t speed; + gpio_output_type_t type; } output_opts; struct { @@ -171,9 +170,7 @@ gpio_reserved_pin_t reserve_gpio_pin( * */ gpio_reserved_pin_t gpio_enable_alternate_function( - gpio_alternate_function_t fn, - gpio_pin_t hint, - int* error_out); + gpio_alternate_function_t fn, gpio_pin_t hint, int* error_out); /* * Releases the GPIO pin so it can be reserved again in the future. @@ -184,4 +181,9 @@ gpio_reserved_pin_t gpio_enable_alternate_function( */ void release_gpio_pin(gpio_reserved_pin_t gpio_pin); +/* + * Returns whether the GPIO pin has high or low input. + */ +bool get_gpio_pin_input_state(gpio_reserved_pin_t pin); + #endif /* KERN_GPIO_GPIO_MANAGE_H_ */ diff --git a/include/kern/mem.h b/include/kern/mem.h index 20b09bb..bc6c4e2 100644 --- a/include/kern/mem.h +++ b/include/kern/mem.h @@ -22,6 +22,8 @@ int debug_kalloc_assert_consistency(char* error, size_t len); void debug_print_blocks(); +int debug_is_heap_empty(); + #endif diff --git a/include/shared/array_list.h b/include/shared/array_list.h new file mode 100644 index 0000000..8b942ad --- /dev/null +++ b/include/shared/array_list.h @@ -0,0 +1,105 @@ +#ifndef SHARED_ARRAY_LIST_H_ +#define SHARED_ARRAY_LIST_H_ + +#include "kern/common.h" +#include "kern/mem.h" + +#define ALLOC kalloc +#define FREE kfree + +#define array_list_t(type) array_list_##type##_t +#define array_list_new(type) array_list_##type##_new +#define array_list_length(type) array_list_##type##_length +#define array_list_reserve(type) array_list_##type##_reserve +#define array_list_add(type) array_list_##type##_add +#define array_list_remove(type) array_list_##type##remove +#define array_list_ref(type) array_list_##type##_get +#define array_list_free(type) array_list_##type##_free + +#define array_list_foreach(ar, val) \ + typeof((ar)->elements[0]) val; \ + if ((ar)->size > 0) val = (ar)->elements[0]; \ + for (size_t _idx_ = 0; _idx_ < (ar)->size; \ + val = (++_idx_) >= (ar)->size ? val : (ar)->elements[_idx_]) + +#define ARRAY_LIST_DECL(type) \ + typedef struct { \ + size_t reserved; \ + size_t size; \ + type* elements; \ + } array_list_t(type); \ + size_t array_list_length(type)(const array_list_t(type)*); \ + array_list_t(type) * array_list_new(type)(); \ + bool array_list_reserve(type)(array_list_t(type)*, size_t len); \ + bool array_list_add(type)(array_list_t(type)*, type val); \ + bool array_list_remove(type)(array_list_t(type)*, size_t idx, type * out); \ + type* array_list_ref(type)(array_list_t(type)*, size_t idx); \ + void array_list_free(type)(array_list_t(type)*); + +#define ARRAY_LIST_IMPL(type) \ + array_list_t(type) * array_list_new(type)() \ + { \ + array_list_t(type)* ret = ALLOC(sizeof(array_list_t(type))); \ + ret->size = 0; \ + ret->reserved = 0; \ + ret->elements = NULL; \ + return ret; \ + } \ + size_t array_list_length(type)(const array_list_t(type) * lst) \ + { \ + return lst->size; \ + } \ + bool array_list_reserve(type)(array_list_t(type) * lst, size_t newlen) \ + { \ + if (lst->reserved < newlen) { \ + type* new_arr = ALLOC(sizeof(type) * newlen); \ + if (!new_arr) { \ + return 0; \ + } \ + for (size_t i = 0; i < lst->size; ++i) { \ + new_arr[i] = lst->elements[i]; \ + } \ + FREE(lst->elements); \ + lst->elements = new_arr; \ + lst->reserved = newlen; \ + } \ + return 1; \ + } \ + bool array_list_add(type)(array_list_t(type) * lst, type v) \ + { \ + if (lst->size == lst->reserved) { \ + if (!array_list_reserve(type)( \ + lst, lst->reserved == 0 ? 4 : lst->reserved * 2)) { \ + return 0; \ + } \ + } \ + lst->elements[lst->size++] = v; \ + return 1; \ + } \ + bool array_list_remove(type)( \ + array_list_t(type) * lst, size_t idx, type * out) \ + { \ + if (idx >= lst->size) { \ + return 0; \ + } \ + if (out) *out = lst->elements[idx]; \ + for (size_t i = idx; i < lst->size - 1; ++i) { \ + lst->elements[i] = lst->elements[i + 1]; \ + } \ + lst->size--; \ + return 1; \ + } \ + type* array_list_ref(type)(array_list_t(type) * lst, size_t idx) \ + { \ + if (idx >= lst->size) { \ + return NULL; \ + } \ + return &lst->elements[idx]; \ + } \ + void array_list_free(type)(array_list_t(type) * lst) \ + { \ + FREE(lst->elements); \ + FREE(lst); \ + } + +#endif /* SHARED_ARRAY_LIST_H_ */ diff --git a/include/shared/avl_tree.h b/include/shared/avl_tree.h new file mode 100644 index 0000000..2b174d3 --- /dev/null +++ b/include/shared/avl_tree.h @@ -0,0 +1,270 @@ +#ifndef _SHARED_AVL_TREE_H_ +#define _SHARED_AVL_TREE_H_ + +#define ALLOC kalloc +#define FREE kfree + +#include <assert.h> +#include <stdio.h> + +#include "kern/common.h" +#include "kern/mem.h" +#include "shared/stdmacro.h" + +#define get_height(n) ((n) == NULL ? 0 : (n)->height) +#define max(a, b) ((a) < (b) ? (b) : (a)) +#define reset_height(node) \ + (node)->height = \ + (max(get_height((node)->right), get_height((node)->left)) + 1) + +#define avl_tree_t(T) CONCAT(avl_tree__, T) +#define avl_tree_node_t(T) CONCAT(avl_tree_node__, T) + +#define avl_tree_new(T) CONCAT(avl_tree_new__, T) +#define avl_tree_free(T) CONCAT(avl_tree_free__, T) +#define avl_tree_size(T) CONCAT(avl_tree_size__, T) +#define avl_tree_insert(T) CONCAT(avl_tree_insert__, T) +#define avl_tree_find(T) CONCAT(avl_tree_find__, T) +#define avl_tree_erase(T) CONCAT(avl_tree_erase__, T) +#define avl_tree_height(T) CONCAT(avl_tree_height__, T) + +#define null_dtor(a) + +#define AVL_TREE_DECL(T) \ + typedef struct CONCAT(AVL_TREE_NODE_, T) { \ + T value; \ + size_t height; \ + struct CONCAT(AVL_TREE_NODE_, T) * left; \ + struct CONCAT(AVL_TREE_NODE_, T) * right; \ + } avl_tree_node_t(T); \ + \ + typedef struct { \ + avl_tree_node_t(T) * root; \ + } avl_tree_t(T); \ + \ + size_t avl_tree_height(T)(avl_tree_t(T) * tree); \ + avl_tree_t(T) * avl_tree_new(T)(); \ + void avl_tree_free(T)(avl_tree_t(T) * tree); \ + size_t avl_tree_size(T)(const avl_tree_t(T) * avl_tree); \ + T* avl_tree_insert(T)(avl_tree_t(T) * avl_tree, T value); \ + T* avl_tree_find(T)(const avl_tree_t(T)*, T val); \ + bool avl_tree_erase(T)(avl_tree_t(T) * tree, T val, T * out); + +#define AVL_TREE_IMPL(T, CMP, DTOR) \ + avl_tree_t(T) * avl_tree_new(T)() \ + { \ + avl_tree_t(T)* ret = ALLOC(sizeof(avl_tree_t(T))); \ + ret->root = NULL; \ + return ret; \ + } \ + static void CONCAT(avl_loose_free__, T)(avl_tree_node_t(T) * node) \ + { \ + if (!node) return; \ + CONCAT(avl_loose_free__, T)(node->right); |