PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 satır
5.6KB

  1. // ArduinoCompat/HardwareSPI.cpp
  2. //
  3. // Interface between Arduino-like SPI interface and STM32F4 Discovery and similar
  4. // using STM32F4xx_DSP_StdPeriph_Lib_V1.3.0
  5. #include <RadioHead.h>
  6. #if (RH_PLATFORM == RH_PLATFORM_STM32STD)
  7. #include <wirish.h>
  8. #include <HardwareSPI.h>
  9. #include "stm32f4xx.h"
  10. #include "stm32f4xx_spi.h"
  11. extern "C"
  12. {
  13. #include "gdb_stdio.h"
  14. }
  15. // Symbolic definitions for the SPI pins we intend to use
  16. // Currently we only support SPI1
  17. #define SPIx SPI1
  18. #define SPIx_CLK RCC_APB2Periph_SPI1
  19. #define SPIx_CLK_INIT RCC_APB2PeriphClockCmd
  20. #define SPIx_IRQn SPI2_IRQn
  21. #define SPIx_IRQHANDLER SPI2_IRQHandler
  22. #define SPIx_SCK_PIN GPIO_Pin_5
  23. #define SPIx_SCK_GPIO_PORT GPIOA
  24. #define SPIx_SCK_GPIO_CLK RCC_AHB1Periph_GPIOA
  25. #define SPIx_SCK_SOURCE GPIO_PinSource5
  26. #define SPIx_SCK_AF GPIO_AF_SPI1
  27. #define SPIx_MISO_PIN GPIO_Pin_6
  28. #define SPIx_MISO_GPIO_PORT GPIOA
  29. #define SPIx_MISO_GPIO_CLK RCC_AHB1Periph_GPIOA
  30. #define SPIx_MISO_SOURCE GPIO_PinSource6
  31. #define SPIx_MISO_AF GPIO_AF_SPI1
  32. #define SPIx_MOSI_PIN GPIO_Pin_7
  33. #define SPIx_MOSI_GPIO_PORT GPIOA
  34. #define SPIx_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOA
  35. #define SPIx_MOSI_SOURCE GPIO_PinSource7
  36. #define SPIx_MOSI_AF GPIO_AF_SPI1
  37. HardwareSPI::HardwareSPI(uint32_t spiPortNumber) :
  38. _spiPortNumber(spiPortNumber)
  39. {
  40. }
  41. void HardwareSPI::begin(SPIFrequency frequency, uint32_t bitOrder, uint32_t mode)
  42. {
  43. GPIO_InitTypeDef GPIO_InitStructure;
  44. // NVIC_InitTypeDef NVIC_InitStructure;
  45. SPI_InitTypeDef SPI_InitStructure;
  46. /* Peripheral Clock Enable -------------------------------------------------*/
  47. /* Enable the SPI clock */
  48. RCC_APB2PeriphClockCmd(SPIx_CLK, ENABLE);
  49. /* Enable GPIO clocks */
  50. RCC_AHB1PeriphClockCmd(SPIx_SCK_GPIO_CLK | SPIx_MISO_GPIO_CLK | SPIx_MOSI_GPIO_CLK, ENABLE);
  51. /* SPI GPIO Configuration --------------------------------------------------*/
  52. /* GPIO Deinitialisation */
  53. GPIO_DeInit(SPIx_SCK_GPIO_PORT);
  54. GPIO_DeInit(SPIx_MISO_GPIO_PORT);
  55. GPIO_DeInit(SPIx_MOSI_GPIO_PORT);
  56. /* Connect SPI pins to AF5 */
  57. GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF);
  58. GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF);
  59. GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF);
  60. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  61. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  62. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  63. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
  64. /* SPI SCK pin configuration */
  65. GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN;
  66. GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStructure);
  67. /* SPI MISO pin configuration */
  68. GPIO_InitStructure.GPIO_Pin = SPIx_MISO_PIN;
  69. GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStructure);
  70. /* SPI MOSI pin configuration */
  71. GPIO_InitStructure.GPIO_Pin = SPIx_MOSI_PIN;
  72. GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure);
  73. /* SPI configuration -------------------------------------------------------*/
  74. SPI_I2S_DeInit(SPIx);
  75. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  76. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  77. if (mode == SPI_MODE0)
  78. {
  79. SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  80. SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  81. }
  82. else if (mode == SPI_MODE1)
  83. {
  84. SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  85. SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  86. }
  87. else if (mode == SPI_MODE2)
  88. {
  89. SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  90. SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  91. }
  92. else if (mode == SPI_MODE3)
  93. {
  94. SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  95. SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  96. }
  97. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  98. // Prescaler is divided into PCLK2 (84MHz) to get SPI baud rate/clock speed
  99. // 256 => 328.125kHz
  100. // 128 => 656.25kHz
  101. // 64 => 1.3125MHz
  102. // 32 => 2.625MHz
  103. // 16 => 5.25MHz
  104. // 8 => 10.5MHz
  105. // 4 => 21.0MHz
  106. switch (frequency)
  107. {
  108. case SPI_21_0MHZ:
  109. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  110. break;
  111. case SPI_10_5MHZ:
  112. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
  113. break;
  114. case SPI_5_25MHZ:
  115. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
  116. break;
  117. case SPI_2_625MHZ:
  118. default:
  119. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
  120. break;
  121. case SPI_1_3125MHZ:
  122. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
  123. break;
  124. case SPI_656_25KHZ:
  125. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
  126. break;
  127. case SPI_328_125KHZ:
  128. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  129. break;
  130. }
  131. if (bitOrder == LSBFIRST)
  132. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;
  133. else
  134. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  135. SPI_InitStructure.SPI_CRCPolynomial = 7;
  136. SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  137. /* Initializes the SPI communication */
  138. SPI_Init(SPIx, &SPI_InitStructure);
  139. /* Enable SPI1 */
  140. SPI_Cmd(SPIx, ENABLE);
  141. }
  142. void HardwareSPI::end(void)
  143. {
  144. SPI_DeInit(SPIx);
  145. }
  146. uint8_t HardwareSPI::transfer(uint8_t data)
  147. {
  148. // Wait for TX empty
  149. while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)
  150. ;
  151. SPI_SendData(SPIx, data);
  152. // Wait for RX not empty
  153. while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET)
  154. ;
  155. return SPI_ReceiveData(SPIx);
  156. }
  157. #endif