first cut at turnon scripts for EasyTimer v2
[fw/altos] / src / drivers / ao_aprs.c
index a9047149d981c3c0af7343bbaeab018fe14f80c7..b0645465c586ddb6e88f11f29ff37962cfc61277 100644 (file)
@@ -186,7 +186,7 @@ static uint16_t sysCRC16(const uint8_t *buffer, uint8_t length, uint16_t crc)
 
         for (bit = 0; bit < 8; ++bit)
         {
-            crc ^= (value & 0x01);
+           crc = (uint16_t) (crc ^ (value & 0x01));
             crc = ( crc & 0x01 ) ? ( crc >> 1 ) ^ 0x8408 : ( crc >> 1 );
             value = value >> 1;
         } // END for
@@ -234,7 +234,7 @@ static void timeInit()
 #define TNC_TX_DELAY 45
 
 /// The size of the TNC output buffer.
-#define TNC_BUFFER_SIZE 40
+#define TNC_BUFFER_SIZE 48
 
 /// States that define the current mode of the 1200 bps (A-FSK) state machine.
 typedef enum
@@ -282,7 +282,7 @@ tncSetCallsign(void)
                TNC_AX25_HEADER[TNC_CALLSIGN_OFF + i] = ' ' << 1;
 
        /* Fill in the SSID with the low digit of the serial number */
-       TNC_AX25_HEADER[TNC_SSID_OFF] = 0x60 | ((ao_config.aprs_ssid & 0xf) << 1);
+       TNC_AX25_HEADER[TNC_SSID_OFF] = (uint8_t) (0x60 | ((ao_config.aprs_ssid & 0xf) << 1));
 #endif
 }
 
@@ -310,6 +310,7 @@ static uint8_t tncBitStuff;
 /// Buffer to hold the message portion of the AX.25 packet as we prepare it.
 static uint8_t tncBuffer[TNC_BUFFER_SIZE];
 
+#pragma GCC diagnostic ignored "-Wformat-overflow="
 /**
  *   Initialize the TNC internal variables.
  */
@@ -490,7 +491,7 @@ static void tnc1200TimerTick()
 static void tncCompressInt(uint8_t *dest, int32_t value, int len) {
        int i;
        for (i = len - 1; i >= 0; i--) {
-               dest[i] = value % 91 + 33;
+               dest[i] = (uint8_t) (value % 91 + 33);
                value /= 91;
        }
 }
@@ -527,7 +528,7 @@ static int tncComment(uint8_t *buf)
        int16_t apogee = ao_ignite_decivolt(AO_SENSE_DROGUE(&packet));
 #endif
 #ifdef AO_SENSE_MAIN
-       int16_t main = ao_ignite_decivolt(AO_SENSE_MAIN(&packet));
+       int16_t main_value = ao_ignite_decivolt(AO_SENSE_MAIN(&packet));
 #endif
 
        return sprintf((char *) buf,
@@ -548,8 +549,8 @@ static int tncComment(uint8_t *buf)
                       apogee%10
 #endif
 #ifdef AO_SENSE_MAIN
-                      , main/10,
-                      main%10
+                      , main_value/10,
+                      main_value%10
 #endif
                       , ao_serial_number
                );
@@ -611,7 +612,7 @@ fixed23_mul(uint32_t x, uint32_t y)
 static inline uint32_t
 fixed30_mul(uint32_t x, uint32_t y)
 {
-       return ((uint64_t) x * y + fixed30_half) >> 30;
+       return (uint32_t) (((uint64_t) x * y + fixed30_half) >> 30);
 }
 
 /*
@@ -620,15 +621,18 @@ fixed30_mul(uint32_t x, uint32_t y)
  */
 
 static uint32_t
