This code is to collect data from the ADCs in burst mode, decimate the data, encapsulate it in a simple UDP-like packet and then transmit it over the serial port.

Dependencies:   mbed

Revision:
0:03e8a03052c9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/comms.cpp	Fri Aug 27 15:20:30 2010 +0000
@@ -0,0 +1,86 @@
+#include "mbed.h"
+#include "comms.h"
+
+void le2be_u16(uint8_t* buffer, uint16_t in_word) {  
+        *buffer++ = (uint8_t)((in_word & 0xFF00) >> 8);
+        *buffer = (uint8_t)(in_word & 0x00FF);
+}
+
+/**
+ * This function is used to calculate a one's complement based checksum
+ * as is commonly used in IP based protocols
+ */
+uint16_t chksum_u16(uint32_t in_word) {
+    uint32_t temp = in_word & 0x0000FFFF;
+    temp += (in_word & 0xFFFF0000)>>16;
+    return (uint16_t)( (temp & 0x0000FFFF) + ((temp & 0xFFFF0000)>>16) );
+}
+
+/**
+ * Transport constructor.
+ * Set up the pseudo header and packet to be used in communications
+ */
+Transport::Transport (uint32_t src_addr, uint32_t dst_addr, uint32_t ID) {
+    // Set up IPv4 pseudo header for checksum calculation
+    pseudo_header_.src_addr = src_addr;
+    pseudo_header_.dst_addr = dst_addr;
+    pseudo_header_.protocol = PROTOCOL;
+    pseudo_header_.length = sizeof(header_);
+    // Set up default ports
+    header_.src_port = PORT_BASE + ID;
+    header_.dst_port = PORT_BASE;
+    header_.length = sizeof(header_);
+    // Calculate checksum of the pseudo-header: this should save some future recalculation
+    uint32_t w_checksum = chksum_u16(src_addr);
+    w_checksum = chksum_u16(dst_addr+w_checksum);
+    w_checksum = chksum_u16(pseudo_header_.protocol+w_checksum);
+    pseudo_header_.checksum = chksum_u16(pseudo_header_.length+w_checksum);
+    // Now calculate checksum of the UDP packet header + pseudo-header
+    w_checksum = chksum_u16(header_.src_port+pseudo_header_.checksum);
+    w_checksum = chksum_u16(header_.dst_port+w_checksum);
+    header_.checksum = chksum_u16(header_.length+w_checksum);
+    // Load up the packet
+    le2be_u16((packet_+0),header_.src_port);
+    le2be_u16((packet_+2),header_.dst_port);
+    le2be_u16((packet_+4),header_.length);
+    le2be_u16((packet_+6),header_.checksum);
+}
+
+/**
+ * Provides a pointer to a buffer containing a formatted packet and
+ * the total length of said packet.
+ */
+void Transport::get_packet (uint8_t** buffer, uint16_t* length) {
+    *buffer = packet_;
+    *length = header_.length;
+}
+
+/**
+ * Loads the transport packet with an array of 16bit samples.
+ * This will require translating the words into big-endian.
+ */
+void Transport::load_data (uint16_t* buffer, uint16_t length) {
+    uint8_t* pkt_ptr = packet_ + sizeof(header_);
+    for (uint16_t i=0; i<length; i++) {
+        le2be_u16(pkt_ptr,*buffer++);
+        pkt_ptr += 2;
+    }
+    // Set the header length (in octets/bytes)
+    header_.length = sizeof(header_) + (length<<1);
+    le2be_u16((packet_+4),header_.length);
+    // For now set the checksum to IGNORE
+    header_.checksum = 0x0000;
+    le2be_u16((packet_+6),header_.checksum);
+}
+
+/**
+ * Set the destination port.
+ */
+void Transport::set_dst_port (uint16_t port) {
+    // Store the port both in the local struct...
+    header_.dst_port = port;
+    // ...and in the transmission packet
+    le2be_u16((packet_+2),port);
+    //packet_[2] = (uint8_t)((port & 0xFF00) >> 8);
+    //packet_[3] = (uint8_t)(port & 0x00FF);
+}
\ No newline at end of file