/platform/spark/firmware/wiring/inc/fast_pin.h

https://github.com/BrewPi/firmware · C Header · 166 lines · 94 code · 34 blank · 38 comment · 4 complexity · b5c2758aff1eed1427a7b58a266faa95 MD5 · raw file

  1. /*
  2. ******************************************************************************
  3. * Copyright (c) 2015 Particle Industries, Inc. All rights reserved.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation, either
  8. * version 3 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  17. ******************************************************************************
  18. */
  19. #ifndef FAST_PIN_H
  20. #define FAST_PIN_H
  21. #include "platforms.h"
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. #include "pinmap_hal.h"
  26. /* Disabling USE_BIT_BAND since bitbanding is much slower! as per comment
  27. * by @pkourany on PR: https://github.com/spark/firmware/pull/556 */
  28. #define USE_BIT_BAND 0
  29. #if USE_BIT_BAND
  30. /* Use CortexM3 Bit-Band access to perform GPIO atomic read-modify-write */
  31. //Below is defined in stm32fxxx.h
  32. //PERIPH_BASE = 0x40000000 /* Peripheral base address in the alias region */
  33. //PERIPH_BB_BASE = 0x42000000 /* Peripheral base address in the bit-band region */
  34. /* A mapping formula shows how to reference each word in the alias region to a
  35. corresponding bit in the bit-band region. The mapping formula is:
  36. bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number + 4)
  37. where:
  38. - bit_word_addr: is the address of the word in the alias memory region that
  39. maps to the targeted bit.
  40. - bit_band_base is the starting address of the alias region
  41. - byte_offset is the number of the byte in the bit-band region that contains
  42. the targeted bit
  43. - bit_number is the bit position of the targeted bit
  44. */
  45. #define GPIO_ResetBit_BB(Addr, Bit) \
  46. (*(__IO uint32_t *) (PERIPH_BB_BASE | ((Addr - PERIPH_BASE) << 5) | ((Bit) << 2)) = 0)
  47. #define GPIO_SetBit_BB(Addr, Bit) \
  48. (*(__IO uint32_t *) (PERIPH_BB_BASE | ((Addr - PERIPH_BASE) << 5) | ((Bit) << 2)) = 1)
  49. #define GPIO_GetBit_BB(Addr, Bit) \
  50. (*(__IO uint32_t *) (PERIPH_BB_BASE | ((Addr - PERIPH_BASE) << 5) | ((Bit) << 2)))
  51. static STM32_Pin_Info* pin_map = HAL_Pin_Map();
  52. inline void pinSetFast(pin_t _pin) __attribute__((always_inline));
  53. inline void pinResetFast(pin_t _pin) __attribute__((always_inline));
  54. inline int32_t pinReadFast(pin_t _pin) __attribute__((always_inline));
  55. inline void pinSetFast(pin_t _pin)
  56. {
  57. GPIO_SetBit_BB((__IO uint32_t)&pin_map[_pin].gpio_peripheral->ODR, pin_map[_pin].gpio_pin_source);
  58. }
  59. inline void pinResetFast(pin_t _pin)
  60. {
  61. GPIO_ResetBit_BB((__IO uint32_t)&pin_map[_pin].gpio_peripheral->ODR, pin_map[_pin].gpio_pin_source);
  62. }
  63. inline int32_t pinReadFast(pin_t _pin)
  64. {
  65. return GPIO_GetBit_BB((__IO uint32_t)&pin_map[_pin].gpio_peripheral->IDR, pin_map[_pin].gpio_pin_source);
  66. }
  67. #else
  68. #ifndef STM32F10X
  69. #if defined(STM32F10X_MD) || defined(STM32F10X_HD)
  70. #define STM32F10X
  71. #endif
  72. #endif
  73. #ifdef STM32F10X
  74. inline void pinSetFast(pin_t _pin) __attribute__((always_inline));
  75. inline void pinResetFast(pin_t _pin) __attribute__((always_inline));
  76. inline int32_t pinReadFast(pin_t _pin) __attribute__((always_inline));
  77. inline void pinSetFast(pin_t _pin)
  78. {
  79. PIN_MAP[_pin].gpio_peripheral->BSRR = PIN_MAP[_pin].gpio_pin;
  80. }
  81. inline void pinResetFast(pin_t _pin)
  82. {
  83. PIN_MAP[_pin].gpio_peripheral->BRR = PIN_MAP[_pin].gpio_pin;
  84. }
  85. inline int32_t pinReadFast(pin_t _pin)
  86. {
  87. return ((PIN_MAP[_pin].gpio_peripheral->IDR & PIN_MAP[_pin].gpio_pin) == 0 ? LOW : HIGH);
  88. }
  89. #elif defined(STM32F2XX)
  90. static STM32_Pin_Info* PIN_MAP = HAL_Pin_Map();
  91. inline void pinSetFast(pin_t _pin) __attribute__((always_inline));
  92. inline void pinResetFast(pin_t _pin) __attribute__((always_inline));
  93. inline int32_t pinReadFast(pin_t _pin) __attribute__((always_inline));
  94. inline void pinSetFast(pin_t _pin)
  95. {
  96. PIN_MAP[_pin].gpio_peripheral->BSRRL = PIN_MAP[_pin].gpio_pin;
  97. }
  98. inline void pinResetFast(pin_t _pin)
  99. {
  100. PIN_MAP[_pin].gpio_peripheral->BSRRH = PIN_MAP[_pin].gpio_pin;
  101. }
  102. inline int32_t pinReadFast(pin_t _pin)
  103. {
  104. return ((PIN_MAP[_pin].gpio_peripheral->IDR & PIN_MAP[_pin].gpio_pin) == 0 ? LOW : HIGH);
  105. }
  106. #elif PLATFORM_ID==3
  107. // make them unresolved symbols so attempted use will result in a linker error
  108. void pinResetFast(pin_t _pin);
  109. void pinSetFast(pin_t _pin);
  110. void pinReadFast(pin_t _pin);
  111. #elif PLATFORM_ID==PLATFORM_NEWHAL
  112. // no need to generate a warning for newhal
  113. #define pinSetFast(pin) digitalWrite(pin, HIGH)
  114. #define pinResetFast(pin) digitalWrite(pin, LOW)
  115. #else
  116. #warning "*** MCU architecture not supported by the fastPin library. ***"
  117. #define pinSetFast(pin) digitalWrite(pin, HIGH)
  118. #define pinResetFast(pin) digitalWrite(pin, LOW)
  119. #endif
  120. #endif //USE_BIT_BAND
  121. inline void digitalWriteFast(pin_t pin, uint8_t value)
  122. {
  123. if (value)
  124. pinSetFast(pin);
  125. else
  126. pinResetFast(pin);
  127. }
  128. #ifdef __cplusplus
  129. }
  130. #endif
  131. #endif /* FAST_PIN_H */