![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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.
comms.cpp@0:03e8a03052c9, 2010-08-27 (annotated)
- Committer:
- jimurai
- Date:
- Fri Aug 27 15:20:30 2010 +0000
- Revision:
- 0:03e8a03052c9
Who changed what in which revision?
User | Revision | Line number | New 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 | } |