1 | #include "plc.h"
|
---|
2 | #include "main.h"
|
---|
3 | #include "cmsis_os.h"
|
---|
4 | #include <string.h>
|
---|
5 | #include <stdlib.h>
|
---|
6 |
|
---|
7 | plc_data_typeDef PLC_Data[AMOUNT_BLOCK_PLC] = {0}; // ïî êîëëè÷åñòâó îïðàøèâàåìûõ áëîêîâ
|
---|
8 |
|
---|
9 | plc_common_typeDef plc_common = {0, 1};
|
---|
10 |
|
---|
11 | extern UART_HandleTypeDef huart2;
|
---|
12 | extern xQueueHandle QueueCmdTxPLC, QueueCmdRxPLC;
|
---|
13 | /* ----------------------------------------------------------------------------------------- */
|
---|
14 | /* ######################################################################################### */
|
---|
15 | /* PLC CALCULATE CRC ----------------------------------------------------------------------- */
|
---|
16 | uint16_t plc_calc_cs(uint8_t *buff, uint16_t len)
|
---|
17 | {
|
---|
18 | uint32_t cs16 = 0;
|
---|
19 | for(uint16_t i = 0; i < len; i++) cs16 += buff[i];
|
---|
20 |
|
---|
21 | cs16 = (0x00ff&cs16) + (cs16>>8);
|
---|
22 | cs16 = (0x00ff&cs16) + (cs16>>8);
|
---|
23 | return cs16;
|
---|
24 | }
|
---|
25 | /* ----------------------------------------------------------------------------------------- */
|
---|
26 | /* ######################################################################################### */
|
---|
27 | /* PLC ESCAPE ENCODER ---------------------------------------------------------------------- */
|
---|
28 | uint16_t escape_encoder(uint8_t *buff, uint16_t len_buf, uint8_t *out_biff)
|
---|
29 | {
|
---|
30 | _Bool flag = 0;
|
---|
31 | uint16_t tmpLen = 0;
|
---|
32 | for(uint16_t i = 0; i < len_buf; i++){
|
---|
33 | if(!flag){
|
---|
34 | if(buff[i] == 0x7D) flag = 1;
|
---|
35 | else out_biff[tmpLen++] = buff[i];
|
---|
36 | }
|
---|
37 | else {
|
---|
38 | if((buff[i] == 0x5E) || (buff[i] == 0x5D)){
|
---|
39 | out_biff[tmpLen++] = buff[i] | 0x20;
|
---|
40 | flag = 0;
|
---|
41 | }
|
---|
42 | else return 0;
|
---|
43 | }
|
---|
44 | }
|
---|
45 | return tmpLen;
|
---|
46 | }
|
---|
47 | /* ----------------------------------------------------------------------------------------- */
|
---|
48 | /* ######################################################################################### */
|
---|
49 | /* PLC PARSE PACKET RX --------------------------------------------------------------------- */
|
---|
50 | uint8_t _parse_packet_receive(plc_RxData_typeDef *ParseRx, plc_buff_typeDef *buff)
|
---|
51 | {
|
---|
52 | uint8_t *tmpBuff = (uint8_t*)malloc((sizeof(uint8_t) * buff->len));
|
---|
53 | if(tmpBuff == NULL) return 0;
|
---|
54 | uint16_t tmpLen = 0;
|
---|
55 | //_Bool flag = 0;
|
---|
56 |
|
---|
57 | ParseRx->LenBuff = 0;
|
---|
58 | ParseRx->Query = 0;
|
---|
59 | ParseRx->Valid = 0;
|
---|
60 |
|
---|
61 |
|
---|
62 | tmpLen = escape_encoder(buff->data, buff->len, tmpBuff);
|
---|
63 | if(tmpLen == 0){
|
---|
64 | free(tmpBuff);
|
---|
65 | return 0;
|
---|
66 | }
|
---|
67 | /*for(uint16_t i = 0; i < buff->len; i++){
|
---|
68 | if(!flag){
|
---|
69 | if(buff->data[i] == 0x7D) flag = 1;
|
---|
70 | else tmpBuff[tmpLen++] = buff->data[i];
|
---|
71 | }
|
---|
72 | else {
|
---|
73 | if((buff->data[i] == 0x5E) || (buff->data[i] == 0x5D)){
|
---|
74 | tmpBuff[tmpLen++] = buff->data[i] | 0x20;
|
---|
75 | flag = 0;
|
---|
76 | }
|
---|
77 | else {
|
---|
78 | free(tmpBuff);
|
---|
79 | return 0;
|
---|
80 | }
|
---|
81 | }
|
---|
82 | }*/
|
---|
83 |
|
---|
84 | if(plc_calc_cs(tmpBuff, tmpLen) != 0x00FF){
|
---|
85 | free(tmpBuff);
|
---|
86 | return 0;
|
---|
87 | }
|
---|
88 |
|
---|
89 | if(!(tmpBuff[0] & 0x80)){ // åñëè ýòî çàïðîñ äàííûõ
|
---|
90 | uint8_t route = tmpBuff[tmpBuff[0] / 2 + 1];
|
---|
91 | uint8_t odd_route = tmpBuff[0] % 2; // óçíàåì òåòðàäó
|
---|
92 | if(odd_route)route >>= 4; // åñëè ñòàðøàÿ òåòðàäà
|
---|
93 | route &= 0x3F;
|
---|
94 | if(route == PLC_ADDR_BOARD)ParseRx->Query = 1;
|
---|
95 | }
|
---|
96 |
|
---|
97 | ParseRx->Pointer = tmpBuff[0];
|
---|
98 |
|
---|
99 | ParseRx->LenBuff = tmpLen - 2;
|
---|
100 | memcpy(ParseRx->Buff, &tmpBuff[1], tmpLen - 1);
|
---|
101 |
|
---|
102 | ParseRx->Valid = 1;
|
---|
103 |
|
---|
104 | free(tmpBuff);
|
---|
105 | return 1;
|
---|
106 | }
|
---|
107 |
|
---|
108 | /* ----------------------------------------------------------------------------------------- */
|
---|
109 | /* ######################################################################################### */
|
---|
110 | /* PLC CODER ESQ --------------------------------------------------------------------------- */
|
---|
111 | void _pack_esq(plc_buff_typeDef *buff, uint8_t x)
|
---|
112 | {
|
---|
113 | if((x == 0x7d) || (x == 0x7e)){
|
---|
114 | buff->data[buff->len++] = 0x7D;
|
---|
115 | x &= 0xDF;
|
---|
116 | }
|
---|
117 | buff->data[buff->len++] = x;
|
---|
118 | }
|
---|
119 |
|
---|
120 | /* ----------------------------------------------------------------------------------------- */
|
---|
121 | /* ######################################################################################### */
|
---|
122 | /* PLC PREPARE PACKET TX ------------------------------------------------------------------- */
|
---|
123 | void _prepare_packet_send(plc_TxData_typeDef *PrepareTx, plc_buff_typeDef *buff)
|
---|
124 | {
|
---|
125 | uint8_t cs = ~((uint8_t)plc_calc_cs(&PrepareTx->Pointer, PrepareTx->LenBuff + 1));
|
---|
126 | buff->len = 0;
|
---|
127 | buff->data[buff->len++] = 0x7E;
|
---|
128 | _pack_esq(buff, PrepareTx->Pointer);
|
---|
129 |
|
---|
130 | for(uint16_t i = 0; i < PrepareTx->LenBuff; i++) _pack_esq(buff, PrepareTx->Buff[i]);
|
---|
131 | //_pack_esq(buff, ~((uint8_t)plc_calc_cs(&buff->data[1], buff->len - 1)));
|
---|
132 | _pack_esq(buff, cs);
|
---|
133 |
|
---|
134 | //buff->data[buff->len++] = ~((uint8_t)plc_calc_cs(&buff->data[1], buff->len - 1)); // íå ñ÷èòàåì ïåðâûé 0x7E
|
---|
135 | buff->data[buff->len++] = 0x7E;
|
---|
136 | }
|
---|
137 |
|
---|
138 | uint8_t my_cmd_plc(plc_RxData_typeDef *PLCRxData, plc_TxData_typeDef *PLCTxData) // PLCRxData - ïðèíÿòûé ïàêåò, PLCTxData - ïåðåäàåì
|
---|
139 | {
|
---|
140 | if(PLCRxData->Buff[0] == 0x01){
|
---|
141 |
|
---|
142 | }
|
---|
143 | return 0;
|
---|
144 | }
|
---|
145 |
|
---|
146 | /* ----------------------------------------------------------------------------------------- */
|
---|
147 | /* ######################################################################################### */
|
---|
148 | /* PLC RECEIVE ----------------------------------------------------------------------------- */
|
---|
149 | void plc_receive(uint8_t ch)
|
---|
150 | {
|
---|
151 | portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
---|
152 | static plc_buff_typeDef OutBuff = {0}, InBuff = {0};
|
---|
153 | static plc_TxData_typeDef PLCTxData = {0};
|
---|
154 | static plc_RxData_typeDef PLCRxData = {0};
|
---|
155 | static uint8_t pointer;
|
---|
156 |
|
---|
157 | static volatile struct {
|
---|
158 | _Bool Marker: 1;
|
---|
159 | _Bool MarkerSearch: 1;
|
---|
160 | _Bool Send: 1;
|
---|
161 | }flag = {0, 0, 0};
|
---|
162 |
|
---|
163 | /**********************************************************/
|
---|
164 | if(!flag.Send){ // åñëè ìû íå èùåì ìàðêåð
|
---|
165 | if(xQueueReceiveFromISR(QueueCmdTxPLC, &PLCTxData, &xHigherPriorityTaskWoken) == pdTRUE){ // åñëè åñòü äàííûå â î÷åðåäè
|
---|
166 | _prepare_packet_send(&PLCTxData, &OutBuff); // ãîòîâèì äàííûå äëÿ ïåðåäà÷è
|
---|
167 | flag.MarkerSearch = 1; // ôëàã äëÿ ïîèñêà ìàðêåðà
|
---|
168 | if(!(PLCTxData.Pointer & 0x80)) flag.Send = 1; // åñëè ïåðåäàåì êîìàíäó
|
---|
169 | }
|
---|
170 | }
|
---|
171 |
|
---|
172 | if(ch == 0x7E){ // êîíåö ïàêåòà
|
---|
173 | if(flag.Marker){
|
---|
174 | if(pointer == PLC_MARKER_BOARD){ // åñëè ìîé ìàðêåð, òî ïåðåäàåì
|
---|
175 | HAL_GPIO_WritePin(USART_TX_EN_GPIO_Port, USART_TX_EN_Pin, GPIO_PIN_SET);
|
---|
176 | HAL_UART_Transmit(&huart2, OutBuff.data, OutBuff.len, 1000);
|
---|
177 | HAL_GPIO_WritePin(USART_TX_EN_GPIO_Port, USART_TX_EN_Pin, GPIO_PIN_RESET);
|
---|
178 | flag.MarkerSearch = 0;
|
---|
179 | flag.Send = 0;
|
---|
180 | pointer = 0x00;
|
---|
181 | }
|
---|
182 | flag.Marker = 0;
|
---|
183 | }
|
---|
184 | if(InBuff.len > 1){ // åñëè äëèííà ïàêåòà áîëüøå 1, òî îáðàáàòûâàåì ïàêåò
|
---|
185 | _parse_packet_receive(&PLCRxData, &InBuff);
|
---|
186 | xQueueSendFromISR(QueueCmdRxPLC, &PLCRxData, &xHigherPriorityTaskWoken);
|
---|
187 | }
|
---|
188 | InBuff.len = 0;
|
---|
189 | }
|
---|
190 | else{
|
---|
191 | if(flag.MarkerSearch){ // åñëè åñòü ôëàã äëÿ ïîèñêà ìàðêåðà
|
---|
192 | pointer = ch;
|
---|
193 | flag.Marker = 1;
|
---|
194 | }
|
---|
195 | InBuff.data[InBuff.len++] = ch; // êîïèì äàííûå
|
---|
196 | if(InBuff.len == (MAX_LEN_PLC_BUFF - 1)) InBuff.len = 0;
|
---|
197 | }
|
---|
198 | }
|
---|