summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndres Blanco2017-11-10 09:48:09 -0600
committerAndres Blanco2017-11-10 09:48:09 -0600
commit6f7ce9214bfb55ce40ffa94ee0270b0d8b398337 (patch)
tree3e259976267167b8856854c66b72bbea025ab0e7
downloadgps-tracking-using-sub-1ghz-6f7ce9214bfb55ce40ffa94ee0270b0d8b398337.tar.gz
gps-tracking-using-sub-1ghz-6f7ce9214bfb55ce40ffa94ee0270b0d8b398337.tar.xz
gps-tracking-using-sub-1ghz-6f7ce9214bfb55ce40ffa94ee0270b0d8b398337.zip
Initial commit
-rw-r--r--gps_python_html/cc13xx_map.html202
-rw-r--r--gps_python_html/css/main.css196
-rw-r--r--gps_python_html/gps_tracker_gui_v0.7.py349
-rw-r--r--gps_python_html/gpsdata.js2
-rw-r--r--gps_python_html/images/tilogo.pngbin0 -> 7182 bytes
-rw-r--r--gps_python_html/ti_logo.icobin0 -> 370070 bytes
-rw-r--r--patches/collector.patch481
-rw-r--r--patches/concentrator.patch2921
-rw-r--r--patches/node.patch1055
-rw-r--r--patches/sensor.patch807
10 files changed, 6013 insertions, 0 deletions
diff --git a/gps_python_html/cc13xx_map.html b/gps_python_html/cc13xx_map.html
new file mode 100644
index 0000000..b073d4e
--- /dev/null
+++ b/gps_python_html/cc13xx_map.html
@@ -0,0 +1,202 @@
1<!DOCTYPE html>
2<html>
3<!--
4/******************************************************************************
5
6@file cc13xx_map.html
7
8@brief front end file
9
10Group: WCS LPC
11$Target Device: DEVICES $
12
13******************************************************************************
14$License: BSD3 2016 $
15******************************************************************************
16$Release Name: PACKAGE NAME $
17$Release Date: PACKAGE RELEASE DATE $
18*****************************************************************************/
19-->
20
21<head>
22
23
24 <!-- Stylesheets -->
25 <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.css" />
26 <!-- Bootstrap core CSS -->
27 <link href="css/main.css" rel="stylesheet">
28
29 <title>TI CC13xx GPS Range Test</title>
30
31</head>
32
33<body>
34 <script type="text/javascript" src="gpsdata.js"></script>
35 <script>
36 function Node(address) {
37 this.address = address;
38 this.markers = [];
39 }
40
41 // Color gradient for RSSI mapping
42 var gradient = [
43 "#21FF21", "#24F61F", "#27ED1E", "#2AE41D", "#2EDB1C", "#31D31B",
44 "#34CA1A", "#37C119", "#3BB817", "#3EAF16", "#41A715", "#459E14",
45 "#489513", "#4B8C12", "#4E8311", "#527B0F", "#55720E", "#58690D",
46 "#5B600C", "#5F570B", "#624F0A", "#654609", "#693D07", "#6C3406",
47 "#6F2B05", "#722304", "#761A03", "#791102", "#7C0801", "#800000"
48 ];
49 var map;
50 var icons = [];
51 var rssi = [];
52 var nodes = [];
53 var known_addresses = [];
54 var visible = true;
55 var markers = [];
56
57 function initMap() {
58 var i;
59 var z = 15;
60
61 // Create icon format
62 for (i = gradient.length - 1; i >= 0; i--) {
63 var newicon = {
64 path: google.maps.SymbolPath.CIRCLE,
65 scale: z * z * z * z / 10000,
66 strokeOpacity: 0,
67 fillColor: gradient[i],
68 fillOpacity: 1, //.6
69 labelOrigin: new google.maps.Point(0, 4)
70 };
71 icons.push(newicon);
72
73 var r = String(i);
74 rssi.push(r);
75 }
76
77 var temp_lat = 32.91192;
78 var temp_lng = -96.75291;
79
80 if (gps.length > 0) {
81 temp_lat = gps[0].lat;
82 temp_lng = gps[0].lng;
83 }
84
85 // Create Google Map
86 map = new google.maps.Map(document.getElementById('map'), {
87 zoom: z,
88 center: {
89 lat: temp_lat,
90 lng: temp_lng
91 }
92 });
93
94 if (gps.length == 0) {
95 // Attempt to geolocate for center position (prompts user to allow location access)
96 if (navigator.geolocation) {
97 navigator.geolocation.getCurrentPosition(function(position) {
98 var pos = {
99 lat: position.coords.latitude,
100 lng: position.coords.longitude
101 };
102
103 map.setCenter(pos);
104 }, function() {
105 handleLocationError(true, infoWindow, map.getCenter());
106 });
107 } else {
108 // Browser doesn't support Geolocation
109 handleLocationError(false, infoWindow, map.getCenter());
110 }
111 }
112
113 i = 0;
114 while (i < gps.length) {
115 var newmarker = addMarker(i);
116 markers[i] = new google.maps.Marker(newmarker);
117 markers[i].addListener('click', function() {
118 var addr = this.address
119 if (visible) {
120 for (var j = 0; j < markers.length; j++) {
121 if (markers[j].address != addr)
122 markers[j].setVisible(false)
123 }
124 visible = false;
125 } else {
126 for (var j = 0; j < markers.length; j++) {
127 if (markers[j].address != addr)
128 markers[j].setVisible(true)
129 }
130 visible = true;
131 }
132 });
133 i++;
134 }
135
136 setInterval(function() {
137 imp('gpsdata.js', function(script) {});
138 while (i < gps.length) {
139 var newmarker = addMarker(i);
140 markers[i] = new google.maps.Marker(newmarker);
141 google.maps.event.addListener(markers[i], 'click', function() {
142 markers[i].setVisible(false); // maps API hide call
143 });
144 i++;
145 }
146 }, 500);
147
148 }
149
150 function addMarker(j) {
151 var r = gps[j].rssi + 75;
152 if (r > 57)
153 r = 57;
154 else if (r < 0)
155 r = 0;
156 r = Math.round(r / 2);
157
158 var m = {
159 position: gps[j],
160 zIndex: r,
161 icon: icons[r],
162 map: map,
163 title: 'Node ' + String(gps[j].addr) + '\nRSSI: ' + String(gps[j].rssi) + ' dBm\n' +
164 'Altitude: ' + String(gps[j].alt) + ' m\n' + 'Time: ' + String(gps[j].time),
165 address: gps[j].addr
166 };
167 return m;
168 }
169
170 function imp(sr, c, tgt) {
171 tgt = tgt || document.body;
172 var s = document.createElement('SCRIPT');
173 s.charset = 'UTF-8';
174 if (typeof c === 'function') {
175 s.onload = function() {
176 c(s);
177 };
178 s.onreadystatechange = function() {
179 (/loaded|complete/).test(s.readyState) && c(s);
180 };
181 }
182 s.src = sr;
183 tgt.appendChild(s);
184 return s;
185 }
186 </script>
187 <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB3akvFscd6l5WE2M8bjB6ZGzK1Vk5gXvw&callback=initMap">
188 </script>
189
190 <div class="wrapper">
191 <div class="header">
192 <h2 align="left">CC13XX GPS Range Tester</h2>
193 </div>
194 </div>
195 <!-- main Content -->
196 <div id="map">
197
198 </div>
199
200</body>
201
202</html> \ No newline at end of file
diff --git a/gps_python_html/css/main.css b/gps_python_html/css/main.css
new file mode 100644
index 0000000..e5f0d16
--- /dev/null
+++ b/gps_python_html/css/main.css
@@ -0,0 +1,196 @@
1html,
2body,
3h1,
4h3,
5h4,
6h5,
7h6,
8p {
9 height: 100%;
10 margin: 0px;
11 padding: 0px;
12}
13
14h2 {
15 height: 100%;
16 margin: 0px;
17 padding: 5px;
18 font-size: 13px;
19 color: black;
20}
21
22#map {
23 height: 50%;
24 margin: 30px;
25}
26
27.clear,
28.header:after {
29 content: "";
30 display: table;
31 clear: both
32}
33
34.header .help,
35.subHeaderIn .help {
36 position: absolute;
37 right: 10px;
38 bottom: 10px
39}
40
41body {
42 font: 14px Arial;
43 background: #900;
44 padding: 0;
45 color: #999;
46 -webkit-tap-highlight-color: transparent
47}
48
49.wrapSection {
50 margin: 0 0 20px;
51 padding: 15px 20px;
52 border: 1px solid #e0e0e0;
53 border-radius: 6px;
54 -webkit-border-radius: 6px;
55 -moz-border-radius: 6px
56}
57
58.wrapSection legend {
59 padding: 1px 15px;
60 background: #fff;
61 border: 1px solid #189;
62 color: #189;
63 -moz-border-radius: 4px
64}
65
66.wrapSection div.dataFS {
67 color: #999;
68 font-size: 14px;
69 line-height: 20px
70}
71
72.wrapSection .inWrapSec {
73 color: #aaa;
74 font-size: 14px
75}
76
77#mainContent {
78 background: #fff;
79 vertical-align: top;
80 border: 1px solid #f0f0f0
81}
82
83.header .help,
84.headerIn .menuTop {
85 -webkit-background-size: cover;
86 -moz-background-size: cover;
87 -o-background-size: cover
88}
89
90.header,
91.headerIn {
92 border-bottom: 5px solid #ccc
93}
94
95.header .help {
96 background-image: url(../images/icons/help.png);
97 background-size: cover;
98 background-repeat: no-repeat;
99 height: 25px;
100 width: 25px;
101 cursor: pointer
102}
103
104.header,
105.header .logo {
106 background-image: url(../images/tilogo.png);
107 background-position: center;
108 background-repeat: no-repeat
109}
110
111.header .logo {
112 height: 55px;
113 width: 200px;
114 margin-bottom: 15px
115}
116
117.header {
118 height: 110px;
119 background-color: #FFF
120}
121
122.headerIn .menuTop,
123.subHeaderIn .help {
124 height: 25px;
125 width: 25px;
126 cursor: pointer
127}
128
129.headerIn {
130 background-color: #900;
131 padding: 15px
132}
133
134.headerIn h1 {
135 text-align: center;
136 color: #fff;
137 padding-right: 25px
138}
139
140.headerIn .menuTop {
141 float: left;
142 background-image: url(../images/icons/menu.png);
143 background-size: cover;
144 background-repeat: no-repeat
145}
146
147.subHeaderIn .help {
148 background-image: url(../images/icons/help.png);
149 background-size: cover
150}
151
152.headerInSub {
153 padding: 15px;
154 background-color: #f5f5f5;
155 border-bottom: 1px solid #eee
156}
157
158.headerInSub .subTitle {
159 text-align: center;
160 font-size: 16px;
161 font-weight: 700;
162 color: #aaa
163}
164
165#help,
166#wireless,
167.regButton {
168 cursor: pointer
169}
170
171.contentSplash {
172 color: #fff;
173 padding: 50px 15px;
174 max-width: 470px;
175 margin: 0 auto
176}
177
178.contentSplash .splashPageTxt {
179 padding-bottom: 20px
180}
181
182.contentSplash h2 {
183 text-align: center
184}
185
186#help {
187 float: right;
188 background-image: url(../images/icons/help.png);
189 -webkit-background-size: cover;
190 -moz-background-size: cover;
191 -o-background-size: cover;
192 background-size: cover;
193 background-repeat: no-repeat;
194 height: 22px;
195 width: 22px
196} \ No newline at end of file
diff --git a/gps_python_html/gps_tracker_gui_v0.7.py b/gps_python_html/gps_tracker_gui_v0.7.py
new file mode 100644
index 0000000..295caa9
--- /dev/null
+++ b/gps_python_html/gps_tracker_gui_v0.7.py
@@ -0,0 +1,349 @@
1import time
2import serial
3import webbrowser
4import os
5from serial.tools import list_ports
6import datetime
7from tkinter import *
8from tkinter import ttk
9from tkinter import messagebox
10from tkinter.filedialog import askopenfilename
11from tkinter.filedialog import asksaveasfilename
12from serial.tools import list_ports
13import csv
14import re
15
16#
17# /******************************************************************************
18
19# @file gps_tracker_gui.py
20
21# @brief front end file
22
23# Group: WCS LPC
24# $Target Device: DEVICES $
25
26# ******************************************************************************
27# $License: BSD3 2016 $
28# ******************************************************************************
29# $Release Name: PACKAGE NAME $
30# $Release Date: PACKAGE RELEASE DATE $
31# *****************************************************************************/
32#
33
34class App:
35
36 # GLOBALS
37 nodes = []
38 known_addresses = []
39 gpsTurnedOn = FALSE
40 gpsStayOn = FALSE
41 ser = serial.Serial()
42 comport = ''
43 csvName = ''
44 append = FALSE
45 cancel = FALSE
46 serReads = [1]
47
48 # DEFINITIONS
49 class Node:
50 def __init__(self, address):
51 self.addr = address
52 self.gps = []
53
54 class Fix:
55 lat = ''
56 lng = ''
57 latDM = ''
58 lngDM = ''
59 alt = ''
60 rssi = ''
61 fixTime = '' # Time GPS fix was taken
62 plotTime = '' # Time fix is plotted
63
64 # FUNCTIONS
65 def writeData(self, addr, fix, overwrite_csv):
66 f = open('gpsdata.js', 'rb+')
67 f.seek(-1, 2)
68 f.truncate()
69 f.close()
70 f = open('gpsdata.js', 'r+')
71 f.seek(0, 2)
72 f.write('{ addr: ' + str(addr) + ', ' \
73 + 'lat: ' + fix.lat + ', ' \
74 + 'lng: ' + fix.lng + ', ' \
75 + 'alt: ' + fix.alt + ', ' \
76 + 'rssi: ' + fix.rssi + ', ' \
77 + 'time: \'' + fix.fixTime + '\' },\n]')
78 f.close()
79 now = datetime.datetime.utcnow()
80
81 #if(not overwrite_csv):
82 with open(self.csvName, 'a', newline='') as csvfile:
83 writer = csv.writer(csvfile)
84 writer.writerow((str(addr), fix.lat, fix.lng, fix.alt, fix.rssi, fix.fixTime, str(now.year) \
85 + '-' + str(now.month).zfill(2) \
86 + '-' + str(now.day).zfill(2), fix.latDM, fix.lngDM, fix.plotTime))
87
88 def addFix(self, addr, fix, overwrite_csv):
89 if addr not in self.known_addresses:
90 self.nodes.append(self.Node(addr))
91 self.known_addresses.append(addr)
92 self.nodes[self.known_addresses.index(addr)].gps.append(fix)
93 self.writeData(addr, fix, overwrite_csv)
94
95 def serialUpdate(self, event):
96 ports = sorted(list_ports.comports())
97 self.port_names = []
98 for i, port in enumerate(ports):
99 if "Application" in port.description:
100 self.port_names.append(port.device)
101 self.serialBox['values'] = self.port_names
102
103 def serialGet(self, event):
104 self.comport = self.serialBox.get()
105
106 def overwriteCSV(self, ow):
107 self.overwrite = TRUE
108 ow.destroy()
109
110 def appendCSV(self, ow):
111 self.overwrite = FALSE
112 ow.destroy()
113
114 def cancelCSV(self, ow):
115 self.cancel = TRUE
116 ow.destroy()
117
118 # MAIN PROGRAM FUNCTIONS
119 def startGPS(self):
120
121 self.serialBox.state = "disabled"
122
123 if(self.gpsTurnedOn == FALSE):
124 self.gpsTurnedOn = TRUE
125 self.overwrite = FALSE
126 self.cancel = FALSE
127
128 self.csvName = asksaveasfilename(initialdir = "/csv", title = "New csv File", defaultextension = ".csv",filetypes = (("csv files","*.csv"),("all files","*.*")))
129
130 # Overwrite or append file?
131 if os.path.isfile(self.csvName):
132 ow = Toplevel()
133 ow.title('Overwrite')
134 ow.geometry('300x100')
135 frame1 = Frame(ow)
136 frame2 = Frame(ow)
137 frame1.place(relx=0.05, rely=0.1, relheight=0.4, relwidth=0.9)
138 frame2.place(relx=0.05, rely=0.5, relheight=0.4, relwidth=0.9)
139
140 Label(frame1, text="Overwrite or append to existing file?").place(relx=0.5, rely=0, anchor=N)
141 Button(frame2, text='Overwrite', command=lambda: self.overwriteCSV(ow)).place(relx=0, relwidth=0.3, anchor=NW)
142 Button(frame2, text='Append', command=lambda: self.appendCSV(ow)).place(relx=0.5, relwidth=0.3, anchor=N)
143 Button(frame2, text='Cancel', command=lambda: self.cancelCSV(ow)).place(relx=1, relwidth=0.3, anchor=NE)
144 self.master.wait_window(ow)
145 else:
146 self.overwrite = TRUE
147
148 if self.cancel == FALSE:
149 if self.overwrite:
150 f = open(self.csvName, 'w')
151 f.truncate()
152 f.close()
153 with open(self.csvName, 'w', newline='') as csvfile:
154 writer = csv.writer(csvfile)
155 writer.writerow(('Node Address', 'Latitude (°)', 'Longitude (°)', \
156 'Altitude (m)', 'RSSI (dBm)', 'Time of Fix (UTC)', 'Date', \
157 'Latitude (DM)', 'Longitude (DM)', 'Time of Plot (UTC)'))
158
159 self.ser = serial.Serial(self.comport, 115200, timeout=0.5)
160
161 # Erase js file
162 f = open('gpsdata.js', 'r+')
163 f.truncate()
164 f.write('var gps = [\n]')
165 f.close()
166
167 webbrowser.open('cc13xx_map.html')
168
169 self.gpsStayOn = TRUE
170
171 else:
172 self.stopGPS()
173
174 if self.gpsStayOn:
175 in_str = ''
176
177 if self.ser.in_waiting > 0:
178 try:
179 in_byte = self.ser.read(1)
180
181 except:
182 self.stopGPS()
183
184 else:
185 in_str = in_byte.decode('utf-8')
186
187 if in_str == '$':
188 try:
189 in_byte = self.ser.read(18)
190
191 except TypeError as e:
192 in_str = ''
193 messagebox.showinfo('Error', 'COM Port Disconnected')
194 self.stopGPS()
195
196 else:
197 address = in_byte[0]
198 rssi = int.from_bytes(bytes([in_byte[1]]), byteorder='little', signed=True)
199 latDM = int.from_bytes(in_byte[2:4], byteorder='little', signed=True)
200 latm = int.from_bytes(in_byte[4:7], byteorder='little', signed=False)
201 lngDM = int.from_bytes(in_byte[7:9], byteorder='little', signed=True)
202 lngm = int.from_bytes(in_byte[9:12], byteorder='little', signed=False)
203 altA = int.from_bytes(in_byte[12:14], byteorder='little', signed=False)
204 alta = in_byte[14]
205 time = in_byte[15:]
206
207 gps = self.Fix()
208
209 latmstr = str(latm).zfill(6)
210 lngmstr = str(lngm).zfill(6)
211
212 gps.latDM = str(latDM)[0:-2] + ' ' + str(latDM)[-2:] + '.' + latmstr
213 gps.lngDM = str(lngDM)[0:-2] + ' ' + str(lngDM)[-2:] + '.' + lngmstr
214 gps.lat = str(latDM)[0:-2] \
215 + str(float(str(latDM)[-2:] \
216 + '.' + latmstr)/60)[1:10]
217 gps.lng = str(lngDM)[0:-2] \
218 + str(float(str(lngDM)[-2:] \
219 + '.' \
220 + lngmstr)/60)[1:10]
221 gps.alt = str(altA) + '.' + str(alta)
222 gps.fixTime = str(time[0]).zfill(2) + ':' \
223 + str(time[1]).zfill(2) + ':' \
224 + str(time[2]).zfill(2)
225 gps.rssi = str(rssi)
226
227 now = datetime.datetime.utcnow()
228 gps.plotTime = str(now.hour).zfill(2) + ':' \
229 + str(now.minute).zfill(2) + ':' \
230 + str(now.second).zfill(2)
231
232 self.addFix(address, gps, self.overwrite)
233
234 self.master.after(100, self.startGPS)
235 else:
236 self.gpsTurnedOn = FALSE
237
238 def stopGPS(self):
239 if self.gpsStayOn:
240 self.ser.close()
241 self.serialBox.set('')
242 self.serialBox.state = "enabled"
243 self.gpsStayOn = FALSE
244 self.csvName = ''
245
246 def saveCSV(self):
247 f_name = asksaveasfilename(initialdir="/", title="Filename to save as", \
248 defaultextension=".csv", \
249 filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
250 with open(f_name, 'w', newline='') as csvfile:
251 writer = csv.writer(csvfile)
252 writer.writerow(('Node Address', 'Latitude (°)', 'Longitude (°)', 'Altitude (m)', \
253 'RSSI (dBm)', 'Time of Fix (UTC)', 'Date', 'Latitude (DM)', \
254 'Longitude (DM)', 'Time of Plot (UTC)'))
255 for n in self.nodes:
256 for fix in n.gps:
257 writer.writerow((str(n.addr), fix.lat, fix.lng, fix.alt, fix.rssi, \
258 fix.fixTime, str(now.year) + '-' + str(now.month).zfill(2) \
259 + '-' + str(now.day).zfill(2), fix.latDM, fix.lngDM, fix.plotTime))
260
261 def openCSV(self):
262 # Reset variables
263 self.nodes = []
264 self.known_addresses = []
265
266 f = open('gpsdata.js', 'r+')
267 f.truncate()
268 f.write('var gps = [\n]')
269 f.close()
270
271 f = open('gpsdata.js', 'rb+')
272 f.seek(-1, 2)
273 f.truncate()
274 f = open('gpsdata.js', 'r+')
275 f.seek(0, 2)
276
277 self.csvName = askopenfilename(initialdir="/csv", title="Select file to open", \
278 filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
279 with open(self.csvName) as csvfile:
280 readCSV = csv.reader(csvfile)
281 for i, row in enumerate(readCSV):
282 if i > 0:
283 f.write('{ addr: ' + row[0] + ', ' \
284 + 'lat: ' + row[1] + ', ' \
285 + 'lng: ' + row[2] + ', ' \
286 + 'alt: ' + row[3] + ', ' \
287 + 'rssi: ' + row[4] + ', ' \
288 + 'time: \'' + row[5] + '\' },\n')
289 f.write(']')
290 f.close()
291 self.csvName = ''
292
293 webbrowser.open('cc13xx_map.html')
294
295 def __init__(self, master):
296
297 self.master = master
298 self.master.title('GPS Range Test')
299 self.master.resizable(width=False, height=False)
300 self.master.geometry("275x240")
301
302 #title = Label(root,text='TI CC13xx GPS to Map')
303 self.frame1 = Frame(root)
304 self.frame2 = Frame(root)
305 self.frame4 = Frame(root)
306 self.frame5 = Frame(root)
307
308 self.frame1.place(relx=0.1, rely=0.1, relheight=0.15, relwidth=0.8)
309 self.frame2.place(relx=0.1, rely=0.25, relheight=0.25, relwidth=0.8)
310 self.frame4.place(relx=0.1, rely=0.5, relheight=0.2, relwidth=0.8)
311 self.frame5.place(relx=0.1, rely=0.73, relheight=0.2, relwidth=0.8)
312
313 # title
314 self.Title = Label(self.frame1, text="TI CC13xx GPS Range Test", \
315 justify=CENTER, font=("Arial Bold", 10))
316 self.Title.pack(fill=BOTH)
317
318 # Buttons
319 self.bStart = Button(self.frame4, state=NORMAL, text="Start", \
320 command=self.startGPS).place(rely=0.15, relheight=.7, relwidth=.45)
321 self.bStop = Button(self.frame4, state=NORMAL, text="Stop", \
322 command=self.stopGPS).place(relx=0.55, rely=0.15, relheight=.7, relwidth=.45)
323 self.bOpen = Button(self.frame5, state=NORMAL, text="Open .csv", \
324 command=self.openCSV).place(rely=0.15, relheight=.7, relwidth=1)
325
326 # Get COM ports
327 self.port_names = []
328 ports = sorted(list_ports.comports())
329 for i, port in enumerate(ports):
330 if "Application" in port.description:
331 self.port_names.append(port.device)
332
333 # Com Ports Dropdown
334 self.serialLabel = Label(self.frame2, text="Serial Port", font=("Arial", 8))
335 self.serialLabel.place(rely=0)
336 self.serialBox = ttk.Combobox(self.frame2)
337 self.serialBox.bind("<<ComboboxSelected>>", self.serialGet)
338 self.serialBox.bind("<Button-1>", self.serialUpdate)
339 self.serialBox.place(rely=0.4, relwidth=1)
340 self.serialBox['values'] = self.port_names
341
342 # Create CSV Folder
343 if not os.path.isdir('csv'):
344 os.makedirs('csv')
345
346# Start GUI
347root = Tk()
348app = App(root)
349root.mainloop()
diff --git a/gps_python_html/gpsdata.js b/gps_python_html/gpsdata.js
new file mode 100644
index 0000000..b0501af
--- /dev/null
+++ b/gps_python_html/gpsdata.js
@@ -0,0 +1,2 @@
1var gps = [
2] \ No newline at end of file
diff --git a/gps_python_html/images/tilogo.png b/gps_python_html/images/tilogo.png
new file mode 100644
index 0000000..84ce771
--- /dev/null
+++ b/gps_python_html/images/tilogo.png
Binary files differ
diff --git a/gps_python_html/ti_logo.ico b/gps_python_html/ti_logo.ico
new file mode 100644
index 0000000..87c4b0f
--- /dev/null
+++ b/gps_python_html/ti_logo.ico
Binary files differ
diff --git a/patches/collector.patch b/patches/collector.patch
new file mode 100644
index 0000000..39a0758
--- /dev/null
+++ b/patches/collector.patch
@@ -0,0 +1,481 @@
1diff -urN collector.c collector_new/collector.c
2--- collector.c 2017-09-11 10:19:01.093000000 -0500
3+++ collector_new/collector.c 2017-06-27 12:31:46.794033500 -0500
4@@ -57,6 +57,10 @@
5 #include "smsgs.h"
6 #include "collector.h"
7
8+#ifdef GPS_SENSOR
9+#include "gps_collector.h"
10+#endif
11+
12 /******************************************************************************
13 Constants and definitions
14 *****************************************************************************/
15@@ -90,6 +94,7 @@
16 #define CONFIG_FRAME_CONTROL (Smsgs_dataFields_tempSensor | \
17 Smsgs_dataFields_lightSensor | \
18 Smsgs_dataFields_humiditySensor | \
19+ Smsgs_dataFields_gpsSensor | \
20 Smsgs_dataFields_msgStats | \
21 Smsgs_dataFields_configSettings)
22
23@@ -974,6 +979,24 @@
24 pBuf += 2;
25 }
26
27+ if(sensorData.frameControl & Smsgs_dataFields_gpsSensor)
28+ {
29+ sensorData.gpsSensor.lat.DM = Util_buildUint16(pBuf[0], pBuf[1]);
30+ sensorData.gpsSensor.lat.m = Util_buildUint32(pBuf[2], pBuf[3], pBuf[4], 0);
31+ sensorData.gpsSensor.lng.DM = Util_buildUint16(pBuf[5], pBuf[6]);
32+ sensorData.gpsSensor.lng.m = Util_buildUint32(pBuf[7], pBuf[8], pBuf[9], 0);
33+ sensorData.gpsSensor.alt.A = Util_buildUint16(pBuf[10], pBuf[11]);
34+ sensorData.gpsSensor.alt.a = pBuf[12];
35+ sensorData.gpsSensor.time.h = pBuf[13];
36+ sensorData.gpsSensor.time.m = pBuf[14];
37+ sensorData.gpsSensor.time.s = pBuf[15];
38+
39+ if(sensorData.gpsSensor.time.h != 0xFF)
40+ gpsUpdateData(pDataInd->srcAddr.addr.shortAddr, pDataInd->rssi, sensorData.gpsSensor);
41+
42+ pBuf += 16;
43+ }
44+
45 if(sensorData.frameControl & Smsgs_dataFields_msgStats)
46 {
47 sensorData.msgStats.joinAttempts = Util_buildUint16(pBuf[0], pBuf[1]);
48diff -urN config.h collector_new/config.h
49--- config.h 2017-09-11 10:19:01.103000000 -0500
50+++ collector_new/config.h 2017-07-10 10:03:19.500742800 -0500
51@@ -49,6 +49,8 @@
52 /******************************************************************************
53 Includes
54 *****************************************************************************/
55+#include <api_mac.h>
56+#include <features.h>
57
58 #ifdef __cplusplus
59 extern "C"
60@@ -88,7 +90,7 @@
61 #define CONFIG_MAC_SUPERFRAME_ORDER 15
62
63 /*! Setting for Phy ID */
64-#define CONFIG_PHY_ID (APIMAC_STD_US_915_PHY_1)
65+#define CONFIG_PHY_ID (APIMAC_GENERIC_US_LRM_915_PHY_129)
66
67 #if ((CONFIG_PHY_ID >= APIMAC_MRFSK_STD_PHY_ID_BEGIN) && (CONFIG_PHY_ID <= APIMAC_MRFSK_STD_PHY_ID_END))
68 /*! Setting for channel page */
69@@ -119,7 +121,7 @@
70 #define CONFIG_RANGE_EXT_MODE APIMAC_HIGH_GAIN_MODE
71 */
72 #define CONFIG_RANGE_EXT_MODE APIMAC_NO_EXTENDER
73-
74+//#define CONFIG_RANGE_EXT_MODE APIMAC_HIGH_GAIN_MODE
75 /*! Setting Default Key*/
76 #define KEY_TABLE_DEFAULT_KEY {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,\
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
78diff -urN gps_collector.c collector_new/gps_collector.c
79--- gps_collector.c 1969-12-31 18:00:00.000000000 -0600
80+++ collector_new/gps_collector.c 2017-06-27 12:31:46.804033700 -0500
81@@ -0,0 +1,181 @@
82+/******************************************************************************
83+
84+ @file gps_collector.c
85+
86+ @brief TIMAC 2.0 Collector GPS Application
87+
88+ Group: WCS LPC
89+ Target Device: CC13xx
90+
91+ ******************************************************************************
92+
93+ Copyright (c) 2016-2017, Texas Instruments Incorporated
94+ All rights reserved.
95+
96+ Redistribution and use in source and binary forms, with or without
97+ modification, are permitted provided that the following conditions
98+ are met:
99+
100+ * Redistributions of source code must retain the above copyright
101+ notice, this list of conditions and the following disclaimer.
102+
103+ * Redistributions in binary form must reproduce the above copyright
104+ notice, this list of conditions and the following disclaimer in the
105+ documentation and/or other materials provided with the distribution.
106+
107+ * Neither the name of Texas Instruments Incorporated nor the names of
108+ its contributors may be used to endorse or promote products derived
109+ from this software without specific prior written permission.
110+
111+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
112+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
113+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
114+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
115+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
116+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
117+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
118+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
119+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
120+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
121+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122+
123+ ******************************************************************************
124+ Release Name: simplelink_cc13x0_sdk_1_30_00_06"
125+ Release Date: 2017-03-08 14:43:30
126+ *****************************************************************************/
127+
128+/******************************************************************************
129+ Includes
130+ *****************************************************************************/
131+#include <string.h>
132+#include <stdint.h>
133+
134+#include <xdc/std.h>
135+#include <xdc/runtime/System.h>
136+
137+#include <ti/sysbios/BIOS.h>
138+#include <ti/sysbios/knl/Task.h>
139+#include <ti/sysbios/knl/Semaphore.h>
140+#include <ti/sysbios/knl/Clock.h>
141+#include <ti/drivers/UART.h>
142+
143+#include "board.h"
144+#include "util.h"
145+#include "api_mac.h"
146+#include "cllc.h"
147+#include "csf.h"
148+#include "smsgs.h"
149+#include "collector.h"
150+#include "gps_collector.h"
151+
152+/******************************************************************************
153+ Constants and definitions
154+ *****************************************************************************/
155+#define GPS_TASK_STACK_SIZE 1024
156+#define GPS_TASK_PRIORITY 2
157+
158+/******************************************************************************
159+ Global variables
160+ *****************************************************************************/
161+UART_Handle uart_gps;
162+UART_Params uartParams_gps;
163+
164+Semaphore_Struct gpsSemStruct;
165+Semaphore_Handle gpsSemHandle;
166+
167+
168+/******************************************************************************
169+ Local variables
170+ *****************************************************************************/
171+static Task_Params gpsTaskParams;
172+Task_Struct gpsTask; /* not static so you can see in ROV */
173+static uint8_t gpsTaskStack[GPS_TASK_STACK_SIZE];
174+
175+static struct gpsSensorNode latestGpsNode;
176+
177+/******************************************************************************
178+ Local function prototypes
179+ *****************************************************************************/
180+static void gpsTaskFunction(UArg arg0, UArg arg1);
181+static void gpsUpdatePC(struct gpsSensorNode* node);
182+
183+/******************************************************************************
184+ Public Functions
185+ *****************************************************************************/
186+void gpsTask_init(void)
187+{
188+ /* Construct a Semaphore object */
189+ Semaphore_Params semParams;
190+ Semaphore_Params_init(&semParams);
191+ Semaphore_construct(&gpsSemStruct, 0, &semParams);
192+ gpsSemHandle = Semaphore_handle(&gpsSemStruct);
193+
194+ /* Create the GPS task */
195+ Task_Params_init(&gpsTaskParams);
196+ gpsTaskParams.stackSize = GPS_TASK_STACK_SIZE;
197+ gpsTaskParams.priority = GPS_TASK_PRIORITY;
198+ gpsTaskParams.stack = &gpsTaskStack;
199+ Task_construct(&gpsTask, gpsTaskFunction, &gpsTaskParams, NULL);
200+
201+ UART_init();
202+
203+ /* Create a UART with data processing off. */
204+ UART_Params_init(&uartParams_gps);
205+ uartParams_gps.writeDataMode = UART_DATA_BINARY;
206+ uartParams_gps.readDataMode = UART_DATA_BINARY;
207+ uartParams_gps.readReturnMode = UART_RETURN_FULL;
208+ uartParams_gps.readEcho = UART_ECHO_OFF;
209+ uartParams_gps.baudRate = 115200;
210+ uartParams_gps.readTimeout = 500000 / Clock_tickPeriod;
211+
212+ uart_gps = UART_open(Board_UART0, &uartParams_gps);
213+
214+ if (uart_gps == NULL) {
215+ /* UART_open() failed */
216+ while (1);
217+ }
218+
219+}
220+
221+static void gpsTaskFunction(UArg arg0, UArg arg1)
222+{
223+ while(1)
224+ {
225+ Semaphore_pend(gpsSemHandle, BIOS_WAIT_FOREVER);
226+
227+ /* Send GPS node data through UART */
228+ gpsUpdatePC(&latestGpsNode);
229+ }
230+}
231+
232+void gpsUpdateData(uint16_t address, int8_t rssi, Smsgs_gpsSensorField_t gpsData)
233+{
234+ latestGpsNode.address = address;
235+ latestGpsNode.rssi = rssi;
236+ latestGpsNode.gpsData = gpsData;
237+
238+ Semaphore_post(gpsSemHandle);
239+}
240+
241+/******************************************************************************
242+ Local Functions
243+ *****************************************************************************/
244+
245+static void gpsUpdatePC(struct gpsSensorNode* node)
246+{
247+ char s = '$';
248+ char n = '\n';
249+ UART_write(uart_gps, &s, 1);
250+ UART_write(uart_gps, &node->address, 1);
251+ UART_write(uart_gps, &node->rssi, 1);
252+ UART_write(uart_gps, &node->gpsData.lat.DM, 2);
253+ UART_write(uart_gps, &node->gpsData.lat.m, 3);
254+ UART_write(uart_gps, &node->gpsData.lng.DM, 2);
255+ UART_write(uart_gps, &node->gpsData.lng.m, 3);
256+ UART_write(uart_gps, &node->gpsData.alt.A, 2);
257+ UART_write(uart_gps, &node->gpsData.alt.a, 1);
258+ UART_write(uart_gps, &node->gpsData.time.h, 1);
259+ UART_write(uart_gps, &node->gpsData.time.m, 1);
260+ UART_write(uart_gps, &node->gpsData.time.s, 1);
261+ UART_write(uart_gps, &n, 1);
262+}
263diff -urN gps_collector.h collector_new/gps_collector.h
264--- gps_collector.h 1969-12-31 18:00:00.000000000 -0600
265+++ collector_new/gps_collector.h 2017-06-27 12:31:46.804033700 -0500
266@@ -0,0 +1,97 @@
267+/******************************************************************************
268+
269+ @file gps_collector.h
270+
271+ @brief TIMAC 2.0 Collector GPS Application Header
272+
273+ Group: WCS LPC
274+ Target Device: CC13xx
275+
276+ ******************************************************************************
277+
278+ Copyright (c) 2016-2017, Texas Instruments Incorporated
279+ All rights reserved.
280+
281+ Redistribution and use in source and binary forms, with or without
282+ modification, are permitted provided that the following conditions
283+ are met:
284+
285+ * Redistributions of source code must retain the above copyright
286+ notice, this list of conditions and the following disclaimer.
287+
288+ * Redistributions in binary form must reproduce the above copyright
289+ notice, this list of conditions and the following disclaimer in the
290+ documentation and/or other materials provided with the distribution.
291+
292+ * Neither the name of Texas Instruments Incorporated nor the names of
293+ its contributors may be used to endorse or promote products derived
294+ from this software without specific prior written permission.
295+
296+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
297+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
298+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
299+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
300+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
301+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
302+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
303+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
304+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
305+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
306+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
307+
308+ ******************************************************************************
309+ Release Name: simplelink_cc13x0_sdk_1_30_00_06"
310+ Release Date: 2017-03-08 14:43:30
311+ *****************************************************************************/
312+#ifndef GPS_COLLECTOR_H
313+#define GPS_COLLECTOR_H
314+
315+/******************************************************************************
316+ Includes
317+ *****************************************************************************/
318+
319+#include <stdbool.h>
320+#include <stdint.h>
321+
322+#include "api_mac.h"
323+#include "smsgs.h"
324+#include "collector.h"
325+
326+
327+#ifdef __cplusplus
328+extern "C"
329+{
330+#endif
331+
332+/******************************************************************************
333+ Constants and definitions
334+ *****************************************************************************/
335+//#undef USE_UART_PRINTF
336+
337+/******************************************************************************
338+ Structures
339+ *****************************************************************************/
340+struct gpsSensorNode {
341+ uint8_t address;
342+ int8_t rssi;
343+ Smsgs_gpsSensorField_t gpsData;
344+};
345+
346+
347+/******************************************************************************
348+ Global Variables
349+ *****************************************************************************/
350+
351+
352+/******************************************************************************
353+ Function Prototypes
354+ *****************************************************************************/
355+void gpsTask_init(void);
356+void gpsUpdateData(uint16_t address, int8_t rssi, Smsgs_gpsSensorField_t gpsData);
357+
358+
359+#ifdef __cplusplus
360+}
361+#endif
362+
363+#endif /* GPS_COLLECTOR_H */
364diff -urN main.c collector_new/main.c
365--- main.c 2017-09-11 10:19:01.133000000 -0500
366+++ collector_new/main.c 2017-06-27 13:01:32.059782700 -0500
367@@ -116,6 +116,10 @@
368 #include "board_palna.h"
369 #endif
370
371+#ifdef GPS_SENSOR
372+#include "gps_collector.h"
373+#endif
374+
375 /******************************************************************************
376 Constants
377 *****************************************************************************/
378@@ -164,7 +168,7 @@
379 { 0 };
380 #endif
381
382-#if defined(USE_UART_PRINTF)
383+#if defined(USE_UART_PRINTF) && !defined(GPS_SENSOR)
384 UART_Params uartParams;
385 #endif
386
387@@ -351,7 +355,7 @@
388 SPI_init();
389 #endif
390
391-#if defined(USE_UART_PRINTF)
392+#if defined(USE_UART_PRINTF) && !defined(GPS_SENSOR)
393 /* Enable System_printf(..) UART output */
394 UART_init();
395 UART_Params_init(&uartParams);
396@@ -366,6 +370,10 @@
397 taskParams.priority = 1;
398 Task_construct(&myTask, taskFxn, &taskParams, NULL);
399
400+#ifdef GPS_SENSOR
401+ gpsTask_init();
402+#endif
403+
404 #ifdef DEBUG_SW_TRACE
405 IOCPortConfigureSet(IOID_8, IOC_PORT_RFC_TRC, IOC_STD_OUTPUT
406 | IOC_CURRENT_4MA | IOC_SLEW_ENABLE);
407diff -urN smsgs.h collector_new/smsgs.h
408--- smsgs.h 2017-09-11 10:19:01.143000000 -0500
409+++ collector_new/smsgs.h 2017-06-27 12:31:46.824034100 -0500
410@@ -188,6 +188,8 @@
411 #define SMSGS_SENSOR_LIGHT_LEN 2
412 /*! Length of the humiditySensor portion of the sensor data message */
413 #define SMSGS_SENSOR_HUMIDITY_LEN 4
414+/*! Length of the gpsSensor portion of the sensor data message */
415+#define SMSGS_SENSOR_GPS_LEN 16
416 /*! Length of the messageStatistics portion of the sensor data message */
417 #define SMSGS_SENSOR_MSG_STATS_LEN 36
418 /*! Length of the configSettings portion of the sensor data message */
419@@ -239,6 +241,8 @@
420 Smsgs_dataFields_msgStats = 0x0008,
421 /*! Config Settings */
422 Smsgs_dataFields_configSettings = 0x0010,
423+ /*! GPS Sensor */
424+ Smsgs_dataFields_gpsSensor = 0x0020,
425 } Smsgs_dataFields_t;
426
427 /*!
428@@ -373,6 +377,41 @@
429 } Smsgs_humiditySensorField_t;
430
431 /*!
432+ GPS Sensor Field
433+ */
434+typedef struct _Smsgs_gpssensorfield_t
435+{
436+ /*! Latitude coordinate from GPS module (Degrees Minutes Format - DM.m) */
437+ struct glat_s
438+ {
439+ int16_t DM;
440+ uint32_t m;
441+ } lat;
442+
443+ /*! Longitude coordinate from GPS module (Degrees Minutes Format - DM.m) */
444+ struct glng_s
445+ {
446+ int16_t DM;
447+ uint32_t m;
448+ } lng;
449+
450+ /*! Altitude from GPS module (A.a meters) */
451+ struct galt_s
452+ {
453+ uint16_t A;
454+ uint8_t a;
455+ } alt;
456+
457+ /*! Time of GPS fix in UTC */
458+ struct time_s
459+ {
460+ uint8_t h;
461+ uint8_t m;
462+ uint8_t s;
463+ } time;
464+} Smsgs_gpsSensorField_t;
465+
466+/*!
467 Message Statistics Field
468 */
469 typedef struct _Smsgs_msgstatsfield_t
470@@ -472,6 +511,11 @@
471 */
472 Smsgs_humiditySensorField_t humiditySensor;
473 /*!
474+ GPS Sensor field - valid only if Smsgs_dataFields_gpsSensor
475+ is set in frameControl.
476+ */
477+ Smsgs_gpsSensorField_t gpsSensor;
478+ /*!
479 Message Statistics field - valid only if Smsgs_dataFields_msgStats
480 is set in frameControl.
481 */
diff --git a/patches/concentrator.patch b/patches/concentrator.patch
new file mode 100644
index 0000000..2ca8447
--- /dev/null
+++ b/patches/concentrator.patch
@@ -0,0 +1,2921 @@
1diff -urN board_palna.c concentrator_new/board_palna.c
2--- board_palna.c 1969-12-31 18:00:00.000000000 -0600
3+++ concentrator_new/board_palna.c 2017-07-07 13:15:02.843061400 -0500
4@@ -0,0 +1,99 @@
5+/******************************************************************************
6+
7+ @file board_palna.c
8+
9+ @brief This file contains the interface to the CC1310-CC1190 LP PA/LNA
10+
11+ Group: WCS LPC
12+ $Target Device: DEVICES $
13+
14+ ******************************************************************************
15+ $License: BSD3 2016 $
16+ ******************************************************************************
17+ $Release Name: PACKAGE NAME $
18+ $Release Date: PACKAGE RELEASE DATE $
19+ *****************************************************************************/
20+
21+/******************************************************************************
22+ Includes
23+ *****************************************************************************/
24+
25+#include <xdc/std.h>
26+
27+#include <ti/drivers/PIN.h>
28+#include <ti/drivers/pin/PINCC26XX.h>
29+
30+#include "board.h"
31+#include "board_palna.h"
32+
33+/******************************************************************************
34+ Constants
35+ *****************************************************************************/
36+
37+#define Board_DIO28_HGM IOID_28
38+#define Board_DIO29_LNA IOID_29
39+#define Board_DIO30_PA IOID_30
40+
41+/******************************************************************************
42+ Typedefs
43+ *****************************************************************************/
44+
45+/******************************************************************************
46+ Local Variables
47+ *****************************************************************************/
48+
49+/*
50+ SensorTag LED has exactly the same attributes as that of
51+ BoardGpioInitTable[]. There is no need to create a new one.
52+ */
53+static PIN_Config palnaPinTable[] =
54+ {
55+ Board_DIO28_HGM | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL
56+ | PIN_DRVSTR_MAX, /* High Gain Mode by Default */
57+ Board_DIO29_LNA | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL
58+ | PIN_DRVSTR_MAX, /* LNA Off by Default */
59+ Board_DIO30_PA | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL
60+ | PIN_DRVSTR_MAX, /* PA Off by Default */
61+ PIN_TERMINATE /* Terminate list */
62+ };
63+
64+/* PA/LNA pin state */
65+static PIN_State palnaPinState;
66+
67+/* PA/LNA Pin Handle */
68+static PIN_Handle palnaPinHandle;
69+
70+/******************************************************************************
71+ Local Function Prototypes
72+ *****************************************************************************/
73+
74+/******************************************************************************
75+ Public Functions
76+ *****************************************************************************/
77+
78+/*!
79+ Initialize PA/LNA
80+
81+ Public function defined in board_palna.h
82+ */
83+void Board_Palna_initialize(uint32_t hgm)
84+{
85+ if (hgm)
86+ {
87+ if (!palnaPinHandle)
88+ {
89+ /* Open PA/LNA PIN driver */
90+ palnaPinHandle = PIN_open(&palnaPinState, palnaPinTable);
91+
92+ /* Set IO muxing for RFC GPOs */
93+ PINCC26XX_setMux(palnaPinHandle, Board_DIO29_LNA, IOC_PORT_RFC_GPO0);
94+ PINCC26XX_setMux(palnaPinHandle, Board_DIO30_PA, IOC_PORT_RFC_GPO1);
95+ }
96+
97+ PIN_setOutputValue(palnaPinHandle, Board_DIO28_HGM, (hgm & 1));
98+
99+ }
100+}
101+
102+
103+
104diff -urN board_palna.h concentrator_new/board_palna.h
105--- board_palna.h 1969-12-31 18:00:00.000000000 -0600
106+++ concentrator_new/board_palna.h 2017-07-07 13:15:02.845561400 -0500
107@@ -0,0 +1,47 @@
108+/******************************************************************************
109+
110+ @file board_palna.h
111+
112+ @brief This file contains the PA/LNA Service definitions and prototypes.
113+
114+ Group: WCS LPC
115+ $Target Device: DEVICES $
116+
117+ ******************************************************************************
118+ $License: BSD3 2016 $
119+ ******************************************************************************
120+ $Release Name: PACKAGE NAME $
121+ $Release Date: PACKAGE RELEASE DATE $
122+ *****************************************************************************/
123+#ifndef BOARD_PALNA_H
124+#define BOARD_PALNA_H
125+
126+/******************************************************************************
127+ Includes
128+ *****************************************************************************/
129+
130+#ifdef __cplusplus
131+extern "C"
132+{
133+#endif
134+
135+/******************************************************************************
136+ Typedefs
137+ *****************************************************************************/
138+
139+
140+
141+/******************************************************************************
142+ API Functions
143+ *****************************************************************************/
144+
145+/*!
146+ * @brief Initialize PA/LNA
147+ */
148+void Board_Palna_initialize(uint32_t hgm);
149+
150+#ifdef __cplusplus
151+}
152+#endif
153+
154+#endif /* BOARD_PALNA_H */
155diff -urN ConcentratorGPS.c concentrator_new/ConcentratorGPS.c
156--- ConcentratorGPS.c 1969-12-31 18:00:00.000000000 -0600
157+++ concentrator_new/ConcentratorGPS.c 2017-07-07 13:15:02.850561400 -0500
158@@ -0,0 +1,146 @@
159+/*
160+ * Copyright (c) 2015-2016, Texas Instruments Incorporated
161+ * All rights reserved.
162+ *
163+ * Redistribution and use in source and binary forms, with or without
164+ * modification, are permitted provided that the following conditions
165+ * are met:
166+ *
167+ * * Redistributions of source code must retain the above copyright
168+ * notice, this list of conditions and the following disclaimer.
169+ *
170+ * * Redistributions in binary form must reproduce the above copyright
171+ * notice, this list of conditions and the following disclaimer in the
172+ * documentation and/or other materials provided with the distribution.
173+ *
174+ * * Neither the name of Texas Instruments Incorporated nor the names of
175+ * its contributors may be used to endorse or promote products derived
176+ * from this software without specific prior written permission.
177+ *
178+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
179+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
180+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
181+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
182+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
183+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
184+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
185+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
186+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
187+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
188+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
189+ */
190+
191+/***** Includes *****/
192+
193+#include <xdc/std.h>
194+#include <xdc/runtime/System.h>
195+
196+#include <ti/sysbios/BIOS.h>
197+
198+#include <ti/sysbios/knl/Task.h>
199+#include <ti/sysbios/knl/Semaphore.h>
200+#include <ti/sysbios/knl/Event.h>
201+
202+/* Drivers */
203+#include <ti/drivers/PIN.h>
204+#include <ti/display/Display.h>
205+#include <ti/display/DisplayExt.h>
206+
207+/* Board Header files */
208+#include "Board.h"
209+
210+#include "ConcentratorRadioTask.h"
211+#include "ConcentratorTask.h"
212+#include "RadioProtocol.h"
213+
214+#include <stdlib.h>
215+#include <ti/drivers/UART.h>
216+
217+#include "ConcentratorGPS.h"
218+
219+/***** Variable declarations *****/
220+UART_Handle uart;
221+UART_Params uartParams;
222+
223+void gpsPacketReceive(EasyLink_RxPacket* rxPacket, union ConcentratorPacket* latestPacket);
224+
225+/***** Function definitions *****/
226+void gpsUartInit(void)
227+{
228+ /* Create a UART with data processing off. */
229+ UART_Params_init(&uartParams);
230+ uartParams.writeDataMode = UART_DATA_BINARY;
231+ uartParams.readDataMode = UART_DATA_BINARY;
232+ uartParams.readReturnMode = UART_RETURN_FULL;
233+ uartParams.readEcho = UART_ECHO_OFF;
234+ uartParams.baudRate = 115200;
235+
236+ uart = UART_open(Board_UART0, &uartParams);
237+
238+ if (uart == NULL) {
239+ /* UART_open() failed */
240+ while (1);
241+ }
242+}
243+
244+void updateGpsNode(struct gpsSensorNode* node) {
245+ uint8_t i;
246+ for (i = 0; i < CONCENTRATOR_MAX_NODES; i++) {
247+ if (knownGpsSensorNodes[i].address == node->address)
248+ {
249+ knownGpsSensorNodes[i].gpsData = node->gpsData;
250+ knownGpsSensorNodes[i].latestRssi = node->latestRssi;
251+ break;
252+ }
253+ }
254+}
255+
256+void addNewGpsNode(struct gpsSensorNode* node) {
257+ *lastAddedGpsSensorNode = *node;
258+
259+ /* Increment and wrap */
260+ lastAddedGpsSensorNode++;
261+ if (lastAddedGpsSensorNode > &knownGpsSensorNodes[CONCENTRATOR_MAX_NODES-1])
262+ {
263+ lastAddedGpsSensorNode = knownGpsSensorNodes;
264+ }
265+}
266+
267+void gpsUpdatePC(struct gpsSensorNode* node)
268+{
269+ char s = '$';
270+ char n = '\n';
271+ UART_write(uart, &s, 1);
272+ UART_write(uart, &node->address, 1);
273+ UART_write(uart, &node->latestRssi, 1);
274+ UART_write(uart, &node->gpsData.lat.DM, 2);
275+ UART_write(uart, &node->gpsData.lat.m, 3);
276+ UART_write(uart, &node->gpsData.lng.DM, 2);
277+ UART_write(uart, &node->gpsData.lng.m, 3);
278+ UART_write(uart, &node->gpsData.alt.A, 2);
279+ UART_write(uart, &node->gpsData.alt.a, 1);
280+ UART_write(uart, &node->gpsData.time.h, 1);
281+ UART_write(uart, &node->gpsData.time.m, 1);
282+ UART_write(uart, &node->gpsData.time.s, 1);
283+ UART_write(uart, &n, 1);
284+}
285+
286+void gpsPacketReceive(EasyLink_RxPacket* rxPacket, union ConcentratorPacket* latestPacket)
287+{
288+ /* Save packet */
289+ latestPacket->header.sourceAddress = rxPacket->payload[0];
290+ latestPacket->header.packetType = rxPacket->payload[1];
291+ latestPacket->gpsSensorPacket.gpsData.lat.DM = (rxPacket->payload[2] << 8 | rxPacket->payload[3]);
292+ latestPacket->gpsSensorPacket.gpsData.lat.m = (rxPacket->payload[4] << 16 |
293+ rxPacket->payload[5] << 8 |
294+ rxPacket->payload[6]);
295+ latestPacket->gpsSensorPacket.gpsData.lng.DM = (rxPacket->payload[7] << 8 | rxPacket->payload[8]);
296+ latestPacket->gpsSensorPacket.gpsData.lng.m = (rxPacket->payload[9] << 16 |
297+ rxPacket->payload[10] << 8 |
298+ rxPacket->payload[11]);
299+ latestPacket->gpsSensorPacket.gpsData.alt.A = (rxPacket->payload[12] << 8 | rxPacket->payload[13]);
300+ latestPacket->gpsSensorPacket.gpsData.alt.a = rxPacket->payload[14];
301+ latestPacket->gpsSensorPacket.gpsData.time.h = rxPacket->payload[15];
302+ latestPacket->gpsSensorPacket.gpsData.time.m = rxPacket->payload[16];
303+ latestPacket->gpsSensorPacket.gpsData.time.s = rxPacket->payload[17];
304+}
305diff -urN ConcentratorGPS.h concentrator_new/ConcentratorGPS.h
306--- ConcentratorGPS.h 1969-12-31 18:00:00.000000000 -0600
307+++ concentrator_new/ConcentratorGPS.h 2017-07-07 13:15:02.853061400 -0500
308@@ -0,0 +1,137 @@
309+/*
310+ * Copyright (c) 2015-2016, Texas Instruments Incorporated
311+ * All rights reserved.
312+ *
313+ * Redistribution and use in source and binary forms, with or without
314+ * modification, are permitted provided that the following conditions
315+ * are met:
316+ *
317+ * * Redistributions of source code must retain the above copyright
318+ * notice, this list of conditions and the following disclaimer.
319+ *
320+ * * Redistributions in binary form must reproduce the above copyright
321+ * notice, this list of conditions and the following disclaimer in the
322+ * documentation and/or other materials provided with the distribution.
323+ *
324+ * * Neither the name of Texas Instruments Incorporated nor the names of
325+ * its contributors may be used to endorse or promote products derived
326+ * from this software without specific prior written permission.
327+ *
328+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
329+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
330+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
331+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
332+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
333+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
334+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
335+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
336+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
337+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
338+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
339+ */
340+
341+#ifndef TASKS_CONCENTRATORGPS_H_
342+#define TASKS_CONCENTRATORGPS_H_
343+
344+#include "stdint.h"
345+#include "ConcentratorRadioTask.h"
346+#include "RadioProtocol.h"
347+#include "ConcentratorTask.h"
348+
349+struct gpsDataUART_s {
350+ struct ulat_s {
351+ char D[4];
352+ char M[10];
353+ char dir;
354+ } lat;
355+
356+ struct ulng_s {
357+ char D[4];
358+ char M[9];
359+ char dir;
360+ } lng;
361+
362+ struct ualt_s
363+ {
364+ char A[8]; // altitude
365+ char a[4];
366+ } alt;
367+
368+ struct utime_s {
369+ char h[4];
370+ char m[4];
371+ char s[4];
372+ } time;
373+};
374+
375+///* GPS Lat/Lng data in Degrees Minutes (DM), where D is signed */
376+//struct gpsData_s {
377+// struct glat_s // DM = [0][1:3]
378+// {
379+// int8_t D;
380+// uint32_t M;
381+// } lat;
382+// struct glng_s // DM = [0:1][2:4]
383+// {
384+// int16_t D;
385+// uint32_t M;
386+// } lng;
387+// struct time_s // h.m.s (UTC) = [0].[1].[2]
388+// {
389+// uint8_t h;
390+// uint8_t m;
391+// uint8_t s;
392+// } time;
393+//};
394+
395+/* GPS Lat/Lng data in Degrees Minutes (DM), where D is signed */
396+struct gpsData_s {
397+ struct lat_s // DM.m = [0:1].[2:4]
398+ {
399+ int16_t DM;
400+ uint32_t m;
401+ } lat;
402+
403+ struct lng_s // DM = [0:1].[2:4]
404+ {
405+ int16_t DM;
406+ uint32_t m;
407+ } lng;
408+
409+ struct alt_s
410+ {
411+ uint16_t A; // altitude: A.a Meters
412+ uint8_t a;
413+ } alt;
414+
415+ struct time_s // h.m.s (UTC) = [0].[1].[2]
416+ {
417+ uint8_t h;
418+ uint8_t m;
419+ uint8_t s;
420+ } time;
421+};
422+
423+struct gpsSensorPacket_s {
424+ struct PacketHeader header;
425+ struct gpsData_s gpsData;
426+};
427+
428+struct gpsSensorNode {
429+ uint8_t address;
430+ struct gpsData_s gpsData;
431+ int8_t latestRssi;
432+};
433+
434+extern struct gpsSensorNode latestActiveGpsSensorNode;
435+extern struct gpsSensorNode knownGpsSensorNodes[];
436+extern struct gpsSensorNode* lastAddedGpsSensorNode;
437+
438+void gpsUartInit(void);
439+void addNewGpsNode(struct gpsSensorNode* node);
440+void updateGpsNode(struct gpsSensorNode* node);
441+void gpsUpdatePC(struct gpsSensorNode* node);
442+
443+#endif /* TASKS_CONCENTRATORGPS_H_ */
444+
445+
446diff -urN ConcentratorRadioTask.c concentrator_new/ConcentratorRadioTask.c
447--- ConcentratorRadioTask.c 1969-12-31 18:00:00.000000000 -0600
448+++ concentrator_new/ConcentratorRadioTask.c 2017-07-07 16:02:31.929194300 -0500
449@@ -0,0 +1,278 @@
450+/*
451+ * Copyright (c) 2015-2016, Texas Instruments Incorporated
452+ * All rights reserved.
453+ *
454+ * Redistribution and use in source and binary forms, with or without
455+ * modification, are permitted provided that the following conditions
456+ * are met:
457+ *
458+ * * Redistributions of source code must retain the above copyright
459+ * notice, this list of conditions and the following disclaimer.
460+ *
461+ * * Redistributions in binary form must reproduce the above copyright
462+ * notice, this list of conditions and the following disclaimer in the
463+ * documentation and/or other materials provided with the distribution.
464+ *
465+ * * Neither the name of Texas Instruments Incorporated nor the names of
466+ * its contributors may be used to endorse or promote products derived
467+ * from this software without specific prior written permission.
468+ *
469+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
470+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
471+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
472+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
473+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
474+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
475+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
476+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
477+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
478+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
479+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
480+ */
481+
482+/***** Includes *****/
483+#include <xdc/std.h>
484+#include <xdc/runtime/System.h>
485+
486+#include "ConcentratorRadioTask.h"
487+
488+#include <ti/sysbios/BIOS.h>
489+
490+#include <ti/sysbios/knl/Task.h>
491+#include <ti/sysbios/knl/Semaphore.h>
492+#include <ti/sysbios/knl/Event.h>
493+
494+/* Drivers */
495+#include <ti/drivers/rf/RF.h>
496+#include <ti/drivers/PIN.h>
497+
498+/* Board Header files */
499+#include "Board.h"
500+
501+#include "easylink/EasyLink.h"
502+#include "RadioProtocol.h"
503+
504+#include "ConcentratorGPS.h"
505+
506+
507+/***** Defines *****/
508+#define CONCENTRATORRADIO_TASK_STACK_SIZE 1024
509+#define CONCENTRATORRADIO_TASK_PRIORITY 3
510+
511+#define RADIO_EVENT_ALL 0xFFFFFFFF
512+#define RADIO_EVENT_VALID_PACKET_RECEIVED (uint32_t)(1 << 0)
513+#define RADIO_EVENT_INVALID_PACKET_RECEIVED (uint32_t)(1 << 1)
514+
515+#define CONCENTRATORRADIO_MAX_RETRIES 2
516+#define NORERADIO_ACK_TIMEOUT_TIME_MS (160)
517+
518+
519+#define CONCENTRATOR_ACTIVITY_LED Board_PIN_LED0
520+
521+/***** Type declarations *****/
522+
523+
524+
525+/***** Variable declarations *****/
526+static Task_Params concentratorRadioTaskParams;
527+Task_Struct concentratorRadioTask; /* not static so you can see in ROV */
528+static uint8_t concentratorRadioTaskStack[CONCENTRATORRADIO_TASK_STACK_SIZE];
529+Event_Struct radioOperationEvent; /* not static so you can see in ROV */
530+static Event_Handle radioOperationEventHandle;
531+
532+
533+
534+static ConcentratorRadio_PacketReceivedCallback packetReceivedCallback;
535+static union ConcentratorPacket latestRxPacket;
536+static EasyLink_TxPacket txPacket;
537+static struct AckPacket ackPacket;
538+static uint8_t concentratorAddress;
539+static int8_t latestRssi;
540+
541+
542+/***** Prototypes *****/
543+static void concentratorRadioTaskFunction(UArg arg0, UArg arg1);
544+static void rxDoneCallback(EasyLink_RxPacket * rxPacket, EasyLink_Status status);
545+static void notifyPacketReceived(union ConcentratorPacket* latestRxPacket);
546+static void sendAck(uint8_t latestSourceAddress);
547+extern void gpsPacketReceive(EasyLink_RxPacket* rxPacket, union ConcentratorPacket* latestPacket);
548+
549+/* Pin driver handle */
550+static PIN_Handle ledPinHandle;
551+static PIN_State ledPinState;
552+
553+/* Configure LED Pin */
554+PIN_Config ledPinTable[] = {
555+ CONCENTRATOR_ACTIVITY_LED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
556+ PIN_TERMINATE
557+};
558+
559+/***** Function definitions *****/
560+void ConcentratorRadioTask_init(void) {
561+
562+ /* Open LED pins */
563+ ledPinHandle = PIN_open(&ledPinState, ledPinTable);
564+ if (!ledPinHandle)
565+ {
566+ System_abort("Error initializing board 3.3V domain pins\n");
567+ }
568+
569+ /* Create event used internally for state changes */
570+ Event_Params eventParam;
571+ Event_Params_init(&eventParam);
572+ Event_construct(&radioOperationEvent, &eventParam);
573+ radioOperationEventHandle = Event_handle(&radioOperationEvent);
574+
575+ /* Create the concentrator radio protocol task */
576+ Task_Params_init(&concentratorRadioTaskParams);
577+ concentratorRadioTaskParams.stackSize = CONCENTRATORRADIO_TASK_STACK_SIZE;
578+ concentratorRadioTaskParams.priority = CONCENTRATORRADIO_TASK_PRIORITY;
579+ concentratorRadioTaskParams.stack = &concentratorRadioTaskStack;
580+ Task_construct(&concentratorRadioTask, concentratorRadioTaskFunction, &concentratorRadioTaskParams, NULL);
581+}
582+
583+void ConcentratorRadioTask_registerPacketReceivedCallback(ConcentratorRadio_PacketReceivedCallback callback) {
584+ packetReceivedCallback = callback;
585+}
586+
587+static void concentratorRadioTaskFunction(UArg arg0, UArg arg1)
588+{
589+ /* Initialize EasyLink */
590+ if(EasyLink_init(RADIO_EASYLINK_MODULATION) != EasyLink_Status_Success) {
591+ System_abort("EasyLink_init failed");
592+ }
593+
594+
595+ /* If you wish to use a frequency other than the default use
596+ * the below API
597+ * EasyLink_setFrequency(868000000);
598+ */
599+ /* Set concentrator address */;
600+ concentratorAddress = RADIO_CONCENTRATOR_ADDRESS;
601+ EasyLink_enableRxAddrFilter(&concentratorAddress, 1, 1);
602+
603+ /* Set up Ack packet */
604+ ackPacket.header.sourceAddress = concentratorAddress;
605+ ackPacket.header.packetType = RADIO_PACKET_TYPE_ACK_PACKET;
606+
607+ /* Enter receive */
608+ if(EasyLink_receiveAsync(rxDoneCallback, 0) != EasyLink_Status_Success) {
609+ System_abort("EasyLink_receiveAsync failed");
610+ }
611+
612+ while (1) {
613+ uint32_t events = Event_pend(radioOperationEventHandle, 0, RADIO_EVENT_ALL, BIOS_WAIT_FOREVER);
614+
615+ /* If valid packet received */
616+ if(events & RADIO_EVENT_VALID_PACKET_RECEIVED) {
617+
618+ /* Send ack packet */
619+ sendAck(latestRxPacket.header.sourceAddress);
620+
621+ /* Call packet received callback */
622+ notifyPacketReceived(&latestRxPacket);
623+
624+ /* Go back to RX */
625+ if(EasyLink_receiveAsync(rxDoneCallback, 0) != EasyLink_Status_Success) {
626+ System_abort("EasyLink_receiveAsync failed");
627+ }
628+
629+ /* toggle Activity LED */
630+ PIN_setOutputValue(ledPinHandle, CONCENTRATOR_ACTIVITY_LED,
631+ !PIN_getOutputValue(CONCENTRATOR_ACTIVITY_LED));
632+ }
633+
634+ /* If invalid packet received */
635+ if(events & RADIO_EVENT_INVALID_PACKET_RECEIVED) {
636+ /* Go back to RX */
637+ if(EasyLink_receiveAsync(rxDoneCallback, 0) != EasyLink_Status_Success) {
638+ System_abort("EasyLink_receiveAsync failed");
639+ }
640+ }
641+ }
642+}
643+
644+static void sendAck(uint8_t latestSourceAddress) {
645+
646+ /* Set destinationAdress, but use EasyLink layers destination adress capability */
647+ txPacket.dstAddr[0] = latestSourceAddress;
648+
649+ /* Copy ACK packet to payload, skipping the destination adress byte.
650+ * Note that the EasyLink API will implcitily both add the length byte and the destination address byte. */
651+ memcpy(txPacket.payload, &ackPacket.header, sizeof(ackPacket));
652+ txPacket.len = sizeof(ackPacket);
653+
654+ /* Send packet */
655+ if (EasyLink_transmit(&txPacket) != EasyLink_Status_Success)
656+ {
657+ System_abort("EasyLink_transmit failed");
658+ }
659+}
660+
661+static void notifyPacketReceived(union ConcentratorPacket* latestRxPacket)
662+{
663+ if (packetReceivedCallback)
664+ {
665+ packetReceivedCallback(latestRxPacket, latestRssi);
666+ }
667+}
668+
669+static void rxDoneCallback(EasyLink_RxPacket * rxPacket, EasyLink_Status status)
670+{
671+ union ConcentratorPacket* tmpRxPacket;
672+
673+ /* If we received a packet successfully */
674+ if (status == EasyLink_Status_Success)
675+ {
676+ /* Save the latest RSSI, which is later sent to the receive callback */
677+ latestRssi = (int8_t)rxPacket->rssi;
678+
679+ /* Check that this is a valid packet */
680+ tmpRxPacket = (union ConcentratorPacket*)(rxPacket->payload);
681+
682+ /* If this is a known packet */
683+ if (tmpRxPacket->header.packetType == RADIO_PACKET_TYPE_ADC_SENSOR_PACKET)
684+ {
685+ /* Save packet */
686+ latestRxPacket.header.sourceAddress = rxPacket->payload[0];
687+ latestRxPacket.header.packetType = rxPacket->payload[1];
688+ latestRxPacket.adcSensorPacket.adcValue = (rxPacket->payload[2] << 8) | rxPacket->payload[3];
689+
690+ /* Signal packet received */
691+ Event_post(radioOperationEventHandle, RADIO_EVENT_VALID_PACKET_RECEIVED);
692+ }
693+ else if (tmpRxPacket->header.packetType == RADIO_PACKET_TYPE_DM_SENSOR_PACKET)
694+ {
695+ /* Save packet */
696+ latestRxPacket.header.sourceAddress = rxPacket->payload[0];
697+ latestRxPacket.header.packetType = rxPacket->payload[1];
698+ latestRxPacket.dmSensorPacket.adcValue = (rxPacket->payload[2] << 8) | rxPacket->payload[3];
699+ latestRxPacket.dmSensorPacket.batt = (rxPacket->payload[4] << 8) | rxPacket->payload[5];
700+ latestRxPacket.dmSensorPacket.time100MiliSec = (rxPacket->payload[6] << 24) |
701+ (rxPacket->payload[7] << 16) |
702+ (rxPacket->payload[8] << 8) |
703+ rxPacket->payload[9];
704+ latestRxPacket.dmSensorPacket.button = rxPacket->payload[10];
705+
706+ /* Signal packet received */
707+ Event_post(radioOperationEventHandle, RADIO_EVENT_VALID_PACKET_RECEIVED);
708+ }
709+ else if (tmpRxPacket->header.packetType == RADIO_PACKET_TYPE_GPS_SENSOR_PACKET)
710+ {
711+ gpsPacketReceive(rxPacket, &latestRxPacket);
712+
713+ /* Signal packet received */
714+ Event_post(radioOperationEventHandle, RADIO_EVENT_VALID_PACKET_RECEIVED);
715+ }
716+ else
717+ {
718+ /* Signal invalid packet received */
719+ Event_post(radioOperationEventHandle, RADIO_EVENT_INVALID_PACKET_RECEIVED);
720+ }
721+ }
722+ else
723+ {
724+ /* Signal invalid packet received */
725+ Event_post(radioOperationEventHandle, RADIO_EVENT_INVALID_PACKET_RECEIVED);
726+ }
727+}
728diff -urN ConcentratorRadioTask.h concentrator_new/ConcentratorRadioTask.h
729--- ConcentratorRadioTask.h 1969-12-31 18:00:00.000000000 -0600
730+++ concentrator_new/ConcentratorRadioTask.h 2017-07-07 13:15:02.920561400 -0500
731@@ -0,0 +1,61 @@
732+/*
733+ * Copyright (c) 2015-2016, Texas Instruments Incorporated
734+ * All rights reserved.
735+ *
736+ * Redistribution and use in source and binary forms, with or without
737+ * modification, are permitted provided that the following conditions
738+ * are met:
739+ *
740+ * * Redistributions of source code must retain the above copyright
741+ * notice, this list of conditions and the following disclaimer.
742+ *
743+ * * Redistributions in binary form must reproduce the above copyright
744+ * notice, this list of conditions and the following disclaimer in the
745+ * documentation and/or other materials provided with the distribution.
746+ *
747+ * * Neither the name of Texas Instruments Incorporated nor the names of
748+ * its contributors may be used to endorse or promote products derived
749+ * from this software without specific prior written permission.
750+ *
751+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
752+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
753+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
754+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
755+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
756+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
757+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
758+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
759+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
760+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
761+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
762+ */
763+
764+#ifndef TASKS_CONCENTRATORRADIOTASKTASK_H_
765+#define TASKS_CONCENTRATORRADIOTASKTASK_H_
766+
767+#include "stdint.h"
768+#include "RadioProtocol.h"
769+#include "ConcentratorGPS.h"
770+
771+enum ConcentratorRadioOperationStatus {
772+ ConcentratorRadioStatus_Success,
773+ ConcentratorRadioStatus_Failed,
774+ ConcentratorRadioStatus_FailedNotConnected,
775+};
776+
777+union ConcentratorPacket {
778+ struct PacketHeader header;
779+ struct gpsSensorPacket_s gpsSensorPacket;
780+ struct AdcSensorPacket adcSensorPacket;
781+ struct DualModeSensorPacket dmSensorPacket;
782+};
783+
784+typedef void (*ConcentratorRadio_PacketReceivedCallback)(union ConcentratorPacket* packet, int8_t rssi);
785+
786+/* Create the ConcentratorRadioTask and creates all TI-RTOS objects */
787+void ConcentratorRadioTask_init(void);
788+
789+/* Register the packet received callback */
790+void ConcentratorRadioTask_registerPacketReceivedCallback(ConcentratorRadio_PacketReceivedCallback callback);
791+
792+#endif /* TASKS_CONCENTRATORRADIOTASKTASK_H_ */
793diff -urN ConcentratorTask.c concentrator_new/ConcentratorTask.c
794--- ConcentratorTask.c 1969-12-31 18:00:00.000000000 -0600
795+++ concentrator_new/ConcentratorTask.c 2017-07-07 13:15:02.950561400 -0500
796@@ -0,0 +1,298 @@
797+/*
798+ * Copyright (c) 2015-2016, Texas Instruments Incorporated
799+ * All rights reserved.
800+ *
801+ * Redistribution and use in source and binary forms, with or without
802+ * modification, are permitted provided that the following conditions
803+ * are met:
804+ *
805+ * * Redistributions of source code must retain the above copyright
806+ * notice, this list of conditions and the following disclaimer.
807+ *
808+ * * Redistributions in binary form must reproduce the above copyright
809+ * notice, this list of conditions and the following disclaimer in the
810+ * documentation and/or other materials provided with the distribution.
811+ *
812+ * * Neither the name of Texas Instruments Incorporated nor the names of
813+ * its contributors may be used to endorse or promote products derived
814+ * from this software without specific prior written permission.
815+ *
816+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
817+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
818+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
819+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
820+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
821+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
822+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
823+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
824+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
825+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
826+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
827+ */
828+
829+/***** Includes *****/
830+
831+#include <xdc/std.h>
832+#include <xdc/runtime/System.h>
833+
834+#include <ti/sysbios/BIOS.h>
835+
836+#include <ti/sysbios/knl/Task.h>
837+#include <ti/sysbios/knl/Semaphore.h>
838+#include <ti/sysbios/knl/Event.h>
839+
840+/* Drivers */
841+#include <ti/drivers/PIN.h>
842+#include <ti/display/Display.h>
843+#include <ti/display/DisplayExt.h>
844+
845+/* Board Header files */
846+#include "Board.h"
847+
848+#include "ConcentratorRadioTask.h"
849+#include "ConcentratorTask.h"
850+#include "RadioProtocol.h"
851+
852+#include "ConcentratorGPS.h"
853+
854+/***** Defines *****/
855+#define CONCENTRATOR_TASK_STACK_SIZE 1024
856+#define CONCENTRATOR_TASK_PRIORITY 3
857+
858+#define CONCENTRATOR_EVENT_ALL 0xFFFFFFFF
859+#define CONCENTRATOR_EVENT_NEW_ADC_SENSOR_VALUE (uint32_t)(1 << 0)
860+#define CONCENTRATOR_EVENT_NEW_GPS_SENSOR_VALUE (uint32_t)(1 << 1)
861+
862+#define CONCENTRATOR_DISPLAY_LINES 8
863+
864+/***** Type declarations *****/
865+struct AdcSensorNode {
866+ uint8_t address;
867+ uint16_t latestAdcValue;
868+ uint8_t button;
869+ int8_t latestRssi;
870+};
871+
872+/***** Variable declarations *****/
873+static Task_Params concentratorTaskParams;
874+Task_Struct concentratorTask; /* not static so you can see in ROV */
875+static uint8_t concentratorTaskStack[CONCENTRATOR_TASK_STACK_SIZE];
876+Event_Struct concentratorEvent; /* not static so you can see in ROV */
877+static Event_Handle concentratorEventHandle;
878+static struct AdcSensorNode latestActiveAdcSensorNode;
879+struct AdcSensorNode knownSensorNodes[CONCENTRATOR_MAX_NODES];
880+static struct AdcSensorNode* lastAddedSensorNode = knownSensorNodes;
881+static Display_Handle hDisplayLcd;
882+static Display_Handle hDisplaySerial;
883+
884+struct gpsSensorNode latestActiveGpsSensorNode;
885+struct gpsSensorNode knownGpsSensorNodes[CONCENTRATOR_MAX_NODES];
886+struct gpsSensorNode* lastAddedGpsSensorNode = knownGpsSensorNodes;
887+
888+
889+/***** Prototypes *****/
890+static void concentratorTaskFunction(UArg arg0, UArg arg1);
891+static void packetReceivedCallback(union ConcentratorPacket* packet, int8_t rssi);
892+static void updateLcd(void);
893+static void addNewNode(struct AdcSensorNode* node);
894+static void updateNode(struct AdcSensorNode* node);
895+static uint8_t isKnownNodeAddress(uint8_t address);
896+
897+/***** Function definitions *****/
898+void ConcentratorTask_init(void) {
899+
900+ /* Create event used internally for state changes */
901+ Event_Params eventParam;
902+ Event_Params_init(&eventParam);
903+ Event_construct(&concentratorEvent, &eventParam);
904+ concentratorEventHandle = Event_handle(&concentratorEvent);
905+
906+ /* Create the concentrator radio protocol task */
907+ Task_Params_init(&concentratorTaskParams);
908+ concentratorTaskParams.stackSize = CONCENTRATOR_TASK_STACK_SIZE;
909+ concentratorTaskParams.priority = CONCENTRATOR_TASK_PRIORITY;
910+ concentratorTaskParams.stack = &concentratorTaskStack;
911+ Task_construct(&concentratorTask, concentratorTaskFunction, &concentratorTaskParams, NULL);
912+
913+ gpsUartInit();
914+}
915+
916+static void concentratorTaskFunction(UArg arg0, UArg arg1)
917+{
918+ /* Initialize display and try to open both UART and LCD types of display. */
919+ Display_Params params;
920+ Display_Params_init(&params);
921+ params.lineClearMode = DISPLAY_CLEAR_BOTH;
922+
923+ /* Open both an available LCD display and an UART display.
924+ * Whether the open call is successful depends on what is present in the
925+ * Display_config[] array of the board file.
926+ *
927+ * Note that for SensorTag evaluation boards combined with the SHARP96x96
928+ * Watch DevPack, there is a pin conflict with UART such that one must be
929+ * excluded, and UART is preferred by default. To display on the Watch
930+ * DevPack, add the precompiler define BOARD_DISPLAY_EXCLUDE_UART.
931+ */
932+ hDisplayLcd = Display_open(Display_Type_LCD, &params);
933+ hDisplaySerial = Display_open(Display_Type_UART, &params);
934+
935+ /* Check if the selected Display type was found and successfully opened */
936+ if (hDisplaySerial)
937+ {
938+ Display_printf(hDisplaySerial, 0, 0, "Waiting for nodes...");
939+ }
940+
941+ /* Check if the selected Display type was found and successfully opened */
942+ if (hDisplayLcd)
943+ {
944+ Display_printf(hDisplayLcd, 0, 0, "Waiting for nodes...");
945+ }
946+
947+ /* Register a packet received callback with the radio task */
948+ ConcentratorRadioTask_registerPacketReceivedCallback(packetReceivedCallback);
949+
950+ /* Enter main task loop */
951+ while(1) {
952+ /* Wait for event */
953+ uint32_t events = Event_pend(concentratorEventHandle, 0, CONCENTRATOR_EVENT_ALL, BIOS_WAIT_FOREVER);
954+
955+ /* If we got a new ADC sensor value */
956+ if(events & CONCENTRATOR_EVENT_NEW_ADC_SENSOR_VALUE) {
957+ /* If we knew this node from before, update the value */
958+ if(isKnownNodeAddress(latestActiveAdcSensorNode.address)) {
959+ updateNode(&latestActiveAdcSensorNode);
960+ }
961+ else {
962+ /* Else add it */
963+ addNewNode(&latestActiveAdcSensorNode);
964+ }
965+
966+ /* Update the values on the LCD */
967+ updateLcd();
968+ }
969+
970+ /* If we got a new ADC sensor value */
971+ if(events & CONCENTRATOR_EVENT_NEW_GPS_SENSOR_VALUE) {
972+ /* If we knew this node from before, update the value */
973+ if(isKnownNodeAddress(latestActiveGpsSensorNode.address)) {
974+ updateGpsNode(&latestActiveGpsSensorNode);
975+ }
976+ else {
977+ /* Else add it */
978+ addNewGpsNode(&latestActiveGpsSensorNode);
979+ }
980+
981+ /* Update the values on the LCD */
982+ gpsUpdatePC(&latestActiveGpsSensorNode);
983+ }
984+ }
985+}
986+
987+static void packetReceivedCallback(union ConcentratorPacket* packet, int8_t rssi)
988+{
989+ /* If we recived an ADC sensor packet, for backward compatibility */
990+ if (packet->header.packetType == RADIO_PACKET_TYPE_ADC_SENSOR_PACKET)
991+ {
992+ /* Save the values */
993+ latestActiveAdcSensorNode.address = packet->header.sourceAddress;
994+ latestActiveAdcSensorNode.latestAdcValue = packet->adcSensorPacket.adcValue;
995+ latestActiveAdcSensorNode.button = 0; //no button value in ADC packet
996+ latestActiveAdcSensorNode.latestRssi = rssi;
997+
998+ Event_post(concentratorEventHandle, CONCENTRATOR_EVENT_NEW_ADC_SENSOR_VALUE);
999+ }
1000+ /* If we recived an DualMode ADC sensor packet*/
1001+ else if(packet->header.packetType == RADIO_PACKET_TYPE_DM_SENSOR_PACKET)
1002+ {
1003+
1004+ /* Save the values */
1005+ latestActiveAdcSensorNode.address = packet->header.sourceAddress;
1006+ latestActiveAdcSensorNode.latestAdcValue = packet->dmSensorPacket.adcValue;
1007+ latestActiveAdcSensorNode.button = packet->dmSensorPacket.button;
1008+ latestActiveAdcSensorNode.latestRssi = rssi;
1009+
1010+ Event_post(concentratorEventHandle, CONCENTRATOR_EVENT_NEW_ADC_SENSOR_VALUE);
1011+ }
1012+ else if(packet->header.packetType == RADIO_PACKET_TYPE_GPS_SENSOR_PACKET)
1013+ {
1014+
1015+ /* Save the values */
1016+ latestActiveGpsSensorNode.address = packet->header.sourceAddress;
1017+ latestActiveGpsSensorNode.gpsData = packet->gpsSensorPacket.gpsData;
1018+ latestActiveGpsSensorNode.latestRssi = rssi;
1019+
1020+ Event_post(concentratorEventHandle, CONCENTRATOR_EVENT_NEW_GPS_SENSOR_VALUE);
1021+ }
1022+}
1023+
1024+static uint8_t isKnownNodeAddress(uint8_t address) {
1025+ uint8_t found = 0;
1026+ uint8_t i;
1027+ for (i = 0; i < CONCENTRATOR_MAX_NODES; i++)
1028+ {
1029+ if (knownSensorNodes[i].address == address)
1030+ {
1031+ found = 1;
1032+ break;
1033+ }
1034+ }
1035+ return found;
1036+}
1037+
1038+static void updateNode(struct AdcSensorNode* node) {
1039+ uint8_t i;
1040+ for (i = 0; i < CONCENTRATOR_MAX_NODES; i++) {
1041+ if (knownSensorNodes[i].address == node->address)
1042+ {
1043+ knownSensorNodes[i].latestAdcValue = node->latestAdcValue;
1044+ knownSensorNodes[i].latestRssi = node->latestRssi;
1045+ knownSensorNodes[i].button = node->button;
1046+ break;
1047+ }
1048+ }
1049+}
1050+
1051+static void addNewNode(struct AdcSensorNode* node) {
1052+ *lastAddedSensorNode = *node;
1053+
1054+ /* Increment and wrap */
1055+ lastAddedSensorNode++;
1056+ if (lastAddedSensorNode > &knownSensorNodes[CONCENTRATOR_MAX_NODES-1])
1057+ {
1058+ lastAddedSensorNode = knownSensorNodes;
1059+ }
1060+}
1061+
1062+static void updateLcd(void) {
1063+ struct AdcSensorNode* nodePointer = knownSensorNodes;
1064+ uint8_t currentLcdLine;
1065+
1066+ /* Clear the display and write header on first line */
1067+ Display_clear(hDisplayLcd);
1068+ Display_printf(hDisplayLcd, 0, 0, "Nodes Value SW RSSI");
1069+
1070+ //clear screen, put cuser to beggining of terminal and print the header
1071+ Display_printf(hDisplaySerial, 0, 0, "\033[2J \033[0;0HNodes Value SW RSSI");
1072+
1073+ /* Start on the second line */
1074+ currentLcdLine = 1;
1075+
1076+ /* Write one line per node */
1077+ while ((nodePointer < &knownSensorNodes[CONCENTRATOR_MAX_NODES]) &&
1078+ (nodePointer->address != 0) &&
1079+ (currentLcdLine < CONCENTRATOR_DISPLAY_LINES))
1080+ {
1081+ /* print to LCD */
1082+ Display_printf(hDisplayLcd, currentLcdLine, 0, "0x%02x %04d %d %04d",
1083+ nodePointer->address, nodePointer->latestAdcValue, nodePointer->button,
1084+ nodePointer->latestRssi);
1085+
1086+ /* print to UART */
1087+ Display_printf(hDisplaySerial, 0, 0, "0x%02x %04d %d %04d",
1088+ nodePointer->address, nodePointer->latestAdcValue, nodePointer->button,
1089+ nodePointer->latestRssi);
1090+
1091+ nodePointer++;
1092+ currentLcdLine++;
1093+ }
1094+}
1095diff -urN ConcentratorTask.h concentrator_new/ConcentratorTask.h
1096--- ConcentratorTask.h 1969-12-31 18:00:00.000000000 -0600
1097+++ concentrator_new/ConcentratorTask.h 2017-07-07 13:15:02.978061400 -0500
1098@@ -0,0 +1,41 @@
1099+/*
1100+ * Copyright (c) 2015, Texas Instruments Incorporated
1101+ * All rights reserved.
1102+ *
1103+ * Redistribution and use in source and binary forms, with or without
1104+ * modification, are permitted provided that the following conditions
1105+ * are met:
1106+ *
1107+ * * Redistributions of source code must retain the above copyright
1108+ * notice, this list of conditions and the following disclaimer.
1109+ *
1110+ * * Redistributions in binary form must reproduce the above copyright
1111+ * notice, this list of conditions and the following disclaimer in the
1112+ * documentation and/or other materials provided with the distribution.
1113+ *
1114+ * * Neither the name of Texas Instruments Incorporated nor the names of
1115+ * its contributors may be used to endorse or promote products derived
1116+ * from this software without specific prior written permission.
1117+ *
1118+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1119+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1120+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1121+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
1122+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1123+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1124+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
1125+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1126+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
1127+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
1128+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1129+ */
1130+
1131+#ifndef TASKS_CONCENTRATORTASK_H_
1132+#define TASKS_CONCENTRATORTASK_H_
1133+
1134+#define CONCENTRATOR_MAX_NODES 7
1135+
1136+/* Create the ConcentratorRadioTask and creates all TI-RTOS objects */
1137+void ConcentratorTask_init(void);
1138+
1139+#endif /* TASKS_CONCENTRATORTASK_H_ */
1140diff -urN easylink/EasyLink.c concentrator_new/easylink/EasyLink.c
1141--- easylink/EasyLink.c 1969-12-31 18:00:00.000000000 -0600
1142+++ concentrator_new/easylink/EasyLink.c 2017-07-07 13:13:56.457000000 -0500
1143@@ -0,0 +1,1116 @@
1144+/*
1145+ * Copyright (c) 2015-2017, Texas Instruments Incorporated
1146+ * All rights reserved.
1147+ *
1148+ * Redistribution and use in source and binary forms, with or without
1149+ * modification, are permitted provided that the following conditions
1150+ * are met:
1151+ *
1152+ * * Redistributions of source code must retain the above copyright
1153+ * notice, this list of conditions and the following disclaimer.
1154+ *
1155+ * * Redistributions in binary form must reproduce the above copyright
1156+ * notice, this list of conditions and the following disclaimer in the
1157+ * documentation and/or other materials provided with the distribution.
1158+ *
1159+ * * Neither the name of Texas Instruments Incorporated nor the names of
1160+ * its contributors may be used to endorse or promote products derived
1161+ * from this software without specific prior written permission.
1162+ *
1163+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1164+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1165+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1166+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
1167+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1168+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1169+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
1170+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1171+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
1172+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
1173+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1174+ */
1175+
1176+/***** Includes *****/
1177+#include "EasyLink.h"
1178+
1179+/* Drivers */
1180+#include <ti/drivers/rf/RF.h>
1181+#include "smartrf_settings/smartrf_settings_predefined.h"
1182+#include "smartrf_settings/smartrf_settings.h"
1183+
1184+#include <ti/sysbios/knl/Semaphore.h>
1185+#include <xdc/runtime/Error.h>
1186+#include <ti/sysbios/BIOS.h>
1187+#include <ti/sysbios/knl/Task.h>
1188+
1189+#ifdef DEVICE_FAMILY
1190+ #undef DEVICE_FAMILY_PATH
1191+ #define DEVICE_FAMILY_PATH(x) <ti/devices/DEVICE_FAMILY/x>
1192+ #include DEVICE_FAMILY_PATH(driverlib/rf_data_entry.h)
1193+ #include DEVICE_FAMILY_PATH(driverlib/rf_prop_mailbox.h)
1194+ #include DEVICE_FAMILY_PATH(driverlib/rf_prop_cmd.h)
1195+ #include DEVICE_FAMILY_PATH(driverlib/chipinfo.h)
1196+ #include DEVICE_FAMILY_PATH(inc/hw_ccfg.h)
1197+ #include DEVICE_FAMILY_PATH(inc/hw_ccfg_simple_struct.h)
1198+#else
1199+ #error "You must define DEVICE_FAMILY at the project level as one of cc26x0, cc26x0r2, cc13x0, etc."
1200+#endif
1201+
1202+#include "Board.h"
1203+
1204+union setupCmd_t{
1205+ rfc_CMD_PROP_RADIO_DIV_SETUP_t divSetup;
1206+ rfc_CMD_PROP_RADIO_SETUP_t setup;
1207+};
1208+
1209+#define EASYLINK_MAX_ADDR_SIZE 8
1210+#define EASYLINK_MAX_ADDR_FILTERS 3
1211+
1212+//Primary IEEE address location
1213+#define EASYLINK_PRIMARY_IEEE_ADDR_LOCATION 0x500012F0
1214+//Secondary IEEE address location
1215+#define EASYLINK_SECONDARY_IEEE_ADDR_LOCATION 0x0001FFC8
1216+
1217+#define EASYLINK_RF_EVENT_MASK ( RF_EventLastCmdDone | RF_EventCmdError | \
1218+ RF_EventCmdAborted | RF_EventCmdStopped | RF_EventCmdCancelled )
1219+
1220+#define EASYLINK_RF_CMD_HANDLE_INVALID -1
1221+
1222+#define RF_MODE_MULTIPLE 0x05
1223+
1224+#define EasyLink_CmdHandle_isValid(handle) (handle >= 0)
1225+
1226+/***** Prototypes *****/
1227+static EasyLink_TxDoneCb txCb;
1228+static EasyLink_ReceiveCb rxCb;
1229+
1230+/***** Variable declarations *****/
1231+
1232+static RF_Object rfObject;
1233+static RF_Handle rfHandle;
1234+
1235+//Rx buffer includes data entry structure, hdr (len=1byte), dst addr (max of 8 bytes) and data
1236+//which must be aligned to 4B
1237+#if defined(__TI_COMPILER_VERSION__)
1238+ #pragma DATA_ALIGN (rxBuffer, 4);
1239+ static uint8_t rxBuffer[sizeof(rfc_dataEntryGeneral_t) + 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH];
1240+#elif defined(__IAR_SYSTEMS_ICC__)
1241+ #pragma data_alignment = 4
1242+ static uint8_t rxBuffer[sizeof(rfc_dataEntryGeneral_t) + 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH];
1243+#elif defined(__GNUC__)
1244+ static uint8_t rxBuffer[sizeof(rfc_dataEntryGeneral_t) + 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH];
1245+#else
1246+ #error This compiler is not supported.
1247+#endif
1248+
1249+static dataQueue_t dataQueue;
1250+static rfc_propRxOutput_t rxStatistics;
1251+
1252+//Tx buffer includes hdr (len=1byte), dst addr (max of 8 bytes) and data
1253+static uint8_t txBuffer[1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH];
1254+
1255+//Addr size for Filter and Tx/Rx operations
1256+//Set default to 1 byte addr to work with SmartRF
1257+//studio default settings
1258+static uint8_t addrSize = 1;
1259+
1260+//Indicating that the API is initialized
1261+static uint8_t configured = 0;
1262+//Indicating that the API suspended
1263+static uint8_t suspended = 0;
1264+
1265+//RF Params alowing configuration of the inactivity timeout, which is the time
1266+//it takes for the radio to shut down when there are no commands in the queue
1267+static RF_Params rfParams;
1268+static bool rfParamsConfigured = 0;
1269+
1270+//Flag used to indicate the muli client operation is enabled
1271+static bool rfModeMultiClient = false;
1272+
1273+//Async Rx timeout value
1274+static uint32_t asyncRxTimeOut = 0;
1275+
1276+//local commands, contents will be defined by modulation type
1277+static union setupCmd_t EasyLink_cmdPropRadioSetup;
1278+static rfc_CMD_FS_t EasyLink_cmdFs;
1279+static RF_Mode EasyLink_RF_prop;
1280+static rfc_CMD_PROP_TX_t EasyLink_cmdPropTx;
1281+static rfc_CMD_PROP_RX_ADV_t EasyLink_cmdPropRxAdv;
1282+
1283+// The table for setting the Rx Address Filters
1284+static uint8_t addrFilterTable[EASYLINK_MAX_ADDR_FILTERS * EASYLINK_MAX_ADDR_SIZE] = {0xaa};
1285+
1286+//Mutex for locking the RF driver resource
1287+static Semaphore_Handle busyMutex;
1288+
1289+//Handle for last Async command, which is needed by EasyLink_abort
1290+static RF_CmdHandle asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID;
1291+
1292+//Callback for Async Tx complete
1293+static void txDoneCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
1294+{
1295+ EasyLink_Status status;
1296+
1297+ //Release now so user callback can call EasyLink API's
1298+ Semaphore_post(busyMutex);
1299+ asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID;
1300+
1301+ if (e & RF_EventLastCmdDone)
1302+ {
1303+ status = EasyLink_Status_Success;
1304+ }
1305+ else if ( (e & RF_EventCmdAborted) || (e & RF_EventCmdCancelled ) )
1306+ {
1307+ status = EasyLink_Status_Aborted;
1308+ }
1309+ else
1310+ {
1311+ status = EasyLink_Status_Tx_Error;
1312+ }
1313+
1314+ if (txCb != NULL)
1315+ {
1316+ txCb(status);
1317+ }
1318+}
1319+
1320+//Callback for Async Rx complete
1321+static void rxDoneCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
1322+{
1323+ EasyLink_Status status = EasyLink_Status_Rx_Error;
1324+ //create rxPacket as a static so that the large payload buffer it is not
1325+ //allocated from the stack
1326+ static EasyLink_RxPacket rxPacket;
1327+ rfc_dataEntryGeneral_t *pDataEntry;
1328+ pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer;
1329+
1330+ //Release now so user callback can call EasyLink API's
1331+ Semaphore_post(busyMutex);
1332+ asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID;
1333+
1334+ if (e & RF_EventLastCmdDone)
1335+ {
1336+ //Check command status
1337+ if (EasyLink_cmdPropRxAdv.status == PROP_DONE_OK)
1338+ {
1339+ //Check that data entry status indicates it is finished with
1340+ if (pDataEntry->status != DATA_ENTRY_FINISHED)
1341+ {
1342+ status = EasyLink_Status_Rx_Error;
1343+ }
1344+ else if ( (rxStatistics.nRxOk == 1) ||
1345+ //or filer disabled and ignore due to addr mistmatch
1346+ ((EasyLink_cmdPropRxAdv.pktConf.filterOp == 1) &&
1347+ (rxStatistics.nRxIgnored == 1)) )
1348+ {
1349+ //copy length from pDataEntry
1350+ rxPacket.len = *(uint8_t*)(&pDataEntry->data) - addrSize;
1351+ //copy address from packet payload (as it is not in hdr)
1352+ memcpy(&rxPacket.dstAddr, (&pDataEntry->data + 1), addrSize);
1353+ //copy payload
1354+ memcpy(&rxPacket.payload, (&pDataEntry->data + 1 + addrSize), rxPacket.len);
1355+ rxPacket.rssi = rxStatistics.lastRssi;
1356+ rxPacket.absTime = rxStatistics.timeStamp;
1357+
1358+ status = EasyLink_Status_Success;
1359+ }
1360+ else if ( rxStatistics.nRxBufFull == 1)
1361+ {
1362+ status = EasyLink_Status_Rx_Buffer_Error;
1363+ }
1364+ else if ( rxStatistics.nRxStopped == 1)
1365+ {
1366+ status = EasyLink_Status_Aborted;
1367+ }
1368+ else
1369+ {
1370+ status = EasyLink_Status_Rx_Error;
1371+ }
1372+ }
1373+ else if ( EasyLink_cmdPropRxAdv.status == PROP_DONE_RXTIMEOUT)
1374+ {
1375+ status = EasyLink_Status_Rx_Timeout;
1376+ }
1377+ else
1378+ {
1379+ status = EasyLink_Status_Rx_Error;
1380+ }
1381+ }
1382+ else if ( (e == RF_EventCmdAborted) || e == RF_EventCmdStopped )
1383+ {
1384+ status = EasyLink_Status_Aborted;
1385+ }
1386+
1387+ if (rxCb != NULL)
1388+ {
1389+ rxCb(&rxPacket, status);
1390+ }
1391+}
1392+
1393+//Callback for Async TX Test mode
1394+static void asyncCmdCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
1395+{
1396+ Semaphore_post(busyMutex);
1397+ asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID;
1398+}
1399+
1400+static EasyLink_Status enableTestMode(EasyLink_CtrlOption mode)
1401+{
1402+ EasyLink_Status status = EasyLink_Status_Cmd_Error;
1403+ //This needs to be static as it is used by the RF driver and Modem after
1404+ //this function exits
1405+ static rfc_CMD_TX_TEST_t txTestCmd = {0};
1406+
1407+ if ( (!configured) || suspended)
1408+ {
1409+ return EasyLink_Status_Config_Error;
1410+ }
1411+ if ( (mode != EasyLink_Ctrl_Test_Tone) &&
1412+ (mode != EasyLink_Ctrl_Test_Signal) )
1413+ {
1414+ return EasyLink_Status_Param_Error;
1415+ }
1416+ //Check and take the busyMutex
1417+ if ( (Semaphore_pend(busyMutex, 0) == FALSE) || (EasyLink_CmdHandle_isValid(asyncCmdHndl)) )
1418+ {
1419+ return EasyLink_Status_Busy_Error;
1420+ }
1421+
1422+ txTestCmd.commandNo = CMD_TX_TEST;
1423+ txTestCmd.startTrigger.triggerType = TRIG_NOW;
1424+ txTestCmd.startTrigger.pastTrig = 1;
1425+ txTestCmd.startTime = 0;
1426+
1427+ txTestCmd.config.bFsOff = 1;
1428+ txTestCmd.syncWord = EasyLink_cmdPropTx.syncWord;
1429+ txTestCmd.config.whitenMode = EasyLink_cmdPropRadioSetup.setup.formatConf.whitenMode;
1430+
1431+ //set tone (unmodulated) or signal (modulated)
1432+ if (mode == EasyLink_Ctrl_Test_Tone)
1433+ {
1434+ txTestCmd.config.bUseCw = 1;
1435+ }
1436+ else
1437+ {
1438+ txTestCmd.config.bUseCw = 0;
1439+ }
1440+
1441+ //generate continuous test signal
1442+ txTestCmd.endTrigger.triggerType = TRIG_NEVER;
1443+
1444+ /* Post command and store Cmd Handle for future abort */
1445+ asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&txTestCmd, RF_PriorityNormal,
1446+ asyncCmdCallback, EASYLINK_RF_EVENT_MASK);
1447+
1448+ /* Has command completed? */
1449+ uint16_t count = 0;
1450+ while (txTestCmd.status != ACTIVE)
1451+ {
1452+ //The command did not complete as fast as expected, sleep for 10ms
1453+ Task_sleep(10000 / Clock_tickPeriod);
1454+
1455+ if (count++ > 500)
1456+ {
1457+ //Should not get here, if we did Something went wrong with the
1458+ //the RF Driver, get out of here and return an error.
1459+ //The next command will likely lock up.
1460+ break;
1461+ }
1462+ }
1463+
1464+ if (txTestCmd.status == ACTIVE)
1465+ {
1466+ status = EasyLink_Status_Success;
1467+ }
1468+
1469+ return status;
1470+}
1471+
1472+EasyLink_Status EasyLink_init(EasyLink_PhyType ui32ModType)
1473+{
1474+ if (configured)
1475+ {
1476+ //Already configure, check and take the busyMutex
1477+ if (Semaphore_pend(busyMutex, 0) == FALSE)
1478+ {
1479+ return EasyLink_Status_Busy_Error;
1480+ }
1481+ RF_close(rfHandle);
1482+ }
1483+
1484+ if (!rfParamsConfigured)
1485+ {
1486+ RF_Params_init(&rfParams);
1487+ //set default InactivityTimeout to 1000us
1488+ rfParams.nInactivityTimeout = EasyLink_ms_To_RadioTime(1);
1489+ rfParamsConfigured = 1;
1490+ }
1491+
1492+ if (ui32ModType == EasyLink_Phy_Custom)
1493+ {
1494+ if(ChipInfo_GetChipType() == CHIP_TYPE_CC2650)
1495+ {
1496+ memcpy(&EasyLink_cmdPropRadioSetup.setup, &RF_cmdPropRadioDivSetup, sizeof(rfc_CMD_PROP_RADIO_SETUP_t));
1497+ }
1498+ else
1499+ {
1500+ memcpy(&EasyLink_cmdPropRadioSetup.divSetup, &RF_cmdPropRadioDivSetup, sizeof(rfc_CMD_PROP_RADIO_DIV_SETUP_t));
1501+ }
1502+ memcpy(&EasyLink_cmdFs, &RF_cmdFs, sizeof(rfc_CMD_FS_t));
1503+ memcpy(&EasyLink_RF_prop, &RF_prop, sizeof(RF_Mode));
1504+ memcpy(&EasyLink_cmdPropRxAdv, RF_pCmdPropRxAdv_preDef, sizeof(rfc_CMD_PROP_RX_ADV_t));
1505+ memcpy(&EasyLink_cmdPropTx, &RF_cmdPropTx, sizeof(rfc_CMD_PROP_TX_t));
1506+ }
1507+ else if ( (ui32ModType == EasyLink_Phy_50kbps2gfsk) && (ChipInfo_GetChipType() != CHIP_TYPE_CC2650) )
1508+ {
1509+ memcpy(&EasyLink_cmdPropRadioSetup.divSetup,
1510+ RF_pCmdPropRadioDivSetup_fsk,
1511+ sizeof(rfc_CMD_PROP_RADIO_DIV_SETUP_t));
1512+ memcpy(&EasyLink_cmdFs, RF_pCmdFs_preDef, sizeof(rfc_CMD_FS_t));
1513+ memcpy(&EasyLink_RF_prop, RF_pProp_fsk, sizeof(RF_Mode));
1514+ memcpy(&EasyLink_cmdPropRxAdv, RF_pCmdPropRxAdv_preDef, sizeof(rfc_CMD_PROP_RX_ADV_t));
1515+ memcpy(&EasyLink_cmdPropTx, RF_pCmdPropTx_preDef, sizeof(rfc_CMD_PROP_TX_t));
1516+ }
1517+ else if ( (ui32ModType == EasyLink_Phy_625bpsLrm) && (ChipInfo_GetChipType() != CHIP_TYPE_CC2650) )
1518+ {
1519+ memcpy(&EasyLink_cmdPropRadioSetup.divSetup,
1520+ RF_pCmdPropRadioDivSetup_lrm,
1521+ sizeof(rfc_CMD_PROP_RADIO_DIV_SETUP_t));
1522+ memcpy(&EasyLink_cmdFs, RF_pCmdFs_preDef, sizeof(rfc_CMD_FS_t));
1523+ memcpy(&EasyLink_RF_prop, RF_pProp_lrm, sizeof(RF_Mode));
1524+ memcpy(&EasyLink_cmdPropRxAdv, RF_pCmdPropRxAdv_preDef, sizeof(rfc_CMD_PROP_RX_ADV_t));
1525+ memcpy(&EasyLink_cmdPropTx, RF_pCmdPropTx_preDef, sizeof(rfc_CMD_PROP_TX_t));
1526+ }
1527+ else if ( (ui32ModType == EasyLink_Phy_2_4_200kbps2gfsk) && (ChipInfo_GetChipType() == CHIP_TYPE_CC2650) )
1528+ {
1529+ memcpy(&EasyLink_cmdPropRadioSetup.setup,
1530+ RF_pCmdPropRadioSetup_2_4G_fsk,
1531+ sizeof(rfc_CMD_PROP_RADIO_SETUP_t));
1532+ memcpy(&EasyLink_cmdFs, RF_pCmdFs_preDef, sizeof(rfc_CMD_FS_t));
1533+ memcpy(&EasyLink_RF_prop, RF_pProp_2_4G_fsk, sizeof(RF_Mode));
1534+ memcpy(&EasyLink_cmdPropRxAdv, RF_pCmdPropRxAdv_preDef, sizeof(rfc_CMD_PROP_RX_ADV_t));
1535+ memcpy(&EasyLink_cmdPropTx, RF_pCmdPropTx_preDef, sizeof(rfc_CMD_PROP_TX_t));
1536+ }
1537+
1538+ else if ( (ui32ModType == EasyLink_Phy_5kbpsSlLr) && (ChipInfo_GetChipType() != CHIP_TYPE_CC2650) )
1539+ {
1540+ memcpy(&EasyLink_cmdPropRadioSetup.setup,
1541+ RF_pCmdPropRadioDivSetup_sl_lr,
1542+ sizeof(rfc_CMD_PROP_RADIO_DIV_SETUP_t));
1543+ memcpy(&EasyLink_cmdFs, RF_pCmdFs_preDef, sizeof(rfc_CMD_FS_t));
1544+ memcpy(&EasyLink_RF_prop, RF_pProp_sl_lr, sizeof(RF_Mode));
1545+ memcpy(&EasyLink_cmdPropRxAdv, RF_pCmdPropRxAdv_preDef, sizeof(rfc_CMD_PROP_RX_ADV_t));
1546+ memcpy(&EasyLink_cmdPropTx, RF_pCmdPropTx_preDef, sizeof(rfc_CMD_PROP_TX_t));
1547+ }
1548+ else
1549+ {
1550+ if (busyMutex != NULL)
1551+ {
1552+ Semaphore_post(busyMutex);
1553+ }
1554+ return EasyLink_Status_Param_Error;
1555+ }
1556+
1557+ if (rfModeMultiClient)
1558+ {
1559+ EasyLink_RF_prop.rfMode = RF_MODE_MULTIPLE;
1560+ }
1561+
1562+ /* Request access to the radio */
1563+ rfHandle = RF_open(&rfObject, &EasyLink_RF_prop,
1564+ (RF_RadioSetup*)&EasyLink_cmdPropRadioSetup.setup, &rfParams);
1565+
1566+ //Set Rx packet size, taking into account addr which is not in the hdr
1567+ //(only length can be)
1568+ EasyLink_cmdPropRxAdv.maxPktLen = EASYLINK_MAX_DATA_LENGTH +
1569+ EASYLINK_MAX_ADDR_SIZE;
1570+ EasyLink_cmdPropRxAdv.pAddr = addrFilterTable;
1571+ addrSize = 1;
1572+ EasyLink_cmdPropRxAdv.addrConf.addrSize = addrSize; //Set addr size to the
1573+ //default
1574+ EasyLink_cmdPropRxAdv.pktConf.filterOp = 1; // Disable Addr filter by
1575+ //default
1576+ EasyLink_cmdPropRxAdv.pQueue = &dataQueue; // Set the Data Entity queue
1577+ // for received data
1578+ EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics;
1579+
1580+ //Set the frequency
1581+ RF_runCmd(rfHandle, (RF_Op*)&EasyLink_cmdFs, RF_PriorityNormal, 0, //asyncCmdCallback,
1582+ EASYLINK_RF_EVENT_MASK);
1583+
1584+ //set default asyncRxTimeOut to 0
1585+ asyncRxTimeOut = 0;
1586+
1587+ //Create a semaphore for blocking commands
1588+ Semaphore_Params params;
1589+ Error_Block eb;
1590+
1591+ // init params
1592+ Semaphore_Params_init(&params);
1593+ Error_init(&eb);
1594+
1595+ // create semaphore instance if not already created
1596+ if (busyMutex == NULL)
1597+ {
1598+ busyMutex = Semaphore_create(0, &params, &eb);
1599+ if (busyMutex == NULL)
1600+ {
1601+ return EasyLink_Status_Mem_Error;
1602+ }
1603+
1604+ Semaphore_post(busyMutex);
1605+ }
1606+ else
1607+ {
1608+ //already configured and taken busyMutex, so release it
1609+ Semaphore_post(busyMutex);
1610+ }
1611+
1612+ configured = 1;
1613+
1614+ return EasyLink_Status_Success;
1615+}
1616+
1617+EasyLink_Status EasyLink_setFrequency(uint32_t ui32Freq)
1618+{
1619+ EasyLink_Status status = EasyLink_Status_Cmd_Error;
1620+ //uint64_t ui64FractFreq;
1621+
1622+ if ( (!configured) || suspended)
1623+ {
1624+ return EasyLink_Status_Config_Error;
1625+ }
1626+ //Check and take the busyMutex
1627+ if (Semaphore_pend(busyMutex, 0) == FALSE)
1628+ {
1629+ return EasyLink_Status_Busy_Error;
1630+ }
1631+
1632+ /* Set the frequency */
1633+ EasyLink_cmdFs.frequency = (uint16_t)(ui32Freq / 1000000);
1634+ EasyLink_cmdFs.fractFreq = (uint16_t) (((uint64_t)ui32Freq -
1635+ ((uint64_t)EasyLink_cmdFs.frequency * 1000000)) * 65536 / 1000000);
1636+
1637+ /* Run command */
1638+ RF_EventMask result = RF_runCmd(rfHandle, (RF_Op*)&EasyLink_cmdFs,
1639+ RF_PriorityNormal, 0, EASYLINK_RF_EVENT_MASK);
1640+
1641+ if (result & RF_EventLastCmdDone)
1642+ {
1643+ status = EasyLink_Status_Success;
1644+ }
1645+
1646+ Semaphore_post(busyMutex);
1647+
1648+ return status;
1649+}
1650+
1651+uint32_t EasyLink_getFrequency(void)
1652+{
1653+ uint32_t freq_khz;
1654+
1655+ if ( (!configured) || suspended)
1656+ {
1657+ return EasyLink_Status_Config_Error;
1658+ }
1659+
1660+ freq_khz = EasyLink_cmdFs.frequency * 1000000;
1661+ freq_khz += ((((uint64_t)EasyLink_cmdFs.fractFreq * 1000000)) / 65536);
1662+
1663+ return freq_khz;
1664+}
1665+
1666+EasyLink_Status EasyLink_setRfPwr(int8_t i8txPowerdBm)
1667+{
1668+ EasyLink_Status status = EasyLink_Status_Cmd_Error;
1669+ rfc_CMD_SCH_IMM_t immOpCmd = {0};
1670+ rfc_CMD_SET_TX_POWER_t cmdSetPower = {0};
1671+ uint8_t txPowerIdx;
1672+
1673+ if ( (!configured) || suspended)
1674+ {
1675+ return EasyLink_Status_Config_Error;
1676+ }
1677+ //Check and take the busyMutex
1678+ if (Semaphore_pend(busyMutex, 0) == FALSE)
1679+ {
1680+ return EasyLink_Status_Busy_Error;
1681+ }
1682+
1683+ immOpCmd.commandNo = CMD_SCH_IMM;
1684+ immOpCmd.startTrigger.triggerType = TRIG_NOW;
1685+ immOpCmd.startTrigger.pastTrig = 1;
1686+ immOpCmd.startTime = 0;
1687+
1688+ cmdSetPower.commandNo = CMD_SET_TX_POWER;
1689+
1690+ if (i8txPowerdBm < rfPowerTable[0].dbm)
1691+ {
1692+ i8txPowerdBm = rfPowerTable[0].dbm;
1693+ }
1694+ else if (i8txPowerdBm > rfPowerTable[rfPowerTableSize-1].dbm )
1695+ {
1696+ i8txPowerdBm = rfPowerTable[rfPowerTableSize-1].dbm;
1697+ }
1698+
1699+ //if max power is requested then the CCFG_FORCE_VDDR_HH must be set in
1700+ //the ccfg
1701+#if (CCFG_FORCE_VDDR_HH != 0x1)
1702+ if (i8txPowerdBm == rfPowerTable[rfPowerTableSize-1].dbm)
1703+ {
1704+ //Release the busyMutex
1705+ Semaphore_post(busyMutex);
1706+ return EasyLink_Status_Config_Error;
1707+ }
1708+#endif
1709+
1710+ for (txPowerIdx = 0;
1711+ txPowerIdx < rfPowerTableSize;
1712+ txPowerIdx++)
1713+ {
1714+ if (i8txPowerdBm >= rfPowerTable[txPowerIdx].dbm)
1715+ {
1716+ cmdSetPower.txPower = rfPowerTable[txPowerIdx].txPower;
1717+ EasyLink_cmdPropRadioSetup.setup.txPower = rfPowerTable[txPowerIdx].txPower;
1718+ }
1719+ }
1720+
1721+ //point the Operational Command to the immediate set power command
1722+ immOpCmd.cmdrVal = (uint32_t) &cmdSetPower;
1723+
1724+ // Send command
1725+ RF_CmdHandle cmd = RF_postCmd(rfHandle, (RF_Op*)&immOpCmd,
1726+ RF_PriorityNormal, 0, EASYLINK_RF_EVENT_MASK);
1727+
1728+ RF_EventMask result = RF_pendCmd(rfHandle, cmd, (RF_EventLastCmdDone |
1729+ RF_EventCmdError));
1730+
1731+ if (result & RF_EventLastCmdDone)
1732+ {
1733+ status = EasyLink_Status_Success;
1734+ }
1735+
1736+ //Release the busyMutex
1737+ Semaphore_post(busyMutex);
1738+
1739+ return status;
1740+}
1741+
1742+int8_t EasyLink_getRfPwr(void)
1743+{
1744+ uint8_t txPowerIdx;
1745+ int8_t txPowerdBm = 0xff;
1746+
1747+ if ( (!configured) || suspended)
1748+ {
1749+ return EasyLink_Status_Config_Error;
1750+ }
1751+
1752+ for (txPowerIdx = 0;
1753+ txPowerIdx < rfPowerTableSize;
1754+ txPowerIdx++)
1755+ {
1756+ if (rfPowerTable[txPowerIdx].txPower == EasyLink_cmdPropRadioSetup.setup.txPower)
1757+ {
1758+ txPowerdBm = rfPowerTable[txPowerIdx].dbm;
1759+ continue;
1760+ }
1761+ }
1762+
1763+ //if CCFG_FORCE_VDDR_HH is not set max power cannot be achieved
1764+#if (CCFG_FORCE_VDDR_HH != 0x1)
1765+ if (txPowerdBm == rfPowerTable[rfPowerTableSize-1].dbm)
1766+ {
1767+ txPowerdBm = rfPowerTable[rfPowerTableSize-2].dbm;
1768+ }
1769+#endif
1770+
1771+ return txPowerdBm;
1772+}
1773+
1774+uint32_t EasyLink_getAbsTime(void)
1775+{
1776+ if ( (!configured) || suspended)
1777+ {
1778+ return EasyLink_Status_Config_Error;
1779+ }
1780+
1781+ return RF_getCurrentTime();
1782+}
1783+
1784+EasyLink_Status EasyLink_transmit(EasyLink_TxPacket *txPacket)
1785+{
1786+ EasyLink_Status status = EasyLink_Status_Tx_Error;
1787+
1788+ if ( (!configured) || suspended)
1789+ {
1790+ return EasyLink_Status_Config_Error;
1791+ }
1792+ //Check and take the busyMutex
1793+ if (Semaphore_pend(busyMutex, 0) == FALSE)
1794+ {
1795+ return EasyLink_Status_Busy_Error;
1796+ }
1797+ if (txPacket->len > EASYLINK_MAX_DATA_LENGTH)
1798+ {
1799+ return EasyLink_Status_Param_Error;
1800+ }
1801+
1802+ memcpy(txBuffer, txPacket->dstAddr, addrSize);
1803+ memcpy(txBuffer + addrSize, txPacket->payload, txPacket->len);
1804+
1805+ //packet length to Tx includes address
1806+ EasyLink_cmdPropTx.pktLen = txPacket->len + addrSize;
1807+ EasyLink_cmdPropTx.pPkt = txBuffer;
1808+
1809+ if (txPacket->absTime != 0)
1810+ {
1811+ EasyLink_cmdPropTx.startTrigger.triggerType = TRIG_ABSTIME;
1812+ EasyLink_cmdPropTx.startTrigger.pastTrig = 1;
1813+ EasyLink_cmdPropTx.startTime = txPacket->absTime;
1814+ }
1815+ else
1816+ {
1817+ EasyLink_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
1818+ EasyLink_cmdPropTx.startTrigger.pastTrig = 1;
1819+ EasyLink_cmdPropTx.startTime = 0;
1820+ }
1821+
1822+ // Send packet
1823+ RF_CmdHandle cmdHdl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTx,
1824+ RF_PriorityNormal, 0, EASYLINK_RF_EVENT_MASK);
1825+
1826+ // Wait for Command to complete
1827+ RF_EventMask result = RF_pendCmd(rfHandle, cmdHdl, (RF_EventLastCmdDone |
1828+ RF_EventCmdError));
1829+
1830+
1831+ if (result & RF_EventLastCmdDone)
1832+ {
1833+ status = EasyLink_Status_Success;
1834+ }
1835+
1836+ //Release the busyMutex
1837+ Semaphore_post(busyMutex);
1838+
1839+
1840+ return status;
1841+}
1842+
1843+EasyLink_Status EasyLink_transmitAsync(EasyLink_TxPacket *txPacket, EasyLink_TxDoneCb cb)
1844+{
1845+ EasyLink_Status status = EasyLink_Status_Tx_Error;
1846+
1847+ //Check if not configure or already an Async command being performed
1848+ if ( (!configured) || suspended)
1849+ {
1850+ return EasyLink_Status_Config_Error;
1851+ }
1852+ //Check and take the busyMutex
1853+ if ( (Semaphore_pend(busyMutex, 0) == FALSE) || (EasyLink_CmdHandle_isValid(asyncCmdHndl)) )
1854+ {
1855+ return EasyLink_Status_Busy_Error;
1856+ }
1857+ if (txPacket->len > EASYLINK_MAX_DATA_LENGTH)
1858+ {
1859+ return EasyLink_Status_Param_Error;
1860+ }
1861+
1862+ //store application callback
1863+ txCb = cb;
1864+
1865+ memcpy(txBuffer, txPacket->dstAddr, addrSize);
1866+ memcpy(txBuffer + addrSize, txPacket->payload, txPacket->len);
1867+
1868+ //packet length to Tx includes address
1869+ EasyLink_cmdPropTx.pktLen = txPacket->len + addrSize;
1870+ EasyLink_cmdPropTx.pPkt = txBuffer;
1871+
1872+ if (txPacket->absTime != 0)
1873+ {
1874+ EasyLink_cmdPropTx.startTrigger.triggerType = TRIG_ABSTIME;
1875+ EasyLink_cmdPropTx.startTrigger.pastTrig = 1;
1876+ EasyLink_cmdPropTx.startTime = txPacket->absTime;
1877+ }
1878+ else
1879+ {
1880+ EasyLink_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
1881+ EasyLink_cmdPropTx.startTrigger.pastTrig = 1;
1882+ EasyLink_cmdPropTx.startTime = 0;
1883+ }
1884+
1885+ /* Send packet */
1886+ asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTx,
1887+ RF_PriorityNormal, txDoneCallback, EASYLINK_RF_EVENT_MASK);
1888+
1889+ if (EasyLink_CmdHandle_isValid(asyncCmdHndl))
1890+ {
1891+ status = EasyLink_Status_Success;
1892+ }
1893+
1894+ //busyMutex will be released by the callback
1895+
1896+ return status;
1897+}
1898+
1899+EasyLink_Status EasyLink_receive(EasyLink_RxPacket *rxPacket)
1900+{
1901+ EasyLink_Status status = EasyLink_Status_Rx_Error;
1902+ RF_EventMask result;
1903+ rfc_dataEntryGeneral_t *pDataEntry;
1904+
1905+ if ( (!configured) || suspended)
1906+ {
1907+ return EasyLink_Status_Config_Error;
1908+ }
1909+ //Check and take the busyMutex
1910+ if (Semaphore_pend(busyMutex, 0) == FALSE)
1911+ {
1912+ return EasyLink_Status_Busy_Error;
1913+ }
1914+
1915+ pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer;
1916+ //data entry rx buffer includes hdr (len-1Byte), addr (max 8Bytes) and data
1917+ pDataEntry->length = 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH;
1918+ pDataEntry->status = 0;
1919+ dataQueue.pCurrEntry = (uint8_t*) pDataEntry;
1920+ dataQueue.pLastEntry = NULL;
1921+ EasyLink_cmdPropRxAdv.pQueue = &dataQueue; /* Set the Data Entity queue for received data */
1922+ EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics;
1923+
1924+ if (rxPacket->absTime != 0)
1925+ {
1926+ EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_ABSTIME;
1927+ EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1;
1928+ EasyLink_cmdPropRxAdv.startTime = rxPacket->absTime;
1929+ }
1930+ else
1931+ {
1932+ EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW;
1933+ EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1;
1934+ EasyLink_cmdPropRxAdv.startTime = 0;
1935+ }
1936+
1937+ if (rxPacket->rxTimeout != 0)
1938+ {
1939+ EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME;
1940+ EasyLink_cmdPropRxAdv.endTime = RF_getCurrentTime() + rxPacket->rxTimeout;
1941+ }
1942+ else
1943+ {
1944+ EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER;
1945+ EasyLink_cmdPropRxAdv.endTime = 0;
1946+ }
1947+
1948+ //Clear the Rx statistics structure
1949+ memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t));
1950+
1951+ RF_CmdHandle rx_cmd = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,
1952+ RF_PriorityNormal, 0, EASYLINK_RF_EVENT_MASK);
1953+
1954+ /* Wait for Command to complete */
1955+ result = RF_pendCmd(rfHandle, rx_cmd, (RF_EventLastCmdDone | RF_EventCmdError));
1956+
1957+ if (result & RF_EventLastCmdDone)
1958+ {
1959+ //Check command status
1960+ if (EasyLink_cmdPropRxAdv.status == PROP_DONE_OK)
1961+ {
1962+ //Check that data entry status indicates it is finished with
1963+ if (pDataEntry->status != DATA_ENTRY_FINISHED)
1964+ {
1965+ status = EasyLink_Status_Rx_Error;
1966+ }
1967+ //check Rx Statistics
1968+ else if ( (rxStatistics.nRxOk == 1) ||
1969+ //or filer disabled and ignore due to addr mistmatch
1970+ ((EasyLink_cmdPropRxAdv.pktConf.filterOp == 1) &&
1971+ (rxStatistics.nRxIgnored == 1)) )
1972+ {
1973+ //copy length from pDataEntry (- addrSize)
1974+ rxPacket->len = *(uint8_t*)(&pDataEntry->data) - addrSize;
1975+ //copy address
1976+ memcpy(rxPacket->dstAddr, (&pDataEntry->data + 1), addrSize);
1977+ //copy payload
1978+ memcpy(&rxPacket->payload, (&pDataEntry->data + 1 + addrSize), (rxPacket->len));
1979+ rxPacket->rssi = rxStatistics.lastRssi;
1980+
1981+ status = EasyLink_Status_Success;
1982+ rxPacket->absTime = rxStatistics.timeStamp;
1983+ }
1984+ else if ( rxStatistics.nRxBufFull == 1)
1985+ {
1986+ status = EasyLink_Status_Rx_Buffer_Error;
1987+ }
1988+ else if ( rxStatistics.nRxStopped == 1)
1989+ {
1990+ status = EasyLink_Status_Aborted;
1991+ }
1992+ else
1993+ {
1994+ status = EasyLink_Status_Rx_Error;
1995+ }
1996+ }
1997+ else if ( EasyLink_cmdPropRxAdv.status == PROP_DONE_RXTIMEOUT)
1998+ {
1999+ status = EasyLink_Status_Rx_Timeout;
2000+ }
2001+ else
2002+ {
2003+ status = EasyLink_Status_Rx_Error;
2004+ }
2005+ }
2006+
2007+ //Release the busyMutex
2008+ Semaphore_post(busyMutex);
2009+
2010+ return status;
2011+}
2012+
2013+EasyLink_Status EasyLink_receiveAsync(EasyLink_ReceiveCb cb, uint32_t absTime)
2014+{
2015+ EasyLink_Status status = EasyLink_Status_Rx_Error;
2016+ rfc_dataEntryGeneral_t *pDataEntry;
2017+
2018+ //Check if not configure of already an Async command being performed
2019+ if ( (!configured) || suspended)
2020+ {
2021+ return EasyLink_Status_Config_Error;
2022+ }
2023+ //Check and take the busyMutex
2024+ if ( (Semaphore_pend(busyMutex, 0) == FALSE) || (EasyLink_CmdHandle_isValid(asyncCmdHndl)) )
2025+ {
2026+ return EasyLink_Status_Busy_Error;
2027+ }
2028+
2029+ rxCb = cb;
2030+
2031+ pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer;
2032+ //data entry rx buffer includes hdr (len-1Byte), addr (max 8Bytes) and data
2033+ pDataEntry->length = 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH;
2034+ pDataEntry->status = 0;
2035+ dataQueue.pCurrEntry = (uint8_t*) pDataEntry;
2036+ dataQueue.pLastEntry = NULL;
2037+ EasyLink_cmdPropRxAdv.pQueue = &dataQueue; /* Set the Data Entity queue for received data */
2038+ EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics;
2039+
2040+ if (absTime != 0)
2041+ {
2042+ EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_ABSTIME;
2043+ EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1;
2044+ EasyLink_cmdPropRxAdv.startTime = absTime;
2045+ }
2046+ else
2047+ {
2048+ EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW;
2049+ EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1;
2050+ EasyLink_cmdPropRxAdv.startTime = 0;
2051+ }
2052+
2053+ if (asyncRxTimeOut != 0)
2054+ {
2055+ EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME;
2056+ EasyLink_cmdPropRxAdv.endTime = RF_getCurrentTime() + asyncRxTimeOut;
2057+ }
2058+ else
2059+ {
2060+ EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER;
2061+ EasyLink_cmdPropRxAdv.endTime = 0;
2062+ }
2063+
2064+ //Clear the Rx statistics structure
2065+ memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t));
2066+
2067+ asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,
2068+ RF_PriorityNormal, rxDoneCallback, EASYLINK_RF_EVENT_MASK);
2069+
2070+ if (EasyLink_CmdHandle_isValid(asyncCmdHndl))
2071+ {
2072+ status = EasyLink_Status_Success;
2073+ }
2074+
2075+ //busyMutex will be released in callback
2076+
2077+ return status;
2078+}
2079+
2080+EasyLink_Status EasyLink_abort(void)
2081+{
2082+ EasyLink_Status status = EasyLink_Status_Cmd_Error;
2083+
2084+ if ( (!configured) || suspended)
2085+ {
2086+ return EasyLink_Status_Config_Error;
2087+ }
2088+ //check an Async command is running, if not return success
2089+ if (!EasyLink_CmdHandle_isValid(asyncCmdHndl))
2090+ {
2091+ return EasyLink_Status_Aborted;
2092+ }
2093+
2094+ //force abort (gracefull param set to 0)
2095+ if (RF_cancelCmd(rfHandle, asyncCmdHndl, 0) == RF_StatSuccess)
2096+ {
2097+ /* Wait for Command to complete */
2098+ RF_EventMask result = RF_pendCmd(rfHandle, asyncCmdHndl, (RF_EventLastCmdDone | RF_EventCmdError |
2099+ RF_EventCmdAborted | RF_EventCmdCancelled | RF_EventCmdStopped));
2100+
2101+ if (result & RF_EventLastCmdDone)
2102+ {
2103+ status = EasyLink_Status_Success;
2104+ }
2105+ }
2106+ else
2107+ {
2108+ status = EasyLink_Status_Cmd_Error;
2109+ }
2110+
2111+ return status;
2112+}
2113+
2114+EasyLink_Status EasyLink_enableRxAddrFilter(uint8_t* pui8AddrFilterTable, uint8_t ui8AddrSize, uint8_t ui8NumAddrs)
2115+{
2116+ EasyLink_Status status = EasyLink_Status_Param_Error;
2117+
2118+ if ( (!configured) || suspended)
2119+ {
2120+ return EasyLink_Status_Config_Error;
2121+ }
2122+ if ( Semaphore_pend(busyMutex, 0) == FALSE )
2123+ {
2124+ return EasyLink_Status_Busy_Error;
2125+ }
2126+
2127+ if ( (pui8AddrFilterTable != NULL) &&
2128+ (ui8AddrSize != 0) && (ui8NumAddrs != 0) &&
2129+ (ui8AddrSize == addrSize) &&
2130+ (ui8NumAddrs <= EASYLINK_MAX_ADDR_FILTERS) )
2131+ {
2132+ memcpy(addrFilterTable, pui8AddrFilterTable, EASYLINK_MAX_ADDR_SIZE * EASYLINK_MAX_ADDR_FILTERS);
2133+ EasyLink_cmdPropRxAdv.addrConf.addrSize = ui8AddrSize;
2134+ EasyLink_cmdPropRxAdv.addrConf.numAddr = ui8NumAddrs;
2135+ EasyLink_cmdPropRxAdv.pktConf.filterOp = 0;
2136+
2137+ status = EasyLink_Status_Success;
2138+ }
2139+ else if (pui8AddrFilterTable == NULL)
2140+ {
2141+ //disable filter
2142+ EasyLink_cmdPropRxAdv.pktConf.filterOp = 1;
2143+
2144+ status = EasyLink_Status_Success;
2145+ }
2146+
2147+ //Release the busyMutex
2148+ Semaphore_post(busyMutex);
2149+
2150+ return status;
2151+}
2152+
2153+EasyLink_Status EasyLink_setCtrl(EasyLink_CtrlOption Ctrl, uint32_t ui32Value)
2154+{
2155+ EasyLink_Status status = EasyLink_Status_Param_Error;
2156+ switch(Ctrl)
2157+ {
2158+ case EasyLink_Ctrl_AddSize:
2159+ if (ui32Value <= EASYLINK_MAX_ADDR_SIZE)
2160+ {
2161+ addrSize = (uint8_t) ui32Value;
2162+ EasyLink_cmdPropRxAdv.addrConf.addrSize = addrSize;
2163+ status = EasyLink_Status_Success;
2164+ }
2165+ break;
2166+ case EasyLink_Ctrl_Idle_TimeOut:
2167+ rfParams.nInactivityTimeout = ui32Value;
2168+ rfParamsConfigured = 1;
2169+ status = EasyLink_Status_Success;
2170+ break;
2171+ case EasyLink_Ctrl_MultiClient_Mode:
2172+ rfModeMultiClient = (bool) ui32Value;
2173+ status = EasyLink_Status_Success;
2174+ break;
2175+ case EasyLink_Ctrl_AsyncRx_TimeOut:
2176+ asyncRxTimeOut = ui32Value;
2177+ status = EasyLink_Status_Success;
2178+ break;
2179+ case EasyLink_Ctrl_Test_Tone:
2180+ status = enableTestMode(EasyLink_Ctrl_Test_Tone);
2181+ break;
2182+ case EasyLink_Ctrl_Test_Signal:
2183+ status = enableTestMode(EasyLink_Ctrl_Test_Signal);
2184+ break;
2185+ }
2186+
2187+ return status;
2188+}
2189+
2190+EasyLink_Status EasyLink_getCtrl(EasyLink_CtrlOption Ctrl, uint32_t* pui32Value)
2191+{