[1] | 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 | }
|
---|