#ifdef CONFIG_SCORE_ENABLE #include #include "app_serv.h" #include "score_tsk.h" #include "data.h" #include "datadesc.h" #include "uart2.h" #include "time.h" OS_STK ScoreTaskStk[SCORE_TASK_STK_SIZE]; OS_EVENT *ScoreQuery = NULL; void *ScoreQueryTbl[SCORE_QUERY_LEN]; const CPU_INT32U uart_speed[SCORE_UART_SPEED_COUNT] = {1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}; #define SCORE_RTS_SET() {FIO0SET_bit.P0_1 = 1;} #define SCORE_RTS_CLR() {FIO0CLR_bit.P0_1 = 1;} CPU_INT08U k07_buf[K07_MAX_PACKET_LEN]; CPU_INT32U score_state[SCORE_COUNT]; #define K07_SYN 0xFF #define K07_STX 0x02 #define K07_ETX 0x03 #define K07_CR 0x0d extern int GetPricePerMin(CPU_INT08U channel, CPU_INT08U mode); /// int GetScoreEvent(int* event) { CPU_INT08U err = 0; if (!ScoreQuery) return 0; int evt = (int)OSQPend(ScoreQuery, 1, &err); if (err != 0) return 0; *event = evt; return 1; } /// void PostScoreEvent(int event) { if (!ScoreQuery) return; OSQPost(ScoreQuery, (void *)event); } void PostScoreNumber(CPU_INT08U channel, CPU_INT16U number, CPU_INT08U dot) { CPU_INT32U event; event = SCORE_EVENT_SET_NUMBER1 + (channel & SCORE_EVENT_CHANNEL_MASK) + ((number & SCORE_EVENT_NUMBER_MASK) << SCORE_EVENT_NUMBER_OFFSET); if (dot) event |= SCORE_EVENT_DOT_FLAG; PostScoreEvent(event); } void PostScoreClear(CPU_INT08U channel) { CPU_INT32U event; event = SCORE_EVENT_SET_NUMBER1 + (channel & SCORE_EVENT_CHANNEL_MASK) + SCORE_EVENT_CLEAR_FLAG; PostScoreEvent(event); } /// void to_hex_str(char* str, CPU_INT08U val) { CPU_INT08U byte; byte = (val >> 4) & 0x0f; if (byte >= 0xa) { str[0] = 'A' + (byte - 0xa); } else { str[0] = '0' + byte; } byte = val & 0x0f; if (byte >= 0xa) { str[1] = 'A' + (byte - 0xa); } else { str[1] = '0' + byte; } } /// int from_hex_str(char* str, CPU_INT08U* val) { CPU_INT08U value = 0; if ((str[0] >= 'A') && (str[0] <= 'F')) { value += 0x0a + (CPU_INT08U)(str[0] - 'A'); } else if ((str[0] >= 'a') && (str[0] <= 'f')) { value += 0x0a + (CPU_INT08U)(str[0] - 'a'); } else if ((str[0] >= '0') && (str[0] <= '9')) { value += (CPU_INT08U)(str[0] - '0'); } else { return -1; } value <<= 4; if ((str[1] >= 'A') && (str[1] <= 'F')) { value += 0x0a + (CPU_INT08U)(str[1] - 'A'); } else if ((str[1] >= 'a') && (str[1] <= 'f')) { value += 0x0a + (CPU_INT08U)(str[1] - 'a'); } else if ((str[1] >= '0') && (str[1] <= '9')) { value += (CPU_INT08U)(str[1] - '0'); } else { return -2; } *val = value; return 0; } /// чтение ответного пакета int k07_read_pkt(CPU_INT08U *packet, CPU_INT32U timeout) { int byte_ctr = 0; CPU_INT32U time_stamp = OSTimeGet(); while (OSTimeGet() - time_stamp < timeout) { int res = Uart2_Getc(); if (res >= 0) { byte_ctr++; *packet++ = (CPU_INT08U)res; break; } OSTimeDly(1); } if (!byte_ctr) { return 0; } time_stamp = OSTimeGet(); while ((OSTimeGet() - time_stamp < timeout) && (byte_ctr < K07_MAX_PACKET_LEN)) { int res = Uart2_Getc(); if (res >= 0) { byte_ctr++; *packet++ = (CPU_INT08U)res; if (res == K07_CR) break; } OSTimeDly(1); } return byte_ctr; } /// CPU_INT16U k07_make_req(CPU_INT08U* packet, CPU_INT08U dst_addr, CPU_INT08U src_addr, char cmd, char scode, char *data, CPU_INT08U data_len) { CPU_INT08U i; CPU_INT08U byte; CPU_INT08U* begin = packet; CPU_INT08U checksum = 0x00; char symbuf[2]; *packet++ = K07_SYN; *packet++ = K07_SYN; *packet++ = K07_SYN; *packet++ = K07_STX; to_hex_str(symbuf, dst_addr); byte = symbuf[0]; *packet++ = byte; checksum += byte; byte = symbuf[1]; *packet++ = byte; checksum += byte; to_hex_str(symbuf, src_addr); byte = symbuf[0]; *packet++ = byte; checksum += byte; byte = symbuf[1]; *packet++ = byte; checksum += byte; *packet++ = cmd; checksum += cmd; *packet++ = scode; checksum += scode; for (i = 0; i < data_len; i++) { *packet++ = *data; checksum += *data++; } *packet++ = K07_ETX; to_hex_str(symbuf, checksum); byte = symbuf[0]; *packet++ = byte; byte = symbuf[1]; *packet++ = byte; *packet++ = K07_CR; return (CPU_INT16U)(packet - begin); } /// проверка ответа, возвращает длину данных int k07_check_resp(CPU_INT08U* packet, CPU_INT08U packet_len, CPU_INT08U* dst_addr, CPU_INT08U* src_addr, char cmd, char **data) { CPU_INT08U i; CPU_INT08U byte; CPU_INT08U checksum = 0x00; while (*packet != K07_STX) { if (*packet != K07_SYN) { return 0; } packet++; if (packet_len) packet_len--; else return 0; } if (packet_len < 11) { return -1; } if (*packet != K07_STX) { return -3; } packet++; packet_len--; if (from_hex_str((char*)&packet[0], dst_addr) != 0) { return -4; } if (from_hex_str((char*)&packet[2], src_addr) != 0) { return -5; } if (packet[4] != cmd) { return -6; } if (packet[5] != '0') { return -7; } if ((packet[packet_len - 1] != K07_CR) || (packet[packet_len - 4] != K07_ETX)) { return -8; } for (i = 0; i < packet_len - 4; i++) { checksum += packet[i]; } if ((from_hex_str((char*)&packet[packet_len - 3], &byte) != 0) || (byte != checksum)) { return -9; } if (data) *data = (char*)&packet[6]; return packet_len - 10; } /// CPU_INT08U k07_make_number_str(char *data, CPU_INT16U number, CPU_INT08U zeros, CPU_INT08U column) { CPU_INT08U byte; char* d = data; CPU_INT08U non_zero = (zeros > 0) ? 1 : 0; *d++ = 0x11; if (column) { *d++ = 0x20; *d++ = 0x20; } byte = ((number / 1000) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = ' '; byte = ((number / 100) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = ' '; byte = ((number / 10) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = ' '; byte = (number % 10); *d++ = '0' + byte; return d - data; } /// CPU_INT08U k07_make_number3_str(char *data, CPU_INT16U* number, CPU_INT08U zeros, CPU_INT08U column) { CPU_INT08U byte; char* d = data; CPU_INT08U non_zero = (zeros > 0) ? 1 : 0; *d++ = 0x11; if (!column) { *d++ = 0x20; *d++ = 0x20; } byte = ((number[0] / 1000) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = ' '; byte = ((number[0] / 100) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = '0'; *d++ = '.'; byte = ((number[0] / 10) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = ' '; byte = (number[0] % 10); *d++ = '0' + byte; non_zero = (zeros > 0) ? 1 : 0; *d++ = 0x09; if (!column) { *d++ = 0x20; *d++ = 0x20; } byte = ((number[1] / 1000) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = ' '; byte = ((number[1] / 100) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = '0'; *d++ = '.'; byte = ((number[1] / 10) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = ' '; byte = (number[1] % 10); *d++ = '0' + byte; non_zero = (zeros > 0) ? 1 : 0; *d++ = 0x09; if (!column) { *d++ = 0x20; *d++ = 0x20; } byte = ((number[2] / 1000) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = ' '; byte = ((number[2] / 100) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = '0'; *d++ = '.'; byte = ((number[2] / 10) % 10); if (byte > 0) non_zero = 1; if (non_zero) *d++ = '0' + byte; else *d++ = ' '; byte = (number[2] % 10); *d++ = '0' + byte; return d - data; } /// CPU_INT08U k07_make_empty_str(char *data) { data[0] = 0x11; data[1] = 0x20; data[2] = 0x20; data[3] = 0x20; data[4] = 0x20; data[5] = 0x20; data[6] = 0x20; return 7; } /// CPU_INT08U k07_make_time_str(char *data, CPU_INT08U hour, CPU_INT08U min, CPU_INT08U dot, CPU_INT08U column) { CPU_INT08U ctr = 0; CPU_INT08U byte; *data++ = 0x11; ctr++; if (column) { *data++ = 0x20; ctr++; *data++ = 0x20; ctr++; } byte = ((hour / 10) % 10); *data++ = '0' + byte; ctr++; byte = (hour % 10); *data++ = '0' + byte; ctr++; if (dot) { if (column) { *data++ = '.'; ctr++; } else { *data++ = ':'; ctr++; } } byte = ((min / 10) % 10); *data++ = '0' + byte; ctr++; byte = (min % 10); *data++ = '0' + byte; ctr++; return ctr; } /// CPU_INT08U k07_make_digit_str(char *data, CPU_INT16U digit, CPU_INT08U dot, CPU_INT08U column) { char* d = data; CPU_INT08U byte; *d++ = 0x11; if (column) { *d++ = 0x20; *d++ = 0x20; } byte = ((digit / 1000) % 10); *d++ = '0' + byte; byte = ((digit / 100) % 10); *d++ = '0' + byte; if (dot) { if (column) { *d++ = '.'; } else { *d++ = ':'; } } byte = ((digit / 10) % 10); *d++ = '0' + byte; byte = (digit % 10); *d++ = '0' + byte; return d - data; } /// int k07_write_string(CPU_INT08U dest, char* str, CPU_INT08U str_len, CPU_INT08U repeat) { while (repeat--) { CPU_INT16U txlen = k07_make_req(k07_buf, dest, K07_SELF_ADDR, 'g', '!', str, str_len); SCORE_RTS_SET(); OSTimeDly(1); Uart2_Flush(); Uart2_WriteData(k07_buf, txlen); Uart2_WaitTxEnd(); SCORE_RTS_CLR(); Uart2_Flush(); int rxlen = k07_read_pkt(k07_buf, K07_RX_TIMEOUT); if (rxlen > 0) { CPU_INT08U dst, src; rxlen = k07_check_resp(k07_buf, rxlen, &dst, &src, 'g', NULL); if (rxlen >= 0) { return 0; } } } return -1; } /// int k07_write_address(CPU_INT08U dest, char* str, CPU_INT08U str_len) { CPU_INT16U txlen = k07_make_req(k07_buf, dest, K07_SELF_ADDR, 'A', '#', str, str_len); SCORE_RTS_SET(); OSTimeDly(1); Uart2_Flush(); Uart2_WriteData(k07_buf, txlen); Uart2_WaitTxEnd(); SCORE_RTS_CLR(); Uart2_Flush(); return 0; } /// возращает указатель на данные внутри пакета и их длину, в src записывается, откуда пришел ответ int k07_read_info(char **data, CPU_INT08U dest, CPU_INT08U* src, CPU_INT08U repeat) { while (repeat--) { CPU_INT16U txlen = k07_make_req(k07_buf, dest, K07_SELF_ADDR, 'A', '?', "", 0); SCORE_RTS_SET(); OSTimeDly(1); Uart2_Flush(); Uart2_WriteData(k07_buf, txlen); Uart2_WaitTxEnd(); SCORE_RTS_CLR(); Uart2_Flush(); int rxlen = k07_read_pkt(k07_buf, K07_RX_TIMEOUT); if (rxlen > 0) { CPU_INT08U dst; rxlen = k07_check_resp(k07_buf, rxlen, &dst, src, 'A', data); if ((rxlen >= 0) && (dst == K07_SELF_ADDR)) { return rxlen; } } } return -1; } CPU_INT32U GetRs485Speed(void) { CPU_INT32U speed; GetData(&ScoreRs485SpeedDesc, &speed, 0, DATA_FLAG_DIRECT_INDEX); if (speed < SCORE_UART_SPEED_COUNT) { return uart_speed[speed]; } return uart_speed[3]; } /// void ScoreTask(void *p_arg) { Uart2_Init(GetRs485Speed()); for (CPU_INT08U i = 0; i < SCORE_COUNT / 2; i++) { PostScoreNumber(i, i + 1, 0); PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1 + i); } while (1) { int event; if (GetScoreEvent(&event)) { switch (event) { case SCORE_EVENT_CHANGE_SPEED: Uart2_Init(GetRs485Speed()); break; case SCORE_EVENT_SETUP1: case SCORE_EVENT_SETUP2: case SCORE_EVENT_SETUP3: case SCORE_EVENT_SETUP4: case SCORE_EVENT_SETUP5: case SCORE_EVENT_SETUP6: { CPU_INT08U index = event - SCORE_EVENT_SETUP1; CPU_INT08U len; char *data; char str[16]; CPU_INT08U src; CPU_INT32U val32; CPU_INT08U addr; CPU_INT32U column; GetData(&ScoreColumnDesc, &column, index, DATA_FLAG_DIRECT_INDEX); score_state[index] = SCORE_STATE_SET; if (k07_read_info(&data, 255, &src, K07_REPEAT_COUNT) < 14) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } OSTimeDly(200); // серийный номер memcpy(str, &data[6], 8); if (index < SCORE_TIME_COUNT) { addr = index + 1; to_hex_str(&str[8], addr); to_hex_str(&str[10], 0); } else { addr = (index - SCORE_TIME_COUNT) * 3 + 16; to_hex_str(&str[8], addr); to_hex_str(&str[10], addr + 2); } k07_write_address(src, str, 12); OSTimeDly(2000); if (k07_read_info(&data, addr, &src, K07_REPEAT_COUNT) < 14) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } OSTimeDly(1000); len = k07_make_number_str(str, 8888, 0, column); if (k07_write_string(addr, str, len, K07_REPEAT_COUNT) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } if (index >= SCORE_TIME_COUNT) { if (k07_write_string(addr + 1, str, len, K07_REPEAT_COUNT) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } if (k07_write_string(addr + 2, str, len, K07_REPEAT_COUNT) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } } OSTimeDly(1000); len = k07_make_number_str(str, addr, 0, column); if (k07_write_string(addr, str, len, 1) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } if (index >= SCORE_TIME_COUNT) { len = k07_make_number_str(str, addr + 1, 0, column); if (k07_write_string(addr + 1, str, len, 1) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } len = k07_make_number_str(str, addr + 2, 0, column); if (k07_write_string(addr + 2, str, len, 1) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } } OSTimeDly(1000); len = k07_make_number_str(str, 0, 1, column); if (k07_write_string(addr, str, len, 1) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } if (index >= SCORE_TIME_COUNT) { if (k07_write_string(addr + 1, str, len, 1) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } if (k07_write_string(addr + 2, str, len, 1) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } } OSTimeDly(1000); len = k07_make_empty_str(str); if (k07_write_string(addr, str, len, 1) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } if (index >= SCORE_TIME_COUNT) { if (k07_write_string(addr + 1, str, len, 1) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } if (k07_write_string(addr + 2, str, len, 1) != 0) { score_state[index] = SCORE_STATE_FAIL; score_cmd = 0; break; } } OSTimeDly(1000); val32 = addr; SetData(&ScoreRs485AddressDesc, &val32, index, DATA_FLAG_DIRECT_INDEX); val32 = 1; SetData(&ScoreEnableDesc, &val32, index, DATA_FLAG_DIRECT_INDEX); score_state[index] = SCORE_STATE_OK; score_cmd = 0; } break; case SCORE_EVENT_UPDATE_PRICE1: case SCORE_EVENT_UPDATE_PRICE2: case SCORE_EVENT_UPDATE_PRICE3: { CPU_INT08U index = event - SCORE_EVENT_UPDATE_PRICE1; CPU_INT08U len; CPU_INT32U addr; CPU_INT32U en; char str[32]; CPU_INT32U column; GetData(&ScoreEnableDesc, &en, SCORE_TIME_COUNT + index, DATA_FLAG_DIRECT_INDEX); if (en) { CPU_INT16U number[3]; GetData(&ScoreRs485AddressDesc, &addr, SCORE_TIME_COUNT + index, DATA_FLAG_DIRECT_INDEX); GetData(&ScoreColumnDesc, &column, SCORE_TIME_COUNT + index, DATA_FLAG_DIRECT_INDEX); for (CPU_INT08U i = 0; i < 3; i++) { number[i] = GetPricePerMin(index, i); } len = k07_make_number3_str(str, number, 0, column); if (k07_write_string(addr, str, len, 1) == 0) { score_state[SCORE_TIME_COUNT + index] = SCORE_STATE_OK; } } } break; default: { if ((event & SCORE_EVENT_SET_NUMBER_MASK) == SCORE_EVENT_SET_NUMBER) { CPU_INT08U index; CPU_INT16U number; CPU_INT08U dot; CPU_INT08U len; CPU_INT32U addr; CPU_INT32U en; char str[16]; CPU_INT32U column; index = event & SCORE_EVENT_CHANNEL_MASK; GetData(&ScoreEnableDesc, &en, index, DATA_FLAG_DIRECT_INDEX); if (en) { GetData(&ScoreColumnDesc, &column, index, DATA_FLAG_DIRECT_INDEX); number = (event >> SCORE_EVENT_NUMBER_OFFSET) & SCORE_EVENT_NUMBER_MASK; dot = (event & SCORE_EVENT_DOT_FLAG) ? 1 : 0; if (event & SCORE_EVENT_CLEAR_FLAG) { len = k07_make_empty_str(str); } else { len = k07_make_digit_str(str, number, dot, column); } GetData(&ScoreRs485AddressDesc, &addr, index, DATA_FLAG_DIRECT_INDEX); if (k07_write_string(addr, str, len, 1) == 0) { score_state[index] = SCORE_STATE_OK; } } } } } } else { /* static CPU_INT08U sec_blink = 0; if (OSTimeGet() - time_stamp > 500) { time_stamp = OSTimeGet(); CPU_INT08U len; CPU_INT32U addr; char str[16]; TRTC_Data rtc; Sec2Date(&rtc, SystemTime); len = k07_make_time_str(str, rtc.hour, rtc.min, sec_blink & 0x01); sec_blink++; GetData(&ScoreRs485AddressDesc, &addr, 0, DATA_FLAG_DIRECT_INDEX); if (k07_write_string(addr, str, len, 1) != 0) { } } */ } OSTimeDly(10); } } /// void InitScoreTask(void) { int i; // RTS PINSEL0_bit.P0_1 = 0x0; PINMODE0_bit.P0_1 = 0; FIO0DIR_bit.P0_1 = 1; FIO0MASK_bit.P0_1 = 0; SCORE_RTS_CLR(); for (i = 0; i < SCORE_COUNT; i++) { score_state[i] = SCORE_STATE_OFF; } ScoreQuery = OSQCreate(&ScoreQueryTbl[0], SCORE_QUERY_LEN); OSTaskCreate(ScoreTask, (void *)0, (OS_STK *)&ScoreTaskStk[SCORE_TASK_STK_SIZE-1], SCORE_TASK_PRIO); } #endif