Jappe Lino
/
bat
interface towards a Garmin plotter to make measurements come up as boats
Revision 0:70a1315acc03, committed 2011-07-05
- Comitter:
- jappelino
- Date:
- Tue Jul 05 08:16:13 2011 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 70a1315acc03 MODSERIAL.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MODSERIAL.lib Tue Jul 05 08:16:13 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/AjK/code/MODSERIAL/#70bb7c1769fa
diff -r 000000000000 -r 70a1315acc03 SerialBuffered.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SerialBuffered.lib Tue Jul 05 08:16:13 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/AjK/libraries/SerialBuffered/lfp8fd \ No newline at end of file
diff -r 000000000000 -r 70a1315acc03 garmin_test.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/garmin_test.cpp Tue Jul 05 08:16:13 2011 +0000 @@ -0,0 +1,20 @@ +char garmin_readable_test(void){ + + return(1); + +} + +char garmin_read_test(void){ + +static char garmin_string[] = {"123$GPRMC,080158,A,5918.8362,N,01803.7725,E.0.0"}; + +static char index; + + index++; + + if(index > 45) + index = 0; + + return(garmin_string[index]); + +} \ No newline at end of file
diff -r 000000000000 -r 70a1315acc03 garmin_test.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/garmin_test.h Tue Jul 05 08:16:13 2011 +0000 @@ -0,0 +1,2 @@ +char garmin_readable_test(void); +char garmin_read_test(void); \ No newline at end of file
diff -r 000000000000 -r 70a1315acc03 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jul 05 08:16:13 2011 +0000 @@ -0,0 +1,807 @@ +#include "mbed.h" +#include "SerialBuffered.h" +#include "garmin_test.h" +#include "MODSERIAL.h" + +#define IDLE 0 +#define SEARCH_START 1 +#define CAPTURE 2 +#define FETCH_DATA 3 + +#define U0RBRTHR 0x4000C000 +#define U0DLL U0RBRTHR +#define U0RBR U0RBRTHR +#define U0THR U0RBRTHR +#define U0FCR 0x4000C008 +#define U0IER 0x4000C004 +#define U0DLM U0IER + + +#define U0LCR 0x4000C00C +#define U0LSR 0x4000C014 +#define U0SCR 0x4000C01C +#define U0ACR 0x4000C020 +#define U0FDR 0x4000C028 +#define U0TER 0x4000C030 +#define U0FIFOLVL 0x4000C058 + +#define CLKOUTCFG 0x400FC1C8 +#define PINSEL3 0x4002C00C + + +DigitalOut mled0(LED1); +DigitalOut mled1(LED2); +DigitalOut mled2(LED3); +DigitalOut mled3(LED4); + + MODSERIAL bg(p9,p10); + MODSERIAL bg2(p13,p14); + //Serial pc(USBTX, USBRX); // tx, rx + + +static volatile char garmin_buffer[50]; +static char ais_2_garmin[]={'!','A','I','V','D','M',',','1',',',',','1',',','A',',','1','3','u','?','e','t','P','v','2',';',\ + '1','B','J','d','D','Q','t','U','M','1','U','1','C','b','0','6','9','D',',','0','*','7','B',0 + }; int i; +int item; + +#define Z_SIZE 50 +static char Zigbee_buffer[Z_SIZE]; +static int p_z = 0; + +int analyze_buffer(void); +void packet_data(void); +void print_bg(char *message); +void debug_print(char *message); +int iChecksum( char* message ); +void packet_data_no_printf(void); +void print_pc(char *message); +void rxCallback(void); +void Rx_int(); +void rxCallback_Zigbee(void); +void int_to_speed(int speed); +void ais_crc(void); +void adjust_boat_east(void); +int find_solar_amphour(void); +int find_fridge_amphour(void); +int string_2_int(char *p_s); +void init_usb_serial(void); + +volatile int p_rx=0; +volatile int rec_state = SEARCH_START; +volatile int ais_ready=0; +int gi; +int b; +int speed; +char *p_f; +int z_sequence; + + +char db[2]; + static volatile char Rx_buffer[2000]; + char crlf[]={0x0A,0x0D,0}; + +int main() { + + + extern volatile int p_rx; + extern volatile char Rx_buffer[2000]; + int p_s,p_f; + int degrees = 0x30; + + + p_s = 0; + p_f = 0; + + z_sequence = 0; + + init_usb_serial(); + + bg2.baud(38400); + bg.baud(38400); + + bg.attach(&rxCallback_Zigbee, MODSERIAL::RxIrq); + bg2.attach(&rxCallback, MODSERIAL::RxIrq); + + print_pc("tjosan"); + print_pc(&crlf[0]); + + + for(;;){ + + while(ais_ready == 0); // wait for interrupt routine to fill up data + + ais_ready = 0; + + mled3 = 1; + + b++; + + ais_2_garmin[35] = degrees++; + + int_to_speed(speed++); + + if(speed > 170) + speed = 0; + + if(degrees > 0x33) + degrees = 0x30; + + if(b>2){ + + mled3 = 0; + + b = 0; + + } + ais_2_garmin[15] = 0x33; + + print_pc(&Zigbee_buffer[0]); + print_pc(&crlf[0]); + + + if(p_s != 0){ + + int_to_speed(p_s); + + ais_crc(); + __disable_irq(); + print_bg(&ais_2_garmin[0]); + __enable_irq(); + print_pc(&ais_2_garmin[0]); + print_pc(&crlf[0]); + + } + + if(p_f != 0){ + + adjust_boat_east(); // prepere for the next "boat" + + ais_2_garmin[15] = 0x34; // change boat identity + + int_to_speed(p_f); + + ais_crc(); + __disable_irq(); + print_bg(&ais_2_garmin[0]); + __enable_irq(); + print_pc(&ais_2_garmin[0]); + print_pc(&crlf[0]); + + } + + if( z_sequence == 2){ + + p_s = find_solar_amphour(); + + p_f = find_fridge_amphour(); + + } + + z_sequence++; + if(z_sequence > 2){ + + z_sequence = 0; + + for(i = 0 ; i < Z_SIZE; i++) // erase data in zigbee buffer + Zigbee_buffer[i] = 0; + + } + } + + } +void init_usb_serial(void){ + + int *p_reg; + + p_reg = (int *) U0LCR; + *p_reg = 0x83; + p_reg = (int *) U0FCR; + *p_reg = 0x01; + p_reg = (int *) U0DLL; + *p_reg = 832; + p_reg = (int *) U0DLM; + *p_reg = 0; + p_reg = (int *) U0FDR; + p_reg = (int *) U0LCR; + *p_reg = (*p_reg) & 0x7F; + +} + +int string_2_int(char *p_s){ + +int i; + + i = (*p_s++ - 0x30) * 10; + + i = i + (*p_s - 0x30); + + return(i); + +} + +int find_fridge_amphour(void){ + + char *p_b; + + int a; + + int i = 0; + + p_b = &Zigbee_buffer[0]; + + while(*p_b != 'A' && i < 50) // search for the identifying character + p_b++; + + if( i < 50){ + + a = (*(p_b + 7) - 0x30) * 100 + (*(p_b + 8) - 0x30) * 10; + + } + else + a = 0; + + return(a); +} +int find_solar_amphour(void){ + + char *p_b; + + int a; + + int i = 0; + + p_b = &Zigbee_buffer[0]; + + while(*p_b != 'D' && i < 50) // search for the identifying character + p_b++; + + if( i < 50){ + + a = (*(p_b + 7) - 0x30) * 100 + (*(p_b + 8) - 0x30) * 10; + + } + else + a = 0; + + return(a); +} + +void adjust_boat_east(void){ + + char a; + + a = ais_2_garmin[26]; + + a = a + 4; + + if(a > 87 && a < 98) + a = a + 8; + + if(a > 119){ + + ais_2_garmin[25]++; + + a = 0x30; + + } + + ais_2_garmin[26] = a; + + +} + +void int_to_speed(int speed){ + +int low_part,high_part; + + high_part = (speed & 0x3C0) >> 6; + + low_part = speed & 0x3F; + + ais_2_garmin[22] = high_part + 0x30; + + if(ais_2_garmin[22] > 87) + ais_2_garmin[22] = ais_2_garmin[22] + 8; + + ais_2_garmin[23] = low_part + 0x30; + + if(ais_2_garmin[23] > 87) + ais_2_garmin[23] = ais_2_garmin[23] + 8; + + + + +} + +void rxCallback_Zigbee(void) { +static int c,d; + + d = bg.getc(); + + Zigbee_buffer[p_z++] = d; + + if(p_z > Z_SIZE) + p_z = 0; + + c++; + + if(c == 10) + mled1 = 1; + + if(c >= 20){ + + c = 0; + mled1 = 0; + + } + + +} +void rxCallback(void) { + +static char nmea_in; +extern volatile int rec_state; +extern volatile char Rx_buffer[2000]; +extern volatile int p_rx; +extern volatile int ais_ready; +int head; + + +// Rx_buffer[p_rx++] = bg2.getc(); + + mled0 = 1; + + nmea_in= bg2.getc(); + + switch (rec_state) { + + case IDLE: + + mled0 = 1; + + break; + + + case SEARCH_START: + + if (nmea_in == '$') { + + rec_state = CAPTURE; + + } + + break; + + case CAPTURE: + + garmin_buffer[item++] = nmea_in; + + if(item >6){ + + head = analyze_buffer(); + + if(head == 17){ + + mled2 = 1; + + gi++; + + if(gi >= 2){ + + gi = 0; + + mled0 = 0; + mled2 = 0; + mled3 = 0; + + } + + rec_state = FETCH_DATA; // we found our nmea sentence + + } + + else{ + + rec_state = SEARCH_START; // not rigth sentence, go back to search rigth header + + item = 0; + + } + } + + break; + + case FETCH_DATA: + + garmin_buffer[item++] = nmea_in; + + if(item > 40){ + + packet_data_no_printf(); + + item = 0; + + ais_ready = 17; + + rec_state = SEARCH_START; + + } + break; + + default: + + mled0 = 1; + + break; + } + + if(p_rx > 1100){ + p_rx = 1100; + mled2 = 0; + } + +} +int analyze_buffer(void){ + + extern volatile char garmin_buffer[50]; + + char t_1,t_2,t_3,t_4,t_5; + + t_1 = garmin_buffer[0]; + + t_2 = garmin_buffer[1]; + + t_3 = garmin_buffer[2]; + + t_4 = garmin_buffer[3]; + + t_5 = garmin_buffer[4]; + + if(t_1 == 'G' && t_2 == 'P' && t_3 == 'R' && t_4 == 'M' && t_5 == 'C') + return(17); + else + return(0); + +} + +void packet_data_no_printf(void){ + + extern volatile char garmin_buffer[50]; + + extern char ais_2_garmin[48]; + + char long_ais[7],lat_ais[7]; + + int i; + + long long_1, long_2,lat_1,lat_2; + + char longitude[8],latitude[8]; + + for(i = 0; i < 4; i++) + latitude[i] = garmin_buffer[i + 15]; + + for(i = 4; i < 8 ; i++) + latitude[i] = garmin_buffer[i + 16]; // don't copy the "." + + for(i = 0; i < 5; i++) + longitude[i] = garmin_buffer[i + 27]; + + for(i = 5; i < 8; i++) + longitude[i] = garmin_buffer[i + 28]; + + // strip of 0x30 from all values + + for(i = 0; i < 8 ; i++) + longitude[i] = longitude[i] - 0x30; + + for(i = 0; i < 8 ; i++) + latitude[i] = latitude[i] - 0x30; + + long_1 = longitude[3] * 100000 + longitude[4] * 10000 + longitude[5] * 1000 + longitude[6] * 100 + longitude[7] * 10; + + long_1 = long_1 * 6; + + long_1 = long_1 / 10; + + long_2 = longitude[0] * 100 + longitude[1] * 10 + longitude[2]; + + long_2 = long_2 * 600000; + + long_2 = long_2 + long_1; + + lat_1 = latitude[2] * 100000 + latitude[3] * 10000 + latitude[4] * 1000 + latitude[5] * 100 + latitude[6] * 10 + latitude[7]; + + lat_2 = latitude[0] * 10 + latitude[1]; + + lat_2 = lat_2 * 600000; + + lat_2 = lat_2 + lat_1; + + // do the bit fiddling to pack 8 bits into 6 bit and back into 8 bit format according to the AIVDM format + + long_ais[0] = ((long_2 >> 23) & 0x3F) + 0x30; + + long_ais[1] = ((long_2 >> 17) & 0x3F) + 0x30; + + long_ais[2] = ((long_2 >> 11) & 0x3F) + 0x30; + + long_ais[3] = ((long_2 >> 5) & 0x38) + 0x30; + + lat_ais[0] = ((lat_2 >> 20) & 0x3F) + 0x30; + + lat_ais[1] = ((lat_2 >> 14) & 0x3F) + 0x30; + +// if(lat_ais[1] > 87) +// lat_ais[1] = lat_ais[1] + 0x08; + + lat_ais[2] = ((lat_2 >> 8) & 0x3F) + 0x30; + + lat_ais[3] = ((lat_2 >> 2) & 0x3F) + 0x30; + + ais_2_garmin[24] = long_ais[0]; + + ais_2_garmin[25] = long_ais[1]; + + ais_2_garmin[26] = long_ais[2]; + + ais_2_garmin[27] = long_ais[3]; + + ais_2_garmin[29] = lat_ais[0]; + + ais_2_garmin[30] = lat_ais[1]; + + ais_2_garmin[31] = lat_ais[2]; + + ais_2_garmin[32] = lat_ais[3]; + + for( i = 24; i < 33 ; i++){ // adjust for codes not used + + if(ais_2_garmin[i] > 87) + ais_2_garmin[i] = ais_2_garmin[i] + 8; + + } + +} + +void ais_crc(void){ + + int checksum,pos; + + checksum = 0; + + pos = 0; + + while(ais_2_garmin[pos++] != '*'); + + checksum = iChecksum(&ais_2_garmin[0]); + + ais_2_garmin[pos] = ((checksum & 0xF0) >> 4) + 0x30; + + if(ais_2_garmin[pos] > 0x39) + ais_2_garmin[pos] = ais_2_garmin[pos] + 7; + + ais_2_garmin[pos+1] = (checksum & 0x0F) + 0x30; + + if(ais_2_garmin[pos+1] > 0x39) + ais_2_garmin[pos+1] = ais_2_garmin[pos+1] + 7; + +} + +void packet_data(void){ + + extern volatile char garmin_buffer[50]; + + extern char ais_2_garmin[48]; + + char long_ais[7],lat_ais[7]; + + char p_buffer[40]; + + int i; + + long long_1, long_2,lat_1,lat_2; + + char longitude[8],latitude[8]; + + char crlf[] = {0x0A,0x0D,0}; + + int checksum,pos; + + for(i = 0; i < 4; i++) + latitude[i] = garmin_buffer[i + 15]; + + for(i = 4; i < 8 ; i++) + latitude[i] = garmin_buffer[i + 16]; // don't copy the "." + + for(i = 0; i < 5; i++) + longitude[i] = garmin_buffer[i + 27]; + + for(i = 5; i < 8; i++) + longitude[i] = garmin_buffer[i + 28]; + + debug_print("from Garmin latitude: "); + + for(i = 0; i < 8 ; i++) + p_buffer[i] = latitude[i]; + + p_buffer[8] = 0; + + debug_print(&p_buffer[0]); + + debug_print("from Garmin longitude: "); + + for(i = 0 ; i < 8 ; i++) + p_buffer[i] = longitude[i]; + + p_buffer[8] = 0; + + debug_print(&p_buffer[0]); + + debug_print(&crlf[0]); + + // strip of 0x30 from all values + + for(i = 0; i < 8 ; i++) + longitude[i] = longitude[i] - 0x30; + + for(i = 0; i < 8 ; i++) + latitude[i] = latitude[i] - 0x30; + + // + + long_1 = longitude[3] * 100000 + longitude[4] * 10000 + longitude[5] * 1000 + longitude[6] * 100 + longitude[7] * 10; + +// long_1 = long_1 * 5; + +// long_1 = long_1 / 3; + + long_1 = long_1 * 6; + + long_1 = long_1 / 10; + + long_2 = longitude[0] * 100 + longitude[1] * 10 + longitude[2]; + + long_2 = long_2 * 600000; + + long_2 = long_2 + long_1; + + Serial pc(USBTX, USBRX); // tx, rx + + pc.printf("longitude converted into minutes/10000: %d \n",long_2); + + lat_1 = latitude[2] * 100000 + latitude[3] * 10000 + latitude[4] * 1000 + latitude[5] * 100 + latitude[6] * 10 + latitude[7]; + + // lat_1 = lat_1 ; + + // lat_1 = lat_1 *10; + + // lat_1 = lat_1 / 6 ; + + lat_2 = latitude[0] * 10 + latitude[1]; + + lat_2 = lat_2 * 600000; + + lat_2 = lat_2 + lat_1; + + pc.printf("latitude converted into minutes/10000: %d \n\n",lat_2); + + // do the bit fiddling to pack 8 bits into 6 bit and back into 8 bit format according to the AIVDM format + + long_ais[0] = ((long_2 >> 23) & 0x3F) + 0x30; + + long_ais[1] = ((long_2 >> 17) & 0x3F) + 0x30; + + long_ais[2] = ((long_2 >> 11) & 0x3F) + 0x30; + + long_ais[3] = ((long_2 >> 5) & 0x38) + 0x30; + + pc.printf("longitude : %c%c%c%c\n",long_ais[0],long_ais[1],long_ais[2],long_ais[3]); + + lat_ais[0] = ((lat_2 >> 20) & 0x3F) + 0x30; + + lat_ais[1] = ((lat_2 >> 14) & 0x3F) + 0x30; + + pc.printf("lat_1 %x \n",lat_ais[1]); + if(lat_ais[1] > 87) + lat_ais[1] = lat_ais[1] + 0x08; + pc.printf("lat_1 modified %x \n",lat_ais[1]); + + lat_ais[2] = ((lat_2 >> 8) & 0x3F) + 0x30; + + lat_ais[3] = ((lat_2 >> 2) & 0x3F) + 0x30; + + pc.printf("latitude: %c%c%c%c\n\n",lat_ais[0],lat_ais[1],lat_ais[2],lat_ais[3]); + + debug_print("original string to Garmin: "); + + debug_print(&ais_2_garmin[0]); + + pc.printf("\n"); + + ais_2_garmin[24] = long_ais[0]; + + ais_2_garmin[25] = long_ais[1]; + + ais_2_garmin[26] = long_ais[2]; + + ais_2_garmin[27] = long_ais[3]; + + ais_2_garmin[29] = lat_ais[0]; + + ais_2_garmin[30] = lat_ais[1]; + + ais_2_garmin[31] = lat_ais[2]; + + ais_2_garmin[32] = lat_ais[3]; + + pos = 0; + + while(ais_2_garmin[pos++] != '*'); + + checksum = iChecksum(&ais_2_garmin[0]); + + ais_2_garmin[pos] = ((checksum & 0xF0) >> 4) + 0x30; + + if(ais_2_garmin[pos] > 0x39) + ais_2_garmin[pos] = ais_2_garmin[pos] + 7; + + ais_2_garmin[pos+1] = (checksum & 0x0F) + 0x30; + + if(ais_2_garmin[pos+1] > 0x39) + ais_2_garmin[pos+1] = ais_2_garmin[pos+1] + 7; + + +} void debug_print(char *message){ + + +// Serial bg_d(p28,p27); + +// bg_d.printf(message); + + Serial pc(USBTX, USBRX); + + pc.printf(message); + +} +void print_bg(char *message){ + + + + while(*message != 0){ + + while(bg.writeable() == 0); + + bg.putc((int) *message++); + + } + +} +void print_pc(char *message){ + + int *p_reg; + int *p_lsr; + + p_lsr = (int *) U0LSR; + + p_reg = (int *) U0THR; + + while(*message != 0){ + + while ((*p_lsr & 0x20) == 0); // wait until holding register empty + + *p_reg = *message++; + + } + +} +int iChecksum( char* message ) +{ +int sum = 0; + for( char* c = message+1; *c!='*'; c++ ) + { + sum^=*c; + } + return sum; +}
diff -r 000000000000 -r 70a1315acc03 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Jul 05 08:16:13 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e