📄 lowr.c
字号:
LastCommand=0x0301;
SendLowrMessage(LastCommand,temp,0,"GetLowrDispParams");
GetLowrMessage(1);
LastCommand=0x0302;
SendLowrMessage(LastCommand,temp,0,"UnfreezeLowrDisp");
GetLowrMessage(1);
} // GetLowrDisplay(void)
/* -------------------------------------------------------------------------- */
PROCX BYTE SetLowrChkSum(BYTE * a, INT len)
{
INT i;
BYTE sum=0;
for(i=0;i<len;i++) {
sum+=a[i];
}
sum=-sum;
return sum;
} // SetLowrChkSum()
/* -------------------------------------------------------------------------- */
PROCX void debugOUT(BYTE *message, INT len)
{
INT i,c;
BYTE qq;
c=0;
for(i=0;i<len;i++) {
fprintf(Gdebug_out,outfmt,qq=*(message+i));
if(qq>=32 && qq<=126) {
fprintf(Gdebug_out,"%c ",qq);
}
else {
fprintf(Gdebug_out," ");
}
if(++c>15) {
fprintf(Gdebug_out,"\n");
c=0;
}
}
fprintf(Gdebug_out,"\n");fflush(Gdebug_out);
} // void debugOUT
/* -------------------------------------------------------------------------- */
PROCX void debugOUTstd(BYTE *message, INT len, INT width)
{
INT i,c;
c=0;
for(i=0;i<len;i++) {
printf("%02x ",message[i]);
if(++c>width-1) {
printf("\n");
c=0;
}
}
printf("\n");fflush(stdout);
} // void debugOUTstd
/* -------------------------------------------------------------------------- */
//
// builds header and message and transmits it to the serial port. Does NOT check
// for receipt of message.
//
// NOTE: MsgLen does not include the checksum byte so the number of bytes sent
// in a data message is MsgLen+1
//
PROCX void SendLowrMessage(INT command, BYTE *message, INT MsgLen, char *msgtype)
{
//
// Set 'Lasts'
//
LastLowrLen=MsgLen;
LastCommand=command;
memcpy(LastLowrGPSMsg,message,MsgLen);//
// build header
//
Hdr.hdrs.command = command;
Hdr.hdrs.preamble = 0x8155;
Hdr.hdrs.length = MsgLen;
Hdr.hdrs.reserved = 0;
Hdr.hdrs.checksum = SetLowrChkSum(Hdr.Header,7);
memset(SerialMessageOut,0,MAX_LENGTH);
//
// Send Header to Serial Port
//
#if !DEBUGREAD
AsyncSend(Hdr.Header, 8);
#endif
if(Gdebug==1) {
fprintf(Gdebug_out,"Sending header for: %s\n",msgtype);
debugOUT(Hdr.Header,8);
}
//
// do we have data to send after the header?
//
if(MsgLen) { // Yes, data to send with Header
memcpy(SerialMessageOut,message,MsgLen);
//
// Set checksum on message
//
SerialMessageOut[MsgLen] = SetLowrChkSum(SerialMessageOut,MsgLen);
#if !DEBUGREAD
AsyncSend(SerialMessageOut, (INT)(MsgLen+1));
#endif
//
// Dumping the send buffer to a file?
//
if(Gdebug==1) {
fprintf(Gdebug_out,"Sending: %s\n",msgtype);
debugOUT(SerialMessageOut,(INT)(MsgLen+1));
}
} // if(MsgLen)
} // SendLowrMessage
/* -------------------------------------------------------------------------- */
PROCX short swapshortendian(short val)
{
BYTE temp;
union swap {
BYTE a[2];
short num;
} swap;
swap.num=val;
temp=swap.a[0];
swap.a[0]=swap.a[1];
swap.a[1]=temp;
return swap.num;
} // short swapshortendian
/* -------------------------------------------------------------------------- */
PROCX void DoMemoryDeltas(INT b)
{
INT i,a,q;
INT deltas;
deltas=b/4;
for(i=1;i<deltas*2;i+=2) {
a = swapshortendian(LowrMemRead.data.data[i-1]);
LowrLastLat += a;
q = swapshortendian(LowrMemRead.data.data[i]);
LowrLastLong += q;
record.type='T'; // Not first record this track
record.la = LatMMtoDeg(LowrLastLat);
record.lo = LongMMtoDeg(LowrLastLong);
set_ns();
settime_record(0); // no time on Lowrance track points
sprintf(Text,"%c;%d;;",record.type,datatype);
push_track();
}
} // DoMemoryDeltas
/* -------------------------------------------------------------------------- */
PROCX void GetPlotTrailPointer(INT trk)
{
BYTE Message[5];
Message[0]=trk-1;
LastCommand=0x0307;
SendLowrMessage(LastCommand, Message, (INT)1, (char*)"GetPlotTrailPointer");
GetLowrMessage(1);
} // GetPlotTrailPointer
/* -------------------------------------------------------------------------- */
PROCX void readstarttofinish(long Start, long Finish, char * what, void (*fcn)(INT))
{
short cnt,cc;
INT chunk;
chunk=160;
Finish+=rstfOffset;
while((Finish-Start+1) >= (long)chunk)
{
cc=kbraw();
cc=toupper(cc);
if(cc=='Y') {
fprintf(stderr,"\nOperator Abort rstf 1\n");
AbortNow=1;
return;
} else if(cc=='X') {
fprintf(stderr,"\nOperator Exit rstf 1\n");
byebye(0);
}
LowrMemGet.Address=Start;
LowrMemGet.CtgSelect = 0;
LowrMemGet.Count = chunk; // get structure elements
LastCommand=0x0008;
SendLowrMessage(LastCommand,(BYTE*)&LowrMemGet,
sizeof(struct LowrMemGet), (char*)"Reading Memory1");
GetLowrMessage(1);
fcn(chunk);
totalread+=chunk;
fprintf(stderr,"%05d Bytes of %s Read\r",totalread,what);
Start+=chunk;
}
//
// get the rest of the Tail side
//
cnt=Finish-Start+1;
if(cnt > 0) {
cc=kbraw();
cc=toupper(cc);
if(cc=='Y') {
fprintf(stderr,"\nOperator Abort rstf 2\n");
AbortNow=1;
return;
} else if(cc=='X') {
fprintf(stderr,"\nOperator Exit rstf 2\n");
byebye(0);
}
LastCommand=0x0008;
LowrMemGet.Address=Start;
LowrMemGet.CtgSelect = 0;
LowrMemGet.Count = cnt;
SendLowrMessage(LastCommand, (BYTE*)&LowrMemGet,
sizeof(struct LowrMemGet), (char*)"Reading Memory2");
GetLowrMessage(1);
fcn(cnt);
totalread+=cnt;
fprintf(stderr,"%05d Bytes of %s Read\r",totalread,what);
}
fprintf(stderr,"\n");
} // readstarttofinish
/* -------------------------------------------------------------------------- */
PROCX void GetLowrTrackMem(INT trk)
{
long StartOfBuffer, EndOfBuffer;
GetPlotTrailPointer(trk);
//
// Evidently the last 4 bytes of the structure is the checksum.
//
// End the first reading at the end of the structure - 4
//
EndOfBuffer=LowrTrailOriginMem.StructurePointer+LowrTrailOriginMem.StructureSize-4;
//
// We will start reading the second read just after the Structure and will read through the
// Head pointer.
//
StartOfBuffer=LowrTrailOriginMem.StructurePointer+16;
//
// Read the 4 longs in the structure
//
LowrMemGet.Address=LowrTrailOriginMem.StructurePointer;
LowrMemGet.CtgSelect = 0;
LowrMemGet.Count = 16;
LastCommand=0x0008;
SendLowrMessage(LastCommand,(BYTE*)&LowrMemGet,
sizeof(struct LowrMemGet), (char*)"GetLowrMem");
//
// read and parse the returned 0x0088 record which contains the 4 longs of the structure
//
GetLowrMessage(1);
//
// Set up origins remembering the structure elements are BIG endian not little endian
//
BaseLatitude = swaplongendian(LowrMemRead.data.ptp.BaseLatitude);
BaseLongitude = swaplongendian(LowrMemRead.data.ptp.BaseLongitude);
TailAdrPointer = swaplongendian(LowrMemRead.data.ptp.TailAdrPointer);
HeadAdrPointer = swaplongendian(LowrMemRead.data.ptp.HeadAdrPointer);
if((TailAdrPointer==0L) || (HeadAdrPointer == 0L) || (HeadAdrPointer==TailAdrPointer)) {
fprintf(stderr,"No Tracks to send\n");
return;
}
datatype=10000; // ID's lowrance track
settime_record(0); // no time on Lowrance track points
record.type='N'; // first record
LowrLastLat=BaseLatitude;
LowrLastLong=BaseLongitude;
record.la = LatMMtoDeg(LowrLastLat);
record.lo = LongMMtoDeg(LowrLastLong);
set_ns();
sprintf(Text,"%c;%d;;",record.type,datatype);
push_track();
//
// Start reading at TailAdrPointer
//
// Use chunks of 160 bytes cuz spec recommend that number. 160 bytes is 40 delta pairs
//
// Read from Tail to end of buffer to end first reading 160 bytes at a time
//
// If TailPointer<HeadPointer, read through HeadPtr, not the end of the buffer
//
totalread=1; // Allow for base
//
// is the read just one chunk?
//
rstfOffset=-1;
if(TailAdrPointer<HeadAdrPointer) {
readstarttofinish(TailAdrPointer,HeadAdrPointer,"deltas", DoMemoryDeltas);
return;
} // if(TailAdrPointer<HeadAdrPointer)
//
// Read the head side. We read from the point just past the 4 longs in the structure up
// to but not including the tail pointer
//
//
// Two chunks must be read
//
// First, from the tail pointer to the end of the buffer
//
readstarttofinish(TailAdrPointer,EndOfBuffer,"deltas", DoMemoryDeltas);
//
// and then from the start of the buffer through the head pointer
readstarttofinish(StartOfBuffer,HeadAdrPointer,"deltas", DoMemoryDeltas);
} // void GetLowrTrackMem(INT trk)
/* -------------------------------------------------------------------------- */
PROCX void DoLowrMemRead(void)
{
memcpy(&LowrMemRead, SerialMessage, LowrMemBytesRead);
} // void DoLowrMemRead(void)
/* -------------------------------------------------------------------------- */
PROCX void DoLowrTrackMem(void)
{
memcpy(&LowrTrailOriginMem, SerialMessage, sizeof(struct LowrTrailOriginMem));
} // void DoLowrTrackMem(void)
/* -------------------------------------------------------------------------- */
PROCX void GetLowrTrack(INT trk)
{
BYTE Message[5];
short i,chunk;
Message[0]=trk-1;
LastCommand=0x0312;
SendLowrMessage(LastCommand, Message, (INT)1, (char*)"GetLowrTrack");
GetLowrMessage(1);
TotalDeltas=LowrTrailOrigin.NumberOfDeltas;
if(TotalDeltas == 0) {
fprintf(stderr,"No points in trail %d\n",trk); fflush(stdout);
return;
}
datatype=10000; // ID's lowrance track
settime_record(0); // not time on Lowrance track points
record.type='N'; // first record
LowrLastLat=LowrTrailOrigin.OriginY;
LowrLastLong=LowrTrailOrigin.OriginX;
record.la = LatMMtoDeg(LowrLastLat);
record.lo = LongMMtoDeg(LowrLastLong);
set_ns();
sprintf(Text,"%c;%d;;",record.type,datatype);
push_track();
//
// get chunks of 40
//
Total=1;
fprintf(stderr,"T%05d of %d\r", Total, TotalDeltas+1);
chunk=TotalDeltas/40;
ND.pt=trk-1;
ND.no=40;
for(i=1;i<=chunk;i++)
{
LastCommand=0x0313;
SendLowrMessage(LastCommand, (BYTE*)&ND, (INT)3, (char*)"GetLowrTrack Deltas");
GetLowrMessage(1);
}
//
// get the rest
//
ND.pt=trk-1;
ND.no=TotalDeltas-(chunk*40);
LastCommand=0x0313;
SendLowrMessage(LastCommand, (BYTE *)&ND, (INT)3, (char*)"GetLowrTrack Deltas");
GetLowrMessage(1);
fprintf(stderr,"\n");
} // GetLowrTrack()
struct LowrPlotTrailDeltas {
BYTE Reserved;
BYTE PlotTrailNumber;
short NumberofDeltas;
short Deltas[80];
} LowrPlotTrailDeltas;
/* -------------------------------------------------------------------------- */
PROCX void DoLowrPlotTrailDeltas(void)
{
INT i;
memcpy(&LowrPlotTrailDeltas, SerialMessage, sizeof(struct LowrPlotTrailDeltas));
for(i=1;i<LowrPlotTrailDeltas.NumberofDeltas*2;i+=2) {
LowrLastLat += LowrPlotTrailDeltas.Deltas[i-1];
LowrLastLong += LowrPlotTrailDeltas.Deltas[i];
record.type='T'; // Not first record this track
record.la = LatMMtoDeg(LowrLastLat);
record.lo = LongMMtoDeg(LowrLastLong);
set_ns();
settime_record(0); // no time on Lowrance track points
sprintf(Text,"%c;%d;;",record.type,datatype);
push_track();
++Total;
fprintf(stderr,"T%05d\r", Total);
}
} // void DoLowrPlotTrailDeltas(void);
/* -------------------------------------------------------------------------- */
PROCX void DoLowrPlotTrailOrigin(void)
{
memcpy(&LowrTrailOrigin, SerialMessage, sizeof(struct LowrTrailOrigin));
} // void DoLowrPlotTrailOrigin(void)
/* -------------------------------------------------------------------------- */
PROCX void GetLowrWPT(short no)
{
BYTE *M;
M=(BYTE *)&no;
LastCommand=GetWaypoint;
LastLowrLen=2;
SendLowrMessage(LastCommand, M, LastLowrLen, (char *)"GetLowrWPT");
GetLowrMessage(1);
} // GetLowrWPT(short no)
/* -------------------------------------------------------------------------- */
//
// * Note: unix_time = garmin_time + 631065600L
// unix_time = Lowrance_time + 694224000L
// garmin_time = Lowrance_time + 63158400L
// Lowrance_time = garmin_time - 63158400L
// Called by LowrParse
//
PROCX void DoLowrWPT(void)
{
struct LowrWPTr * kstat;
kstat = (struct LowrWPTr *)SerialMessage;
validwp=0;
if(kstat->Status==0) return;
validwp=1;
++LowrValidWpts;
memcpy(&LowrWPTr,SerialMessage,sizeof(struct LowrWPTr));
settime_record(LowrWPTr.Date+63158400L);
record.type='W';
record.la=LatMMtoDeg(LowrWPTr.Latitude);
record.lo=LongMMtoDeg(LowrWPTr.Longitude);
set_ns();
strcpy(record.ident,(char *)LowrWPTr.Name);
record.ident[13]=0;
trim(record.ident);
record.icon_smbl=convert_from_Lowr(LowrWPTr.IconSymbol);
// strcpy(record.comment,(char *)LowrWPTr.Name);
record.comment[0]=0;
// trim(record.comment);
datatype=30000+LowrWPTr.WaypointNumber;
sprintf(Text,"%c;%d;%s;%s",'W',datatype,record.ident,record.comment);
trim(Text);
set_ns();
// printf("WPT# : %d\n",LowrWPTr.WaypointNumber);
// printf("WPT Status : %d\n",LowrWPTr.Status);
// printf("WPT IconSymbol : %d\n",LowrWPTr.IconSymbol);
// printf("WPT Latitude: (mm) : %ld\n",LowrWPTr.Latitude);
// printf("WPT Longitude (mm) : %ld\n",LowrWPTr.Longitude);
// printf("WPT Latitude (h.hhh): %lf\n",LatMMtoDeg(LowrWPTr.Latitude));
// printf("WPT Longitude(h.hhh): %lf\n",LongMMtoDeg(LowrWPTr.Longitude));
// printf("WPT Name : %s\n",LowrWPTr.Name);
// printf("WPT Date (secs) : %ld\n",LowrWPTr.Date);
} // DoLowrWPT
/* -------------------------------------------------------------------------- */
PROCX void GetLowrWpts()
{
INT i;
INT cc;
INT readto;
//
// Zero based, i.e. wpt #0 is the first
//
if(LwrRangeHi<0)
readto=LowrID.NumOfWaypoints;
else
readto=LwrRangeHi;
if(readto>LowrID.NumOfWaypoints) readto = LowrID.NumOfWaypoints;
fprintf(stderr,"W0000 of %04d Active:%04d\r",readto,LowrValidWpts);
for(i=LwrRangeLo-1;i<readto;i++) {
GetLowrWPT((short)i);
if(validwp) push_waypoint();
fprintf(stderr,"W%04d of %04d Active:%04d\r",i+1,readto,LowrValidWpts);
cc=kbraw();
cc=toupper(cc);
if(cc=='X') {
fprintf(stderr,"\nOperator Exit 1\n");
byebye(0);
} else if(cc=='Y') {
fprintf(stderr,"\nOperator Abort 1\n");
return;
}
}
} // GetLowrWpts()
struct RteGet {
BYTE Reserved;
short RouteNumber;
BYTE NumOfWaypoints;
BYTE Name[13];
short Waypoints[200]; // Room for 200 wpts per route
} RteGet;
/* -------------------------------------------------------------------------- */
PROCX void GetLowrRoute(short rte)
{
route_number=rte+1; // Route printed will be Lowr/Eagle external number.
route_point=0;
LastCommand=0x0305;
SendLowrMessage(LastCommand,(BYTE*)&rte,2,"GetLowrRoute");
GetLowrMessage(1);
} // GetLowrRoute()
/* -------------------------------------------------------------------------- */
PROCX void GetLowrRts()
{
INT i;
for(i=0;i<LowrID.NumOfRoutes;i++) GetLowrRoute(i);
fprintf(stderr,"\n");
} // GetLowrRts()
PROCX void DoLowrRoute(void)
{
INT i;
char buf[100];
memcpy(&RteGet,SerialMessage,4);
if(RteGet.NumOfWaypoints>200) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -