Browse Source

commiting before I integrate latest changes on desktop

curiousmuch 4 years ago
parent
commit
6268ed8fab
3 changed files with 247 additions and 4 deletions
  1. 243 0
      main/aprs_decoder.c
  2. 1 1
      main/cc1200_protocol.h
  3. 3 3
      main/main.c

+ 243 - 0
main/aprs_decoder.c

@@ -0,0 +1,243 @@
+/*
+ * aprs_decoder.c
+ *
+ *  Created on: Aug 25, 2019
+ *      Author: curiousmuch
+ */
+
+
+typedef enum {
+	NORMAL,
+	FRAME_DECODED,
+	ERROR_FCS_MISMATCH,
+	ERROR_PACKET_FORMAT,
+	ERROR_BUFFER_OVERFLOW
+} decoder_output_t;
+
+typedef enum {
+	NONE,
+	BUFFER_OVERFLOW,
+	BIT_STUFFING_FAILURE,
+	FCS_MISMATCH,
+} decoder_error_t;
+
+typedef enum {
+	FLAG_SEARCH,
+	FLAG_FOUND,
+	FRAME_START,
+	PACKET_END,
+	FRAME_END,
+	ABORT,
+} decoder_state_t;
+
+typedef struct {
+	decoder_state_t decoder_state;
+	uint8_t 		*frame_buffer;
+	uint8_t 		frame_buffer_index;
+	uint8_t 		frame_buffer_len;
+	uint8_t 		flag_buffer;
+	uint8_t			flag_buffer_index;
+	uint8_t			byte_buffer;
+	uint8_t 		current_nrzi_bit;
+	uint8_t 		previous_nrzi_bit;
+	uint8_t 		current_bit;
+	uint8_t 		one_count;
+	uint32_t 		byte_buffer_index;
+	uint8_t			skip_bit_flag;
+} decoder_varibles_t;
+
+decoder_varibles_t v;
+
+#define APRS_MAX_FRAME 256
+
+void frame_buffer_init(uint8_t *buf, uint8_t len)
+{
+	v.frame_buffer = buf;
+	v.frame_buffer_len = len;
+}
+
+void aprs_decode_init(void)
+{
+	v.decoder_state = FLAG_SEARCH;
+	v.frame_buffer_index = 0;
+	//v.frame_max_len = APRS_MAX_FRAME;
+	v.flag_buffer = 0;
+	v.flag_buffer_index = 0;
+	v.byte_buffer_index = 0;
+	v.byte_buffer = 0;
+	v.current_nrzi_bit = 0;
+	v.previous_nrzi_bit = 0;
+	v.current_bit = 0;
+	v.one_count = 0;
+	v.skip_bit_flag = 0;
+}
+
+uint8_t flag_found(void)
+{
+	if (v.flag_buffer == 0x7E)
+		return 1;
+	else
+		return 0;
+}
+
+decoder_output_t aprs_decode_feed_bit(uint8_t nrzi_bit)
+{
+	v.current_nrzi_bit = nrzi_bit;
+
+	// decoder NRZI
+	if (v.previous_nrzi_bit == v.current_nrzi_bit)
+	{
+		v.current_bit = 1;
+		v.one_count =+ 1;
+	}
+	else
+	{
+		v.current_bit = 0;
+		v.one_count = 0;
+	}
+	v.previous_nrzi_bit = v.current_nrzi_bit;
+
+	// load bit into flag buffer
+	v.flag_buffer = (v.flag_buffer >> 1) + (v.current_bit*0x80);
+
+	switch(v.decoder_state)
+	{
+		case FLAG_SEARCH:
+			if (flag_found())
+			{
+				// set state variable
+				v.decoder_state = FLAG_FOUND;
+
+				// re-initialize buffer indexes
+				v.flag_buffer_index = 0;
+				v.frame_buffer_index = 0;
+			}
+			else
+			{
+				v.decoder_state = FLAG_SEARCH;
+			}
+			break;
+		case FLAG_FOUND:
+			if (v.flag_buffer_index == 7)	// check every 8 bits for flag again
+			{
+				if (flag_found())	// if flag is found, payload hasn't started
+				{
+					v.decoder_state = FLAG_FOUND;
+					v.flag_buffer_index = 0;
+				}
+				else
+				{
+					v.decoder_state = FRAME_START;
+
+					// load current bits in byte buffer and remove 0 stuffing
+					uint8_t i, bit;
+					v.skip_bit_flag = 0;
+					v.byte_buffer_index = 0;
+					v.one_count = 0;
+
+					for (i=0;i<7;i++)
+					{
+						bit = (v.flag_buffer << i) & 0x80; // load bit
+
+						// count ones for to remove bit stuffing
+						if (bit)
+							v.one_count =+ 1;
+						else
+							v.one_count = 0;
+
+						// skip bit or store in v.byte_buffer
+						if (v.skip_bit_flag)
+						{
+							v.skip_bit_flag = 0;
+
+							// if "0" is not stuffed packet is invalid
+							if (bit != 0)
+								v.decoder_state = ABORT;
+						}
+						else
+						{
+							v.byte_buffer |= bit*(0x8>>i);
+							v.byte_buffer_index =+ 1;
+						}
+
+						if (v.one_count == 5)
+							v.skip_bit_flag = 1;
+					}
+
+					// check if byte buffer is full
+					if (v.byte_buffer_index == 7)
+					{
+						v.frame_buffer[v.frame_buffer_index] = v.byte_buffer;
+						v.byte_buffer = 0;
+						v.byte_buffer_index = 0;
+						v.frame_buffer_index += 1;
+					}
+
+					break;
+				}
+			}
+			v.flag_buffer_index =+ 1;
+			break;
+		case FRAME_START:
+			// skip stuffed "0"
+			if (v.skip_bit_flag == 1)
+			{
+				v.skip_bit_flag = 0;
+
+				// bit will only not be stuffed properly if the HDLC flag is being received
+				// indicating the end of the frame or the packet has become corrupted.
+				if (v.current_bit != 0)
+				{
+					v.decoder_state = PACKET_END;
+					break;
+				}
+			}
+			else
+			{
+				// load bit
+				v.byte_buffer |= v.current_bit*(0x8>>v.byte_buffer_index);
+				v.byte_buffer_index =+ 1;
+
+				// check if byte buffer is full
+				if (v.byte_buffer_index == 7)
+				{
+					v.frame_buffer[v.frame_buffer_index] = v.byte_buffer;
+					v.byte_buffer = 0;
+					v.byte_buffer_index = 0;
+					v.frame_buffer_index += 1;
+
+					// check for overflow
+					if (v.frame_buffer_index == v.frame_buffer_len)
+					{
+						v.decoder_state = ABORT;
+						break;
+					}
+				}
+
+			}
+
+			if(v.one_count == 5)
+				v.skip_bit_flag = 1;
+			break;
+		default:
+			// we're in trouble.
+			break;
+	}
+
+	if (v.decoder_state == FRAME_END)
+	{
+		// calculate CRC
+
+		// re-initialize state machine
+		return FRAME_DECODED;
+	}
+
+	if (v.decoder_state == ABORT)
+	{
+		// re-initialize state machine
+		aprs_decoder_init();
+	}
+	return NORMAL;
+}
+
+

