HW_UART_ATY.c 12 KB

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