-ao_fixed_log2(uint32_t x)
+ao_fixed_log2(int32_t ix)
 {
        uint32_t        result;
        uint32_t        frac = fixed23_one;
+       uint32_t        x;
 
        /* Bounds check for sanity */
-       if (x <= 0)
+       if (ix <= 0)
                return 0;
 
+       x = (uint32_t) ix;
+
        if (x >= fixed30_one)
                return 0xffffffff;
 
@@ -693,58 +697,128 @@ ao_fixed_log2(uint32_t x)
 #define APRS_LOG_CONVERT       fixed23_real(1.714065192056127)
 #define APRS_LOG_BASE          fixed23_real(346.920048461100941)
 
-static int
+static int32_t
 ao_aprs_encode_altitude(int meters)
 {
-       return fixed23_floor(fixed23_mul(ao_fixed_log2(meters) + APRS_LOG_CONVERT, APRS_LOG_BASE) + fixed23_half);
+       return (int32_t) fixed23_floor(fixed23_mul(ao_fixed_log2(meters) + APRS_LOG_CONVERT, APRS_LOG_BASE) + fixed23_half);
 }
 
 /**
  *   Generate the plain text position packet.
  */
-static int tncPositionPacket(void)
+static uint8_t tncPositionPacket(void)
 {
     static int32_t     latitude;
     static int32_t     longitude;
     static int32_t     altitude;
-    int32_t            lat, lon, alt;
-    uint8_t    *buf;
+    uint8_t            *buf;
 
     if (ao_gps_data.flags & AO_GPS_VALID) {
        latitude = ao_gps_data.latitude;
        longitude = ao_gps_data.longitude;
-       altitude = ao_gps_data.altitude;
+       altitude = AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data);
        if (altitude < 0)
            altitude = 0;
     }
 
     buf = tncBuffer;
-    *buf++ = '!';
 
-    /* Symbol table ID */
-    *buf++ = '/';
+#ifdef AO_APRS_TEST
+#define AO_APRS_FORMAT_COMPRESSED      0
+#define AO_APRS_FORMAT_UNCOMPRESSED    1
+    switch (AO_APRS_FORMAT_COMPRESSED) {
+#else
+    switch (ao_config.aprs_format) {
+#endif
+    case AO_APRS_FORMAT_COMPRESSED:
+    default:
+    {
+           int32_t             lat, lon, alt;
+
+           *buf++ = '!';
+
+           /* Symbol table ID */
+           *buf++ = '/';
 
-    lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000;
-    lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000;
+           lat = (int32_t) (((int64_t) 380926 * (900000000 - latitude)) / 10000000);
+           lon = (int32_t) (((int64_t) 190463 * (1800000000 + longitude)) / 10000000);
 
-    alt = ao_aprs_encode_altitude(altitude);
+           alt = ao_aprs_encode_altitude(altitude);
 
-    tncCompressInt(buf, lat, 4);
-    buf += 4;
-    tncCompressInt(buf, lon, 4);
-    buf += 4;
+           tncCompressInt(buf, lat, 4);
+           buf += 4;
+           tncCompressInt(buf, lon, 4);
+           buf += 4;
 
-    /* Symbol code */
-    *buf++ = '\'';
+           /* Symbol code */
+           *buf++ = '\'';
 
-    tncCompressInt(buf, alt, 2);
-    buf += 2;
+           tncCompressInt(buf, alt, 2);
+           buf += 2;
 
-    *buf++ = 33 + ((1 << 5) | (2 << 3));
+           *buf++ = 33 + ((1 << 5) | (2 << 3));
+
+           break;
+    }
+    case AO_APRS_FORMAT_UNCOMPRESSED:
+    {
+           char        lat_sign = 'N', lon_sign = 'E';
+           int32_t     lat = latitude;
+           int32_t     lon = longitude;
+           int32_t     alt = 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;
+
+           if (lat < 0) {
+                   lat_sign = 'S';
+                   lat = -lat;
+           }
+
+           if (lon < 0) {
+                   lon_sign = 'W';
+                   lon = -lon;
+           }
+
+           /* Round latitude and longitude by 0.005 minutes */
+           lat = lat + 833;
+           if (lat > 900000000)
+                   lat = 900000000;
+           lon = lon + 833;
+           if (lon > 1800000000)
+                   lon = 1800000000;
+
+           lat_deg = (uint16_t) (lat / 10000000);
+           lat -= lat_deg * 10000000;
+           lat *= 60;
+           lat_min = (uint16_t) (lat / 10000000);
+           lat -= lat_min * 10000000;
+           lat_frac = (uint16_t) (lat / 100000);
+
+           lon_deg = (uint16_t) (lon / 10000000);
+           lon -= lon_deg * 10000000;
+           lon *= 60;
+           lon_min = (uint16_t) (lon / 10000000);
+           lon -= lon_min * 10000000;
+           lon_frac = (uint16_t) (lon / 100000);
+
+           /* Convert from meters to feet */
+           alt = (alt * 328 + 50) / 100;
+
+           buf += sprintf((char *) tncBuffer, "!%02u%02u.%02u%c/%03u%02u.%02u%c'/A=%06lu ",
+                          lat_deg, lat_min, lat_frac, lat_sign,
+                          lon_deg, lon_min, lon_frac, lon_sign,
+                          (long) alt);
+           break;
+    }
+    }
 
     buf += tncComment(buf);
 
-    return buf - tncBuffer;
+    return (uint8_t) (buf - tncBuffer);
 }
 
 static int16_t
@@ -757,7 +831,7 @@ tncFill(uint8_t *buf, int16_t len)
     while (tncMode != TNC_TX_READY && l < len) {
        b = 0;
        for (bit = 0; bit < 8; bit++) {
-           b = b << 1 | (timeNCO >> 15);
+           b = (uint8_t) (b << 1 | (timeNCO >> 15));
            timeNCO += timeNCOFreq;
        }
        *buf++ = b;
@@ -790,8 +864,8 @@ void ao_aprs_send(void)
     crc = sysCRC16(tncBuffer, tncLength, crc ^ 0xffff);
 
     // Save the CRC in the message.
-    tncBuffer[tncLength++] = crc & 0xff;
-    tncBuffer[tncLength++] = (crc >> 8) & 0xff;
+    tncBuffer[tncLength++] = (uint8_t) (crc & 0xff);
+    tncBuffer[tncLength++] = (uint8_t) ((crc >> 8) & 0xff);
 
     // Prepare the variables that are used in the real-time clock interrupt.
     tncBitCount = 0;