Brian Silverman | aa9183a | 2013-12-08 10:33:47 -0800 | [diff] [blame] | 1 | #ifndef CAPE_UTIL_H_ |
| 2 | #define CAPE_UTIL_H_ |
| 3 | |
Brian Silverman | 391beca | 2013-12-28 22:32:48 -0800 | [diff] [blame] | 4 | #include <stdint.h> |
| 5 | |
Brian Silverman | 1b6fbd0 | 2013-12-12 18:08:47 -0800 | [diff] [blame] | 6 | #include <STM32F2XX.h> |
| 7 | |
Brian Silverman | aa9183a | 2013-12-08 10:33:47 -0800 | [diff] [blame] | 8 | #define ALIAS_WEAK(f) __attribute__ ((weak, alias (#f))) |
| 9 | |
Brian Silverman | 2df8441 | 2013-12-10 14:00:40 -0800 | [diff] [blame] | 10 | // MSG has to be separated_with_spaces. |
| 11 | #define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(!!(COND))*2-1] |
| 12 | |
Brian Silverman | aa9183a | 2013-12-08 10:33:47 -0800 | [diff] [blame] | 13 | // Prevents the compiler from reordering memory operations around this. |
| 14 | static inline void compiler_memory_barrier(void) { |
| 15 | __asm__ __volatile__("" ::: "memory"); |
| 16 | } |
| 17 | |
Brian Silverman | 25a06d9 | 2013-12-15 16:28:52 -0800 | [diff] [blame] | 18 | // Count leading zeros. |
| 19 | // Returns 0 if bit 31 is set etc. |
| 20 | __attribute__((always_inline)) static __INLINE uint32_t __clz(uint32_t value) { |
| 21 | uint32_t result; |
| 22 | __asm__("clz %0, %1" : "=r" (result) : "r" (value)); |
| 23 | return result; |
| 24 | } |
| 25 | |
Brian Silverman | 1b6fbd0 | 2013-12-12 18:08:47 -0800 | [diff] [blame] | 26 | // Sets number_of_bits (shifted left shift number of slots) to value in |
| 27 | // variable. |
| 28 | // This means that the total shift is number_bits*shift. |
| 29 | #define SET_BITS(variable, number_bits, value, shift) do { \ |
| 30 | variable = (((variable) & \ |
| 31 | ~(((1 << (number_bits)) - 1) << (shift * (number_bits)))) | \ |
| 32 | ((value) << (shift * (number_bits)))); \ |
| 33 | } while (0); |
| 34 | |
| 35 | // A convenient way to set up a GPIO pin for some alternate function without |
| 36 | // missing part or messing up which bits need setting to what. |
| 37 | // pin is the 0-indexed pin number. |
| 38 | // afr is 0-0xF for the various alternate functions. |
| 39 | static inline void gpio_setup_alt(GPIO_TypeDef *port, int pin, int afr) { |
| 40 | SET_BITS(port->MODER, 2, 2 /* alternate function */, pin); |
| 41 | if (pin < 8) { |
| 42 | SET_BITS(port->AFR[0], 4, afr, pin); |
| 43 | } else { |
| 44 | SET_BITS(port->AFR[1], 4, afr, (pin - 8)); |
| 45 | } |
| 46 | } |
| 47 | |
Brian Silverman | 18b0164 | 2013-12-13 21:12:25 -0800 | [diff] [blame] | 48 | // A convenient way to set up a GPIO pin for output (push-pull) without missing |
| 49 | // part or messing up which bits need setting to what. |
| 50 | // speed is 0 (slow) to 3 (fast) |
| 51 | static inline void gpio_setup_out(GPIO_TypeDef *port, int pin, int speed) { |
| 52 | SET_BITS(port->MODER, 2, 1 /* output */, pin); |
| 53 | SET_BITS(port->OSPEEDR, 2, speed, pin); |
| 54 | } |
| 55 | |
Brian Silverman | 391beca | 2013-12-28 22:32:48 -0800 | [diff] [blame] | 56 | static inline void gpio_setup_in(GPIO_TypeDef *port, int pin) { |
| 57 | SET_BITS(port->MODER, 2, 0 /* input */, pin); |
| 58 | } |
| 59 | |
Brian Silverman | 04fac62 | 2014-01-26 18:32:15 -0800 | [diff] [blame] | 60 | // dir: 0 => none, 1 => up, 2 => down |
| 61 | static inline void gpio_set_pupd(GPIO_TypeDef *port, int pin, int dir) { |
| 62 | SET_BITS(port->PUPDR, 2, dir, pin); |
| 63 | } |
| 64 | |
Brian Silverman | 25a06d9 | 2013-12-15 16:28:52 -0800 | [diff] [blame] | 65 | // exti is which EXTI line to set |
| 66 | // port is 0 for A, 1 for B, etc |
| 67 | static inline void EXTI_set(int exti, int port) { |
| 68 | SET_BITS(SYSCFG->EXTICR[exti / 4], 4, port, exti % 4); |
| 69 | } |
| 70 | |
Brian Silverman | 391beca | 2013-12-28 22:32:48 -0800 | [diff] [blame] | 71 | static inline void gpio_on(GPIO_TypeDef *port, int pin) { |
| 72 | port->BSRRL = 1 << pin; |
| 73 | } |
| 74 | |
| 75 | static inline void gpio_off(GPIO_TypeDef *port, int pin) { |
| 76 | port->BSRRH = 1 << pin; |
| 77 | } |
| 78 | |
| 79 | void led_write(uint32_t value, int bits); |
| 80 | |
Brian Silverman | aa9183a | 2013-12-08 10:33:47 -0800 | [diff] [blame] | 81 | #endif // CAPE_UTIL_H_ |