+ 1 - 1
main/cc1200_protocol.h

@@ -63,7 +63,7 @@ static const cc1200_reg_settings_t APRS_RX_SETTINGS[]=
   {CC120X_IQIC,              0xCB},
   {CC120X_CHAN_BW,           0x9C},
   {CC120X_MDMCFG1, 			 0x00},	// Random guess
-  {CC120X_MDMCFG0,           0x41},
+  {CC120X_MDMCFG0,           0x45},
   //{CC120X_MDMCFG0,           0x05},
   // 6 kHz
   {CC120X_SYMBOL_RATE2,      0x63},

+ 3 - 3
main/main.c

@@ -107,6 +107,8 @@ int window_get_size(void)
 	return WINDOW_SIZE;
 }
 
+// APRS Decoder
+
 
 // Timer Functions
 void IRAM_ATTR rx_timer_isr(void *para)
@@ -203,8 +205,6 @@ void RX_Task(void *pvParameters)
 
 	while(1)
 	{
-
-		//ulNotificationValue = ulTaskNotifyTake(pdTRUE, 0);
 		if( xSemaphoreTake(xRadioRXISRSemaphore, portMAX_DELAY) == pdTRUE)
 		{
 
@@ -212,7 +212,7 @@ void RX_Task(void *pvParameters)
 			EXTERNAL_DATA = (int)cc1200_radio_read_CFM();
 			//disable_debug_IO(DEBUG_0);
 			//enable_debug_IO(DEBUG_0);
-			//f_output += (50000 * (((int)EXTERNAL_DATA) - f_output)) / 100000;
+			f_output += (50000 * (((int)EXTERNAL_DATA) - f_output)) / 100000;
 			window_add((int) EXTERNAL_DATA);
 			E_s1 = goertzelFilter(window, 1200, WINDOW_SIZE);
 			E_s2 = goertzelFilter(window, 2200, WINDOW_SIZE);