altos: Get CC115L radio working.
[fw/altos] / src / drivers / ao_aprs.c
index 1a074ba516fed78c691d3fc01d629cc60e8cf754..6ab61e6a3018f9d945bce57be25eb5176e251a3c 100644 (file)
 
 #include <ao_aprs.h>
 
-typedef int bool_t;
-typedef int32_t int32;
-#define false 0
-#define true 1
-
 // Public methods, constants, and data structures for each class.
 
 static void timeInit(void);
@@ -258,12 +253,31 @@ typedef enum
 
 /// AX.25 compliant packet header that contains destination, station call sign, and path.
 /// 0x76 for SSID-11, 0x78 for SSID-12
-static const uint8_t TNC_AX25_HEADER[] = { 
+static uint8_t TNC_AX25_HEADER[] = { 
     'A' << 1, 'P' << 1, 'A' << 1, 'M' << 1, ' ' << 1, ' ' << 1, 0x60, \
-    'K' << 1, 'D' << 1, '7' << 1, 'S' << 1, 'Q' << 1, 'G' << 1, 0x78, \
+    'N' << 1, '0' << 1, 'C' << 1, 'A' << 1, 'L' << 1, 'L' << 1, 0x78, \
     'W' << 1, 'I' << 1, 'D' << 1, 'E' << 1, '2' << 1, ' ' << 1, 0x65, \
     0x03, 0xf0 };
 
+#define TNC_CALLSIGN_OFF       7
+#define TNC_CALLSIGN_LEN       6
+
+static void
+tncSetCallsign(void)
+{
+#ifndef AO_APRS_TEST
+       uint8_t i;
+
+       for (i = 0; i < TNC_CALLSIGN_LEN; i++) {
+               if (!ao_config.callsign[i])
+                       break;
+               TNC_AX25_HEADER[TNC_CALLSIGN_OFF + i] = ao_config.callsign[i] << 1;
+       }
+       for (; i < TNC_CALLSIGN_LEN; i++)
+               TNC_AX25_HEADER[TNC_CALLSIGN_OFF + i] = ' ' << 1;
+#endif
+}
+
 /// The next bit to transmit.
 static uint8_t tncTxBit;
 
@@ -285,9 +299,6 @@ static uint8_t tncLength;
 /// A copy of the last 5 bits we've transmitted to determine if we need to bit stuff on the next bit.
 static uint8_t tncBitStuff;
 
-/// Pointer to TNC buffer as we save each byte during message preparation.
-static uint8_t *tncBufferPnt;
-
 /// Buffer to hold the message portion of the AX.25 packet as we prepare it.
 static uint8_t tncBuffer[TNC_BUFFER_SIZE];
 
@@ -471,18 +482,18 @@ static void tnc1200TimerTick()
 /**
  *   Generate the plain text position packet.
  */
-static void tncPositionPacket(void)
+static int tncPositionPacket(void)
 {
-    int32_t    latitude = 45.4694766 * 10000000;
-    int32_t    longitude = -122.7376250 * 10000000;
-    uint32_t   altitude = 10000;
+    int32_t    latitude = ao_gps_data.latitude;
+    int32_t    longitude = ao_gps_data.longitude;
+    int32_t    altitude = ao_gps_data.altitude;
+
     uint16_t   lat_deg;
     uint16_t   lon_deg;
     uint16_t   lat_min;
     uint16_t   lat_frac;
     uint16_t   lon_min;
     uint16_t   lon_frac;
-    int                c;
 
     char       lat_sign = 'N', lon_sign = 'E';
 
@@ -496,26 +507,37 @@ static void tncPositionPacket(void)
        longitude = -longitude;
     }
 
+    /* Round latitude and longitude by 0.005 minutes */
+    latitude = latitude + 833;
+    if (latitude > 900000000)
+       latitude = 900000000;
+    longitude = longitude + 833;
+    if (longitude > 1800000000)
+           longitude = 1800000000;
+
     lat_deg = latitude / 10000000;
     latitude -= lat_deg * 10000000;
     latitude *= 60;
     lat_min = latitude / 10000000;
     latitude -= lat_min * 10000000;
-    lat_frac = (latitude + 50000) / 100000;
+    lat_frac = latitude / 100000;
 
     lon_deg = longitude / 10000000;
     longitude -= lon_deg * 10000000;
     longitude *= 60;
     lon_min = longitude / 10000000;
     longitude -= lon_min * 10000000;
-    lon_frac = (longitude + 50000) / 100000;
-
-    c = sprintf ((char *) tncBufferPnt, "=%02u%02u.%02u%c\\%03u%02u.%02u%cO /A=%06u\015",
-               lat_deg, lat_min, lat_frac, lat_sign,
-               lon_deg, lon_min, lon_frac, lon_sign,
-               altitude * 100 / 3048);
-    tncBufferPnt += c;
-    tncLength += c;
+    lon_frac = longitude / 100000;
+
+    if (altitude < 0)
+       altitude = 0;
+
+    altitude = (altitude * (int32_t) 10000 + (3048/2)) / (int32_t) 3048;
+    
+    return sprintf ((char *) tncBuffer, "=%02u%02u.%02u%c\\%03u%02u.%02u%cO /A=%06u\015",
+                   lat_deg, lat_min, lat_frac, lat_sign,
+                   lon_deg, lon_min, lon_frac, lon_sign,
+                   altitude);
 }
 
 static int16_t
@@ -552,25 +574,17 @@ void ao_aprs_send(void)
 
     timeInit();
     tncInit();
+    tncSetCallsign();
 
-    // Set a pointer to our TNC output buffer.
-    tncBufferPnt = tncBuffer;
-
-    // Set the message length counter.
-    tncLength = 0;
-
-    tncPositionPacket();
+    tncLength = tncPositionPacket();
 
     // Calculate the CRC for the header and message.
     crc = sysCRC16(TNC_AX25_HEADER, sizeof(TNC_AX25_HEADER), 0xffff);
     crc = sysCRC16(tncBuffer, tncLength, crc ^ 0xffff);
 
     // Save the CRC in the message.
-    *tncBufferPnt++ = crc & 0xff;
-    *tncBufferPnt = (crc >> 8) & 0xff;
-
-    // Update the length to include the CRC bytes.
-    tncLength += 2;
+    tncBuffer[tncLength++] = crc & 0xff;
+    tncBuffer[tncLength++] = (crc >> 8) & 0xff;
 
     // Prepare the variables that are used in the real-time clock interrupt.
     tncBitCount = 0;
@@ -579,7 +593,7 @@ void ao_aprs_send(void)
     tncIndex = 0;
     tncMode = TNC_TX_SYNC;
 
-    ao_radio_send_lots(tncFill);
+    ao_radio_send_aprs(tncFill);
 }
 
 /** @} */