HW_UART_ATY.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /**
  2. * @file HW_UART_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2023 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief Familiar functions of uart for STC51
  20. *
  21. * @version
  22. * - 1_01_221231 > ATY
  23. * -# Preliminary version, first Release
  24. * - 1_02_240410 > ATY
  25. * -# add multy addr and channel
  26. * -# add lock
  27. * - Undone: over with "\r\n" type
  28. * - todo: printf in multi platform
  29. ********************************************************************************
  30. */
  31. #ifndef __HW_UART_ATY_C
  32. #define __HW_UART_ATY_C
  33. #include "HW_UART_ATY.h"
  34. /******************************* For user *************************************/
  35. /******************************************************************************/
  36. /**
  37. * @brief uart send byte and init uart if not initialized
  38. * @param byte byte to send
  39. * @param dev
  40. * @return uint8_t
  41. */
  42. uint8_t UartSendByte(uint8_t byte, struct HW_UART_ATY_Dev* dev)
  43. {
  44. __ATY_LOCK(dev);
  45. if(dev->uartInitFlag == 0){
  46. dev->uartInitFlag = 1;
  47. dev->uartInit(dev->rx);
  48. }
  49. while(dev->rxCount)
  50. dev->rx[dev->rxCount--] = 0;
  51. dev->uartSendByte(byte);
  52. __ATY_UNLOCK(dev);
  53. return 0;
  54. }
  55. /**
  56. * @brief
  57. *
  58. * @param dev
  59. */
  60. void UartRxClear(struct HW_UART_ATY_Dev* dev)
  61. {
  62. if(!dev->rxCount) return;
  63. while(dev->rxCount)
  64. dev->rx[dev->rxCount--] = 0;
  65. }
  66. /**
  67. * @brief uart send bytes
  68. * @param bytes bytes to send
  69. * @param len bytes to send
  70. * @param dev
  71. */
  72. void UartSendBytes(uint8_t* bytes, uint16_t len, struct HW_UART_ATY_Dev* dev)
  73. {
  74. while(len--)
  75. UartSendByte(*bytes++, dev);
  76. }
  77. /**
  78. * @brief uart send string
  79. * @param str data to send
  80. * @param dev
  81. */
  82. void UartSendStr(uint8_t* str, struct HW_UART_ATY_Dev* dev)
  83. {
  84. while(*str)
  85. UartSendByte(*str++, dev);
  86. }
  87. /**
  88. * @brief uart send float data in specified endian
  89. * @param dataFloat float number
  90. * @param endian
  91. * @param dev
  92. */
  93. void UartSendFloat(float dataFloat, uint8_t endian, struct HW_UART_ATY_Dev* dev)
  94. {
  95. union result
  96. {
  97. float temp_f;
  98. uint8_t temp_uint8[4];
  99. }resultA, resultB;
  100. resultA.temp_f = dataFloat;
  101. if(endian == 'B'){
  102. resultB.temp_uint8[0] = resultA.temp_uint8[3];
  103. resultB.temp_uint8[1] = resultA.temp_uint8[2];
  104. resultB.temp_uint8[2] = resultA.temp_uint8[1];
  105. resultB.temp_uint8[3] = resultA.temp_uint8[0];
  106. }
  107. else if(endian == 'L'){
  108. resultB.temp_uint8[0] = resultA.temp_uint8[0];
  109. resultB.temp_uint8[1] = resultA.temp_uint8[1];
  110. resultB.temp_uint8[2] = resultA.temp_uint8[2];
  111. resultB.temp_uint8[3] = resultA.temp_uint8[3];
  112. }
  113. UartSendBytes(resultB.temp_uint8, 4, dev);
  114. }
  115. /**
  116. * @brief uart send float data in ASCII character type
  117. * @param dataFloat number to send, use double to get better
  118. * @param DECIMALS_NUM
  119. * @param dev
  120. * @note float and double is the same in C51
  121. */
  122. void UartSendFloatStr(float dataFloat, uint8_t DECIMALS_NUM, struct HW_UART_ATY_Dev* dev)
  123. // void UartSendFloatStr(double dataFloat)
  124. {
  125. uint8_t i = 0;
  126. uint8_t dataStr[10]; // ulongint 4294967295, 6.4f
  127. unsigned long int tempSaveData = 0;
  128. for(i = 0; i < 10; i++)
  129. dataStr[i] = 0;
  130. if(dataFloat < 0)
  131. {
  132. dataFloat = -dataFloat;
  133. UartSendByte('-', dev);
  134. }
  135. tempSaveData = (dataFloat * 10000) + 0.5;
  136. for(i = 0; tempSaveData != 0; i++)
  137. {
  138. dataStr[10 - 1 - i] = tempSaveData % 10;
  139. tempSaveData /= 10;
  140. }
  141. // UartSendByte(i + 48);
  142. if(i < 5)
  143. i = 5;
  144. while(i--)
  145. {
  146. UartSendByte(dataStr[10 - 1 - i] + 48, dev);
  147. if(i == DECIMALS_NUM)
  148. UartSendByte('.', dev);
  149. }
  150. UartSendByte(' ', dev);
  151. }
  152. /**
  153. * @brief uart receive data process
  154. * @note put at main while
  155. * @param dev
  156. */
  157. void UartReceiveProcess(struct HW_UART_ATY_Dev* dev)
  158. {
  159. if(dev->uartInitFlag == 0){
  160. dev->uartInitFlag = 1;
  161. dev->uartInit(dev->rx);
  162. }
  163. if(dev->rcvOverTimeOutCount > dev->rcvOverTimeOutCountNum)
  164. {
  165. dev->rcvOverTimeOutCount = 0;
  166. if(dev->rxCount != 0)
  167. {
  168. dev->rcvOverFlag = 0;
  169. dev->uartReceiveProcess_User();
  170. while(dev->rxCount){
  171. dev->rx[dev->rxCount--] = 0;
  172. }
  173. }
  174. }
  175. else
  176. dev->rcvOverTimeOutCount++;
  177. }
  178. /******************************* For user *************************************/
  179. #if defined (__STC51_ATY)
  180. #define BRT (uint32_t)(65536 - (uint32_t)FOSC / BAUD_RATE / 4)
  181. // #define FOSC 5529600UL // 5.5296MHz MCU frequency
  182. #define FOSC 24000000UL // 24MHz MCU frequency
  183. #define BAUD_RATE 115200
  184. /**
  185. * @brief uart hardware init
  186. * @note put at main init
  187. */
  188. void UartInit(void)
  189. {
  190. SCON = 0x50; // 8bit data, variable baud rate
  191. AUXR |= 0x40; // timer clk 1T mode
  192. AUXR &= 0xFE; // user timer 1 as uart1 baud generate
  193. TMOD &= 0x0F; // set timer mode
  194. TL1 = BRT; // set timer origin value
  195. TH1 = BRT >> 8; // set timer origin value
  196. ET1 = 0; // disable timer IT
  197. TR1 = 1; // start timer 1
  198. // TI = 1;
  199. uartMsgStruct_t.rxCount = 0x00;
  200. uartMsgStruct_t.txCount = 0x00;
  201. uartMsgStruct_t.busyFlag = 0;
  202. ES = 1; // UART interrupt enable
  203. EA = 1; // Global interrupt enable
  204. }
  205. /**
  206. * @brief uart IT callback function
  207. */
  208. void UartIsr(void) INTERRUPT(4)
  209. {
  210. if(TI)
  211. {
  212. TI = 0;
  213. uartMsgStruct_t.busyFlag = 0;
  214. }
  215. if(RI)
  216. {
  217. RI = 0;
  218. if(uartMsgStruct_t.rxCount < UART_RX_MAX_LEN)
  219. {
  220. uartMsgStruct_t.overCount = 0;
  221. uartMsgStruct_t.rx[uartMsgStruct_t.rxCount++] = SBUF;
  222. }
  223. }
  224. }
  225. /**
  226. * @brief uart send byte
  227. * @param byte byte to send
  228. */
  229. void UartSendByte(uint8_t byte)
  230. {
  231. uint8_t errCount = 0;
  232. while(uartMsgStruct_t.busyFlag == 1)
  233. {
  234. errCount++;
  235. if(errCount > 200)
  236. break;
  237. }
  238. uartMsgStruct_t.busyFlag = 1;
  239. SBUF = byte;
  240. }
  241. #elif defined(__STM32_HAL_ATY)
  242. #include "usart.h"
  243. #ifndef __MICROLIB
  244. // for standart lib(not use MicroLIB)
  245. #pragma import(__use_no_semihosting)
  246. // define _sys_exit to avoid semi-host mode
  247. void _sys_exit(int x)
  248. {
  249. x = x;
  250. }
  251. struct __FILE
  252. {
  253. int handle;
  254. };
  255. FILE __stdout;
  256. #endif /* __MICROLIB */
  257. /* In gcc, using printf() output, if there is no "\n" in output data, no data
  258. will be printed on the screen until "\n" is encountered or the buffer overflows
  259. Another way to refresh the output data is to run "fflush(stdout)" after
  260. sending the data to force a refresh of the output stream
  261. */
  262. #ifdef __GNUC__
  263. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  264. #define GETCHAR_PROTOTYPE int __io_getchar(void)
  265. #else
  266. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  267. #define GETCHAR_PROTOTYPE int fgetc(FILE *f)
  268. #endif /* __GNUC__ */
  269. PUTCHAR_PROTOTYPE \
  270. {
  271. #ifdef LL
  272. LL_USART_TransmitData8(PRINTF_UART, ch);
  273. while(!LL_USART_IsActiveFlag_TC(PRINTF_UART)){}
  274. #else
  275. HAL_UART_Transmit(&PRINTF_UART, (uint8_t*)&ch, 1, 0xFFFF);
  276. #endif
  277. return ch;
  278. }
  279. GETCHAR_PROTOTYPE \
  280. {
  281. uint8_t ch = 0;
  282. HAL_UART_Receive(&PRINTF_UART, &ch, 1, 0xFFFF);
  283. return ch;
  284. }
  285. #endif /* PLATFORM */
  286. /******************************************************************************/
  287. #endif /* __HW_UART_ATY_C */
  288. /************************************ etc *************************************/
  289. /* init */
  290. /* STM32 (Open uart global IT, open rx DMA(Mode Normal, Width Byte) and default DMA IT) */
  291. // // uart2
  292. // extern DMA_HandleTypeDef hdma_usart2_rx;
  293. // void UartReceiveProcess_User_2(void);
  294. // void UartInit_2(uint8_t* rx)
  295. // {
  296. // // __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
  297. // HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rx, UART_RX_MAX_LEN);
  298. // __HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
  299. // }
  300. // void UartSendByte_2(uint8_t byte)
  301. // {
  302. // // LL
  303. // // LL_USART_TransmitData8(huart2, byte);
  304. // // while(!LL_USART_IsActiveFlag_TC(huart2)){}
  305. // // HAL
  306. // HAL_UART_Transmit(&huart2, (uint8_t*)&byte, 1, 0xFFFF);
  307. // }
  308. // struct HW_UART_ATY_Dev HW_UART_ATY_Dev_2 = {
  309. // // .rx = uartRx1,
  310. // .rx = {0},
  311. // .rxCount = 0,
  312. // .txCount = 0,
  313. // .rcvOverTimeOutCountNum = 2000,
  314. // .rcvOverTimeOutCount = 0,
  315. // .rcvOverFlag = 0,
  316. // .uartInitFlag = 0,
  317. // .uartInit = UartInit_2,
  318. // .uartSendByte = UartSendByte_2,
  319. // .uartReceiveProcess_User = UartReceiveProcess_User_2,
  320. // .lock = _ATY_UNLOCKED,
  321. // .debugEnable = 0,
  322. // // .LOG = printf
  323. // };
  324. // // uart3
  325. // extern DMA_HandleTypeDef hdma_usart3_rx;
  326. // void UartReceiveProcess_User_3(void);
  327. // void UartInit_3(uint8_t* rx)
  328. // {
  329. // // __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
  330. // HAL_UARTEx_ReceiveToIdle_DMA(&huart3, rx, UART_RX_MAX_LEN);
  331. // __HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT);
  332. // }
  333. // void UartSendByte_3(uint8_t byte)
  334. // {
  335. // // LL
  336. // // LL_USART_TransmitData8(huart3, byte);
  337. // // while(!LL_USART_IsActiveFlag_TC(huart3)){}
  338. // // HAL
  339. // HAL_UART_Transmit(&huart3, (uint8_t*)&byte, 1, 0xFFFF);
  340. // }
  341. // struct HW_UART_ATY_Dev HW_UART_ATY_Dev_3 = {
  342. // // .rx = uartRx1,
  343. // .rx = {0},
  344. // .rxCount = 0,
  345. // .txCount = 0,
  346. // .rcvOverTimeOutCountNum = 2000,
  347. // .rcvOverTimeOutCount = 0,
  348. // .rcvOverFlag = 0,
  349. // .uartInitFlag = 0,
  350. // .uartInit = UartInit_3,
  351. // .uartSendByte = UartSendByte_3,
  352. // .uartReceiveProcess_User = UartReceiveProcess_User_3,
  353. // .lock = _ATY_UNLOCKED,
  354. // .debugEnable = 0,
  355. // // .LOG = printf
  356. // };
  357. // void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)
  358. // {
  359. // if(huart == &huart2){
  360. // HAL_UART_DMAStop(&huart2);
  361. // HW_UART_ATY_Dev_2.rcvOverTimeOutCount = 0;
  362. // HW_UART_ATY_Dev_2.rxCount = UART_RX_MAX_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
  363. // HW_UART_ATY_Dev_2.rcvOverFlag = 0;
  364. // HAL_UARTEx_ReceiveToIdle_DMA(&huart2, HW_UART_ATY_Dev_2.rx, UART_RX_MAX_LEN);
  365. // __HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
  366. // }
  367. // else if(huart == &huart3){
  368. // HAL_UART_DMAStop(&huart3);
  369. // HW_UART_ATY_Dev_3.rcvOverTimeOutCount = 0;
  370. // HW_UART_ATY_Dev_3.rxCount = UART_RX_MAX_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);
  371. // HW_UART_ATY_Dev_3.rcvOverFlag = 0;
  372. // HAL_UARTEx_ReceiveToIdle_DMA(&huart3, HW_UART_ATY_Dev_3.rx, UART_RX_MAX_LEN);
  373. // __HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT);
  374. // }
  375. // /* if process is not too long, process function can be used at this call back;
  376. // otherwise put process at other cycle like while or timer cycle */
  377. // // UartReceiveProcess_User_2();
  378. // // UartReceiveProcess_User_3();
  379. // }
  380. /* 51 */
  381. /* use */
  382. // void main()
  383. // {
  384. // UartSendStr("Hello word!", &HW_UART_ATY_Dev_2);
  385. // UartSendStr("Hello word!", &HW_UART_ATY_Dev_3);
  386. // while (1)
  387. // {
  388. // UartReceiveProcess(&HW_UART_ATY_Dev_2);
  389. // UartReceiveProcess(&HW_UART_ATY_Dev_3);
  390. // }
  391. // }
  392. // /**
  393. // * @brief uart receive data analysis in user define self
  394. // */
  395. // void UartReceiveProcess_User_2(void)
  396. // {
  397. // if((HW_UART_ATY_Dev_2.rx[0] == 'O'
  398. // && HW_UART_ATY_Dev_2.rx[1] == 'K'
  399. // && HW_UART_ATY_Dev_2.rx[2] == '?'))
  400. // UartSendStr("OK!", &HW_UART_ATY_Dev_2);
  401. // }
  402. // void UartReceiveProcess_User_3(void)
  403. // {
  404. // if((HW_UART_ATY_Dev_3.rx[0] == 'O'
  405. // && HW_UART_ATY_Dev_3.rx[1] == 'K'
  406. // && HW_UART_ATY_Dev_3.rx[2] == '?'))
  407. // UartSendStr("OK!", &HW_UART_ATY_Dev_3);
  408. //
  409. // Modbus_Process(HW_UART_ATY_Dev_3.rx, HW_UART_ATY_Dev_3.rxCount, &MODBUS_S_LOW_ATY_Dev_1);
  410. //
  411. //
  412. // // UartSendStr(HW_UART_ATY_Dev_1.rx, &HW_UART_ATY_Dev_3);
  413. // if(memcmp("DSTART", (char*)HW_UART_ATY_Dev_1.rx, strlen("DSTART")) == 0)
  414. // {
  415. // printf("\r\nDebug START!");
  416. // }
  417. // else if(memcmp("temp", (char*)HW_UART_ATY_Dev_1.rx, strlen("temp")) == 0)
  418. // {
  419. // printf("\r\ntemp %c%c%c",
  420. // HW_UART_ATY_Dev_1.rx[strlen("temp_")],
  421. // HW_UART_ATY_Dev_1.rx[strlen("temp_") + 1],
  422. // HW_UART_ATY_Dev_1.rx[strlen("temp_") + 2]);
  423. // }
  424. // }
  425. /******************************************************************************/
  426. /******************************** End Of File *********************************/