net_outbound.c
Go to the documentation of this file.
1 
5 #include "net.h"
6 
7 #include <stdlib.h>
8 #include "main.h"
9 
11 int outbuff_start = 0;
12 int outbuff_end = 0;
13 
15 
17 
18 int packetCounter = 0;
19 
20 const unsigned int PACKET_LENGTH = API_HEADER_LENGTH + sizeof(struct telem_block) + 1;
21 
22 // Create a telem block returns null if fails
24  struct telem_block *telem = malloc(sizeof (struct telem_block));
25  *(int *)(&(telem->type)) = packet;
26  packetCounter++;
27  return telem;
28 }
29 
31  return packetCounter;
32 }
33 
34 // Create a telemetry block to use for debugging, only creates one instance
36  // If the telemetry block does not exist, create it filled with ones
37  // of the respective types
38  if (debugTelemetry == 0) {
39  switch(packet){
40  case PRIORITY0:
41  debugTelemetry->data.p1_block.lat = 1;
42  debugTelemetry->data.p1_block.lon = 1;
43  debugTelemetry->data.p1_block.sysTime = 1;
44  debugTelemetry->data.p1_block.roll = 1;
45  debugTelemetry->data.p1_block.pitch = 1;
46  debugTelemetry->data.p1_block.yaw = 1;
47  debugTelemetry->data.p1_block.rollRate = 1;
48  debugTelemetry->data.p1_block.pitchRate = 1;
49  debugTelemetry->data.p1_block.yawRate = 1;
50  debugTelemetry->data.p1_block.airspeed = 1;
51  debugTelemetry->data.p1_block.alt = 1;
52  debugTelemetry->data.p1_block.UTC = 1;
53  debugTelemetry->data.p1_block.gSpeed = 1;
54  debugTelemetry->data.p1_block.heading = 1;
55  debugTelemetry->data.p1_block.rollRateSetpoint = 1;
56  debugTelemetry->data.p1_block.rollSetpoint = 1;
57  debugTelemetry->data.p1_block.pitchRateSetpoint = 1;
58  debugTelemetry->data.p1_block.pitchSetpoint = 1;
59  debugTelemetry->data.p1_block.throttleSetpoint = 1;
60  break;
61  case PRIORITY1:
62  debugTelemetry->data.p2_block.rollKD = 1;
63  debugTelemetry->data.p2_block.rollKP = 1;
64  debugTelemetry->data.p2_block.pitchKD = 1;
65  debugTelemetry->data.p2_block.pitchKP = 1;
66  debugTelemetry->data.p2_block.yawKD = 1;
67  debugTelemetry->data.p2_block.yawKP = 1;
68  debugTelemetry->data.p2_block.lastCommandsSent[0] = 1;
69  debugTelemetry->data.p2_block.lastCommandsSent[1] = 1;
70  debugTelemetry->data.p2_block.lastCommandsSent[2] = 1;
71  debugTelemetry->data.p2_block.lastCommandsSent[3] = 1;
72  debugTelemetry->data.p2_block.batteryLevel1 = 1;
73  //debugTelemetry->data.p2_block.batteryLevel2 = 1;
74  debugTelemetry->data.p2_block.ch1In = 1;
75  debugTelemetry->data.p2_block.ch2In = 1;
76  debugTelemetry->data.p2_block.ch3In = 1;
77  debugTelemetry->data.p2_block.ch4In = 1;
78  debugTelemetry->data.p2_block.ch5In = 1;
79  debugTelemetry->data.p2_block.ch6In = 1;
80  debugTelemetry->data.p2_block.ch7In = 1;
81  debugTelemetry->data.p2_block.ch8In = 1;
82  debugTelemetry->data.p2_block.ch1Out = 1;
83  debugTelemetry->data.p2_block.ch2Out = 1;
84  debugTelemetry->data.p2_block.ch3Out = 1;
85  debugTelemetry->data.p2_block.ch4Out = 1;
86  debugTelemetry->data.p2_block.ch5Out = 1;
87  debugTelemetry->data.p2_block.ch6Out = 1;
88  debugTelemetry->data.p2_block.ch7Out = 1;
89  debugTelemetry->data.p2_block.ch8Out = 1;
90  debugTelemetry->data.p2_block.yawRateSetpoint = 1;
91  debugTelemetry->data.p2_block.headingSetpoint = 1;
92  debugTelemetry->data.p2_block.altitudeSetpoint = 1;
93  debugTelemetry->data.p2_block.flapSetpoint = 1;
94  debugTelemetry->data.p2_block.cameraStatus = 1;
95  debugTelemetry->data.p2_block.wirelessConnection = 1;
96  debugTelemetry->data.p2_block.autopilotActive = 1;
97  debugTelemetry->data.p2_block.gpsStatus = 1;
98  //debugTelemetry->data.p2_block.pathChecksum = 1;
99  debugTelemetry->data.p2_block.numWaypoints = 1;
100  debugTelemetry->data.p2_block.waypointIndex = 1;
101  //debugTelemetry->data.p2_block.following = 1;
102  break;
103  case PRIORITY2:
104  debugTelemetry->data.p3_block.rollKI = 1;
105  debugTelemetry->data.p3_block.pitchKI = 1;
106  debugTelemetry->data.p3_block.yawKI = 1;
107  debugTelemetry->data.p3_block.headingKD = 1;
108  debugTelemetry->data.p3_block.headingKP = 1;
109  debugTelemetry->data.p3_block.headingKI = 1;
110  debugTelemetry->data.p3_block.altitudeKD = 1;
111  debugTelemetry->data.p3_block.altitudeKP = 1;
112  debugTelemetry->data.p3_block.altitudeKI = 1;
113  debugTelemetry->data.p3_block.throttleKD = 1;
114  debugTelemetry->data.p3_block.throttleKP = 1;
115  debugTelemetry->data.p3_block.throttleKI = 1;
116  debugTelemetry->data.p3_block.flapKD = 1;
117  debugTelemetry->data.p3_block.flapKP = 1;
118  debugTelemetry->data.p3_block.flapKI = 1;
119  debugTelemetry->data.p3_block.startupErrorCodes = 1;
120  debugTelemetry->data.p3_block.startupSettings = 1;
121  break;
122 
123  default:
124  break;
125  }
126  }
127  return debugTelemetry;
128 }
129 
130 // Destroy a telemetryBlock
131 void destroyTelemetryBlock(struct telem_block *telem) {
132  free(telem);
133  telem = 0;
134  packetCounter--;
135 }
136 
137 // Add a telem_block to the outbound telemetry queue
138 // Returns the position in the queue or -1 if no room in queue
141  return -1;
142  }
143  outBuffer[outbuff_end] = telem;
144  outbuff_end++;
146  return getOutboundQueueLength();
147 }
148 
149 // Get the number of items waiting to be sent
151  int length = outbuff_end - outbuff_start;
152  if ( length < 0 ) {
153  return length + OUTBOUND_QUEUE_SIZE;
154  } else {
155  return length;
156  }
157 }
158 
159 // Clear all telem blocks waiting to be sent
161  int cleared = 0;
162  for (cleared = 0; cleared < OUTBOUND_QUEUE_SIZE; cleared++) {
163  if (outBuffer[cleared] != 0) {
164  destroyTelemetryBlock(outBuffer[cleared]);
165  outBuffer[cleared] = 0;
166  }
167  }
168  return cleared;
169 }
170 
171 // Do buffer maintenance
175  if ( getOutboundQueueLength() ) {
177  }
178  } else if ( stagingBuffer.telemetry.asStruct == 0 && getOutboundQueueLength() ) {
180  }
181 }
182 
183 void sendNextByte(void) {
184  unsigned char sendByte; // The byte to send
186  //while (U2STAbits.TRMT == 0);
187  sendByte = stagingBuffer.header[stagingBuffer.sendIndex] & 0xFF;
188  // Compute checksum
189  if (stagingBuffer.sendIndex >= 3) {
190  stagingBuffer.checksum += sendByte & 0xFF;
191  }
192  } else if ( stagingBuffer.sendIndex < PACKET_LENGTH - 1 ) {
194  stagingBuffer.checksum += sendByte & 0xFF;
195  } else if ( stagingBuffer.sendIndex == PACKET_LENGTH - 1) {
196  sendByte = 0xFF - (stagingBuffer.checksum & 0xFF);
197  } else {
198  IFS1bits.U2TXIF = 0;
199  return;
200  }
201 
203  IFS1bits.U2TXIF = 0;
204  U2TXREG = sendByte;
205 }
206 
207 // Put the next telemetry
208 void stageTelemetryBlock(struct telem_block *telem) {
212  // Send index should be reset last for reasons
214  sendNextByte();
215 }
216 
217 // Pop next telem_block from outgoing buffer, null if no telemetry
219  struct telem_block* telem = outBuffer[outbuff_start];
220  outbuff_start += 1;
221  outBuffer[outbuff_start - 1] = 0;
223  return telem;
224 }
225 
226 //TODO: Implement method to split telemetry data between multiple packets
227 
228 // generate an api string into the given char array from the telem block
229 // Does not check array length!
230 unsigned int generateApiHeader(unsigned char *apiString, char dataFrame) {
231  unsigned int apiIndex = 0;
232  unsigned int length = API_HEADER_LENGTH - API_HEADER_PREFIX + sizeof(struct telem_block);
233  //unsigned int telemLength = sizeof(struct telem_block);
234 
235  // API Mode header
236  apiString[apiIndex++] = 0x7E;
237  // Packet length
238  apiString[apiIndex++] = 0; // MSB (Can only go up to 100)
239  apiString[apiIndex++] = (length & 0x00FF); // LSB
240 
241  //Frame Type
242  apiString[apiIndex++] = TX_PACKET;
243  // Data frame
244  apiString[apiIndex++] = dataFrame;
245  // Receiver address
246  apiString[apiIndex++] = (RECEIVER_ADDRESS & 0xFF00000000000000) >> 56;
247  apiString[apiIndex++] = (RECEIVER_ADDRESS & 0x00FF000000000000) >> 48;
248  apiString[apiIndex++] = (RECEIVER_ADDRESS & 0x0000FF0000000000) >> 40;
249  apiString[apiIndex++] = (RECEIVER_ADDRESS & 0x000000FF00000000) >> 32;
250  apiString[apiIndex++] = (RECEIVER_ADDRESS & 0x00000000FF000000) >> 24;
251  apiString[apiIndex++] = (RECEIVER_ADDRESS & 0x0000000000FF0000) >> 16;
252  apiString[apiIndex++] = (RECEIVER_ADDRESS & 0x000000000000FF00) >> 8;
253  apiString[apiIndex++] = (RECEIVER_ADDRESS & 0x00000000000000FF);
254 
255  //Reserved Data
256  apiString[apiIndex++] = 0xFF;
257  apiString[apiIndex++] = 0xFE;
258 // *((long long *)(&apiString[apiIndex])) = RECEIVER_ADDRESS;
259 // apiIndex += 8; //Receiver Address is 64 bit
260  //Node Path distance
261  apiString[apiIndex++] = BROADCAST_RADIUS;
262  // Option byte
263  apiString[apiIndex++] = OPTION_BYTE;
264 
265  return apiIndex;
266 }
267 
268 // Send a telemetry block immediately (blocking)
269 int sendTelemetryBlock(struct telem_block *telem) {
270 
271  unsigned char apiHeader[API_HEADER_LENGTH];
272  unsigned int headerLength = generateApiHeader(apiHeader, 0);
273  // Treat the telemetry block as a character array.
274  unsigned char *telemAsArray = (unsigned char*)telem;
275 
276  unsigned int lengthCheck = 0;
277  unsigned char checksum = 0;
278  unsigned int i;
279  // Send the header
280  for (i = 0; i < headerLength; i++ ) {
281  // Culmulative checksum
282  if (i >= API_HEADER_PREFIX) {
283  checksum += apiHeader[i] & 0xFF;
284  }
285  // Wait for data link to clear from previous send
286  while (U2STAbits.TRMT == 0);
287  // Load transmit register
288  U2TXREG = apiHeader[i];
289  }
290  lengthCheck += i;
291  // Send the telemetry
292  for (i = 0; i < sizeof(struct telem_block); i++) {
293  // Culmulative checksum
294  checksum += telemAsArray[i] & 0xFF;
295  // Wait for data link to clear from previous send
296  while (U2STAbits.TRMT == 0);
297  // Load transmit register
298  U2TXREG = telemAsArray[i];
299  }
300  lengthCheck += i;
301  // Send the checksum
302  while (U2STAbits.TRMT == 0);
303  U2TXREG = 0xFF - checksum;
304  lengthCheck += 1;
305 
306  // Note: We send the last piece of data through UART and
307  // then forget about it. We assume it will get handled eventually
308  return 0;
309 }
310 
311 void __attribute__((__interrupt__, no_auto_psv)) _U2TXInterrupt(void) {
312  // Short circuit if nothing in the staging area yet
313  if ( stagingBuffer.telemetry.asStruct == 0 ) {
314  IFS1bits.U2TXIF = 0;
315  return;
316  }
317  sendNextByte();
318 }
int cameraStatus
Definition: net.h:102
unsigned int generateApiHeader(unsigned char *apiString, char dataFrame)
Definition: net_outbound.c:230
int clearOutboundTelemetryQueue(void)
Definition: net_outbound.c:160
unsigned int i
int pitchRateSetpoint
Definition: net.h:88
float yaw
Definition: net.h:81
int outbuff_end
Definition: net_outbound.c:12
const int type
Definition: net.h:135
unsigned char header[API_HEADER_LENGTH]
Definition: net.h:141
char autopilotActive
Definition: net.h:105
float yawKI
Definition: net.h:116
int headingSetpoint
Definition: net.h:103
struct telem_block * getDebugTelemetryBlock(p_priority packet)
Definition: net_outbound.c:35
long int sysTime
Definition: net.h:79
int ch8Out
Definition: net.h:101
char gpsStatus
Definition: net.h:106
int heading
Definition: net.h:86
int ch7Out
Definition: net.h:101
List of defines required for XBEE communication and telemetry.
struct telem_block * popOutboundTelemetryQueue(void)
Definition: net_outbound.c:218
Definition: net.h:62
struct priority2_block p2_block
Definition: net.h:130
int ch4In
Definition: net.h:100
int throttleSetpoint
Definition: net.h:89
int ch2In
Definition: net.h:100
int ch6Out
Definition: net.h:101
int ch2Out
Definition: net.h:101
void destroyTelemetryBlock(struct telem_block *telem)
Definition: net_outbound.c:131
int rollRateSetpoint
Definition: net.h:87
struct telem_block * outBuffer[OUTBOUND_QUEUE_SIZE]
net_outbound.c
Definition: net_outbound.c:10
#define RECEIVER_ADDRESS
Definition: net.h:42
char numWaypoints
Definition: net.h:107
char wirelessConnection
Definition: net.h:104
float yawKD
Definition: net.h:96
float airspeed
Definition: net.h:83
int ch3Out
Definition: net.h:101
float pitchRate
Definition: net.h:82
float pitchKP
Definition: net.h:95
float headingKD
Definition: net.h:117
float yawRate
Definition: net.h:82
float flapKI
Definition: net.h:120
Definition: net.h:63
float rollKP
Definition: net.h:94
float altitudeKD
Definition: net.h:118
float flapKP
Definition: net.h:120
int ch6In
Definition: net.h:100
int ch3In
Definition: net.h:100
float pitch
Definition: net.h:81
int altitudeSetpoint
Definition: net.h:103
int getOutboundQueueLength(void)
Definition: net_outbound.c:150
struct priority3_block p3_block
Definition: net.h:131
packetPayload data
Definition: net.h:136
struct priority1_block p1_block
Definition: net.h:129
int packetCount()
Definition: net_outbound.c:30
long double lon
Definition: net.h:78
int yawRateSetpoint
Definition: net.h:103
void __attribute__((__interrupt__, no_auto_psv))
Definition: net_outbound.c:311
int packetCounter
Definition: net_outbound.c:18
float pitchKD
Definition: net.h:95
unsigned int startupErrorCodes
Definition: net.h:123
void outboundBufferMaintenance(void)
Definition: net_outbound.c:172
int sendTelemetryBlock(struct telem_block *telem)
Definition: net_outbound.c:269
int outbuff_start
Definition: net_outbound.c:11
int flapSetpoint
Definition: net.h:103
float rollKI
Definition: net.h:114
float rollRate
Definition: net.h:82
#define OUTBOUND_QUEUE_SIZE
Definition: net.h:31
void sendNextByte(void)
Definition: net_outbound.c:183
int ch1In
Definition: net.h:100
int ch7In
Definition: net.h:100
float rollKD
Definition: net.h:94
long double lat
Definition: net.h:78
struct telem_block * debugTelemetry
Definition: net_outbound.c:14
int startupSettings
Definition: net.h:124
int batteryLevel1
Definition: net.h:99
int ch8In
Definition: net.h:100
enum _p_priority p_priority
float headingKP
Definition: net.h:117
#define TX_PACKET
Definition: net.h:48
const unsigned int PACKET_LENGTH
Definition: net_outbound.c:20
int ch4Out
Definition: net.h:101
struct telem_block * asStruct
Definition: net.h:143
float throttleKD
Definition: net.h:119
unsigned int sendIndex
Definition: net.h:140
unsigned char checksum
Definition: net.h:146
Definition: net.h:61
#define OPTION_BYTE
Definition: net.h:45
float altitudeKP
Definition: net.h:118
unsigned char * asArray
Definition: net.h:144
int rollSetpoint
Definition: net.h:87
unsigned char apiString[100]
Definition: GPS.c:129
union telem_buffer::@0 telemetry
float alt
Definition: net.h:84
int lastCommandsSent[4]
Definition: net.h:98
void stageTelemetryBlock(struct telem_block *telem)
Definition: net_outbound.c:208
float altitudeKI
Definition: net.h:118
int ch1Out
Definition: net.h:101
float UTC
Definition: net.h:80
struct telem_buffer stagingBuffer
Definition: net_outbound.c:16
float headingKI
Definition: net.h:117
#define API_HEADER_PREFIX
Definition: net.h:40
float pitchKI
Definition: net.h:115
char waypointIndex
Definition: net.h:108
float yawKP
Definition: net.h:96
float flapKD
Definition: net.h:120
int pushOutboundTelemetryQueue(struct telem_block *telem)
Definition: net_outbound.c:139
#define BROADCAST_RADIUS
Definition: net.h:49
float roll
Definition: net.h:81
float gSpeed
Definition: net.h:85
float throttleKP
Definition: net.h:119
#define API_HEADER_LENGTH
Definition: net.h:39
int pitchSetpoint
Definition: net.h:88
int ch5In
Definition: net.h:100
struct telem_block * createTelemetryBlock(p_priority packet)
Definition: net_outbound.c:23
int ch5Out
Definition: net.h:101
float throttleKI
Definition: net.h:119