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.
 
 
 
 
 
 

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