source: S-port/trunk/Core/Src/plc.c

Last change on this file was 1, checked in by AlexLir, 3 years ago
File size: 6.6 KB
Line 
1#include "plc.h"
2#include "main.h"
3#include "cmsis_os.h"
4#include <string.h>
5#include <stdlib.h>
6
7plc_data_typeDef PLC_Data[AMOUNT_BLOCK_PLC] = {0}; // ïî êîëëè÷åñòâó îïðàøèâàåìûõ áëîêîâ
8
9plc_common_typeDef plc_common = {0, 1};
10
11extern UART_HandleTypeDef huart2;
12extern xQueueHandle QueueCmdTxPLC, QueueCmdRxPLC;
13/* ----------------------------------------------------------------------------------------- */
14/* ######################################################################################### */
15/* PLC CALCULATE CRC ----------------------------------------------------------------------- */
16uint16_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 ---------------------------------------------------------------------- */
28uint16_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 --------------------------------------------------------------------- */
50uint8_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 --------------------------------------------------------------------------- */
111void _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 ------------------------------------------------------------------- */
123void _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
138uint8_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 ----------------------------------------------------------------------------- */
149void 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}
Note: See TracBrowser for help on using the repository browser.