Advertisement
Guest User

Stm32tmp/pin.h

a guest
Mar 3rd, 2016
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.02 KB | None | 0 0
  1. /**
  2. *  GPIO pin manipulation class template for STM32.
  3. *
  4. *  Copyright (c) 2009-2012Anton Gusev aka AHTOXA (HTTP://AHTOXA.NET)
  5. *
  6. *  Inspired by AVR macros from Askold Volkov
  7. *
  8. *
  9. * USAGE:
  10. *
  11. *   I. Declare pin typedef:
  12. * typedef Pin<'A', 5, 'H'> PA5;    // PA5, active level = high
  13. * typedef Pin<'A', 6> PA6;         // PA6, active level = high ('H' is default parameter)
  14. * typedef Pin<'B', 12, 'L'> PB12;  // PB12, active level = low
  15. *
  16. *   II. Set pin mode:
  17. * PA5::Mode(OUTPUT);       // configure PA5 as output (push-pull, 50MHz)
  18. * PA5::Direct(OUTPUT);     // the same.
  19. * PA6::Mode(INPUT);        // configure PA6 as input floating (use object and "." notation)
  20. * PB12::Mode(OUTPUT);      // configure PB12 as output
  21. * TX::Mode(ALT_OUTPUT);    // configure TX as alternate output push-pull
  22. *                          // (see "direction" enum for list of all pin modes)
  23. *
  24. *   III. Manipulate pin:
  25. * PA5::On();               // switch PA5 to active state (H)
  26. * PB12::On();              // switch PB12 to active state (L)
  27. * PA5::Off();              // switch PA5 to inactive state (L)
  28. * PB12::Cpl();             // invert PB12 output
  29. *
  30. *   IV. Check pin state:
  31. * if (PA5::Signalled())     // returns non-zero if pin input = active state (H for PA5)
  32. * if (PB12::Latched())      // returns non-zero if pin output = active state (L for PB12)
  33. *
  34. *   V. Use pin registers uniformly:
  35. * locked = PA5::GPIOx->LCKR & PA5::mask; // read PA5 lock state.
  36. *
  37. *   It is also possible to declare object of defined type:
  38. * PA5 PinA5;
  39. * In this case, one can use "dot" notation to call object functions, i.e.
  40. * PinA5.On();
  41. * PB12.Mode(INPUT);
  42. * Note : using objects instead of types can (in some cases) increase memory consumption.
  43. *
  44. *
  45. *  Public domain, AS IS.
  46. *
  47. */
  48.  
  49. #ifndef PIN_H_INCLUDED
  50. #define PIN_H_INCLUDED
  51. #include "stm32f10x.h"
  52. #include <stddef.h>
  53.  
  54. #define     MAKE_PIN_CFG(MODE, CNF) ( (MODE) | (CNF)<<2 )
  55.  
  56. enum direction
  57. {
  58.     ANALOGINPUT =           MAKE_PIN_CFG ( 0, 0 ),
  59.     INPUT =                 MAKE_PIN_CFG ( 0, 1 ),
  60.     INPUTPULLED =           MAKE_PIN_CFG ( 0, 2 ),
  61.  
  62.     OUTPUT_10MHZ =          MAKE_PIN_CFG ( 1, 0 ),
  63.     OUTPUT_OD_10MHZ =       MAKE_PIN_CFG ( 1, 1 ),
  64.     ALT_OUTPUT_10MHZ =      MAKE_PIN_CFG ( 1, 2 ),
  65.     ALT_OUTPUT_OD_10MHZ =   MAKE_PIN_CFG ( 1, 3 ),
  66.  
  67.     OUTPUT_2MHZ =           MAKE_PIN_CFG ( 2, 0 ),
  68.     OUTPUT_OD_2MHZ =        MAKE_PIN_CFG ( 2, 1 ),
  69.     ALT_OUTPUT_2MHZ =       MAKE_PIN_CFG ( 2, 2 ),
  70.     ALT_OUTPUT_OD_2MHZ =    MAKE_PIN_CFG ( 2, 3 ),
  71.  
  72.     OUTPUT =                MAKE_PIN_CFG ( 3, 0 ),
  73.     OUTPUT_OD =             MAKE_PIN_CFG ( 3, 1 ),
  74.     ALT_OUTPUT =            MAKE_PIN_CFG ( 3, 2 ),
  75.     ALT_OUTPUT_OD =         MAKE_PIN_CFG ( 3, 3 )
  76. };
  77.  
  78. #undef MAKE_PIN_CFG
  79.  
  80. template<char port> struct port_gpio_t;
  81.  
  82. template<> struct port_gpio_t<'A'>
  83. {
  84.     enum { GPIOx_BASE = GPIOA_BASE };
  85. };
  86.  
  87. template<> struct port_gpio_t<'B'>
  88. {
  89.     enum { GPIOx_BASE = GPIOB_BASE };
  90. };
  91.  
  92. template<> struct port_gpio_t<'C'>
  93. {
  94.     enum { GPIOx_BASE = GPIOC_BASE };
  95. };
  96.  
  97. template<> struct port_gpio_t<'D'>
  98. {
  99.     enum { GPIOx_BASE = GPIOD_BASE };
  100. };
  101.  
  102. template<> struct port_gpio_t<'E'>
  103. {
  104.     enum { GPIOx_BASE = GPIOE_BASE };
  105. };
  106.  
  107. template<> struct port_gpio_t<'F'>
  108. {
  109.     enum { GPIOx_BASE = GPIOF_BASE };
  110. };
  111.  
  112. template<> struct port_gpio_t<'G'>
  113. {
  114.     enum { GPIOx_BASE = GPIOG_BASE };
  115. };
  116.  
  117. template<char port, int pin_no, char activestate = 'H'> struct Pin;
  118.  
  119. template<char port, int pin_no, char activestate>
  120. struct Pin
  121. {
  122.     enum { GPIOx_BASE = port_gpio_t<port>::GPIOx_BASE };
  123.     enum { IDR_BB_ADDR = PERIPH_BB_BASE + (GPIOx_BASE + offsetof(GPIO_TypeDef, IDR) - PERIPH_BASE) * 32 + pin_no * 4 };
  124.     enum { ODR_BB_ADDR = PERIPH_BB_BASE + (GPIOx_BASE + offsetof(GPIO_TypeDef, ODR) - PERIPH_BASE) * 32 + pin_no * 4 };
  125.     static struct
  126.     {
  127.         GPIO_TypeDef* operator-> () { return (GPIO_TypeDef*)GPIOx_BASE; }
  128.     }GPIOx;
  129.  
  130.  
  131.     static struct{
  132.         uint32_t operator=(uint32_t value){
  133.             pin_no < 8 ? GPIOx->CRL = value :
  134.             GPIOx->CRH = value;
  135.             return value;
  136.         }
  137.         void operator|=(uint32_t value){
  138.             pin_no < 8 ? GPIOx->CRL |= value :
  139.             GPIOx->CRH |= value;
  140.         }
  141.         void operator&=(uint32_t value){
  142.             pin_no < 8 ? GPIOx->CRL &= value :
  143.             GPIOx->CRH &= value;
  144.         }
  145.         operator uint32_t(){
  146.             return pin_no < 8 ? GPIOx->CRL :
  147.             GPIOx->CRH;
  148.         }
  149.     }CRx;
  150.  
  151.     static const int pin = pin_no;
  152.     static const int port_no = port-'A';
  153.     static const uint32_t mask = 1UL << pin_no;
  154.     static const uint32_t shift = (pin_no % 8) << 2;
  155.  
  156.     // IRQn for NVIC_SetPriority, NVIC_EnableIRQ etc
  157.     static const IRQn_Type ext_irqn =
  158.         (pin_no == 0)                    ? EXTI0_IRQn :
  159.         (pin_no == 1)                    ? EXTI1_IRQn :
  160.         (pin_no == 2)                    ? EXTI2_IRQn :
  161.         (pin_no == 3)                    ? EXTI3_IRQn :
  162.         (pin_no == 4)                    ? EXTI4_IRQn :
  163.         (pin_no >= 5) && (pin_no <= 9)   ? EXTI9_5_IRQn :
  164.         (pin_no >= 10) && (pin_no <= 15) ? EXTI15_10_IRQn :
  165.         IRQn(0);
  166.  
  167.     static void On()
  168.     {
  169.         activestate == 'L' ? GPIOx->BRR = mask : GPIOx->BSRR = mask;
  170.     }
  171.     static void Off()
  172.     {
  173.         activestate == 'L' ? GPIOx->BSRR = mask : GPIOx->BRR = mask;
  174.     }
  175.     static void Cpl()
  176.     {
  177.         *(volatile uint32_t *)ODR_BB_ADDR = ~*(volatile uint32_t *)ODR_BB_ADDR;
  178.     }
  179.  
  180.     static void Mode(direction dir)
  181.     {
  182.         CRx = (CRx & ~(0x0F<<shift)) | (dir<<shift);
  183.     }
  184.     static void Direct(direction dir)
  185.     {
  186.         CRx = (CRx & ~(0x0F<<shift)) | (dir<<shift);
  187.     }
  188.     static void PullUp() { GPIOx->BSRR = mask; }
  189.     static void PullDown() { GPIOx->BRR = mask; }
  190.  
  191.     static int Latched()
  192.     {
  193.         int ret = *(volatile uint32_t *)ODR_BB_ADDR;
  194.         return activestate == 'L' ? !ret : ret;
  195.     }
  196.  
  197.     static int Signalled()
  198.     {
  199.         int ret = *(volatile uint32_t *)IDR_BB_ADDR;
  200.         return activestate == 'L' ? !ret : ret;
  201.     }
  202.  
  203.     static void AssignPinExtInt()
  204.     {
  205.         static const uint32_t shft = (pin_no % 4) * 4;
  206.         static const uint32_t EXTICRi = pin_no / 4;
  207.         AFIO->EXTICR[EXTICRi] = (AFIO->EXTICR[EXTICRi] & ~(0xF << shft)) | (port_no << shft);
  208.     }
  209.  
  210.     static void EnablePinExtInt(bool raise, bool fall)
  211.     {
  212.         EXTI->IMR = (EXTI->IMR & ~mask) | (raise || fall ? mask : 0);
  213.         EXTI->RTSR = (EXTI->RTSR & ~mask) | (raise ? mask : 0);
  214.         EXTI->FTSR = (EXTI->FTSR & ~mask) | (fall ? mask : 0);
  215.     }
  216. };
  217.  
  218. #endif // PIN_H_INCLUDED
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement