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

Committer:
jimurai
Date:
Fri Aug 27 15:20:30 2010 +0000
Revision:
0:03e8a03052c9

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jimurai 0:03e8a03052c9 1 #include "mbed.h"
jimurai 0:03e8a03052c9 2 #include "comms.h"
jimurai 0:03e8a03052c9 3
jimurai 0:03e8a03052c9 4 void le2be_u16(uint8_t* buffer, uint16_t in_word) {
jimurai 0:03e8a03052c9 5 *buffer++ = (uint8_t)((in_word & 0xFF00) >> 8);
jimurai 0:03e8a03052c9 6 *buffer = (uint8_t)(in_word & 0x00FF);
jimurai 0:03e8a03052c9 7 }
jimurai 0:03e8a03052c9 8
jimurai 0:03e8a03052c9 9 /**
jimurai 0:03e8a03052c9 10 * This function is used to calculate a one's complement based checksum
jimurai 0:03e8a03052c9 11 * as is commonly used in IP based protocols
jimurai 0:03e8a03052c9 12 */
jimurai 0:03e8a03052c9 13 uint16_t chksum_u16(uint32_t in_word) {
jimurai 0:03e8a03052c9 14 uint32_t temp = in_word & 0x0000FFFF;
jimurai 0:03e8a03052c9 15 temp += (in_word & 0xFFFF0000)>>16;
jimurai 0:03e8a03052c9 16 return (uint16_t)( (temp & 0x0000FFFF) + ((temp & 0xFFFF0000)>>16) );
jimurai 0:03e8a03052c9 17 }
jimurai 0:03e8a03052c9 18
jimurai 0:03e8a03052c9 19 /**
jimurai 0:03e8a03052c9 20 * Transport constructor.
jimurai 0:03e8a03052c9 21 * Set up the pseudo header and packet to be used in communications
jimurai 0:03e8a03052c9 22 */
jimurai 0:03e8a03052c9 23 Transport::Transport (uint32_t src_addr, uint32_t dst_addr, uint32_t ID) {
jimurai 0:03e8a03052c9 24 // Set up IPv4 pseudo header for checksum calculation
jimurai 0:03e8a03052c9 25 pseudo_header_.src_addr = src_addr;
jimurai 0:03e8a03052c9 26 pseudo_header_.dst_addr = dst_addr;
jimurai 0:03e8a03052c9 27 pseudo_header_.protocol = PROTOCOL;
jimurai 0:03e8a03052c9 28 pseudo_header_.length = sizeof(header_);
jimurai 0:03e8a03052c9 29 // Set up default ports
jimurai 0:03e8a03052c9 30 header_.src_port = PORT_BASE + ID;
jimurai 0:03e8a03052c9 31 header_.dst_port = PORT_BASE;
jimurai 0:03e8a03052c9 32 header_.length = sizeof(header_);
jimurai 0:03e8a03052c9 33 // Calculate checksum of the pseudo-header: this should save some future recalculation
jimurai 0:03e8a03052c9 34 uint32_t w_checksum = chksum_u16(src_addr);
jimurai 0:03e8a03052c9 35 w_checksum = chksum_u16(dst_addr+w_checksum);
jimurai 0:03e8a03052c9 36 w_checksum = chksum_u16(pseudo_header_.protocol+w_checksum);
jimurai 0:03e8a03052c9 37 pseudo_header_.checksum = chksum_u16(pseudo_header_.length+w_checksum);
jimurai 0:03e8a03052c9 38 // Now calculate checksum of the UDP packet header + pseudo-header
jimurai 0:03e8a03052c9 39 w_checksum = chksum_u16(header_.src_port+pseudo_header_.checksum);
jimurai 0:03e8a03052c9 40 w_checksum = chksum_u16(header_.dst_port+w_checksum);
jimurai 0:03e8a03052c9 41 header_.checksum = chksum_u16(header_.length+w_checksum);
jimurai 0:03e8a03052c9 42 // Load up the packet
jimurai 0:03e8a03052c9 43 le2be_u16((packet_+0),header_.src_port);
jimurai 0:03e8a03052c9 44 le2be_u16((packet_+2),header_.dst_port);
jimurai 0:03e8a03052c9 45 le2be_u16((packet_+4),header_.length);
jimurai 0:03e8a03052c9 46 le2be_u16((packet_+6),header_.checksum);
jimurai 0:03e8a03052c9 47 }
jimurai 0:03e8a03052c9 48
jimurai 0:03e8a03052c9 49 /**
jimurai 0:03e8a03052c9 50 * Provides a pointer to a buffer containing a formatted packet and
jimurai 0:03e8a03052c9 51 * the total length of said packet.
jimurai 0:03e8a03052c9 52 */
jimurai 0:03e8a03052c9 53 void Transport::get_packet (uint8_t** buffer, uint16_t* length) {
jimurai 0:03e8a03052c9 54 *buffer = packet_;
jimurai 0:03e8a03052c9 55 *length = header_.length;
jimurai 0:03e8a03052c9 56 }
jimurai 0:03e8a03052c9 57
jimurai 0:03e8a03052c9 58 /**
jimurai 0:03e8a03052c9 59 * Loads the transport packet with an array of 16bit samples.
jimurai 0:03e8a03052c9 60 * This will require translating the words into big-endian.
jimurai 0:03e8a03052c9 61 */
jimurai 0:03e8a03052c9 62 void Transport::load_data (uint16_t* buffer, uint16_t length) {
jimurai 0:03e8a03052c9 63 uint8_t* pkt_ptr = packet_ + sizeof(header_);
jimurai 0:03e8a03052c9 64 for (uint16_t i=0; i<length; i++) {
jimurai 0:03e8a03052c9 65 le2be_u16(pkt_ptr,*buffer++);
jimurai 0:03e8a03052c9 66 pkt_ptr += 2;
jimurai 0:03e8a03052c9 67 }
jimurai 0:03e8a03052c9 68 // Set the header length (in octets/bytes)
jimurai 0:03e8a03052c9 69 header_.length = sizeof(header_) + (length<<1);
jimurai 0:03e8a03052c9 70 le2be_u16((packet_+4),header_.length);
jimurai 0:03e8a03052c9 71 // For now set the checksum to IGNORE
jimurai 0:03e8a03052c9 72 header_.checksum = 0x0000;
jimurai 0:03e8a03052c9 73 le2be_u16((packet_+6),header_.checksum);
jimurai 0:03e8a03052c9 74 }
jimurai 0:03e8a03052c9 75
jimurai 0:03e8a03052c9 76 /**
jimurai 0:03e8a03052c9 77 * Set the destination port.
jimurai 0:03e8a03052c9 78 */
jimurai 0:03e8a03052c9 79 void Transport::set_dst_port (uint16_t port) {
jimurai 0:03e8a03052c9 80 // Store the port both in the local struct...
jimurai 0:03e8a03052c9 81 header_.dst_port = port;
jimurai 0:03e8a03052c9 82 // ...and in the transmission packet
jimurai 0:03e8a03052c9 83 le2be_u16((packet_+2),port);
jimurai 0:03e8a03052c9 84 //packet_[2] = (uint8_t)((port & 0xFF00) >> 8);
jimurai 0:03e8a03052c9 85 //packet_[3] = (uint8_t)(port & 0x00FF);
jimurai 0:03e8a03052c9 86 }