Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
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.
 
 
 
 
 
 

166 lines
5.0 KiB

  1. /*!
  2. * \file spi-board.c
  3. *
  4. * \brief Target board SPI driver implementation
  5. *
  6. * \copyright Revised BSD License, see section \ref LICENSE.
  7. *
  8. * \code
  9. * ______ _
  10. * / _____) _ | |
  11. * ( (____ _____ ____ _| |_ _____ ____| |__
  12. * \____ \| ___ | (_ _) ___ |/ ___) _ \
  13. * _____) ) ____| | | || |_| ____( (___| | | |
  14. * (______/|_____)_|_|_| \__)_____)\____)_| |_|
  15. * (C)2013-2017 Semtech
  16. *
  17. * \endcode
  18. *
  19. * \author Miguel Luis ( Semtech )
  20. *
  21. * \author Gregory Cristian ( Semtech )
  22. */
  23. #include "stm32l0xx.h"
  24. #include "utilities.h"
  25. #include "board.h"
  26. #include "gpio.h"
  27. #include "spi-board.h"
  28. static SPI_HandleTypeDef SpiHandle[2];
  29. void SpiInit( Spi_t *obj, SpiId_t spiId, PinNames mosi, PinNames miso, PinNames sclk, PinNames nss )
  30. {
  31. CRITICAL_SECTION_BEGIN( );
  32. obj->SpiId = spiId;
  33. if( spiId == SPI_1 )
  34. {
  35. __HAL_RCC_SPI1_FORCE_RESET( );
  36. __HAL_RCC_SPI1_RELEASE_RESET( );
  37. __HAL_RCC_SPI1_CLK_ENABLE( );
  38. SpiHandle[spiId].Instance = ( SPI_TypeDef* )SPI1_BASE;
  39. GpioInit( &obj->Mosi, mosi, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_DOWN, GPIO_AF0_SPI1 );
  40. GpioInit( &obj->Miso, miso, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_DOWN, GPIO_AF0_SPI1 );
  41. GpioInit( &obj->Sclk, sclk, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_DOWN, GPIO_AF0_SPI1 );
  42. GpioInit( &obj->Nss, nss, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_UP, GPIO_AF0_SPI1 );
  43. }
  44. else
  45. {
  46. __HAL_RCC_SPI2_FORCE_RESET( );
  47. __HAL_RCC_SPI2_RELEASE_RESET( );
  48. __HAL_RCC_SPI2_CLK_ENABLE( );
  49. SpiHandle[spiId].Instance = ( SPI_TypeDef* )SPI2_BASE;
  50. GpioInit( &obj->Mosi, mosi, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_DOWN, GPIO_AF0_SPI2 );
  51. GpioInit( &obj->Miso, miso, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_DOWN, GPIO_AF0_SPI2 );
  52. GpioInit( &obj->Sclk, sclk, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_DOWN, GPIO_AF0_SPI2 );
  53. GpioInit( &obj->Nss, nss, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_UP, GPIO_AF0_SPI2 );
  54. }
  55. if( nss == NC )
  56. {
  57. SpiHandle[spiId].Init.NSS = SPI_NSS_SOFT;
  58. SpiFormat( obj, SPI_DATASIZE_8BIT, SPI_POLARITY_LOW, SPI_PHASE_1EDGE, 0 );
  59. }
  60. else
  61. {
  62. SpiFormat( obj, SPI_DATASIZE_8BIT, SPI_POLARITY_LOW, SPI_PHASE_1EDGE, 1 );
  63. }
  64. SpiFrequency( obj, 10000000 );
  65. HAL_SPI_Init( &SpiHandle[spiId] );
  66. CRITICAL_SECTION_END( );
  67. }
  68. void SpiDeInit( Spi_t *obj )
  69. {
  70. HAL_SPI_DeInit( &SpiHandle[obj->SpiId] );
  71. GpioInit( &obj->Mosi, obj->Mosi.pin, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  72. GpioInit( &obj->Miso, obj->Miso.pin, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_DOWN, 0 );
  73. GpioInit( &obj->Sclk, obj->Sclk.pin, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  74. GpioInit( &obj->Nss, obj->Nss.pin, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 1 );
  75. }
  76. void SpiFormat( Spi_t *obj, int8_t bits, int8_t cpol, int8_t cpha, int8_t slave )
  77. {
  78. SpiHandle[obj->SpiId].Init.Direction = SPI_DIRECTION_2LINES;
  79. if( bits == SPI_DATASIZE_8BIT )
  80. {
  81. SpiHandle[obj->SpiId].Init.DataSize = SPI_DATASIZE_8BIT;
  82. }
  83. else
  84. {
  85. SpiHandle[obj->SpiId].Init.DataSize = SPI_DATASIZE_16BIT;
  86. }
  87. SpiHandle[obj->SpiId].Init.CLKPolarity = cpol;
  88. SpiHandle[obj->SpiId].Init.CLKPhase = cpha;
  89. SpiHandle[obj->SpiId].Init.FirstBit = SPI_FIRSTBIT_MSB;
  90. SpiHandle[obj->SpiId].Init.TIMode = SPI_TIMODE_DISABLE;
  91. SpiHandle[obj->SpiId].Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  92. SpiHandle[obj->SpiId].Init.CRCPolynomial = 7;
  93. if( slave == 0 )
  94. {
  95. SpiHandle[obj->SpiId].Init.Mode = SPI_MODE_MASTER;
  96. }
  97. else
  98. {
  99. SpiHandle[obj->SpiId].Init.Mode = SPI_MODE_SLAVE;
  100. }
  101. }
  102. void SpiFrequency( Spi_t *obj, uint32_t hz )
  103. {
  104. uint32_t divisor = 0;
  105. uint32_t sysClkTmp = SystemCoreClock;
  106. uint32_t baudRate;
  107. while( sysClkTmp > hz )
  108. {
  109. divisor++;
  110. sysClkTmp = ( sysClkTmp >> 1 );
  111. if( divisor >= 7 )
  112. {
  113. break;
  114. }
  115. }
  116. baudRate =( ( ( divisor & 0x4 ) == 0 ) ? 0x0 : SPI_CR1_BR_2 ) |
  117. ( ( ( divisor & 0x2 ) == 0 ) ? 0x0 : SPI_CR1_BR_1 ) |
  118. ( ( ( divisor & 0x1 ) == 0 ) ? 0x0 : SPI_CR1_BR_0 );
  119. SpiHandle[obj->SpiId].Init.BaudRatePrescaler = baudRate;
  120. }
  121. uint16_t SpiInOut( Spi_t *obj, uint16_t outData )
  122. {
  123. uint8_t rxData = 0;
  124. if( ( obj == NULL ) || ( SpiHandle[obj->SpiId].Instance ) == NULL )
  125. {
  126. assert_param( LMN_STATUS_ERROR );
  127. }
  128. __HAL_SPI_ENABLE( &SpiHandle[obj->SpiId] );
  129. CRITICAL_SECTION_BEGIN( );
  130. while( __HAL_SPI_GET_FLAG( &SpiHandle[obj->SpiId], SPI_FLAG_TXE ) == RESET );
  131. SpiHandle[obj->SpiId].Instance->DR = ( uint16_t ) ( outData & 0xFF );
  132. while( __HAL_SPI_GET_FLAG( &SpiHandle[obj->SpiId], SPI_FLAG_RXNE ) == RESET );
  133. rxData = ( uint16_t ) SpiHandle[obj->SpiId].Instance->DR;
  134. CRITICAL_SECTION_END( );
  135. return( rxData );
  136. }