| IPAddress::IPAddress() | IPAddress::IPAddress() | ||||
| { | { | ||||
| memset(_address, 0, sizeof(_address)); | |||||
| _address.dword = 0; | |||||
| } | } | ||||
| IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) | IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) | ||||
| { | { | ||||
| _address[0] = first_octet; | |||||
| _address[1] = second_octet; | |||||
| _address[2] = third_octet; | |||||
| _address[3] = fourth_octet; | |||||
| _address.bytes[0] = first_octet; | |||||
| _address.bytes[1] = second_octet; | |||||
| _address.bytes[2] = third_octet; | |||||
| _address.bytes[3] = fourth_octet; | |||||
| } | } | ||||
| IPAddress::IPAddress(uint32_t address) | IPAddress::IPAddress(uint32_t address) | ||||
| { | { | ||||
| memcpy(_address, &address, sizeof(_address)); | |||||
| _address.dword = address; | |||||
| } | } | ||||
| IPAddress::IPAddress(const uint8_t *address) | IPAddress::IPAddress(const uint8_t *address) | ||||
| { | { | ||||
| memcpy(_address, address, sizeof(_address)); | |||||
| memcpy(_address.bytes, address, sizeof(_address)); | |||||
| } | } | ||||
| IPAddress& IPAddress::operator=(const uint8_t *address) | IPAddress& IPAddress::operator=(const uint8_t *address) | ||||
| { | { | ||||
| memcpy(_address, address, sizeof(_address)); | |||||
| memcpy(_address.bytes, address, sizeof(_address.bytes)); | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| IPAddress& IPAddress::operator=(uint32_t address) | IPAddress& IPAddress::operator=(uint32_t address) | ||||
| { | { | ||||
| memcpy(_address, (const uint8_t *)&address, sizeof(_address)); | |||||
| _address.dword = address; | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| bool IPAddress::operator==(const uint8_t* addr) | bool IPAddress::operator==(const uint8_t* addr) | ||||
| { | { | ||||
| return memcmp(addr, _address, sizeof(_address)) == 0; | |||||
| return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0; | |||||
| } | } | ||||
| size_t IPAddress::printTo(Print& p) const | size_t IPAddress::printTo(Print& p) const | ||||
| { | { | ||||
| size_t n = 0; | |||||
| for (int i =0; i < 3; i++) | |||||
| { | |||||
| n += p.print(_address[i], DEC); | |||||
| n += p.print('.'); | |||||
| for (int i= 0; i < 3; i++) { | |||||
| p.print(_address.bytes[i], DEC); | |||||
| p.print('.'); | |||||
| } | } | ||||
| n += p.print(_address[3], DEC); | |||||
| return n; | |||||
| p.print(_address.bytes[3], DEC); | |||||
| return 4; | |||||
| } | } | ||||
| #endif | #endif |
| // A class to make it easier to handle and pass around IP addresses | // A class to make it easier to handle and pass around IP addresses | ||||
| class IPAddress : public Printable { | class IPAddress : public Printable { | ||||
| private: | |||||
| uint8_t _address[4]; // IPv4 address | |||||
| private: | |||||
| union { | |||||
| uint8_t bytes[4]; // IPv4 address | |||||
| uint32_t dword; | |||||
| } _address; | |||||
| // Access the raw byte array containing the address. Because this returns a pointer | // Access the raw byte array containing the address. Because this returns a pointer | ||||
| // to the internal structure rather than a copy of the address this function should only | // to the internal structure rather than a copy of the address this function should only | ||||
| // be used when you know that the usage of the returned uint8_t* will be transient and not | // be used when you know that the usage of the returned uint8_t* will be transient and not | ||||
| // stored. | // stored. | ||||
| uint8_t* raw_address() { return _address; }; | |||||
| uint8_t* raw_address() { return _address.bytes; }; | |||||
| public: | public: | ||||
| // Constructors | // Constructors | ||||
| // Overloaded cast operator to allow IPAddress objects to be used where a pointer | // Overloaded cast operator to allow IPAddress objects to be used where a pointer | ||||
| // to a four-byte uint8_t array is expected | // to a four-byte uint8_t array is expected | ||||
| operator uint32_t() { return *((uint32_t*)_address); }; | |||||
| bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); }; | |||||
| operator uint32_t() { return _address.dword; }; | |||||
| bool operator==(const IPAddress& addr) { return _address.dword == addr._address.dword; }; | |||||
| bool operator==(const uint8_t* addr); | bool operator==(const uint8_t* addr); | ||||
| // Overloaded index operator to allow getting and setting individual octets of the address | // Overloaded index operator to allow getting and setting individual octets of the address | ||||
| uint8_t operator[](int index) const { return _address[index]; }; | |||||
| uint8_t& operator[](int index) { return _address[index]; }; | |||||
| uint8_t operator[](int index) const { return _address.bytes[index]; }; | |||||
| uint8_t& operator[](int index) { return _address.bytes[index]; }; | |||||
| // Overloaded copy operators to allow initialisation of IPAddress objects from other types | // Overloaded copy operators to allow initialisation of IPAddress objects from other types | ||||
| IPAddress& operator=(const uint8_t *address); | IPAddress& operator=(const uint8_t *address); |
| { | { | ||||
| uint8_t buffer[32]; | uint8_t buffer[32]; | ||||
| size_t count = 0; | size_t count = 0; | ||||
| const char PROGMEM *p = (const char PROGMEM *)ifsh; | |||||
| const char *p = (const char *)ifsh; | |||||
| unsigned int len = strlen_P(p); | unsigned int len = strlen_P(p); | ||||
| while (len > 0) { | while (len > 0) { | ||||
| unsigned int nbytes = len; | unsigned int nbytes = len; |
| #if ARDUINO >= 100 | |||||
| #include "Arduino.h" | #include "Arduino.h" | ||||
| #include "IPAddress.h" | #include "IPAddress.h" | ||||
| IPAddress::IPAddress() | |||||
| { | |||||
| memset(_address, 0, sizeof(_address)); | |||||
| } | |||||
| IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) | |||||
| { | |||||
| _address[0] = first_octet; | |||||
| _address[1] = second_octet; | |||||
| _address[2] = third_octet; | |||||
| _address[3] = fourth_octet; | |||||
| } | |||||
| IPAddress::IPAddress(uint32_t address) | |||||
| { | |||||
| memcpy(_address, &address, sizeof(_address)); | |||||
| } | |||||
| IPAddress::IPAddress(const uint8_t *address) | |||||
| { | |||||
| memcpy(_address, address, sizeof(_address)); | |||||
| } | |||||
| IPAddress& IPAddress::operator=(const uint8_t *address) | |||||
| { | |||||
| memcpy(_address, address, sizeof(_address)); | |||||
| return *this; | |||||
| } | |||||
| IPAddress& IPAddress::operator=(uint32_t address) | |||||
| { | |||||
| memcpy(_address, (const uint8_t *)&address, sizeof(_address)); | |||||
| return *this; | |||||
| } | |||||
| bool IPAddress::operator==(const uint8_t* addr) | |||||
| { | |||||
| return memcmp(addr, _address, sizeof(_address)) == 0; | |||||
| } | |||||
| size_t IPAddress::printTo(Print& p) const | size_t IPAddress::printTo(Print& p) const | ||||
| { | { | ||||
| size_t n = 0; | |||||
| for (int i =0; i < 3; i++) | |||||
| { | |||||
| n += p.print(_address[i], DEC); | |||||
| n += p.print('.'); | |||||
| } | |||||
| n += p.print(_address[3], DEC); | |||||
| return n; | |||||
| int i=0; | |||||
| while (1) { | |||||
| p.print(_address.bytes[i], DEC); | |||||
| if (++i >= 4) return 4; | |||||
| p.write('.'); | |||||
| } | |||||
| } | } | ||||
| #endif |
| * adrianm@mcqn.com 1/1/2011 | * adrianm@mcqn.com 1/1/2011 | ||||
| */ | */ | ||||
| #if ARDUINO >= 100 | |||||
| #ifndef IPAddress_h | #ifndef IPAddress_h | ||||
| #define IPAddress_h | #define IPAddress_h | ||||
| class IPAddress : public Printable { | class IPAddress : public Printable { | ||||
| private: | private: | ||||
| uint8_t _address[4]; // IPv4 address | |||||
| // Access the raw byte array containing the address. Because this returns a pointer | |||||
| // to the internal structure rather than a copy of the address this function should only | |||||
| // be used when you know that the usage of the returned uint8_t* will be transient and not | |||||
| // stored. | |||||
| uint8_t* raw_address() { return _address; }; | |||||
| union { | |||||
| uint8_t bytes[4]; // IPv4 address | |||||
| uint32_t dword; | |||||
| } _address; | |||||
| // Access the raw byte array containing the address. Because this returns a pointer | |||||
| // to the internal structure rather than a copy of the address this function should only | |||||
| // be used when you know that the usage of the returned uint8_t* will be transient and not | |||||
| // stored. | |||||
| uint8_t * raw_address() { return _address.bytes; }; | |||||
| public: | public: | ||||
| // Constructors | |||||
| IPAddress(); | |||||
| IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); | |||||
| IPAddress(uint32_t address); | |||||
| IPAddress(const uint8_t *address); | |||||
| // Constructors | |||||
| IPAddress() { | |||||
| _address.dword = 0; | |||||
| } | |||||
| IPAddress(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) { | |||||
| _address.bytes[0] = b1; | |||||
| _address.bytes[1] = b2; | |||||
| _address.bytes[2] = b3; | |||||
| _address.bytes[3] = b4; | |||||
| } | |||||
| IPAddress(uint32_t address) { | |||||
| _address.dword = address; | |||||
| } | |||||
| IPAddress(const uint8_t *address) { | |||||
| // TODO: use unaligned read on Cortex-M4 | |||||
| _address.bytes[0] = *address++; | |||||
| _address.bytes[1] = *address++; | |||||
| _address.bytes[2] = *address++; | |||||
| _address.bytes[3] = *address++; | |||||
| } | |||||
| // Overloaded cast operator to allow IPAddress objects to be used where a pointer | |||||
| // to a four-byte uint8_t array is expected | |||||
| operator uint32_t () { return _address[0] | (_address[1] << 8) | |||||
| | (_address[2] << 16) | (_address[3] << 24); } | |||||
| bool operator==(const IPAddress& addr) { return _address[0] == addr._address[0] | |||||
| && _address[1] == addr._address[1] | |||||
| && _address[2] == addr._address[2] | |||||
| && _address[3] == addr._address[3]; } | |||||
| bool operator==(const uint8_t* addr); | |||||
| // Overloaded cast operator to allow IPAddress objects to be used where a pointer | |||||
| // to a four-byte uint8_t array is expected | |||||
| operator uint32_t () { | |||||
| return _address.dword; | |||||
| } | |||||
| bool operator==(const IPAddress& addr) { | |||||
| return _address.dword == addr._address.dword; | |||||
| } | |||||
| bool operator==(const uint8_t* addr) { | |||||
| // TODO: use unaligned read on Cortex-M4 | |||||
| return (_address.bytes[0] == addr[0] | |||||
| && _address.bytes[1] == addr[1] | |||||
| && _address.bytes[2] == addr[2] | |||||
| && _address.bytes[3] == addr[3]); | |||||
| } | |||||
| // Overloaded index operator to allow getting and setting individual octets of the address | |||||
| uint8_t operator[](int index) const { return _address[index]; }; | |||||
| uint8_t& operator[](int index) { return _address[index]; }; | |||||
| // Overloaded index operator to allow getting and setting individual octets of the address | |||||
| uint8_t operator[](int index) const { | |||||
| return _address.bytes[index]; | |||||
| }; | |||||
| uint8_t& operator[](int index) { | |||||
| return _address.bytes[index]; | |||||
| }; | |||||
| // Overloaded copy operators to allow initialisation of IPAddress objects from other types | |||||
| IPAddress& operator=(const uint8_t *address); | |||||
| IPAddress& operator=(uint32_t address); | |||||
| // Overloaded copy operators to allow initialisation of IPAddress objects from other types | |||||
| IPAddress& operator=(const uint8_t *address) { | |||||
| // TODO: use unaligned read on Cortex-M4 | |||||
| _address.bytes[0] = *address++; | |||||
| _address.bytes[1] = *address++; | |||||
| _address.bytes[2] = *address++; | |||||
| _address.bytes[3] = *address++; | |||||
| return *this; | |||||
| } | |||||
| IPAddress& operator=(uint32_t address) { | |||||
| _address.dword = address; | |||||
| return *this; | |||||
| } | |||||
| virtual size_t printTo(Print& p) const; | |||||
| virtual size_t printTo(Print& p) const; | |||||
| friend class EthernetClass; | |||||
| friend class UDP; | |||||
| friend class Client; | |||||
| friend class Server; | |||||
| friend class DhcpClass; | |||||
| friend class DNSClient; | |||||
| friend class EthernetClass; | |||||
| friend class UDP; | |||||
| friend class Client; | |||||
| friend class Server; | |||||
| friend class DhcpClass; | |||||
| friend class DNSClient; | |||||
| }; | }; | ||||
| const IPAddress INADDR_NONE(0,0,0,0); | |||||
| const IPAddress INADDR_NONE((uint32_t)0); | |||||
| #endif | #endif | ||||
| #endif |
| } | } | ||||
| transmit_previous_timeout = 0; | transmit_previous_timeout = 0; | ||||
| index = tx_packet->index; | index = tx_packet->index; | ||||
| *((uint32_t *)(tx_packet->buf) + index++) = n; | |||||
| //*((uint32_t *)(tx_packet->buf) + index++) = n; | |||||
| ((uint32_t *)(tx_packet->buf))[index++] = n; | |||||
| if (index < MIDI_TX_SIZE/4) { | if (index < MIDI_TX_SIZE/4) { | ||||
| tx_packet->index = index; | tx_packet->index = index; | ||||
| } else { | } else { | ||||
| } | } | ||||
| } | } | ||||
| index = rx_packet->index; | index = rx_packet->index; | ||||
| n = *(uint32_t *)(rx_packet->buf + index); | |||||
| //n = *(uint32_t *)(rx_packet->buf + index); | |||||
| n = ((uint32_t *)rx_packet->buf)[index/4]; | |||||
| //serial_print("midi rx, n="); | //serial_print("midi rx, n="); | ||||
| //serial_phex32(n); | //serial_phex32(n); | ||||
| //serial_print("\n"); | //serial_print("\n"); |
| uint16_t wIndex; | uint16_t wIndex; | ||||
| uint16_t wLength; | uint16_t wLength; | ||||
| uint16_t desc_val; | uint16_t desc_val; | ||||
| uint32_t baud; | |||||
| const uint8_t *desc_addr; | const uint8_t *desc_addr; | ||||
| uint8_t desc_length; | uint8_t desc_length; | ||||
| } | } | ||||
| usb_ack_out(); | usb_ack_out(); | ||||
| usb_send_in(); | usb_send_in(); | ||||
| if (*(long *)cdc_line_coding == 134L) reboot_timer = 15; | |||||
| if (*(long *)cdc_line_coding == 150L) { | |||||
| baud = (uint32_t)cdc_line_coding[0] | |||||
| | ((uint32_t)cdc_line_coding[1] << 8) | |||||
| | ((uint32_t)cdc_line_coding[2] << 16) | |||||
| | ((uint32_t)cdc_line_coding[3] << 24); | |||||
| if (baud == 134UL) reboot_timer = 15; | |||||
| if (baud == 150UL) { | |||||
| UENUM = CDC_TX_ENDPOINT; | UENUM = CDC_TX_ENDPOINT; | ||||
| while (UESTA0X & 0x03) { | while (UESTA0X & 0x03) { | ||||
| UEINTX = 0xFF; | UEINTX = 0xFF; |
| uint32_t usb_serial_class::baud(void) | uint32_t usb_serial_class::baud(void) | ||||
| { | { | ||||
| return *(uint32_t *)cdc_line_coding; | |||||
| //return *(uint32_t *)cdc_line_coding; | |||||
| return (uint32_t)cdc_line_coding[0] | |||||
| | ((uint32_t)cdc_line_coding[1] << 8) | |||||
| | ((uint32_t)cdc_line_coding[2] << 16) | |||||
| | ((uint32_t)cdc_line_coding[3] << 24); | |||||
| } | } | ||||
| uint8_t usb_serial_class::stopbits(void) | uint8_t usb_serial_class::stopbits(void) |