подправил драйвер дисплея

This commit is contained in:
Dmitriy 2021-02-09 22:03:16 +03:00
parent 5fe1e5d358
commit 32efe9ebcb
22 changed files with 38828 additions and 8862 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
Flash Central/Obj/app.o
*.pbi
*.o
*.out
*.pbd
*.map

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

516
PROJECT/app/ftp_app.c Normal file
View File

@ -0,0 +1,516 @@
#ifdef CONFIG_FTP_CLIENT_ENABLE
#include <includes.h>
#include "app_serv.h"
#include "ftp_client.h"
#include <string.h>
#include "time.h"
#include "term_tsk.h"
#include "journal.h"
#include "data.h"
#include "datadesc.h"
#include "ftp_app.h"
/*
92.53.96.10
xmiker_morozov
Qwerty11
*/
// èñïîëüóçåì îáùèé ñ òåðìèíàëîì áóôåð äàííûõ
extern char term_buffer[TERM_BUFFER_SIZE];
extern void PrintEventJournalRecord(TEventRecord *record, char *str_event, char *str_data);
CPU_INT08U time_to_ftp = 0;
///
void FtpCheckTimeToSend(CPU_INT32U systime)
{
CPU_INT32U enabled;
GetData(&FtpEnableDesc, &enabled, 0, DATA_FLAG_SYSTEM_INDEX);
if (enabled)
{
static const CPU_INT32U intervals_sec[8] = {1, 2, 3, 4, 6, 8, 12, 24};
CPU_INT32U hh_mm;
CPU_INT32U interval;
CPU_INT32U last_time;
TRTC_Data rtc_last, rtc_hhmm, rtc_curr;
GetData(&FtpSendIntervalDesc, &interval, 0, DATA_FLAG_SYSTEM_INDEX);
if (interval > 7) return;
interval = intervals_sec[interval];
GetData(&FtpSendHourMinDesc, &hh_mm, 0, DATA_FLAG_SYSTEM_INDEX);
hh_mm *= 60;
GetData(&FtpLastSendTimeDesc, &last_time, 0, DATA_FLAG_SYSTEM_INDEX);
Sec2Date(&rtc_last, last_time);
Sec2Date(&rtc_hhmm, hh_mm);
Sec2Date(&rtc_curr, systime);
if (systime - last_time > interval * 3600)
{
// îòïðàâëÿëè áîëüøå ÷åì çàäàííûé èíòåðâàë íàçàä -> îòïðàâëÿåì âñ¸
time_to_ftp = FTP_FLAG_SEND_COUNTERS | FTP_FLAG_SEND_LOGS;
}
else if ((rtc_curr.hour == rtc_hhmm.hour) && (rtc_curr.min == rtc_hhmm.min) && (systime - last_time >= 60))
{
// ñîâïàë çàäàííûé ÷àñ è ìèíóòà â ñóòêàõ + îòïðàâëÿëè ðàíüøå, ÷åì ìèíóòó íàçàä -> îòïðàâëÿåì âñ¸
time_to_ftp = FTP_FLAG_SEND_COUNTERS | FTP_FLAG_SEND_LOGS;
}
else if (((rtc_curr.hour % interval) == (rtc_hhmm.hour % interval)) && (rtc_curr.min == rtc_hhmm.min) && (systime - last_time >= 60))
{
// åñëè ñîâïàë èíòåðâàë ñ ïåðèîäîì â òå÷åíèå ñóòîê -> îòïðàâëÿåì ñ÷åò÷èêè
time_to_ftp |= FTP_FLAG_SEND_COUNTERS;
}
}
}
// ÷òåíèå î÷åðåäíîé ñòðîêè äëÿ ñîçäàíèÿ ôàéëà csv ñ÷åò÷èêîâ
int ReadFtpCountersString(int index, char *buf)
{
CPU_INT32U i;
static const char header1[] = ";Ñîëÿðèé 1 Êîëëàòýí;Ñîëÿðèé 1 Óëüòðàôèîëåò;Ñîëÿðèé 1 Ìàêñèìàëüíûé;Ñîëÿðèé 2 Êîëëàòýí;Ñîëÿðèé 2 Óëüòðàôèîëåò;Ñîëÿðèé 2 Ìàêñèìàëüíûé;Ñîëÿðèé 3 Êîëëàòýí;Ñîëÿðèé 3 Óëüòðàôèîëåò;Ñîëÿðèé 3 Ìàêñèìàëüíûé\r\n";
static const char line1[] = "Äåíüãè, ðóá.";
static const char line2[] = "Çàïóñêîâ";
static const char line3[] = "Íàðàáîòêà, ìèí.";
static const char header2[] = ";Êîëëàòýí;Óëüòðàôèîëåò;Ìàêñèìàëüíûé\r\n";
static const char header3[] = ";Ñîëÿðèé 1;Ñîëÿðèé 2;Ñîëÿðèé 3\r\n";
static const char line4[] = "Êîëëàòýí, ÷:ìì";
static const char line5[] = "Óëüòðàôèîëåò, ÷:ìì";
static const char header4[] = "Íàëè÷íûå, ðóá.;Áàíê, ðóá.;Âñåãî, ðóá.\r\n";
static const char line6[] = "Òåñòîâûõ çàïóñêîâ";
static const char line7[] = "Âðåìÿ òåñòà, ìèí.";
static const char line10[] = "Êîëè÷åñòâî óáîðîê";
static const char line11[] = "Âðåìÿ óáîðîê, ìèí.";
static const char line12[] = "Ñðåäíåå âðåìÿ óáîðêè, ì:ññ";
static const char line13[] = "Ñðåäíåå âðåìÿ òåñòà, ì:ññ";
switch (index)
{
case 0:
strcpy(buf, header1);
break;
case 1:
strcpy(buf, line1);
for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterSolarMoneyDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 2:
strcpy(buf, line2);
for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterSolarRunsDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 3:
strcpy(buf, line3);
for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterSolarWorkTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 4:
strcpy(buf, line6);
for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterSolarTestRunsDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 5:
strcpy(buf, line6);
for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterSolarTestWorkTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 6:
strcpy(buf, "\r\n");
break;
case 7:
strcpy(buf, header2);
break;
case 8:
strcpy(buf, line1);
for (i = 0; i < SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterModeMoneyDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 9:
strcpy(buf, line2);
for (i = 0; i < SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterModeRunsDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 10:
strcpy(buf, line3);
for (i = 0; i < SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterModeWorkTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 11:
strcpy(buf, line6);
for (i = 0; i < SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterModeTestRunsDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 12:
strcpy(buf, line7);
for (i = 0; i < SOLAR_MODES_COUNT; i++)
{
strcat(buf, ";");
GetDataStr(&CounterModeWorkTestTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 13:
strcpy(buf, "\r\n");
break;
case 14:
strcpy(buf, header3);
break;
case 15:
strcpy(buf, line4);
for (i = 0; i < CHANNELS_NUM; i++)
{
strcat(buf, ";");
GetDataStr(&CounterCollatenTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 16:
strcpy(buf, line5);
for (i = 0; i < CHANNELS_NUM; i++)
{
strcat(buf, ";");
GetDataStr(&CounterUFTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 17:
strcpy(buf, line6);
for (i = 0; i < CHANNELS_NUM; i++)
{
strcat(buf, ";");
GetDataStr(&CounterAllTestCountDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 18:
strcpy(buf, line7);
for (i = 0; i < CHANNELS_NUM; i++)
{
strcat(buf, ";");
GetDataStr(&CounterAllTestTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 19:
strcpy(buf, line13);
for (i = 0; i < CHANNELS_NUM; i++)
{
strcat(buf, ";");
GetDataStr(&CounterTestMeanTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 20:
strcpy(buf, line10);
for (i = 0; i < CHANNELS_NUM; i++)
{
strcat(buf, ";");
GetDataStr(&CounterCleaningCountDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 21:
strcpy(buf, line11);
for (i = 0; i < CHANNELS_NUM; i++)
{
strcat(buf, ";");
GetDataStr(&CounterCleaningTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 22:
strcpy(buf, line12);
for (i = 0; i < CHANNELS_NUM; i++)
{
strcat(buf, ";");
GetDataStr(&CounterCleaningMeanTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
}
strcat(buf, "\r\n");
break;
case 23:
strcpy(buf, "\r\n");
break;
case 24:
strcpy(buf, header4);
break;
case 25:
GetDataStr(&CounterCashMoneyDesc, (CPU_INT08U*)buf, i, DATA_FLAG_DIRECT_INDEX);
strcat(buf, ";");
GetDataStr(&CounterCardMoneyDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
strcat(buf, ";");
GetDataStr(&CounterCommonMoneyDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX);
strcat(buf, "\r\n");
break;
default:
return 0;
}
return 1;
}
// ÷òåíèå î÷åðåäíîé ñòðîêè äëÿ ñîçäàíèÿ ôàéëà csv æóðíàëîâ
int ReadFtpLogString(int index, char *buf)
{
static const char header[] = "Íîìåð çàïèñè;Âðåìÿ;Ñîáûòèå;Äàííûå\r\n";
if (index == 0)
{
strcpy(buf, header);
return 1;
}
else if ((index >= 1) && (index <= EVENT_RECORDS_COUNT))
{
TEventRecord record;
index -= 1;
GetEventRecord(&record, index);
sprintf(buf, "%d;", index);
PrintTimeString(&buf[strlen(buf)], record.time);
strcat(buf, ";");
PrintEventJournalRecord(&record, &buf[strlen(buf)], &buf[128]);
strcat(buf, ";");
strcpy(&buf[strlen(buf)], &buf[128]);
strcat(buf, "\r\n");
return 1;
}
return 0;
}
/// îòïðàâêà íà ftp-ñåðâåð îò÷åòà ñ÷åò÷èêîâ â ôîðìàòå csv
int FtpUploadCsvReport(NET_IP_ADDR ip, CPU_INT32U id, char* login, char* pass, CPU_INT32U time, CPU_INT08U flags)
{
uint16_t port = FTP_CONTROL_PORT;
FtpClientContext *ftp_context = (FtpClientContext *)term_buffer;
char *bufstr = &term_buffer[sizeof(FtpClientContext)];
int str_index;
int res_ftp;
char str[48];
memset(ftp_context, 0, sizeof(FtpClientContext));
if (ftpConnect(ftp_context, &ip, port, FTP_PASSIVE_MODE) != 0)
{
return -1;
}
if (ftpLogin(ftp_context, login, pass, NULL) != 0)
{
ftpClose(ftp_context);
return -2;
}
// ñîçäàäèì ïóòü ê êàòàëîãó âûãðóçêè /solarium/00000001/
res_ftp = ftpChangeWorkingDir(ftp_context, "solarium");
if (res_ftp != 0)
{
res_ftp = ftpMakeDir(ftp_context, "solarium");
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -3;
}
res_ftp = ftpChangeWorkingDir(ftp_context, "solarium");
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -3;
}
}
sprintf(str, "%08d", id);
res_ftp = ftpChangeWorkingDir(ftp_context, str);
if (res_ftp != 0)
{
res_ftp = ftpMakeDir(ftp_context, str);
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -3;
}
res_ftp = ftpChangeWorkingDir(ftp_context, str);
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -3;
}
}
if (flags & FTP_FLAG_SEND_COUNTERS)
{
// Ñ×ÅÒ×ÈÊÈ
res_ftp = ftpChangeWorkingDir(ftp_context, "counters");
if (res_ftp != 0)
{
res_ftp = ftpMakeDir(ftp_context, "counters");
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -3;
}
res_ftp = ftpChangeWorkingDir(ftp_context, "counters");
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -3;
}
}
// èìÿ ôàéëà counters/counters_20191201_121005.csv
strcpy(str, "counters_");
PrintSecDateTimeStringRaw(&str[strlen(str)], time);
strcpy(&str[strlen(str)], ".csv");
res_ftp = ftpOpenFile(ftp_context, str, FTP_FOR_WRITING | FTP_BINARY_TYPE);
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -4;
}
str_index = 0;
while (ReadFtpCountersString(str_index, bufstr))
{
res_ftp = ftpWriteFile(ftp_context, bufstr, strlen(bufstr), 0);
if (res_ftp != 0)
{
ftpDeleteFile(ftp_context, str);
ftpClose(ftp_context);
return -5;
}
str_index++;
}
res_ftp = ftpCloseFile(ftp_context);
if (res_ftp != 0)
{
ftpDeleteFile(ftp_context, str);
ftpClose(ftp_context);
return -6;
}
ftpChangeToParentDir(ftp_context);
// èìÿ ôàéëà counters.csv
strcpy(str, "counters.csv");
res_ftp = ftpOpenFile(ftp_context, str, FTP_FOR_WRITING | FTP_BINARY_TYPE);
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -4;
}
str_index = 0;
while (ReadFtpCountersString(str_index, bufstr))
{
res_ftp = ftpWriteFile(ftp_context, bufstr, strlen(bufstr), 0);
if (res_ftp != 0)
{
ftpDeleteFile(ftp_context, str);
ftpClose(ftp_context);
return -5;
}
str_index++;
}
res_ftp = ftpCloseFile(ftp_context);
if (res_ftp != 0)
{
ftpDeleteFile(ftp_context, str);
ftpClose(ftp_context);
return -6;
}
}
// ÆÓÐÍÀË
// èìÿ ôàéëà log_20191201_121005.csv
if (flags & FTP_FLAG_SEND_LOGS)
{
res_ftp = ftpChangeWorkingDir(ftp_context, "logs");
if (res_ftp != 0)
{
res_ftp = ftpMakeDir(ftp_context, "logs");
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -3;
}
res_ftp = ftpChangeWorkingDir(ftp_context, "logs");
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -3;
}
}
strcpy(str, "log_");
PrintSecDateTimeStringRaw(&str[strlen(str)], time);
strcpy(&str[strlen(str)], ".csv");
res_ftp = ftpOpenFile(ftp_context, str, FTP_FOR_WRITING | FTP_BINARY_TYPE);
if (res_ftp != 0)
{
ftpClose(ftp_context);
return -4;
}
str_index = 0;
while (ReadFtpLogString(str_index, bufstr))
{
res_ftp = ftpWriteFile(ftp_context, bufstr, strlen(bufstr), 0);
if (res_ftp != 0)
{
ftpDeleteFile(ftp_context, str);
ftpClose(ftp_context);
return -5;
}
str_index++;
}
res_ftp = ftpCloseFile(ftp_context);
if (res_ftp != 0)
{
ftpDeleteFile(ftp_context, str);
ftpClose(ftp_context);
return -6;
}
}
ftpClose(ftp_context);
return 0;
}
#endif //#ifdef CONFIG_FTP_CLIENT_ENABLE

17
PROJECT/app/ftp_app.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _FTP_APP_H_
#define _FTP_APP_H_
#include <includes.h>
extern CPU_INT08U time_to_ftp;
#define FTP_FLAG_SEND_COUNTERS 0x01
#define FTP_FLAG_SEND_LOGS 0x02
#define FTP_FLAG_CLEAR_COUNTERS 0x04
#define FTP_FLAG_CLEAR_LOGS 0x08
extern int FtpUploadCsvReport(NET_IP_ADDR ip, CPU_INT32U id, char* login, char* pass, CPU_INT32U time, CPU_INT08U flags);
extern void FtpCheckTimeToSend(CPU_INT32U systime);
#endif //_FTP_APP_H_

View File

@ -271,6 +271,117 @@ int HostWritePulses(CPU_INT32U ip_addr, CPU_INT32U count, CPU_INT32U len_ms)
return HostWriteParam(ip_addr, CONSOLE_TCP_DEFAULT_PORT, "PULSEOUT", str, HOST_SOCKET_DEFAULT_TIMEOUT); return HostWriteParam(ip_addr, CONSOLE_TCP_DEFAULT_PORT, "PULSEOUT", str, HOST_SOCKET_DEFAULT_TIMEOUT);
} }
int HostWriteDataTimeout(NET_SOCK_ID sock, char* str, int len, CPU_INT32U timeout)
{
CPU_INT32U time_stamp = OSTimeGet();
int tx_ctr = 0;
while (tx_ctr < len)
{
NET_ERR err;
int tx_size = NetSock_TxData(sock, &str[tx_ctr], len - tx_ctr, NET_SOCK_FLAG_NONE, &err);
OSTimeDly(10);
if (tx_size > 0)
{
tx_ctr += tx_size;
}
else
{
if ((OSTimeGet() - time_stamp) > timeout)
{
return -1;
}
}
}
return tx_ctr;
}
int HostReadData(NET_SOCK_ID sock, char *str, CPU_INT32U maxlen, CPU_INT32U timeout, NET_ERR *err)
{
CPU_INT32U time_stamp;
char *str_ptr = str;
CPU_INT32U len = 0;
CPU_INT08U exit_while;
time_stamp = OSTimeGet();
do
{
char c;
NET_SOCK_RTN_CODE ret_code;
exit_while = 0;
if (NetNIC_ConnStatusGet() != DEF_ON)
{
*err = NET_SOCK_ERR_FAULT;
break;
}
ret_code = NetSock_RxData(sock, &c, 1, NET_SOCK_FLAG_RX_NO_BLOCK, err);
switch (*err)
{
case NET_SOCK_ERR_NONE:
if (ret_code)
{
time_stamp = OSTimeGet();
*str_ptr++ = c;
len++;
if (c == '\n')
{
char *ptr = strrchr(str, '\n');
if (ptr) *ptr = 0;
ptr = strrchr(str, '\r');
if (ptr) *ptr = 0;
len = strlen(str);
*err = NET_SOCK_ERR_NONE;
exit_while = 1;
}
}
break;
case NET_SOCK_ERR_RX_Q_EMPTY:
if (OSTimeGet() - time_stamp < timeout)
{
OSTimeDly(2);
if (len > 0)
{
exit_while = 1;
}
*err = NET_SOCK_ERR_NONE;
}
break;
case NET_SOCK_ERR_INVALID_DATA_SIZE:
case NET_ERR_INIT_INCOMPLETE:
case NET_SOCK_ERR_NULL_PTR:
case NET_SOCK_ERR_NULL_SIZE:
case NET_SOCK_ERR_NOT_USED:
case NET_SOCK_ERR_CLOSED:
case NET_SOCK_ERR_FAULT:
case NET_SOCK_ERR_INVALID_SOCK:
case NET_SOCK_ERR_INVALID_FAMILY:
case NET_SOCK_ERR_INVALID_PROTOCOL:
case NET_SOCK_ERR_INVALID_TYPE:
case NET_SOCK_ERR_INVALID_STATE:
case NET_SOCK_ERR_INVALID_OP:
case NET_SOCK_ERR_INVALID_FLAG:
case NET_SOCK_ERR_INVALID_ADDR_LEN:
case NET_SOCK_ERR_RX_Q_CLOSED:
case NET_ERR_RX:
case NET_CONN_ERR_INVALID_CONN:
case NET_CONN_ERR_NOT_USED:
case NET_CONN_ERR_NULL_PTR:
case NET_CONN_ERR_INVALID_ADDR_LEN:
case NET_CONN_ERR_ADDR_NOT_USED:
case NET_OS_ERR_LOCK:
break;
default:
*err = NET_ERR_RX;
break;
}
} while ((*err == NET_SOCK_ERR_NONE) && (!exit_while));
return len;
}
/// çàäà÷à îïðîñà êîíòðîëëåðîâ ïîñòîâ ïî ñåòè /// çàäà÷à îïðîñà êîíòðîëëåðîâ ïîñòîâ ïî ñåòè
void HostAppTask(void *p_arg) void HostAppTask(void *p_arg)
{ {

View File

@ -14,4 +14,9 @@ extern int HostCheckIpDevice(CPU_INT32U ip_addr, CPU_INT16U port, CPU_INT32U tim
extern int HostWriteParam(CPU_INT32U ip_addr, CPU_INT16U port, char* param_str, char* param_val, CPU_INT32U timeout); extern int HostWriteParam(CPU_INT32U ip_addr, CPU_INT16U port, char* param_str, char* param_val, CPU_INT32U timeout);
extern int HostWritePulses(CPU_INT32U ip_addr, CPU_INT32U count, CPU_INT32U len_ms); extern int HostWritePulses(CPU_INT32U ip_addr, CPU_INT32U count, CPU_INT32U len_ms);
extern NET_SOCK_ID HostConnectSocket(CPU_INT32U ip_addr, CPU_INT16U port, CPU_INT32U timeout, NET_ERR* err);
extern int HostWriteDataTimeout(NET_SOCK_ID sock, char* str, int len, CPU_INT32U timeout);
extern int HostReadData(NET_SOCK_ID sock, char *str, CPU_INT32U maxlen, CPU_INT32U timeout, NET_ERR *err);
#endif //_HOST_APP_H_ #endif //_HOST_APP_H_

View File

@ -1,12 +1,31 @@
#include <includes.h> #include <includes.h>
#include <intrinsics.h> #include <intrinsics.h>
#include "lcd.h" #include "lcd.h"
#include "symtab.h"
unsigned char lcd_x = 0, lcd_y = 0;
#ifdef CONFIG_LCD_1602A
// ìàêñèìàëüíîå ÷èñëî ïîëüçîâàòåëüñêèõ çíàêîâ â çíàêîãåíåðàòîðå
#define LCD_MAX_CHAR_SYG 8
// ñïèñîê òåêóùèõ ñèìâîëîâ â çíàêîãåíåðàòîðå
unsigned char current_rus_syg[LCD_MAX_CHAR_SYG] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned char current_syg_index = 0;
unsigned char lcd_lines[2][16];
void LCD_putcmd(unsigned char data,unsigned char cmdtype);
#endif
const unsigned char rus_sym_table[64]= const unsigned char rus_sym_table[64]=
{ 0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4, { 0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4,
0xA5,0x03,0x4B,0xA7,0x4D,0x48,0x4F,0xA8, 0xA5,0x03,0x4B,0xA7,0x4D,0x48,0x4F,0xA8,
0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB, 0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB,
#ifdef CONFIG_LCD_1602A
0xAC,0xE2,0xAD,0xAE,'b',0xAF,0xB0,0xB1,
#else
0xAC,0xE2,0xAD,0xAE,0x02,0xAF,0xB0,0xB1, 0xAC,0xE2,0xAD,0xAE,0x02,0xAF,0xB0,0xB1,
#endif
0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7, 0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7,
0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE, 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE,
0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0, 0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0,
@ -17,16 +36,15 @@ void us_delay(unsigned long x)
{ {
while (x--) while (x--)
{ {
for (int i=0; i<5; i++) __no_operation(); for (int i=0; i<10; i++) __no_operation();
} }
} }
#ifdef CONFIG_LCD_1602A
void LCD_putch(unsigned char data) //
void LCD_WriteCGRAM(unsigned char data)
{ {
if (data >= 0xC0) data = rus_sym_table[data-0xC0];
LCD_SET_DATA_OUT();
// LCD Upper 4 bits data // LCD Upper 4 bits data
LCD_SET_RS_PIN(); // RS = 1, E = 1 LCD_SET_RS_PIN(); // RS = 1, E = 1
LCD_SET_E_PIN(); LCD_SET_E_PIN();
@ -46,10 +64,126 @@ void LCD_putch(unsigned char data)
LCD_OUT_DATA(data); LCD_OUT_DATA(data);
us_delay(1); us_delay(1);
// E=0; write data
LCD_CLR_E_PIN();
us_delay(100);
}
unsigned char LCD_ConvertSymOrient(unsigned int sym_ofst, unsigned char byte)
{
unsigned char data = 0;
unsigned char i;
for (i = 0; i < 5; i++)
{
if (symtab[sym_ofst + i] & (1 << byte)) data |= (1 << (4 - i));
}
return data;
}
//
void LCD_CreateChar(unsigned char syg_index, unsigned char data)
{
unsigned int sym_ofst = (data - 0x20) * 5UL;
LCD_putcmd(0x40 + syg_index * 8, LCD_2CYCLE);
LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 0));
LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 1));
LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 2));
LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 3));
LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 4));
LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 5));
LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 6));
LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 7));
}
#endif
void LCD_putch(unsigned char data)
{
unsigned char data_out;
#ifndef CONFIG_LCD_1602A
if (data >= 0xC0) data_out = rus_sym_table[data-0xC0];
else data_out = data;
#else
if (data >= 0xC0)
{
if (rus_sym_table[data-0xC0] < 0xA0)
{
data_out = rus_sym_table[data-0xC0];
}
else
{
CPU_INT08U i;
CPU_INT08U finded = 0;
for (i = 0; i < LCD_MAX_CHAR_SYG; i++)
{
if (data == current_rus_syg[i])
{
data_out = i;
finded = 1;
break;
}
}
if (!finded)
{
CPU_INT08U n, j;
CPU_INT08U *ptr;
for (j = 0; j < LCD_MAX_CHAR_SYG; j++)
{
if (current_rus_syg[j] == 0) break;
ptr = (CPU_INT08U *)lcd_lines;
for (n = 0; n < 32; n++, ptr++)
{
if (current_rus_syg[j] == *ptr)
{
break;
}
}
if (n == 32)
{
current_rus_syg[j] = 0;
break;
}
}
if (j < LCD_MAX_CHAR_SYG) current_syg_index = j;
LCD_CreateChar(current_syg_index, data);
current_rus_syg[current_syg_index] = data;
data_out = current_syg_index;
LCD_goto(lcd_x, lcd_y);
}
}
}
else
{
data_out = data;
}
lcd_lines[lcd_y][lcd_x] = data;
#endif
LCD_SET_DATA_OUT();
// LCD Upper 4 bits data
LCD_SET_RS_PIN(); // RS = 1, E = 1
LCD_SET_E_PIN();
LCD_CLR_RW_PIN();
us_delay(1);
LCD_OUT_DATA(data_out >> 4);
us_delay(1);
// E=0; write data
LCD_CLR_E_PIN();
us_delay(1);
// LCD Lower 4 bits data
LCD_SET_E_PIN(); // RS = 1, E = 1
us_delay(1);
LCD_OUT_DATA(data_out);
us_delay(1);
// E=0; write data // E=0; write data
LCD_CLR_E_PIN(); LCD_CLR_E_PIN();
us_delay(100); us_delay(100);
// OSTimeDly(1); // Wait for busy flag (BF) // OSTimeDly(1); // Wait for busy flag (BF)
lcd_x++;
} }
void LCD_putch_table(unsigned char data) void LCD_putch_table(unsigned char data)
@ -78,6 +212,7 @@ void LCD_putch_table(unsigned char data)
LCD_CLR_E_PIN(); LCD_CLR_E_PIN();
us_delay(100); us_delay(100);
// OSTimeDly(1); // Wait for busy flag (BF) // OSTimeDly(1); // Wait for busy flag (BF)
lcd_x++;
} }
unsigned char LCD_getch() unsigned char LCD_getch()
@ -143,7 +278,8 @@ void LCD_putcmd(unsigned char data,unsigned char cmdtype)
LCD_CLR_E_PIN(); LCD_CLR_E_PIN();
// cmdtype = 0; One cycle write, cmdtype = 1; Two cycle writes // cmdtype = 0; One cycle write, cmdtype = 1; Two cycle writes
if (cmdtype == LCD_2CYCLE) { if (cmdtype == LCD_2CYCLE)
{
// LCD Lower 4 bits data // LCD Lower 4 bits data
us_delay(1); us_delay(1);
LCD_SET_E_PIN(); // RS = 0, E = 1 LCD_SET_E_PIN(); // RS = 0, E = 1
@ -156,10 +292,14 @@ void LCD_putcmd(unsigned char data,unsigned char cmdtype)
us_delay(1); us_delay(1);
//while(LCD_get_status() & 0x80); //while(LCD_get_status() & 0x80);
OSTimeDly(2); // Wait for busy flag (BF) OSTimeDly(3); // Wait for busy flag (BF)
//LCD_get_status(); //LCD_get_status();
} }
else
{
OSTimeDly(3);
}
} }
@ -229,40 +369,36 @@ void InitLcd()
InitLcdPins(); InitLcdPins();
// Wait for more than 15 ms after VCC rises to 4.5 V // Wait for more than 15 ms after VCC rises to 4.5 V
OSTimeDly(30); OSTimeDly(100);
// Send Command 0x30 // Send Command 0x30
LCD_putcmd(0x30,LCD_1CYCLE); LCD_putcmd(0x30,LCD_1CYCLE);
us_delay(40);
// Send Command 0x30 // Send Command 0x30
LCD_putcmd(0x30,LCD_1CYCLE); LCD_putcmd(0x30,LCD_1CYCLE);
us_delay(40);
// Send Command 0x30 // Send Command 0x30
LCD_putcmd(0x30,LCD_1CYCLE); LCD_putcmd(0x30,LCD_1CYCLE);
us_delay(40);
// Function set: Set interface to be 4 bits long (only 1 cycle write). // Function set: Set interface to be 4 bits long (only 1 cycle write).
LCD_putcmd(0x20,LCD_1CYCLE); LCD_putcmd(0x20,LCD_1CYCLE);
us_delay(40);
// Function set: DL=0;Interface is 4 bits, N=1; 2 Lines, F=0; 5x8 dots font) // Function set: DL=0;Interface is 4 bits, N=1; 2 Lines, F=0; 5x8 dots font)
LCD_putcmd(0x28,LCD_2CYCLE); LCD_putcmd(0x28,LCD_2CYCLE);
// Display Off: D=0; Display off, C=0; Cursor Off, B=0; Blinking Off // Display Off: D=0; Display off, C=0; Cursor Off, B=0; Blinking Off
LCD_putcmd(0x08,LCD_2CYCLE); //LCD_putcmd(0x08,LCD_2CYCLE);
// Display On, Cursor Off
LCD_putcmd(0x0C,LCD_2CYCLE);
// Display Clear // Display Clear
LCD_putcmd(0x01,LCD_2CYCLE); LCD_putcmd(0x01,LCD_2CYCLE);
// Entry Mode Set: I/D=1; Increment, S=0; No shift // Entry Mode Set: I/D=1; Increment, S=0; No shift
LCD_putcmd(0x06,LCD_2CYCLE); LCD_putcmd(0x06,LCD_2CYCLE);
// Display On, Cursor Off
LCD_putcmd(0x0C,LCD_2CYCLE);
} }
void LCD_gotoline(unsigned char n) void LCD_gotoline(unsigned char n)
{ {
switch (n){ switch (n){
case 0: LCD_putcmd(LCD_GOTO_LINE_0, LCD_2CYCLE); break; case 0: LCD_putcmd(LCD_GOTO_LINE_0, LCD_2CYCLE); lcd_x = 0; lcd_y = n; break;
case 1: LCD_putcmd(LCD_GOTO_LINE_1, LCD_2CYCLE); break; case 1: LCD_putcmd(LCD_GOTO_LINE_1, LCD_2CYCLE); lcd_x = 0; lcd_y = n; break;
case 2: LCD_putcmd(LCD_GOTO_LINE_2, LCD_2CYCLE); break; #ifndef CONFIG_LCD_1602A
case 3: LCD_putcmd(LCD_GOTO_LINE_3, LCD_2CYCLE); break; case 2: LCD_putcmd(LCD_GOTO_LINE_2, LCD_2CYCLE); lcd_x = 0; lcd_y = n; break;
case 3: LCD_putcmd(LCD_GOTO_LINE_3, LCD_2CYCLE); lcd_x = 0; lcd_y = n; break;
#endif
default: return; default: return;
} }
} }
@ -271,17 +407,26 @@ void LCD_gotoline(unsigned char n)
void LCD_puts(unsigned char *s, unsigned char n) void LCD_puts(unsigned char *s, unsigned char n)
{ {
unsigned char i; unsigned char i;
LCD_putcmd(0x28,LCD_2CYCLE);
LCD_gotoline(n); LCD_gotoline(n);
i=0; i=0;
#ifdef CONFIG_LCD_1602A
while((*s != 0) && (*s != '\n') && (i<16))
#else
while((*s != 0) && (*s != '\n') && (i<20)) while((*s != 0) && (*s != '\n') && (i<20))
#endif
{ {
LCD_putch(*s); LCD_putch(*s);
s++; s++;
i++; i++;
} }
#ifdef CONFIG_LCD_1602A
while(i<16)
#else
while(i<20) while(i<20)
#endif
{ {
LCD_putch(' '); LCD_putch(' ');
i++; i++;
@ -292,10 +437,12 @@ void LCD_puts(unsigned char *s, unsigned char n)
void LCD_goto(unsigned char m, unsigned char n) void LCD_goto(unsigned char m, unsigned char n)
{ {
switch (n){ switch (n){
case 0: LCD_putcmd(LCD_GOTO_LINE_0+m, LCD_2CYCLE); break; case 0: LCD_putcmd(LCD_GOTO_LINE_0+m, LCD_2CYCLE); lcd_x = m; lcd_y = n; break;
case 1: LCD_putcmd(LCD_GOTO_LINE_1+m, LCD_2CYCLE); break; case 1: LCD_putcmd(LCD_GOTO_LINE_1+m, LCD_2CYCLE); lcd_x = m; lcd_y = n; break;
case 2: LCD_putcmd(LCD_GOTO_LINE_2+m, LCD_2CYCLE); break; #ifndef CONFIG_LCD_1602A
case 3: LCD_putcmd(LCD_GOTO_LINE_3+m, LCD_2CYCLE); break; case 2: LCD_putcmd(LCD_GOTO_LINE_2+m, LCD_2CYCLE); lcd_x = m; lcd_y = n; break;
case 3: LCD_putcmd(LCD_GOTO_LINE_3+m, LCD_2CYCLE); lcd_x = m; lcd_y = n; break;
#endif
default: return; default: return;
} }
} }
@ -319,6 +466,10 @@ void LCD_clear(void)
{ {
// Display Clear // Display Clear
LCD_putcmd(0x01,LCD_2CYCLE); LCD_putcmd(0x01,LCD_2CYCLE);
lcd_x = 0; lcd_y = 0;
#ifdef CONFIG_LCD_1602A
memset(lcd_lines, 0, sizeof(lcd_lines));
#endif
} }
void LCD_cursor_on(void) void LCD_cursor_on(void)

View File

@ -0,0 +1,268 @@
#ifdef CONFIG_LCD_1602A
const unsigned char symtab[1120] = { /* 224 * 5 = 1120 bytes */
/********************************************************************************
* In commentaries there are codes of symbols NOT indexes in array *
********************************************************************************/
/********************************************************************************
* 0x00...0x1F - codes of control symbols. *
* They are not printable and therefore absent in this table *
********************************************************************************/
/* 0x20...0x2F */
0x00,0x00,0x00,0x00,0x00, // 'space'
0x00,0x00,0x5f,0x00,0x00, // '!'
0x07,0x00,0x07,0x00,0x00, // '"'
0x14,0x7f,0x14,0x7f,0x14, // '#'
0x24,0x2a,0x7f,0x2a,0x12, // '$'
0x23,0x13,0x08,0x64,0x62, // '%'
0x36,0x49,0x55,0x22,0x50, // '&'
0x05,0x03,0x00,0x00,0x00, // '''
0x1c,0x22,0x41,0x00,0x00, // '('
0x41,0x22,0x1c,0x00,0x00, // ')'
0x14,0x08,0x3e,0x08,0x14, // '*'
0x08,0x08,0x3e,0x08,0x08, // '+'
0x50,0x30,0x00,0x00,0x00, // ','
0x08,0x08,0x08,0x08,0x08, // '-'
0x60,0x60,0x00,0x00,0x00, // '.'
0x20,0x10,0x08,0x04,0x02, // '/'
/* 0x30...0x3F */
0x3E,0x51,0x49,0x45,0x3E, // '0'
0x00,0x42,0x7F,0x40,0x00, // '1'
0x42,0x61,0x51,0x49,0x46, // '2'
0x21,0x41,0x45,0x4b,0x31, // '3'
0x18,0x14,0x12,0x7f,0x10, // '4'
0x27,0x45,0x45,0x45,0x39, // '5'
0x3c,0x4a,0x49,0x49,0x30, // '6'
0x01,0x71,0x09,0x05,0x03, // '7'
0x36,0x49,0x49,0x49,0x36, // '8'
0x06,0x49,0x49,0x29,0x1e, // '9'
0x00,0x36,0x36,0x00,0x00, // ':'
0x00,0x56,0x36,0x00,0x00, // ';'
0x08,0x14,0x22,0x41,0x00, // '<'
0x14,0x14,0x14,0x14,0x14, // '='
0x41,0x22,0x14,0x08,0x00, // '>'
0x02,0x01,0x51,0x09,0x06, // '?'
/* 0x40...0x4F */
0x32,0x49,0x79,0x41,0x3e, // '@'
0x7e,0x11,0x11,0x11,0x7e, // 'A'
0x7F,0x49,0x49,0x49,0x36, // 'B'
0x3e,0x41,0x41,0x41,0x22, // 'C'
0x7f,0x41,0x41,0x22,0x1c, // 'D'
0x7f,0x49,0x49,0x49,0x41, // 'E'
0x7f,0x09,0x09,0x09,0x01, // 'F'
0x3e,0x41,0x49,0x49,0x7a, // 'G'
0x7f,0x08,0x08,0x08,0x7f, // 'H'
0x00,0x41,0x7f,0x41,0x00, // 'I'
0x20,0x40,0x41,0x3f,0x01, // 'J'
0x7f,0x08,0x14,0x22,0x41, // 'K'
0x7f,0x40,0x40,0x40,0x40, // 'L'
0x7f,0x02,0x0c,0x02,0x7f, // 'M'
0x7f,0x04,0x08,0x10,0x7f, // 'N'
0x3e,0x41,0x41,0x41,0x3e, // 'O'
/* 0x50...0x5F */
0x7f,0x09,0x09,0x09,0x06, // 'P'
0x3e,0x41,0x51,0x21,0x5e, // 'Q'
0x7f,0x09,0x19,0x29,0x46, // 'R'
0x46,0x49,0x49,0x49,0x31, // 'S'
0x01,0x01,0x7f,0x01,0x01, // 'T'
0x3f,0x40,0x40,0x40,0x3f, // 'U'
0x1f,0x20,0x40,0x20,0x1f, // 'V'
0x3f,0x40,0x38,0x40,0x3f, // 'W'
0x63,0x14,0x08,0x14,0x63, // 'X'
0x07,0x08,0x70,0x08,0x07, // 'Y'
0x61,0x51,0x49,0x45,0x43, // 'Z'
0x00,0x7f,0x41,0x41,0x00, // '['
0x02,0x04,0x08,0x10,0x20, // '\'
0x00,0x41,0x41,0x7f,0x00, // ']'
0x04,0x02,0x01,0x02,0x04, // '^'
0x40,0x40,0x40,0x40,0x40, // '_'
/* 0x60...0x6F */
0x00,0x01,0x02,0x00,0x00, // '`'
0x20,0x54,0x54,0x54,0x78, // 'a'
0x7f,0x48,0x44,0x44,0x38, // 'b'
0x38,0x44,0x44,0x44,0x20, // 'c'
0x38,0x44,0x44,0x48,0x7f, // 'd'
0x38,0x54,0x54,0x54,0x18, // 'e'
0x08,0x7e,0x09,0x01,0x02, // 'f'
0x08,0x54,0x54,0x54,0x3c, // 'g'
0x7f,0x08,0x04,0x04,0x78, // 'h'
0x00,0x44,0x7d,0x40,0x00, // 'i'
0x20,0x40,0x44,0x3d,0x00, // 'j'
0x7f,0x10,0x28,0x44,0x00, // 'k'
0x00,0x41,0x7f,0x40,0x00, // 'l'
0x7c,0x04,0x18,0x04,0x78, // 'm'
0x7c,0x08,0x04,0x04,0x78, // 'n'
0x38,0x44,0x44,0x44,0x38, // 'o'
/* 0x70...0x7F */
0x7c,0x14,0x14,0x14,0x08, // 'p'
0x08,0x14,0x14,0x14,0x7c, // 'q'
0x7c,0x08,0x04,0x04,0x08, // 'r'
0x48,0x54,0x54,0x54,0x20, // 's'
0x04,0x3f,0x44,0x40,0x20, // 't'
0x3c,0x40,0x40,0x20,0x7c, // 'u'
0x1c,0x20,0x40,0x20,0x1c, // 'v'
0x3c,0x40,0x30,0x40,0x3c, // 'w'
0x44,0x28,0x10,0x28,0x44, // 'x'
0x0c,0x50,0x50,0x50,0x3c, // 'y'
0x44,0x64,0x54,0x4c,0x44, // 'z'
0x00,0x08,0x36,0x41,0x00, // '{'
0x00,0x00,0x7F,0x00,0x00, // '|'
0x00,0x41,0x36,0x08,0x00, // '}'
0x08,0x04,0x08,0x10,0x08, // '~'
0x7F,0x41,0x41,0x41,0x7F, // ''
/* 0x80...0x8F */
0x70,0x4C,0x43,0x4C,0x70, // 'DELTA'
0x3E,0x49,0x49,0x49,0x3E, // 'THETA'
0x60,0x1C,0x03,0x1C,0x60, // 'LAMBDA'
0x63,0x49,0x49,0x49,0x63, // 'KSI'
0x63,0x55,0x49,0x41,0x41, // 'SIGMA'
0x0F,0x08,0x7F,0x08,0x0F, // 'PSI'
0x5E,0x71,0x01,0x71,0x5E, // 'OMEGA'
0x08,0x1C,0x2A,0x08,0x08, // 'left arrow'
0x04,0x02,0x7F,0x02,0x04, // 'up arrow'
0x08,0x08,0x2A,0x1C,0x08, // 'right arrow'
0x10,0x20,0x7F,0x20,0x10, // 'down arrow'
0x10,0x38,0x54,0x10,0x0F, // 'ENTER arrow'
0x00,0x08,0x1C,0x3E,0x00, // 'left triangle'
0x00,0x08,0x0C,0x08,0x00, // 'up triangle (small)'
0x00,0x3E,0x1C,0x08,0x00, // 'right triangle'
0x00,0x10,0x30,0x10,0x00, // 'down triangle (small)'
/* 0x90...0x9F */
0x1C,0x22,0x1C,0x22,0x20, // 'alpha'
0x00,0x7E,0x25,0x1A,0x00, // 'beta'
0x02,0x34,0x48,0x34,0x02, // 'gamma'
0x00,0x3A,0x45,0x39,0x00, // 'delta'
0x28,0x54,0x44,0x28,0x00, // 'epsilon'
0x32,0x2C,0x24,0x24,0x60, // 'zeta'
0x00,0x3C,0x04,0x78,0x00, // 'eta'
0x00,0x3C,0x52,0x3C,0x00, // 'theta'
0x00,0x00,0x3C,0x40,0x00, // 'iota'
0x24,0x54,0x38,0x54,0x48, // 'kappa'
0x00,0x72,0x0C,0x30,0x40, // 'lambda'
0x40,0x3C,0x20,0x1C,0x20, // 'mu'
0x0C,0x70,0x24,0x18,0x00, // 'nu'
0x35,0x2A,0x2A,0x20,0x60, // 'ksi'
0x38,0x44,0x44,0x44,0x38, // 'omicron'
0x4C,0x7C,0x04,0x7C,0x04, // 'pi'
/* 0xA0..0xAF */
0x40,0x7C,0x12,0x0C,0x00, //0 'rho'
0x38,0x54,0x54,0x54,0x22, //1 'sigma'
0x0C,0x44,0x3C,0x04,0x02, //2 'tau'
0x04,0x38,0x40,0x44,0x38, //3 'upsilon'
0xFC,0xFA,0xDA,0xFA,0xFC, //4 'lock key'
0xF8,0xF8,0xDA,0xFA,0xFC, //5 'unlock key'
0x00,0x08,0x1C,0x3E,0x7F, //6 'Left'
0x00,0x7F,0x3E,0x1C,0x08, //7 'Right'
0x00,0x06,0x09,0x09,0x06, //8 'Gradus'
0x00,0x0C,0x0C,0x00,0x00, //9 'Mul'
0x00,0x5F,0x00,0x5F,0x00, //A '!!'
0x7F,0x00,0x7F,0x00,0x7F, //B '|||'
0x00,0x10,0x38,0x10,0x1F, //C 'Enter'
0x7F,0x00,0x7F,0x00,0x60, //D '||.'
0x7F,0x00,0x60,0x00,0x60, //E '|..'
0x60,0x00,0x60,0x00,0x60, //F '...'
/* 0xB0...0xBF */
0x7F,0x0C,0x30,0x7F,0x06, // 'number'
0x24,0x24,0x2E,0x24,0x24, // 'plus-minus'
0x08,0x14,0x00,0x08,0x14, // 'left quotes'
0x14,0x08,0x00,0x14,0x08, // 'right quotes'
0x02,0x05,0x3E,0x41,0x22, // 'Celsius degree'
0x0A,0x55,0x55,0x55,0x28, // 'paragraph'
0x00,0x00,0x18,0x18,0x00, // 'multiply point'
0x22,0x14,0x08,0x14,0x22, // 'multiply cross'
0x10,0x38,0x7F,0x0E,0x04, // 'left-right'
0x1C,0x14,0x08,0x14,0x1C, // 'infinity'
0x15,0x1B,0x00,0x00,0x00, // 'CUBE'
0x03,0x07,0x0F,0x07,0x03, // 'Vertical symbol'
0x03,0x05,0x09,0x05,0x03, // 'Nill Vertical symbol'
0x80,0x80,0x80,0x80,0x80, // 'cursor'
0x04,0x0E,0x15,0x04,0x78, // 'ESCAPE symbol ???'
0x01,0x00,0x01,0x00,0x01, // '...'
/* 0xC0...0xCF */
0x7e,0x11,0x11,0x11,0x7e, // 'À'
0x7F,0x49,0x49,0x49,0x33, // 'Á'
0x7F,0x49,0x49,0x49,0x36, // 'Â'
0x7F,0x01,0x01,0x01,0x03, // 'Ã'
0x70,0x29,0x27,0x21,0x7F, // 'Ä'
0x7f,0x49,0x49,0x49,0x41, // 'Å'
0x77,0x08,0x7f,0x08,0x77, // 'Æ'
0x41,0x49,0x49,0x49,0x36, // 'Ç'
0x7f,0x20,0x10,0x08,0x7f, // 'È'
0x7c,0x21,0x12,0x09,0x7c, // 'É'
0x7f,0x08,0x14,0x22,0x41, // 'K'
0x20,0x41,0x3f,0x01,0x7f, // 'Ë'
0x7f,0x02,0x0c,0x02,0x7f, // 'Ì'
0x7f,0x08,0x08,0x08,0x7f, // 'Í'
0x3e,0x41,0x41,0x41,0x3e, // 'Î'
0x7f,0x01,0x01,0x01,0x7f, // 'Ï'
/* 0xD0...0xDF */
0x7f,0x09,0x09,0x09,0x06, // 'Ð'
0x3e,0x41,0x41,0x41,0x22, // 'Ñ'
0x01,0x01,0x7f,0x01,0x01, // 'Ò'
0x47,0x28,0x10,0x08,0x07, // 'Ó'
0x1c,0x22,0x7f,0x22,0x1c, // 'Ô'
0x63,0x14,0x08,0x14,0x63, // 'Õ'
0x7f,0x40,0x40,0x40,0xff, // 'Ö'
0x07,0x08,0x08,0x08,0x7f, // '×'
0x7f,0x40,0x7f,0x40,0x7f, // 'Ø'
0x7f,0x40,0x7f,0x40,0xff, // 'Ù'
0x01,0x7f,0x48,0x48,0x30, // 'Ú'
0x7f,0x48,0x30,0x00,0x7f, // 'Û'
0x7F,0x48,0x48,0x48,0x30, // 'Ü'
0x22,0x41,0x49,0x49,0x3e, // 'Ý'
0x7f,0x08,0x3e,0x41,0x3e, // 'Þ'
0x46,0x29,0x19,0x09,0x7f, // 'ß'
/* 0xE0...0xEF */
0x20,0x54,0x54,0x54,0x78, // 'à'
0x3c,0x4a,0x4a,0x49,0x31, // 'á'
0x7c,0x54,0x54,0x54,0x28, // 'â'
0x7c,0x04,0x04,0x04,0x0c, // 'ã'
0xe0,0x54,0x4c,0x44,0xfc, // 'ä'
0x38,0x54,0x54,0x54,0x18, // 'å'
0x6c,0x10,0x7c,0x10,0x6c, // 'æ'
0x44,0x44,0x54,0x54,0x28, // 'ç'
0x7c,0x20,0x10,0x08,0x7c, // 'è'
0x78,0x42,0x24,0x12,0x78, // 'é'
0x7c,0x10,0x10,0x28,0x44, // 'ê'
0x20,0x44,0x3c,0x04,0x7c, // 'ë'
0x7c,0x08,0x10,0x08,0x7c, // 'ì'
0x7c,0x10,0x10,0x10,0x7c, // 'í'
0x38,0x44,0x44,0x44,0x38, // 'î'
0x7c,0x04,0x04,0x04,0x7c, // 'ï'
/* 0xF0...0xFF */
0x7c,0x14,0x14,0x14,0x08, // 'p'
0x38,0x44,0x44,0x44,0x20, // 'c'
0x04,0x04,0x7c,0x04,0x04, // 'ò'
0x0c,0x50,0x50,0x50,0x3c, // 'ó'
0x30,0x48,0xfe,0x48,0x30, // 'ô'
0x44,0x28,0x10,0x28,0x44, // 'õ'
0x7c,0x40,0x40,0x40,0xfc, // 'ö'
0x0c,0x10,0x10,0x10,0x7c, // '÷'
0x7c,0x40,0x7c,0x40,0x7c, // 'ø'
0x7c,0x40,0x7c,0x40,0xfc, // 'ù'
0x04,0x7c,0x50,0x50,0x20, // 'ú'
0x7c,0x50,0x20,0x00,0x7c, // 'û'
0x7c,0x50,0x50,0x20,0x00, // 'ü'
0x28,0x44,0x54,0x54,0x38, // 'ý'
0x7c,0x10,0x38,0x44,0x38, // 'þ'
0x08,0x54,0x34,0x14,0x7c, // 'ÿ'
};
#endif

View File

@ -11,11 +11,10 @@
#define SYMB_GO_UP 0x87 #define SYMB_GO_UP 0x87
#define SYMB_GO_DOWN 0x86 #define SYMB_GO_DOWN 0x86
#define SYMB_RIGHT_ARROW 0x13 #define SYMB_RIGHT_ARROW 0x3E
#define SYMB_DESC_MARK 0x84 #define SYMB_DESC_MARK 0x3E
#define SYMB_IND_MARK 0x85 #define SYMB_IND_MARK 0x3C
#define SYMB_POINT_MARK 0xDF #define SYMB_POINT_MARK 0x3E
// ñòðóêòóðà îïèñàíèÿ ïóíêòà ìåíþ // ñòðóêòóðà îïèñàíèÿ ïóíêòà ìåíþ

View File

@ -0,0 +1,875 @@
#include <includes.h>
#include "app_serv.h"
#include "ftp_client.h"
#include <string.h>
#include "time.h"
#include "host_app.h"
/**
* @brief Removes all trailing whitespace from a string
* @param[in,out] s Pointer to a NULL-terminated character string
**/
void strRemoveTrailingSpace(char *s)
{
char *end;
// Search for the first whitespace to remove
// at the end of the string
for (end = NULL; *s != '\0'; s++)
{
if (*s != ' ')
end = NULL;
else if (!end)
end = s;
}
// Trim whitespace from the end
if (end) *end = '\0';
}
/**
* @brief Convert a binary IPv4 address to dot-decimal notation
* @param[in] ipAddr Binary representation of the IPv4 address
* @param[out] str NULL-terminated string representing the IPv4 address
* @return Pointer to the formatted string
**/
char *ipv4AddrToString(uint32_t ipAddr, char *str)
{
uint8_t *p;
static char buffer[16];
// The str parameter is optional
if (!str) str = buffer;
// Cast the address to byte array
p = (uint8_t *) &ipAddr;
// Format IPv4 address
sprintf(str, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
// Return a pointer to the formatted string
return str;
}
/**
* @brief Establish a connection with the specified FTP server
* @param[in] context Pointer to the FTP client context
* @param[in] interface Underlying network interface (optional parameter)
* @param[in] serverAddr IP address of the FTP server
* @param[in] serverPort Port number
* @param[in] flags Connection options
* @return Error code
**/
int ftpConnect(FtpClientContext *context, uint32_t *serverAddr, uint16_t serverPort, uint32_t flags)
{
int error;
uint32_t replyCode;
NET_ERR err;
// Invalid context?
if (context == NULL)
return ERROR_INVALID_PARAMETER;
// Clear context
memset(context, 0, sizeof(FtpClientContext));
// Save the IP address of the FTP server
context->serverAddr = *serverAddr;
// Use passive mode?
if (flags & FTP_PASSIVE_MODE)
context->passiveMode = 1;
else
context->passiveMode = 0;
// Open control socket
context->controlSocket = HostConnectSocket(context->serverAddr, serverPort, FTP_CLIENT_DEFAULT_TIMEOUT, &err);
if ((err != NET_SOCK_ERR_NONE) || (context->controlSocket < 0))
{
return ERROR_OPEN_FAILED;
}
// Wait for the connection greeting reply
error = ftpSendCommand(context, NULL, &replyCode);
// Any communication error to report?
if (error >= 0)
{
// Check FTP response code
if (!FTP_REPLY_CODE_2YZ(replyCode))
error = ERROR_UNEXPECTED_RESPONSE;
}
// Any error to report?
if (error < 0)
{
// Clean up side effects
NetSock_Close(context->controlSocket, &err);
context->controlSocket = -1;
}
// Return status code
return error;
}
/**
* @brief Login to the FTP server using the provided username and password
* @param[in] context Pointer to the FTP client context
* @param[in] username The username to login under
* @param[in] password The password to use
* @param[in] account Account name
* @return Error code
**/
int ftpLogin(FtpClientContext *context, const char *username, const char *password, const char *account)
{
int error;
uint32_t replyCode;
// Invalid context?
if (context == NULL)
return ERROR_INVALID_PARAMETER;
// Format the USER command
sprintf((char*)context->buffer, "USER %s\r\n", username);
// Send the command to the server
error = ftpSendCommand(context, (char const*)context->buffer, &replyCode);
// Any error to report?
if (error) return error;
// Check FTP response code
if (FTP_REPLY_CODE_2YZ(replyCode))
return 0;
else if(!FTP_REPLY_CODE_3YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
// Format the PASS command
sprintf((char*)context->buffer, "PASS %s\r\n", password);
// Send the command to the server
error = ftpSendCommand(context, (char const*)context->buffer, &replyCode);
// Any error to report?
if (error) return error;
// Check FTP response code
if(FTP_REPLY_CODE_2YZ(replyCode))
return 0;
else if(!FTP_REPLY_CODE_3YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
// Format the ACCT command
sprintf((char*)context->buffer, "ACCT %s\r\n", account);
// Send the command to the server
error = ftpSendCommand(context, (char const*)context->buffer, &replyCode);
// Any error to report?
if (error) return error;
// Check FTP response code
if (!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
// Successful processing
return 0;
}
/**
* @brief Set the port to be used in data connection
* @param[in] context Pointer to the FTP client context
* @param[in] ipAddr Host address
* @param[in] port Port number
* @return Error code
**/
int ftpSetPort(FtpClientContext *context, const uint32_t *ipAddr, uint16_t port)
{
int error;
uint32_t replyCode;
char *p;
// Invalid context?
if (context == NULL)
return ERROR_INVALID_PARAMETER;
#if 1
// IPv4 FTP client?
if (1)//(ipAddr->length == sizeof(Ipv4Addr))
{
// Format the PORT command
strcpy((char*)context->buffer, "PORT ");
// Append host address
ipv4AddrToString((uint32_t)ipAddr, (char*)context->buffer + 5);
// Parse the resulting string
for (p = (char*)context->buffer; *p != '\0'; p++)
{
// Change dots to commas
if (*p == '.') *p = ',';
}
// Append port number
sprintf(p, "%d,%d\r\n", (port >> 8), (port & 0xFF));
}
else
#endif
// Invalid IP address?
{
// Report an error
return ERROR_INVALID_ADDRESS;
}
// Send the command to the server
error = ftpSendCommand(context, (char const*)context->buffer, &replyCode);
// Any error to report?
if (error) return error;
// Check FTP response code
if (!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
// Successful processing
return 0;
}
/**
* @brief Enter passive mode
* @param[in] context Pointer to the FTP client context
* @param[out] port The port number the server is listening on
* @return Error code
**/
int ftpSetPassiveMode(FtpClientContext *context, uint16_t *port)
{
int error;
uint32_t replyCode;
char delimiter;
char *p;
// Invalid context?
if (context == NULL)
return ERROR_INVALID_PARAMETER;
#if 1 //(IPV4_SUPPORT == ENABLED)
// IPv4 FTP server?
if (1)//(context->serverAddr.length == sizeof(Ipv4Addr))
{
// Send the command to the server
error = ftpSendCommand(context, "PASV\r\n", &replyCode);
// Any error to report?
if (error) return error;
// Check FTP response code
if (!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
// Delimiter character
delimiter = ',';
// Retrieve the low byte of the port number
p = strrchr((char const*)context->buffer, delimiter);
// Failed to parse the response?
if (!p) return ERROR_INVALID_SYNTAX;
// Convert the resulting string
*port = atoi(p + 1);
// Split the string
*p = '\0';
// Retrieve the high byte of the port number
p = strrchr((char const*)context->buffer, delimiter);
// Failed to parse the response?
if (!p) return ERROR_INVALID_SYNTAX;
// Convert the resulting string
*port |= atoi(p + 1) << 8;
}
else
#endif
//Invalid IP address?
{
// Report an error
return ERROR_INVALID_ADDRESS;
}
// Successful processing
return FTP_NO_ERROR;
}
/**
* @brief Set representation type
* @param[in] context Pointer to the FTP client context
* @param[in] type Single character identifying the desired type
* @return Error code
**/
int ftpSetType(FtpClientContext *context, char type)
{
int error;
uint32_t replyCode;
// Invalid context?
if (context == NULL)
return ERROR_INVALID_PARAMETER;
// Format the TYPE command
sprintf((char*)context->buffer, "TYPE %c\r\n", type);
// Send the command to the server
error = ftpSendCommand(context, (char const*)context->buffer, &replyCode);
// Any error to report?
if (error) return error;
// Check FTP response code
if(!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
// Successful processing
return FTP_NO_ERROR;
}
/**
* @brief Get the working directory from the FTP server
* @param[in] context Pointer to the FTP client context
* @param[out] path Output buffer where to store the current directory
* @param[in] size Size of the output buffer
* @return Error code
**/
int ftpGetWorkingDir(FtpClientContext *context, char *path, uint32_t size)
{
int error;
uint32_t length;
uint32_t replyCode;
char *p;
//Invalid context?
if (context == NULL)
return ERROR_INVALID_PARAMETER;
// Check parameters
if (path == NULL || size == 0)
return ERROR_INVALID_PARAMETER;
// Send the command to the server
error = ftpSendCommand(context, "PWD\r\n", &replyCode);
// Any error to report?
if (error) return error;
// Check FTP response code
if (!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
// Search for the last double quote
p = strrchr((char*)context->buffer, '\"');
// Failed to parse the response?
if (!p) return ERROR_INVALID_SYNTAX;
// Split the string
*p = '\0';
// Search for the first double quote
p = strchr((char const*)context->buffer, '\"');
// Failed to parse the response?
if (!p) return ERROR_INVALID_SYNTAX;
// Retrieve the length of the working directory
length = strlen(p + 1);
// Limit the number of characters to copy
if (length > size - 1)
{
length = size - 1;
}
// Copy the string
strncpy(path, p + 1, length);
// Properly terminate the string with a NULL character
path[length] = '\0';
// Successful processing
return 0;
}
/**
* @brief Open a file for reading, writing, or appending
* @param[in] context Pointer to the FTP client context
* @param[in] path Path to the file to be be opened
* @param[in] flags Access mode
* @return Error code
**/
int ftpOpenFile(FtpClientContext *context, const char *path, uint32_t flags)
{
int error;
uint32_t replyCode;
uint32_t ipAddr;
uint16_t port;
NET_ERR err;
// Invalid context?
if (context == NULL)
return ERROR_INVALID_PARAMETER;
context->dataSocket = NetSock_Open(NET_SOCK_ADDR_FAMILY_IP_V4, NET_SOCK_TYPE_STREAM, NET_SOCK_PROTOCOL_TCP, &err);
if ((err != NET_SOCK_ERR_NONE) || (context->dataSocket < 0))
{
return ERROR_OPEN_FAILED;
}
// Start of exception handling block
do
{
//Set representation type
if (flags & FTP_TEXT_TYPE)
{
// Use ASCII type
error = ftpSetType(context, 'A');
// Any error to report?
if(error) break;
}
else
{
// Use image type
error = ftpSetType(context, 'I');
// Any error to report?
if(error) break;
}
// Check transfer mode
if (!context->passiveMode)
{
NET_SOCK_ADDR_IP server_sock_addr_ip;
Mem_Clr((void*)&server_sock_addr_ip, (CPU_SIZE_T)sizeof(server_sock_addr_ip));
server_sock_addr_ip.Family = NET_SOCK_ADDR_FAMILY_IP_V4;
server_sock_addr_ip.Addr = NET_UTIL_HOST_TO_NET_32(NET_SOCK_ADDR_IP_WILD_CARD);
server_sock_addr_ip.Port = NET_UTIL_HOST_TO_NET_16(FTP_DATA_PORT);
NetSock_Bind(context->dataSocket, (NET_SOCK_ADDR *)&server_sock_addr_ip, (NET_SOCK_ADDR_LEN)NET_SOCK_ADDR_SIZE, (NET_ERR *)&err);
if (err != NET_SOCK_ERR_NONE)
{
NetSock_Close(context->dataSocket, &err);
context->dataSocket = -1;
return -1;
}
NetSock_Listen(context->dataSocket, 1, &err);
if (err != NET_SOCK_ERR_NONE)
{
NetSock_Close(context->dataSocket, &err);
context->dataSocket = -1;
return -1;
}
ipAddr = server_sock_addr_ip.Addr;
port = FTP_DATA_PORT;
// Set the port to be used in data connection
error = ftpSetPort(context, &ipAddr, port);
// Any error to report?
if (error) break;
}
else
{
NET_SOCK_ADDR_IP server_sock_addr_ip;
CPU_INT32U time_stamp;
// Enter passive mode
error = ftpSetPassiveMode(context, &port);
// Any error to report?
if (error) break;
memset(&server_sock_addr_ip, 0, sizeof(server_sock_addr_ip));
server_sock_addr_ip.Family = NET_SOCK_ADDR_FAMILY_IP_V4;
server_sock_addr_ip.Addr = NET_UTIL_HOST_TO_NET_32(context->serverAddr);
server_sock_addr_ip.Port = NET_UTIL_HOST_TO_NET_16(port);
time_stamp = OSTimeGet();
NetSock_Conn((NET_SOCK_ID)context->dataSocket, (NET_SOCK_ADDR *)&server_sock_addr_ip, (NET_SOCK_ADDR_LEN)sizeof(server_sock_addr_ip), &err);
while (NetSock_IsConn((NET_SOCK_ID)context->dataSocket, &err) != DEF_YES)
{
if ((err != NET_SOCK_ERR_CONN_IN_PROGRESS) && (err != NET_SOCK_ERR_NONE))
{
break;
}
if (OSTimeGet() - time_stamp > FTP_CLIENT_DEFAULT_TIMEOUT)
{
error = -1;
break;
}
OSTimeDly(2);
}
if ((err != NET_SOCK_ERR_NONE) || (error))
{
break;
}
}
// Format the command
if (flags & FTP_FOR_WRITING)
sprintf((char*)context->buffer, "STOR %s\r\n", path);
else if(flags & FTP_FOR_APPENDING)
sprintf((char*)context->buffer, "APPE %s\r\n", path);
else
sprintf((char*)context->buffer, "RETR %s\r\n", path);
// Send the command to the server
error = ftpSendCommand(context, (char const*)context->buffer, &replyCode);
// Any error to report?
if (error) break;
// Check FTP response code
if (!FTP_REPLY_CODE_1YZ(replyCode))
{
// Report an error
error = ERROR_UNEXPECTED_RESPONSE;
break;
}
// Check transfer mode
if (!context->passiveMode)
{
NET_SOCK_ADDR_IP client_sock_addr_ip;
NET_SOCK_ADDR_LEN client_sock_addr_ip_size = sizeof(client_sock_addr_ip);
NET_SOCK_ID newSockID;
CPU_BOOLEAN attempt_conn;
CPU_INT32U time_stamp;
time_stamp = OSTimeGet();
do
{
if (NetNIC_ConnStatusGet() != DEF_ON)
{
err = NET_SOCK_ERR_NONE_AVAIL;
break;
}
if (OSTimeGet() - time_stamp > FTP_CLIENT_DEFAULT_TIMEOUT)
{
err = NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT;
break;
}
OSTimeDly(2);
newSockID = NetSock_Accept((NET_SOCK_ID )context->dataSocket, (NET_SOCK_ADDR *)&client_sock_addr_ip, (NET_SOCK_ADDR_LEN *)&client_sock_addr_ip_size, (NET_ERR *)&err);
switch (err)
{
case NET_SOCK_ERR_NONE:
attempt_conn = DEF_NO;
break;
case NET_ERR_INIT_INCOMPLETE:
case NET_SOCK_ERR_NULL_PTR:
case NET_SOCK_ERR_NONE_AVAIL:
case NET_SOCK_ERR_CONN_ACCEPT_Q_NONE_AVAIL:
case NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT:
case NET_OS_ERR_LOCK:
attempt_conn = DEF_YES;
break;
default:
attempt_conn = DEF_NO;
break;
}
} while (attempt_conn == DEF_YES);
// No connection request?
if ((newSockID < 0) || (err != NET_SOCK_ERR_NONE))
{
// Report an error
error = -1;
break;
}
// Close the listening socket
NetSock_Close(context->dataSocket, &err);
context->dataSocket = newSockID;
}
// End of exception handling block
} while(0);
// Any error to report?
if (error)
{
// Clean up side effects
NetSock_Close(context->dataSocket, &err);
context->dataSocket = -1;
}
// Return status code
return error;
}
/**
* @brief Write to a remote file
* @param[in] context Pointer to the FTP client context
* @param[in] data Pointer to a buffer containing the data to be written
* @param[in] length Number of data bytes to write
* @param[in] flags Set of flags that influences the behavior of this function
* @return Error code
**/
int ftpWriteFile(FtpClientContext *context, const void *data, uint32_t length, uint32_t flags)
{
// Invalid context?
if (context == NULL)
return ERROR_INVALID_PARAMETER;
OSTimeDly(10);
if (HostWriteDataTimeout(context->dataSocket, (char*)data, length, FTP_CLIENT_WRITE_TIMEOUT) != length)
{
return -1;
}
OSTimeDly(20);
// Transmit data to the FTP server
return FTP_NO_ERROR;
}
/**
* @brief Close file
* @param[in] context Pointer to the FTP client context
* @return Error code
**/
int ftpCloseFile(FtpClientContext *context)
{
NET_ERR err;
int error;
uint32_t replyCode;
// Invalid context?
if (context == NULL)
return ERROR_INVALID_PARAMETER;
// Close the data socket
NetSock_Close(context->dataSocket, &err);
context->dataSocket = -1;
// Check the transfer status
error = ftpSendCommand(context, NULL, &replyCode);
// Any error to report?
if (error) return error;
// Check FTP response code
if (!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
// Successful processing
return FTP_NO_ERROR;
}
/**
* @brief Delete a file
* @param[in] context Pointer to the FTP client context
* @param[in] path Path to the file to be be deleted
* @return Error code
**/
int ftpDeleteFile(FtpClientContext *context, const char *path)
{
int error;
uint32_t replyCode;
//Invalid context?
if(context == NULL)
return ERROR_INVALID_PARAMETER;
//Format the DELE command
sprintf((char*)context->buffer, "DELE %s\r\n", path);
//Send the command to the server
error = ftpSendCommand(context, (char const*)context->buffer, &replyCode);
//Any error to report?
if(error) return error;
//Check FTP response code
if(!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
//Successful processing
return 0;
}
/**
* @brief Close the connection with the FTP server
* @param[in] context Pointer to the FTP client context
* @return Error code
**/
int ftpClose(FtpClientContext *context)
{
NET_ERR err;
// Invalid context?
if (context == NULL)
{
return ERROR_INVALID_PARAMETER;
}
// Close data socket
if (context->dataSocket >= 0)
{
NetSock_Close(context->dataSocket, &err);
context->dataSocket = -1;
}
// Close control socket
if (context->controlSocket)
{
NetSock_Close(context->controlSocket, &err);
context->controlSocket = -1;
}
// Successful processing
return 0;
}
/**
* @brief Send FTP command and wait for a reply
* @param[in] context Pointer to the FTP client context
* @param[in] command Command line
* @param[out] replyCode Response code from the FTP server
* @return Error code
**/
int ftpSendCommand(FtpClientContext *context, const char *command, uint32_t *replyCode)
{
int length;
char *p;
// Any command line to send?
if (command)
{
if (HostWriteDataTimeout(context->controlSocket, (char*)command, strlen(command), FTP_CLIENT_WRITE_TIMEOUT) != strlen(command))
{
return -1;
}
}
// Multiline replies are allowed for any command
while (1)
{
// Wait for a response from the server
NET_ERR err;
length = HostReadData(context->controlSocket, (char *)context->buffer, FTP_CLIENT_BUFFER_SIZE - 1, FTP_CLIENT_DEFAULT_TIMEOUT, &err);
if (length <= 0)
{
return ERROR_EMPTY_RECEIVE;
}
// Point to the beginning of the buffer
p = (char*)context->buffer;
// Properly terminate the string with a NULL character
p[length] = '\0';
// Remove trailing whitespace from the response
strRemoveTrailingSpace(p);
// Check the length of the response
if (strlen(p) >= 3)
{
// All replies begin with a three digit numeric code
if (isdigit(p[0]) && isdigit(p[1]) && isdigit(p[2]))
{
// A space character follows the response code for the last line
if (p[3] == ' ' || p[3] == '\0')
{
// Get the server response code
*replyCode = strtoul(p, NULL, 10);
// Exit immediately
break;
}
}
}
}
// Successful processing
return 0;
}
/**
* @brief Change the current working directory of the FTP session
* @param[in] context Pointer to the FTP client context
* @param[in] path The new current working directory
* @return Error code
**/
int ftpChangeWorkingDir(FtpClientContext *context, const char *path)
{
int error;
uint32_t replyCode;
//Invalid context?
if(context == NULL)
return ERROR_INVALID_PARAMETER;
//Format the CWD command
sprintf((char*)context->buffer, "CWD %s\r\n", path);
//Send the command to the server
error = ftpSendCommand(context, (char*)context->buffer, &replyCode);
//Any error to report?
if(error) return error;
//Check FTP response code
if(!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
//Successful processing
return 0;
}
/**
* @brief Create a new directory
* @param[in] context Pointer to the FTP client context
* @param[in] path The name of the new directory
* @return Error code
**/
int ftpMakeDir(FtpClientContext *context, const char *path)
{
int error;
uint32_t replyCode;
//Invalid context?
if(context == NULL)
return ERROR_INVALID_PARAMETER;
//Format the MKD command
sprintf((char*)context->buffer, "MKD %s\r\n", path);
//Send the command to the server
error = ftpSendCommand(context, (char*)context->buffer, &replyCode);
//Any error to report?
if(error) return error;
//Check FTP response code
if(!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
//Successful processing
return 0;
}
/**
* @brief Change the current working directory to the parent directory
* @param[in] context Pointer to the FTP client context
* @return Error code
**/
int ftpChangeToParentDir(FtpClientContext *context)
{
int error;
uint32_t replyCode;
//Invalid context?
if(context == NULL)
return ERROR_INVALID_PARAMETER;
//Send the command to the server
error = ftpSendCommand(context, "CDUP\r\n", &replyCode);
//Any error to report?
if(error) return error;
//Check FTP response code
if(!FTP_REPLY_CODE_2YZ(replyCode))
return ERROR_UNEXPECTED_RESPONSE;
//Successful processing
return 0;
}

View File

@ -0,0 +1,99 @@
#ifndef _FTP_CLIENT_H
#define _FTP_CLIENT_H
#include <includes.h>
#include <stdint.h>
#define FTP_CLIENT_DEFAULT_TIMEOUT 10000
#define FTP_CLIENT_BUFFER_SIZE 512
#define FTP_CLIENT_WRITE_TIMEOUT 5000
#define FTP_CONTROL_PORT (21)
#define FTP_DATA_PORT (20)
// Test macros for FTP response codes
#define FTP_REPLY_CODE_1YZ(code) ((code) >= 100 && (code) < 200)
#define FTP_REPLY_CODE_2YZ(code) ((code) >= 200 && (code) < 300)
#define FTP_REPLY_CODE_3YZ(code) ((code) >= 300 && (code) < 400)
#define FTP_REPLY_CODE_4YZ(code) ((code) >= 400 && (code) < 500)
#define FTP_REPLY_CODE_5YZ(code) ((code) >= 500 && (code) < 600)
/**
* @brief Connection options
**/
typedef enum
{
FTP_NO_SECURITY = 0,
FTP_IMPLICIT_SECURITY = 1,
FTP_EXPLICIT_SECURITY = 2,
FTP_ACTIVE_MODE = 0,
FTP_PASSIVE_MODE = 4
} FtpConnectionFlags;
/**
* @brief File opening options
**/
typedef enum
{
FTP_FOR_READING = 0,
FTP_FOR_WRITING = 1,
FTP_FOR_APPENDING = 2,
FTP_BINARY_TYPE = 0,
FTP_TEXT_TYPE = 4
} FtpFileOpeningFlags;
/**
* @brief Flags used by I/O functions
**/
typedef enum
{
FTP_FLAG_PEEK = 0x0200,
FTP_FLAG_WAIT_ALL = 0x0800,
FTP_FLAG_BREAK_CHAR = 0x1000,
FTP_FLAG_BREAK_CRLF = 0x100A,
FTP_FLAG_WAIT_ACK = 0x2000
} FtpFlags;
/**
* @brief FTP client context
**/
typedef struct
{
uint32_t serverAddr; ///<IP address of the FTP server
uint8_t passiveMode; ///<Passive mode
NET_SOCK_ID controlSocket; ///<Control connection socket
NET_SOCK_ID dataSocket; ///<Data connection socket
uint8_t buffer[FTP_CLIENT_BUFFER_SIZE]; ///<Memory buffer for input/output operations
} FtpClientContext;
#define FTP_NO_ERROR (0)
#define ERROR_OPEN_FAILED (-100)
#define ERROR_INVALID_PARAMETER (-101)
#define ERROR_UNEXPECTED_RESPONSE (-102)
#define ERROR_EMPTY_RECEIVE (-103)
#define ERROR_INVALID_ADDRESS (-104)
#define ERROR_INVALID_SYNTAX (-105)
#define isdigit(x) (x >= '0' && x <= '9')
// FTP client related functions
extern int ftpConnect(FtpClientContext *context, uint32_t *serverAddr, uint16_t serverPort, uint32_t flags);
extern int ftpLogin(FtpClientContext *context, const char *username, const char *password, const char *account);
extern int ftpGetWorkingDir(FtpClientContext *context, char *path, uint32_t size);
extern int ftpOpenFile(FtpClientContext *context, const char *path, uint32_t flags);
extern int ftpWriteFile(FtpClientContext *context, const void *data, uint32_t length, uint32_t flags);
extern int ftpCloseFile(FtpClientContext *context);
extern int ftpDeleteFile(FtpClientContext *context, const char *path);
extern int ftpClose(FtpClientContext *context);
extern int ftpSendCommand(FtpClientContext *context, const char *command, uint32_t *replyCode);
extern int ftpChangeWorkingDir(FtpClientContext *context, const char *path);
extern int ftpMakeDir(FtpClientContext *context, const char *path);
extern int ftpChangeToParentDir(FtpClientContext *context);
#endif

View File

@ -1,7 +1,7 @@
#ifndef _VERSION_H_ #ifndef _VERSION_H_
#define _VERSION_H_ #define _VERSION_H_
#define DEVICE_FW_VERSION "06.24" #define DEVICE_FW_VERSION "00.00"
#endif // #ifndef _VERSION_H_ #endif // #ifndef _VERSION_H_

View File

@ -0,0 +1,15 @@
@REM This batch file has been generated by the IAR Embedded Workbench
@REM C-SPY Debugger, as an aid to preparing a command line for running
@REM the cspybat command line utility using the appropriate settings.
@REM
@REM You can launch cspybat by typing the name of this batch file followed
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
@REM Note that this file is generated every time a new debug session
@REM is initialized, so you may want to move or rename the file before
@REM making changes.
@REM
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\common\bin\cspybat" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armproc.dll" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armjlink.dll" %1 --plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armbat.dll" --backend -B "--endian=little" "--cpu=ARM7TDMI-S" "--fpu=None" "-p" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\CONFIG\debugger\NXP\iolpc2368.ddf" "--semihosting" "--device=LPC2368" "--drv_communication=USB0" "--jlink_speed=auto" "--jlink_initial_speed=32"

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<Project/>

63
settings/sk-mlpc2368.dni Normal file
View File

@ -0,0 +1,63 @@
[Stack]
FillEnabled=0
OverflowWarningsEnabled=1
WarningThreshold=90
SpWarningsEnabled=1
WarnLogOnly=1
UseTrigger=1
TriggerName=main
LimitSize=0
ByteLimit=50
[DebugChecksum]
Checksum=803613283
[Exceptions]
StopOnUncaught=_ 0
StopOnThrow=_ 0
[CallStack]
ShowArgs=0
[Disassembly]
MixedMode=1
[InterruptLog]
LogEnabled=0
SumEnabled=0
GraphEnabled=0
ShowTimeLog=1
ShowTimeSum=1
SumSortOrder=0
[Interrupts]
Enabled=1
[MemoryMap]
Enabled=0
Base=0
UseAuto=0
TypeViolation=1
UnspecRange=1
ActionState=1
[Trace1]
Enabled=0
ShowSource=1
[JLinkDriver]
WatchCond=_ 0
Watch0=_ 0 "0x00000000" 4294967295 "0xFFFFFFFF" 0 "0x00000000" 4294967295 "0xFFFFFFFF" 3 0 0 0
Watch1=_ 0 "0x00000000" 4294967295 "0xFFFFFFFF" 0 "0x00000000" 4294967295 "0xFFFFFFFF" 3 0 0 0
[Disassemble mode]
mode=0
[Breakpoints2]
Count=0
[Log file]
LoggingEnabled=_ 0
LogFile=_ ""
Category=_ 0
[TermIOLog]
LoggingEnabled=_ 0
LogFile=_ ""
[Aliases]
Count=0
SuppressDialog=0
[CallStackLog]
Enabled=0
[DriverProfiling]
Enabled=0
Mode=0
Graph=0
Symbiont=0

227
settings/sk-mlpc2368.wsdt Normal file
View File

@ -0,0 +1,227 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<Workspace>
<ConfigDictionary>
<CurrentConfigs>
<Project>sk-mlpc2368/Flash Central</Project>
</CurrentConfigs>
</ConfigDictionary>
<Desktop>
<Static>
<Workspace>
<ColumnWidths>
<Column0>210</Column0>
<Column1>27</Column1>
<Column2>27</Column2>
<Column3>27</Column3>
</ColumnWidths>
</Workspace>
<Build>
<ColumnWidth0>20</ColumnWidth0>
<ColumnWidth1>980</ColumnWidth1>
<ColumnWidth2>261</ColumnWidth2>
<ColumnWidth3>65</ColumnWidth3>
</Build>
<Find-in-Files>
<ColumnWidth0>470</ColumnWidth0>
<ColumnWidth1>67</ColumnWidth1>
<ColumnWidth2>806</ColumnWidth2>
</Find-in-Files>
<TerminalIO/>
</Static>
<Windows>
<Wnd2>
<Tabs>
<Tab>
<Identity>TabID-22094-17165</Identity>
<TabName>Workspace</TabName>
<Factory>Workspace</Factory>
<Session>
<NodeDict>
<ExpandedNode>sk-mlpc2368</ExpandedNode>
<ExpandedNode>sk-mlpc2368/PROJECT</ExpandedNode>
<ExpandedNode>sk-mlpc2368/PROJECT/app</ExpandedNode>
<ExpandedNode>sk-mlpc2368/PROJECT/drivers</ExpandedNode>
<ExpandedNode>sk-mlpc2368/PROJECT/drivers/ccnet</ExpandedNode>
<ExpandedNode>sk-mlpc2368/PROJECT/drivers/lcd</ExpandedNode>
<ExpandedNode>sk-mlpc2368/PROJECT/menu</ExpandedNode>
<ExpandedNode>sk-mlpc2368/PROJECT/services</ExpandedNode>
</NodeDict>
</Session>
</Tab>
</Tabs>
<SelectedTab>0</SelectedTab>
</Wnd2>
<Wnd3>
<Tabs>
<Tab>
<Identity>TabID-15821-17283</Identity>
<TabName>Build</TabName>
<Factory>Build</Factory>
<Session/>
</Tab>
<Tab>
<Identity>TabID-20361-395</Identity>
<TabName>Find in Files</TabName>
<Factory>Find-in-Files</Factory>
<Session/>
</Tab>
</Tabs>
<SelectedTab>0</SelectedTab>
</Wnd3>
</Windows>
<Editor>
<Pane>
<Tab>
<Factory>TextEditor</Factory>
<Filename>$WS_DIR$\PROJECT\app\app_serv.c</Filename>
<XPos>0</XPos>
<YPos>292</YPos>
<SelStart>17841</SelStart>
<SelEnd>17858</SelEnd>
</Tab>
<Tab>
<Factory>TextEditor</Factory>
<Filename>$WS_DIR$\PROJECT\services\ftp_client.c</Filename>
<XPos>0</XPos>
<YPos>735</YPos>
<SelStart>21346</SelStart>
<SelEnd>21346</SelEnd>
</Tab>
<Tab>
<Factory>TextEditor</Factory>
<Filename>$WS_DIR$\PROJECT\app\host_app.c</Filename>
<XPos>0</XPos>
<YPos>272</YPos>
<SelStart>7189</SelStart>
<SelEnd>7189</SelEnd>
</Tab>
<Tab>
<Factory>TextEditor</Factory>
<Filename>$WS_DIR$\PROJECT\app\ftp_app.c</Filename>
<XPos>0</XPos>
<YPos>3</YPos>
<SelStart>55</SelStart>
<SelEnd>55</SelEnd>
</Tab>
<Tab>
<Factory>TextEditor</Factory>
<Filename>$WS_DIR$\PROJECT\app\host_app.h</Filename>
<XPos>0</XPos>
<YPos>0</YPos>
<SelStart>776</SelStart>
<SelEnd>776</SelEnd>
</Tab>
<Tab>
<Factory>TextEditor</Factory>
<Filename>$WS_DIR$\PROJECT\drivers\lcd\lcd.c</Filename>
<XPos>0</XPos>
<YPos>457</YPos>
<SelStart>11064</SelStart>
<SelEnd>11064</SelEnd>
</Tab>
<Tab>
<Factory>TextEditor</Factory>
<Filename>$WS_DIR$\PROJECT\services\validator.c</Filename>
<XPos>0</XPos>
<YPos>285</YPos>
<SelStart>10320</SelStart>
<SelEnd>10336</SelEnd>
</Tab>
<Tab>
<Factory>TextEditor</Factory>
<Filename>$WS_DIR$\OS\app\app.c</Filename>
<XPos>0</XPos>
<YPos>33</YPos>
<SelStart>1131</SelStart>
<SelEnd>1131</SelEnd>
</Tab>
<Tab>
<Factory>TextEditor</Factory>
<Filename>$WS_DIR$\PROJECT\menu\menu.h</Filename>
<XPos>0</XPos>
<YPos>0</YPos>
<SelStart>314</SelStart>
<SelEnd>314</SelEnd>
</Tab>
<ActiveTab>8</ActiveTab>
</Pane>
<ActivePane>0</ActivePane>
<Sizes>
<Pane>
<X>1000000</X>
<Y>1000000</Y>
</Pane>
</Sizes>
<SplitMode>1</SplitMode>
</Editor>
<Positions>
<Top>
<Row0>
<Sizes>
<Toolbar-04b829c8>
<key>iaridepm.enu1</key>
</Toolbar-04b829c8>
</Sizes>
</Row0>
<Row1>
<Sizes/>
</Row1>
</Top>
<Left>
<Row0>
<Sizes>
<Wnd2>
<Rect>
<Top>-2</Top>
<Left>-2</Left>
<Bottom>498</Bottom>
<Right>301</Right>
<x>-2</x>
<y>-2</y>
<xscreen>200</xscreen>
<yscreen>200</yscreen>
<sizeHorzCX>146413</sizeHorzCX>
<sizeHorzCY>275862</sizeHorzCY>
<sizeVertCX>221816</sizeVertCX>
<sizeVertCY>689655</sizeVertCY>
</Rect>
</Wnd2>
</Sizes>
</Row0>
</Left>
<Right>
<Row0>
<Sizes/>
</Row0>
</Right>
<Bottom>
<Row0>
<Sizes>
<Wnd3>
<Rect>
<Top>-2</Top>
<Left>-2</Left>
<Bottom>182</Bottom>
<Right>1368</Right>
<x>-2</x>
<y>-2</y>
<xscreen>1370</xscreen>
<yscreen>184</yscreen>
<sizeHorzCX>1002928</sizeHorzCX>
<sizeHorzCY>253793</sizeHorzCY>
<sizeVertCX>146413</sizeVertCX>
<sizeVertCY>275862</sizeVertCY>
</Rect>
</Wnd3>
</Sizes>
</Row0>
</Bottom>
<Float>
<Sizes/>
</Float>
</Positions>
</Desktop>
</Workspace>

View File

@ -0,0 +1,30 @@
[BREAKPOINTS]
ShowInfoWin = 1
EnableFlashBP = 2
BPDuringExecution = 0
[CFI]
CFISize = 0x00
CFIAddr = 0x00
[CPU]
OverrideMemMap = 0
AllowSimulation = 1
ScriptFile=""
[FLASH]
SkipProgOnCRCMatch = 1
VerifyDownload = 1
AllowCaching = 1
EnableFlashDL = 2
Override = 0
Device="AD7160"
[GENERAL]
WorkRAMSize = 0x00
WorkRAMAddr = 0x00
[SWO]
SWOLogFile=""
[MEM]
RdOverrideOrMask = 0x00
RdOverrideAndMask = 0xFFFFFFFF
RdOverrideAddr = 0xFFFFFFFF
WrOverrideOrMask = 0x00
WrOverrideAndMask = 0xFFFFFFFF
WrOverrideAddr = 0xFFFFFFFF

5527
sk-mlpc2368.dep Normal file

File diff suppressed because it is too large Load Diff

2638
sk-mlpc2368.ewd Normal file

File diff suppressed because it is too large Load Diff

View File

@ -87,7 +87,7 @@
</option> </option>
<option> <option>
<name>OGLastSavedByProductVersion</name> <name>OGLastSavedByProductVersion</name>
<state>6.21.4.52945</state> <state>6.21.1.52845</state>
</option> </option>
<option> <option>
<name>GeneralEnableMisra</name> <name>GeneralEnableMisra</name>
@ -1006,7 +1006,7 @@
</option> </option>
<option> <option>
<name>OGLastSavedByProductVersion</name> <name>OGLastSavedByProductVersion</name>
<state>6.21.4.52945</state> <state>6.21.1.52845</state>
</option> </option>
<option> <option>
<name>GeneralEnableMisra</name> <name>GeneralEnableMisra</name>
@ -1512,7 +1512,7 @@
</option> </option>
<option> <option>
<name>OOCOutputFile</name> <name>OOCOutputFile</name>
<state>sk_mlpc2368.hex</state> <state>version0_00.hex</state>
</option> </option>
<option> <option>
<name>OOCCommandLineProducer</name> <name>OOCCommandLineProducer</name>
@ -1566,7 +1566,7 @@
</option> </option>
<option> <option>
<name>IlinkOutputFile</name> <name>IlinkOutputFile</name>
<state>sk_mlpc2368.out</state> <state>version0_00.out</state>
</option> </option>
<option> <option>
<name>IlinkDebugInfoEnable</name> <name>IlinkDebugInfoEnable</name>
@ -1925,7 +1925,7 @@
</option> </option>
<option> <option>
<name>OGLastSavedByProductVersion</name> <name>OGLastSavedByProductVersion</name>
<state>6.21.4.52945</state> <state>6.21.1.52845</state>
</option> </option>
<option> <option>
<name>GeneralEnableMisra</name> <name>GeneralEnableMisra</name>
@ -3131,6 +3131,12 @@
<file> <file>
<name>$PROJ_DIR$\PROJECT\app\control.h</name> <name>$PROJ_DIR$\PROJECT\app\control.h</name>
</file> </file>
<file>
<name>$PROJ_DIR$\PROJECT\app\ftp_app.c</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\app\ftp_app.h</name>
</file>
<file> <file>
<name>$PROJ_DIR$\PROJECT\app\host_app.c</name> <name>$PROJ_DIR$\PROJECT\app\host_app.c</name>
<excluded> <excluded>
@ -3247,6 +3253,9 @@
<file> <file>
<name>$PROJ_DIR$\PROJECT\drivers\lcd\lcd.h</name> <name>$PROJ_DIR$\PROJECT\drivers\lcd\lcd.h</name>
</file> </file>
<file>
<name>$PROJ_DIR$\PROJECT\drivers\lcd\symtab.h</name>
</file>
</group> </group>
<group> <group>
<name>modem</name> <name>modem</name>
@ -3330,6 +3339,12 @@
<file> <file>
<name>$PROJ_DIR$\PROJECT\services\fr.h</name> <name>$PROJ_DIR$\PROJECT\services\fr.h</name>
</file> </file>
<file>
<name>$PROJ_DIR$\PROJECT\services\ftp_client.c</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\services\ftp_client.h</name>
</file>
<file> <file>
<name>$PROJ_DIR$\PROJECT\services\mode.c</name> <name>$PROJ_DIR$\PROJECT\services\mode.c</name>
</file> </file>