portserial.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "port.h"
  2. #include "main.h"
  3. #include "cmsis_os2.h"
  4. /* ----------------------- Modbus includes ----------------------------------*/
  5. #include "mb.h"
  6. #include "mbport.h"
  7. /* ----------------------- Static variables ---------------------------------*/
  8. static volatile uint8_t rx_buff[256];
  9. static int rx_index;
  10. static int put_index;
  11. static osThreadId_t receiveDataHandle;
  12. static osEventFlagsId_t xSerialEventHandle;
  13. extern UART_HandleTypeDef huart3;
  14. /* ----------------------- Defines ------------------------------------------*/
  15. #define EVENT_MBSLAVE_HANDLE_RECEIVED_DATA 0x00000001UL
  16. #define huart huart3
  17. #define RS485_SLAVE_TX_MODE() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET)
  18. #define RS485_SLAVE_RX_MODE() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET)
  19. /* ----------------------- static functions ---------------------------------*/
  20. static void handleReceivedDataTask(void *argument);
  21. /* ----------------------- Start implementation -----------------------------*/
  22. BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
  23. eMBParity eParity)
  24. {
  25. /* set serial configure parameter */
  26. huart.Init.BaudRate = ulBaudRate;
  27. huart.Init.WordLength = ucDataBits == 8 ? UART_WORDLENGTH_8B : UART_WORDLENGTH_9B;
  28. huart.Init.StopBits = UART_STOPBITS_1;
  29. switch (eParity)
  30. {
  31. case MB_PAR_NONE:
  32. huart.Init.Parity = UART_PARITY_NONE;
  33. break;
  34. case MB_PAR_ODD:
  35. huart.Init.Parity = UART_PARITY_ODD;
  36. break;
  37. case MB_PAR_EVEN:
  38. huart.Init.Parity = UART_PARITY_EVEN;
  39. break;
  40. default:
  41. return FALSE;
  42. }
  43. huart.Init.Mode = UART_MODE_TX_RX;
  44. huart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  45. huart.Init.OverSampling = UART_OVERSAMPLING_16;
  46. /* open serial device */
  47. if (HAL_UART_Init(&huart) != HAL_OK)
  48. {
  49. Error_Handler();
  50. return FALSE;
  51. }
  52. return TRUE;
  53. }
  54. void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
  55. {
  56. if (xRxEnable)
  57. {
  58. /* switch 485 to receive mode */
  59. RS485_SLAVE_RX_MODE();
  60. __HAL_UART_ENABLE_IT(&huart,UART_IT_RXNE);
  61. }
  62. else
  63. {
  64. /* switch 485 to transmit mode */
  65. RS485_SLAVE_TX_MODE();
  66. __HAL_UART_DISABLE_IT(&huart,UART_IT_RXNE);
  67. }
  68. if (xTxEnable)
  69. {
  70. __HAL_UART_ENABLE_IT(&huart,UART_IT_TXE);
  71. }
  72. else
  73. {
  74. __HAL_UART_DISABLE_IT(&huart,UART_IT_TXE);
  75. }
  76. }
  77. void vMBPortClose(void)
  78. {
  79. HAL_UART_AbortReceive_IT(&huart);
  80. HAL_UART_AbortTransmit_IT(&huart);
  81. }
  82. BOOL xMBPortSerialPutByte(CHAR ucByte)
  83. {
  84. if(HAL_UART_Transmit (&huart ,(uint8_t *)&ucByte,1,0x01) != HAL_OK )
  85. return FALSE ;
  86. else
  87. return TRUE;
  88. }
  89. /*
  90. * A Function to send all bytes in one call.
  91. */
  92. BOOL xMBPortSerialPutBytes(volatile UCHAR *ucByte, USHORT usSize)
  93. {
  94. if(HAL_UART_Transmit (&huart ,(uint8_t *)&ucByte,usSize,1000) != HAL_OK )
  95. return FALSE ;
  96. else
  97. return TRUE;
  98. }
  99. BOOL xMBPortSerialGetByte(CHAR * pucByte)
  100. {
  101. // *pucByte = rx_buff[rx_index++];
  102. //
  103. // return TRUE;
  104. if(HAL_UART_Receive (&huart ,(uint8_t *)pucByte,1,0x01) != HAL_OK )
  105. return FALSE ;
  106. else
  107. return TRUE;
  108. }
  109. /*
  110. * Create an interrupt handler for the transmit buffer empty interrupt
  111. * (or an equivalent) for your target processor. This function should then
  112. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
  113. * a new character can be sent. The protocol stack will then call
  114. * xMBPortSerialPutByte( ) to send the character.
  115. */
  116. void prvvUARTTxReadyISR(void)
  117. {
  118. pxMBFrameCBTransmitterEmpty();
  119. }
  120. /*
  121. * Create an interrupt handler for the receive interrupt for your target
  122. * processor. This function should then call pxMBFrameCBByteReceived( ). The
  123. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
  124. * character.
  125. *
  126. * quanghona: This function is called when IDLE is detected. thus will then
  127. * trigger the received message handler.
  128. */
  129. void prvvUARTRxISR(void)
  130. {
  131. //osEventFlagsSet(xSerialEventHandle, EVENT_MBSLAVE_HANDLE_RECEIVED_DATA);
  132. pxMBFrameCBByteReceived( );
  133. }
  134. /*
  135. * Create an interrupt handler for the receive character for your target processor.
  136. * This function should store data to a buffer for received message thread to
  137. * handle later.
  138. */
  139. void prvvUARTRxReceiveCharISR(CHAR data)
  140. {
  141. rx_buff[put_index++] = data;
  142. }
  143. /*
  144. * A thread to handle the received message.
  145. * This thread is wait until a received message flag is set, then it will call
  146. * pxMBFrameCBByteReceived() until all characters in the receive buffer is handled.
  147. */
  148. static void handleReceivedDataTask(void *argument)
  149. {
  150. while (1)
  151. {
  152. osEventFlagsWait(xSerialEventHandle, EVENT_MBSLAVE_HANDLE_RECEIVED_DATA, osFlagsWaitAny, osWaitForever);
  153. while (put_index > 0) {
  154. pxMBFrameCBByteReceived();
  155. put_index--;
  156. }
  157. }
  158. }