Microprocessor and peripheral 2 assignments for AUTH
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.
 
 
 
 
 
 

652 lines
19 KiB

  1. /*!
  2. * \file
  3. * thermostat_shield.c
  4. * \brief
  5. * Nucleo thermostat shield port file. This file contain the implementation of driver
  6. * calls for the shield.
  7. *
  8. * Author: Christos Choutouridis AEM: 8997
  9. * email : <cchoutou@ece.auth.gr>
  10. */
  11. #include "thermostat_shield.h"
  12. /*
  13. * =============== Digital I/O ===============
  14. */
  15. static void SHIELD_LCD_Port_Init (void);
  16. static void SHIELD_LED_Port_Init (void);
  17. static void SHIELD_BRIDGE_Port_Init (void);
  18. static void SHIELD_SR04_Port_Init (void);
  19. /*
  20. * =============== LCD ===============
  21. * LCD_BD4 -- D8 -- PA9
  22. * LCD_BD5 -- D7 -- PA8
  23. * LCD_BD6 -- D6 -- PB10
  24. * LCD_BD7 -- D5 -- PB4
  25. * LCD_RS -- D15 -- PB8
  26. * LCD_EN -- D14 -- PB9
  27. * LCD_BL -- D2 -- PA10
  28. */
  29. /*!
  30. * LCD pin Initialize
  31. */
  32. static void SHIELD_LCD_Port_Init (void) {
  33. GPIO_InitTypeDef GPIO_InitType;
  34. __HAL_RCC_GPIOA_CLK_ENABLE ();
  35. __HAL_RCC_GPIOB_CLK_ENABLE ();
  36. GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
  37. GPIO_InitType.Speed = GPIO_SPEED_LOW;
  38. GPIO_InitType.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
  39. HAL_GPIO_Init(GPIOA, &GPIO_InitType);
  40. GPIO_InitType.Pin = GPIO_PIN_4 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
  41. HAL_GPIO_Init(GPIOB, &GPIO_InitType);
  42. }
  43. void SHIELD_LCD_DB4 (uint8_t en) { _DOUTx(GPIOA, GPIO_PIN_9, en); }
  44. void SHIELD_LCD_DB5 (uint8_t en) { _DOUTx(GPIOA, GPIO_PIN_8, en); }
  45. void SHIELD_LCD_DB6 (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_10, en); }
  46. void SHIELD_LCD_DB7 (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_4, en); }
  47. void SHIELD_LCD_RS (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_8, en); }
  48. void SHIELD_LCD_EN (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_9, en); }
  49. void SHIELD_LCD_BL (uint8_t en) { _DOUTx(GPIOA, GPIO_PIN_10, en); }
  50. /*
  51. * =============== LED ===============
  52. * LED0 -- D4 -- PB5
  53. * LED1 -- D3 -- PB3
  54. */
  55. /*!
  56. * LED pin initialize
  57. */
  58. static void SHIELD_LED_Port_Init (void) {
  59. GPIO_InitTypeDef GPIO_InitType;
  60. __HAL_RCC_GPIOB_CLK_ENABLE ();
  61. GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
  62. GPIO_InitType.Speed = GPIO_SPEED_LOW;
  63. GPIO_InitType.Pin = GPIO_PIN_3 | GPIO_PIN_5;
  64. HAL_GPIO_Init(GPIOB, &GPIO_InitType);
  65. }
  66. void SHIELD_LED0 (uint8_t on) { _DOUTx(GPIOB, GPIO_PIN_5, on); }
  67. void SHIELD_LED1 (uint8_t on) { _DOUTx(GPIOB, GPIO_PIN_3, on); }
  68. /*
  69. * =============== BRIDGE ===============
  70. * BR1 -- D10 -- PB6
  71. * BR2 -- D9 -- PC7
  72. */
  73. /*!
  74. * H-Bridge pin initialize
  75. */
  76. static void SHIELD_BRIDGE_Port_Init (void) {
  77. GPIO_InitTypeDef GPIO_InitType;
  78. __HAL_RCC_GPIOB_CLK_ENABLE ();
  79. __HAL_RCC_GPIOC_CLK_ENABLE ();
  80. GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
  81. GPIO_InitType.Speed = GPIO_SPEED_LOW;
  82. GPIO_InitType.Pin = GPIO_PIN_6;
  83. HAL_GPIO_Init(GPIOB, &GPIO_InitType);
  84. GPIO_InitType.Pin = GPIO_PIN_7;
  85. HAL_GPIO_Init(GPIOC, &GPIO_InitType);
  86. }
  87. void SHIELD_BR1 (uint8_t on) { _DOUTx(GPIOB, GPIO_PIN_6, on); }
  88. void SHIELD_BR2 (uint8_t on) { _DOUTx(GPIOC, GPIO_PIN_7, on); }
  89. /*
  90. * =============== SR04 ===============
  91. * TRIG -- D11 -- PA7
  92. * ECHO -- D12 -- PA6
  93. */
  94. /*!
  95. * SR04 pin initialize
  96. */
  97. static void SHIELD_SR04_Port_Init (void) {
  98. GPIO_InitTypeDef GPIO_InitType;
  99. __HAL_RCC_GPIOA_CLK_ENABLE ();
  100. GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
  101. GPIO_InitType.Speed = GPIO_SPEED_LOW;
  102. GPIO_InitType.Pin = GPIO_PIN_7;
  103. HAL_GPIO_Init(GPIOA, &GPIO_InitType);
  104. GPIO_InitType.Mode = GPIO_MODE_INPUT;
  105. GPIO_InitType.Pull = GPIO_NOPULL;
  106. GPIO_InitType.Pin = GPIO_PIN_6;
  107. HAL_GPIO_Init(GPIOA, &GPIO_InitType);
  108. }
  109. void SHIELD_TRIG (uint8_t on) { _DOUTx(GPIOA, GPIO_PIN_7, on); }
  110. uint8_t SHIELD_ECHO (void) { return _DINx (GPIOA, GPIO_PIN_6); }
  111. /*
  112. * ============= 1 Wire UART6 (AF08)===============
  113. * 1W_Tx -- PA11 (OD+PU)
  114. * 1W_Rx -- PA12 (I)
  115. */
  116. static UART_HandleTypeDef h1w_uart; //!< 1-wire uart handle
  117. /*!
  118. * \brief
  119. * This function handles UART Communication Timeout.
  120. * \param huart: Pointer to a UART_HandleTypeDef structure that contains
  121. * the configuration information for the specified UART module.
  122. * \param Flag: specifies the UART flag to check.
  123. * \param Status: The new Flag status (SET or RESET).
  124. * \param Timeout: Timeout duration
  125. * \return HAL status
  126. */
  127. static HAL_StatusTypeDef _WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) {
  128. uint32_t tickstart = HAL_GetTick();
  129. if (Status != RESET) Status = SET; /* Catch wrong Status */
  130. /* Wait until flag is on FlagStatus Status */
  131. while (__HAL_UART_GET_FLAG (huart, Flag) == Status) {
  132. if ((Timeout == 0) || ((HAL_GetTick() - tickstart ) > Timeout)) {
  133. /* Give up */
  134. huart->gState= HAL_UART_STATE_READY; /* Mark Timeout as ready */
  135. __HAL_UNLOCK (huart); /* Process Unlocked */
  136. return HAL_TIMEOUT; /* Return the TIMEOUT */
  137. }
  138. }
  139. return HAL_OK;
  140. }
  141. /*!
  142. * \brief
  143. * Initialize 1-Wire UART to 8bits, no parity, 1 stop, so it can
  144. * be used for 1-Wire communication
  145. * \return The status of the operation
  146. * \arg LLD_OK Success
  147. * \arg LLD_ERROR The Init failed.
  148. */
  149. static LLD_Status_en _1W_UART_Init (void) {
  150. _1WIRE_UART_CLK_ENABLE (); // Enable 1-wire's USART clock
  151. /*
  152. * USART configured as follows:
  153. * - Word Length = 8 Bits
  154. * - Stop Bit = One Stop bit
  155. * - Parity = No parity
  156. * - BaudRate = _1WIRE_UART_INIT_BR baud
  157. * - Hardware flow control disabled (RTS and CTS signals)
  158. */
  159. h1w_uart.Instance = _1WIRE_UART_INSTANCE;
  160. h1w_uart.Init.BaudRate = _1WIRE_UART_INIT_BR;
  161. h1w_uart.Init.WordLength = UART_WORDLENGTH_8B;
  162. h1w_uart.Init.StopBits = UART_STOPBITS_1;
  163. h1w_uart.Init.Parity = UART_PARITY_NONE;
  164. h1w_uart.Init.Mode = UART_MODE_TX_RX;
  165. if (HAL_UART_Init(&h1w_uart) != HAL_OK)
  166. return LLD_ERROR;
  167. return LLD_OK;
  168. }
  169. /*!
  170. * Init the 1wire interface and allocate all resources for it
  171. * \return The status of the operation
  172. * \arg LLD_OK Success
  173. * \arg LLD_ERROR The Init failed.
  174. */
  175. LLD_Status_en SHIELD_1W_Init (void) {
  176. GPIO_InitTypeDef GPIO_InitStruct;
  177. __HAL_RCC_GPIOA_CLK_ENABLE ();
  178. GPIO_InitStruct.Pin = GPIO_PIN_11;
  179. GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  180. GPIO_InitStruct.Pull = GPIO_PULLUP;
  181. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
  182. GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
  183. HAL_GPIO_WritePin (GPIOA, GPIO_InitStruct.Pin, GPIO_PIN_SET);
  184. HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);
  185. GPIO_InitStruct.Pin = GPIO_PIN_12;
  186. //GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  187. GPIO_InitStruct.Pull = GPIO_NOPULL;
  188. GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
  189. GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  190. /*^
  191. * Mark as alternate because HAL_GPIO_Init ()
  192. * can not configure Input + alternate
  193. */
  194. HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);
  195. return _1W_UART_Init ();
  196. }
  197. /*!
  198. * \brief
  199. * Set a Baudrate to the UART, to use for 1-Wire communication
  200. * \param br The desired baudrate
  201. * \return The status of the operation (part of toolbox)
  202. * \arg DRV_ERROR Fail
  203. * \arg DRV_READY Success
  204. */
  205. drv_status_en SHIELD_1W_UART_BR (uint32_t br) {
  206. /*
  207. * Keep USART configured as already set by Init:
  208. * - Word Length = 8 Bits
  209. * - Stop Bit = One Stop bit
  210. * - Parity = No parity
  211. * - Hardware flow control disabled (RTS and CTS signals)
  212. */
  213. if (! IS_UART_BAUDRATE (br) )
  214. return DRV_ERROR;
  215. h1w_uart.Init.BaudRate = br;
  216. /* Check the Over Sampling */
  217. if(h1w_uart.Init.OverSampling == UART_OVERSAMPLING_8) {
  218. /*------- UART-associated USART registers setting : BRR Configuration ------*/
  219. if((h1w_uart.Instance == USART1)){
  220. h1w_uart.Instance->BRR = UART_BRR_SAMPLING8 (HAL_RCC_GetPCLK2Freq(), h1w_uart.Init.BaudRate);
  221. }
  222. else {
  223. h1w_uart.Instance->BRR = UART_BRR_SAMPLING8 (HAL_RCC_GetPCLK1Freq(), h1w_uart.Init.BaudRate);
  224. }
  225. }
  226. else {
  227. /*------- UART-associated USART registers setting : BRR Configuration ------*/
  228. if((h1w_uart.Instance == USART1)) {
  229. h1w_uart.Instance->BRR = UART_BRR_SAMPLING16 (HAL_RCC_GetPCLK2Freq(), h1w_uart.Init.BaudRate);
  230. }
  231. else {
  232. h1w_uart.Instance->BRR = UART_BRR_SAMPLING16 (HAL_RCC_GetPCLK1Freq(), h1w_uart.Init.BaudRate);
  233. }
  234. }
  235. return DRV_READY;
  236. }
  237. /*!
  238. * \brief
  239. * Read-Write functionality. We use the following USART configuration.
  240. * - Word Length = 8 Bits
  241. * - Stop Bit = One Stop bit
  242. * - Parity = No parity
  243. * \return The byte received. On failure return 0xFFFF (bus released state)
  244. * \note
  245. * Due to the nature of the PCB, the received byte is the actual bus
  246. * condition during the communication frame (time slot)
  247. */
  248. uint16_t SHIELD_1W_RW (uint8_t byte)
  249. {
  250. if (h1w_uart.Init.WordLength != UART_WORDLENGTH_8B) return (uint8_t)0xFFFF;
  251. if (h1w_uart.Init.Parity != UART_PARITY_NONE) return (uint8_t)0xFFFF;
  252. if (_WaitOnFlagUntilTimeout (&h1w_uart, UART_FLAG_TXE, RESET, _1WIRE_UART_TIMEOUT) != HAL_OK)
  253. return 0x1FF;
  254. WRITE_REG (h1w_uart.Instance->DR, (byte & (uint8_t)0xFF));
  255. if (_WaitOnFlagUntilTimeout (&h1w_uart, UART_FLAG_TC, RESET, _1WIRE_UART_TIMEOUT) != HAL_OK)
  256. return 0x2FF;
  257. //if (_WaitOnFlagUntilTimeout (&h1w_uart, UART_FLAG_RXNE, RESET, _1WIRE_UART_TIMEOUT) != HAL_OK)
  258. // return 0xFFFF;
  259. return (uint8_t)(h1w_uart.Instance->DR & (uint8_t)0x00FF);
  260. }
  261. /*!
  262. * \brief
  263. * Receive functionality. We use USART blocking mode.
  264. * \return The byte received. On failure return 0xFF (bus released state)
  265. * \note
  266. * Due to the nature of the PCB, the received byte is the actual bus
  267. * condition during the communication frame (time slot)
  268. */
  269. uint8_t SHIELD_1W_Rx (void) {
  270. uint8_t rx;
  271. if (HAL_UART_Receive (&h1w_uart, &rx, sizeof (uint8_t), _1WIRE_UART_TIMEOUT) != HAL_OK)
  272. rx = 0xFF;
  273. return rx;
  274. }
  275. /*!
  276. * \brief
  277. * Transmit functionality. We use USART blocking mode.
  278. * \return The status of transition
  279. * \arg 0 Success
  280. * \arg 1 Fail
  281. */
  282. uint8_t SHIELD_1W_Tx (uint8_t byte) {
  283. if (HAL_UART_Transmit (&h1w_uart, &byte, sizeof (uint8_t), _1WIRE_UART_TIMEOUT) != HAL_OK)
  284. return 1;
  285. return 0;
  286. }
  287. /*!
  288. * Shield hardware initialization
  289. */
  290. LLD_Status_en SHIELD_Init (void) {
  291. SHIELD_LCD_Port_Init ();
  292. SHIELD_LED_Port_Init ();
  293. SHIELD_BRIDGE_Port_Init ();
  294. SHIELD_SR04_Port_Init ();
  295. SHIELD_1W_Init ();
  296. COM_Init ();
  297. return LLD_OK;
  298. }
  299. /*
  300. * ============= Serial console UART2 (AF07)===============
  301. * COM_Tx -- PA2 (PP)
  302. * COM_Rx -- PA3 (I)
  303. */
  304. static UART_HandleTypeDef com_huart; //!< com uart handle
  305. static deque08_t _com_rxq; //!< deque object
  306. static byte_t _com_rxbuffer[COM_BUFFER_SIZE]; //!< buffer for deque
  307. /*!
  308. * \brief
  309. * Called from USART IRQ to put the read character to queue
  310. * \param Pointer to a UART_HandleTypeDef structure that contains
  311. * the configuration information for the specified UART module.
  312. *
  313. * \return The status of the operation
  314. * \arg HAL_ERROR Fail
  315. * \arg HAL_OK Success
  316. */
  317. static HAL_StatusTypeDef _UART_read_data (UART_HandleTypeDef *huart, deque08_t *q) {
  318. uint8_t r;
  319. __HAL_LOCK(huart); /*
  320. * We don't try to receive valid data while the USART is
  321. * locked from transmitter. It's OK ;)
  322. */
  323. /* Receive data based on Word length and parity */
  324. switch (huart->Init.WordLength) {
  325. default:
  326. case UART_WORDLENGTH_8B:
  327. if(huart->Init.Parity == UART_PARITY_NONE)
  328. r = (uint8_t)(huart->Instance->DR & (uint16_t)0x00FF);
  329. else
  330. r = (uint8_t)(huart->Instance->DR & (uint16_t)0x007F);
  331. break;
  332. case UART_WORDLENGTH_9B:
  333. if(huart->Init.Parity == UART_PARITY_NONE) {
  334. r = (uint8_t)(huart->Instance->DR & (uint16_t)0x01FF);
  335. __HAL_UNLOCK(huart);
  336. return HAL_ERROR;
  337. /* Not supported Configuration */
  338. } else
  339. r = (uint8_t)(huart->Instance->DR & (uint16_t)0x00FF);
  340. break;
  341. }
  342. deque08_push_back (q, r);
  343. /*!<
  344. * \note
  345. * We queue the received bytes. The user application MUST
  346. * read the queue in a regular basis, or else this IRQ will
  347. * find queue full and we will have data loss.
  348. */
  349. __HAL_UNLOCK(huart);
  350. return HAL_OK;
  351. }
  352. void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
  353. {
  354. __HAL_UART_CLEAR_PEFLAG (huart);
  355. huart->ErrorCode = HAL_UART_ERROR_NONE;
  356. huart->gState = HAL_UART_STATE_READY;
  357. /*
  358. * Clear all the error flag at once,
  359. * Set USART READY for re-start,
  360. * Error Callback
  361. */
  362. }
  363. /*!
  364. * \brief
  365. * USART serial handler. Pushes every received character to a queue.
  366. *
  367. * In the IRQ handler there is only Rx functionality provided by this driver.
  368. * The Error handling call the HAL's callback (which are empty)
  369. * The Tx part, is not implemented
  370. */
  371. void USART2_IRQHandler (void) {
  372. uint32_t tmp_flag = 0, tmp_it_source = 0;
  373. // ======= Error handler =========
  374. if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_PE)) != RESET) &&
  375. ((tmp_it_source = __HAL_UART_GET_IT_SOURCE(&com_huart, UART_IT_PE)) != RESET)) {
  376. /* UART parity error interrupt occurred */
  377. com_huart.ErrorCode |= HAL_UART_ERROR_PE;
  378. }
  379. if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_FE)) != RESET) &&
  380. ((tmp_it_source = __HAL_UART_GET_IT_SOURCE(&com_huart, UART_IT_ERR)) != RESET)) {
  381. /* UART frame error interrupt occurred */
  382. com_huart.ErrorCode |= HAL_UART_ERROR_FE;
  383. }
  384. if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_NE)) != RESET) &&
  385. (tmp_it_source != RESET)){
  386. /* UART noise error interrupt occurred */
  387. com_huart.ErrorCode |= HAL_UART_ERROR_NE;
  388. }
  389. if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_ORE)) != RESET) &&
  390. (tmp_it_source != RESET)){
  391. /* USART Over-Run interrupt occurred */
  392. com_huart.ErrorCode |= HAL_UART_ERROR_ORE;
  393. }
  394. if(com_huart.ErrorCode != HAL_UART_ERROR_NONE) {
  395. HAL_UART_ErrorCallback (&com_huart);
  396. }
  397. // ====== Get Data =========
  398. if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_RXNE)) != RESET) &&
  399. ((tmp_it_source = __HAL_UART_GET_IT_SOURCE(&com_huart, UART_IT_RXNE)) != RESET)) {
  400. // Read byte
  401. _UART_read_data (&com_huart, &_com_rxq); // Don't check return status
  402. }
  403. }
  404. /*!
  405. * \brief
  406. * Initialize the UART and UART IRQ handler
  407. * \return The status of the operation
  408. * \arg LLD_ERROR Fail
  409. * \arg LLD_OK Success
  410. */
  411. static LLD_Status_en _COM_UART_Init (void) {
  412. /*
  413. * Enable UART clock
  414. */
  415. _COM_CLK_ENABLE();
  416. deque08_link_buffer (&_com_rxq, _com_rxbuffer);
  417. deque08_set_capacity (&_com_rxq, COM_BUFFER_SIZE);
  418. deque08_init (&_com_rxq);
  419. /*
  420. * USART configured as follows:
  421. * - Word Length = 8 Bits
  422. * - Stop Bit = One Stop bit
  423. * - Parity = No parity
  424. * - BaudRate = COM_BAUDRATE baud
  425. * - Hardware flow control disabled (RTS and CTS signals)
  426. */
  427. com_huart.Instance = COM_UART_INSTANCE;
  428. com_huart.Init.BaudRate = COM_UART_BAUDRATE;
  429. com_huart.Init.WordLength = UART_WORDLENGTH_8B;
  430. com_huart.Init.StopBits = UART_STOPBITS_1;
  431. com_huart.Init.Parity = UART_PARITY_NONE;
  432. com_huart.Init.Mode = UART_MODE_TX_RX;
  433. if (HAL_UART_Init(&com_huart) != HAL_OK)
  434. return LLD_ERROR;
  435. /*
  436. * Enable IRQ for Rx
  437. * Tx IRQ enabled by COM_transmit ()
  438. */
  439. HAL_NVIC_SetPriority (COM_UART_IRQ, 0x0D, 0);
  440. HAL_NVIC_EnableIRQ (COM_UART_IRQ);
  441. /* Enable the UART Data Register not empty Interrupt */
  442. __HAL_UART_ENABLE_IT(&com_huart, UART_IT_RXNE);
  443. /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
  444. //__HAL_UART_ENABLE_IT(&com_huart, UART_IT_ERR);
  445. return LLD_OK;
  446. }
  447. /*!
  448. * Initialize the COM dedicated I/O and allocate resources
  449. * \return The status of the operation
  450. */
  451. LLD_Status_en COM_Init (void) {
  452. GPIO_InitTypeDef GPIO_InitStruct;
  453. __HAL_RCC_GPIOA_CLK_ENABLE ();
  454. GPIO_InitStruct.Pin = GPIO_PIN_2;
  455. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  456. GPIO_InitStruct.Pull = GPIO_NOPULL;
  457. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
  458. GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
  459. HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);
  460. GPIO_InitStruct.Pin = GPIO_PIN_3;
  461. GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  462. // GPIO_InitStruct.Pull = GPIO_NOPULL;
  463. // GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
  464. HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);
  465. return _COM_UART_Init();
  466. }
  467. /*!
  468. * \brief
  469. * Set UART baudrate
  470. * \param br The desired baudrate
  471. * \return The status of the operation
  472. * \arg LLD_ERROR Fail
  473. * \arg LLD_OK Success
  474. */
  475. LLD_Status_en COM_baudrate (uint32_t br) {
  476. // Change only the Baudrate
  477. com_huart.Init.BaudRate = br;
  478. if (HAL_UART_Init(&com_huart) != HAL_OK)
  479. return LLD_ERROR;
  480. return LLD_OK;
  481. }
  482. /*!
  483. * \brief
  484. * USART's putchar functionality to link with io system
  485. * This function is compatible with putchar() in "stdio.h"
  486. */
  487. int COM_putchar (char c) {
  488. if (_WaitOnFlagUntilTimeout (&com_huart, UART_FLAG_TC, RESET, COM_UART_PUTCHAR_TIMEOUT) != HAL_OK)
  489. return 0xFFFF;
  490. WRITE_REG (COM_UART_INSTANCE->DR, (c & (uint8_t)0xFF));
  491. /*!<
  492. * \note
  493. * The sequence:
  494. * - Read operation to USART_SR register [USART_GetFlagStatus()]
  495. * - Write operation to USART_DR register [USART_SendData()]
  496. * clears the TC Flag
  497. *
  498. * The TXE Flag is cleared by the write operation to USART_DR register
  499. * [USART_SendData()]
  500. */
  501. return (int)c;
  502. }
  503. /*!
  504. * \brief
  505. * USART's getchar functionality to link with io system
  506. * This function is compatible with getchar() in "stdio.h"
  507. */
  508. int COM_getchar (void) {
  509. clock_t mark = clock ();
  510. clock_t to = COM_UART_GETCHAR_TIMEOUT*get_freq();
  511. clock_t now;
  512. byte_t r=0;
  513. while (deque08_pop_front (&_com_rxq, &r) == 0) {
  514. now = clock ();
  515. if (_CLOCK_DIFF(now, mark) >= to)
  516. return 0;
  517. }
  518. return r;
  519. }
  520. /*!
  521. * \brief
  522. * Transmit functionality to link with io system
  523. * This function is compatible with htp tx functionality
  524. *
  525. * \param data Pointer to data buffer
  526. * \param size Size of buffer (number of bytes)
  527. * \return The number of bytes to transmit
  528. */
  529. int COM_Transmit (uint8_t *data, int size) {
  530. int r = size;
  531. while (size--) {
  532. //queue08_push (&_com_txq, (byte_t)*data);
  533. COM_putchar(*data++);
  534. }
  535. _WaitOnFlagUntilTimeout (&com_huart, UART_FLAG_TC, SET, COM_UART_PUTCHAR_TIMEOUT);
  536. return r;
  537. }
  538. /*!
  539. * \brief
  540. * Check receive functionality synchronized to IRQ
  541. * This function is compatible with htp rx functionality
  542. *
  543. * \return The number of bytes on queue (<package_size> indicates done)
  544. */
  545. int COM_CheckReceive (void) {
  546. return deque08_size (&_com_rxq);
  547. }
  548. /*!
  549. * \brief
  550. * Receive flush functionality to link with io system
  551. * This function is compatible with htp rx functionality
  552. *
  553. * \param data Pointer to data buffer
  554. * \param size Size of buffer (number of bytes)
  555. * \return The number of received bytes
  556. */
  557. void COM_ReceiveFlush (void) {
  558. deque08_flush (&_com_rxq);
  559. }
  560. /*!
  561. * \brief
  562. * Receive functionality to link with io system
  563. * This function is compatible with htp rx functionality
  564. *
  565. * \param data Pointer to data buffer
  566. * \param size Size of buffer (number of bytes)
  567. * \return The number of received bytes
  568. */
  569. int COM_Receive (uint8_t *data, int size) {
  570. int i;
  571. uint8_t r=1, b;
  572. for (i=0 ; r !=0 && i<size ; ++i) {
  573. r = deque08_pop_front (&_com_rxq, &b);
  574. data[i] = b;
  575. }
  576. return i;
  577. }