diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp
index bfa02e77923ee510dff5de890c17fd306b3f97b1..608af90ac47001bed06b485cac045becc3b92f25 100644
--- a/firmware/application/apps/ui_adsb_rx.cpp
+++ b/firmware/application/apps/ui_adsb_rx.cpp
@@ -220,7 +220,7 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) {
 				callsign = decode_frame_id(frame);
 				entry.set_callsign(callsign);
 				logentry+=callsign+" ";
-			} else if ((msg_type >= 9) && (msg_type <= 18)) {
+			} else if (((msg_type >= 9) && (msg_type <= 18)) || ((msg_type >= 20) && (msg_type <= 22))) {
 				entry.set_frame_pos(frame, raw_data[6] & 4);
 				
 				if (entry.pos.valid) {
diff --git a/firmware/common/adsb.cpp b/firmware/common/adsb.cpp
index f06c064d27cbb04b8b1f3259ca8838ea6e559074..c730bbecbb97bd18c434b056e52a4f2cbf492099 100644
--- a/firmware/common/adsb.cpp
+++ b/firmware/common/adsb.cpp
@@ -211,7 +211,7 @@ void encode_frame_pos(ADSBFrame& frame, const uint32_t ICAO_address, const int32
 adsb_pos decode_frame_pos(ADSBFrame& frame_even, ADSBFrame& frame_odd) {
 	uint8_t * raw_data;
 	uint32_t latcprE, latcprO, loncprE, loncprO;
-	float latE, latO, m, Dlon;
+	float latE, latO, m, Dlon, cpr_lon_odd, cpr_lon_even, cpr_lat_odd, cpr_lat_even;
 	int ni;
 	adsb_pos position { false, 0, 0, 0 };
 	
@@ -237,10 +237,17 @@ adsb_pos decode_frame_pos(ADSBFrame& frame_even, ADSBFrame& frame_odd) {
 	latcprO = ((frame_data_odd[6] & 3) << 15) | (frame_data_odd[7] << 7) | (frame_data_odd[8] >> 1);
 	loncprO = ((frame_data_odd[8] & 1) << 16) | (frame_data_odd[9] << 8) | frame_data_odd[10];
 
+	// Calculate the coefficients
+	cpr_lon_even = loncprE / CPR_MAX_VALUE;
+	cpr_lon_odd = loncprO / CPR_MAX_VALUE;
+
+	cpr_lat_odd = latcprO / CPR_MAX_VALUE;
+	cpr_lat_even = latcprE / CPR_MAX_VALUE;
+
 	// Compute latitude index
-	float j = floor((((59.0 * latcprE) - (60.0 * latcprO)) / 131072.0) + 0.5);
-	latE = (360.0 / 60.0) * (cpr_mod(j, 60) + (latcprE / 131072.0));
-	latO = (360.0 / 59.0) * (cpr_mod(j, 59) + (latcprO / 131072.0));
+	float j = floor(((59.0 * cpr_lat_even) - (60.0 * cpr_lat_odd)) + 0.5);
+	latE = (360.0 / 60.0) * (cpr_mod(j, 60) + cpr_lat_even);
+	latO = (360.0 / 59.0) * (cpr_mod(j, 59) + cpr_lat_odd);
 
 	if (latE >= 270) latE -= 360;
 	if (latO >= 270) latO -= 360;
@@ -255,9 +262,9 @@ adsb_pos decode_frame_pos(ADSBFrame& frame_even, ADSBFrame& frame_odd) {
 		ni = cpr_N(latE, 0);
 		Dlon = 360.0 / ni;
 		
-		m = floor((((loncprE * (cpr_NL(latE) - 1)) - (loncprO * cpr_NL(latE))) / 131072.0) + 0.5);
+		m = floor((cpr_lon_even * (cpr_NL(latE) - 1)) - (cpr_lon_odd * cpr_NL(latE)) + 0.5);
 		
-		position.longitude = Dlon * (cpr_mod(m, ni) + loncprE / 131072.0);
+		position.longitude = Dlon * (cpr_mod(m, ni) + cpr_lon_even);
 		
 		position.latitude = latE;
 	} else {
@@ -265,9 +272,9 @@ adsb_pos decode_frame_pos(ADSBFrame& frame_even, ADSBFrame& frame_odd) {
 		ni = cpr_N(latO, 1);
 		Dlon = 360.0 / ni;
 		
-		m = floor((((loncprE * (cpr_NL(latO) - 1)) - (loncprO * cpr_NL(latO))) / 131072.0) + 0.5);
+		m = floor((cpr_lon_even * (cpr_NL(latO) - 1)) - (cpr_lon_odd * cpr_NL(latO)) + 0.5);
 		
-		position.longitude = Dlon * (cpr_mod(m, ni) + loncprO / 131072.0);
+		position.longitude = Dlon * (cpr_mod(m, ni) + cpr_lon_odd);
 		
 		position.latitude = latO;
 	}
diff --git a/firmware/common/adsb.hpp b/firmware/common/adsb.hpp
index 374fa8de054891f6a0e104fc60432cffeddfbf0e..4e042ff21f6f17ee83c6df62ff30fe8212d6afe8 100644
--- a/firmware/common/adsb.hpp
+++ b/firmware/common/adsb.hpp
@@ -56,6 +56,8 @@ struct adsb_pos {
 	int32_t altitude;
 };
 
+const float CPR_MAX_VALUE = 131072.0;
+
 const float adsb_lat_lut[58] = {
 	10.47047130,    14.82817437,    18.18626357,    21.02939493,
     23.54504487,    25.82924707,    27.93898710,    29.91135686,