From c6cd7a4b72a4a05405694e6eebb3e015aae464ec Mon Sep 17 00:00:00 2001 From: Luc Date: Wed, 14 Apr 2021 11:40:51 +0200 Subject: [PATCH] Add PIO support --- .gitignore | 2 + PIOPatches/USBCore.cpp | 900 +++++++++++++++++++++++++++++++++++++++++ PIOPatches/variant.cpp | 497 +++++++++++++++++++++++ apply_patches.py | 29 ++ platformio.ini | 36 ++ 5 files changed, 1464 insertions(+) create mode 100644 PIOPatches/USBCore.cpp create mode 100644 PIOPatches/variant.cpp create mode 100644 apply_patches.py create mode 100644 platformio.ini diff --git a/.gitignore b/.gitignore index a26923b..7ce5e0f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ Repetier.depend Repetier.layout activate*.bat ~$Translate.xlsx +.vscode +.pioenvs diff --git a/PIOPatches/USBCore.cpp b/PIOPatches/USBCore.cpp new file mode 100644 index 0000000..615bd64 --- /dev/null +++ b/PIOPatches/USBCore.cpp @@ -0,0 +1,900 @@ +// Copyright (c) 2010, Peter Barrett +/* +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "Arduino.h" +#include "USBAPI.h" +#include "Reset.h" +#include +#include "PluggableUSB.h" +#include + +//#define TRACE_CORE(x) x +#define TRACE_CORE(x) + +uint32_t EndPoints[] = +{ + EP_TYPE_CONTROL, + +#ifdef CDC_ENABLED + EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM + EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT + EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN +#endif + +#ifdef PLUGGABLE_USB_ENABLED + //allocate 6 endpoints and remove const so they can be changed by the user + 0, + 0, + 0, + 0, + 0, + 0, +#endif +}; + +/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ +#define TX_RX_LED_PULSE_MS 100 +volatile uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ +volatile uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */ +static char isRemoteWakeUpEnabled = 0; +static char isEndpointHalt = 0; +//================================================================== +//================================================================== + +extern const uint16_t STRING_LANGUAGE[]; +extern const uint8_t STRING_PRODUCT[]; +extern const uint8_t STRING_MANUFACTURER[]; +extern const DeviceDescriptor USB_DeviceDescriptor; +extern const DeviceDescriptor USB_DeviceDescriptorA; + +const uint16_t STRING_LANGUAGE[2] = { + (3<<8) | (2+2), + 0x0409 // English +}; + +#ifndef USB_PRODUCT +#define USB_PRODUCT "Arduino Due" +#endif + +const uint8_t STRING_PRODUCT[] = USB_PRODUCT; + +#ifndef USB_MANUFACTURER +#define USB_MANUFACTURER "Arduino LLC" +#endif + +const uint8_t STRING_MANUFACTURER[] = USB_MANUFACTURER; + +#ifdef CDC_ENABLED +#define DEVICE_CLASS 0x02 +#else +#define DEVICE_CLASS 0x00 +#endif + +// DEVICE DESCRIPTOR +const DeviceDescriptor USB_DeviceDescriptor = + D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1); + +const DeviceDescriptor USB_DeviceDescriptorA = + D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1); + +const QualifierDescriptor USB_DeviceQualifier = + D_QUALIFIER(0x00,0x00,0x00,64,1); + +//! 7.1.20 Test Mode Support +static const unsigned char test_packet_buffer[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // JKJKJKJK * 9 + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, // JJKKJJKK * 8 + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, // JJJJKKKK * 8 + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // JJJJJJJKKKKKKK * 8 + 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD, // JJJJJJJK * 8 + 0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E // {JKKKKKKK * 10}, JK +}; + +//================================================================== +//================================================================== + +volatile uint32_t _usbConfiguration = 0; +volatile uint32_t _usbInitialized = 0; +uint32_t _usbSetInterface = 0; +uint32_t _cdcComposite = 0; + +//================================================================== +//================================================================== + +#define USB_RECV_TIMEOUT +class LockEP +{ + irqflags_t flags; +public: + LockEP(uint32_t ep __attribute__ ((unused))) : flags(cpu_irq_save()) + { + } + ~LockEP() + { + cpu_irq_restore(flags); + } +}; + +// Number of bytes, assumes a rx endpoint +uint32_t USBD_Available(uint32_t ep) +{ + LockEP lock(ep); + return UDD_FifoByteCount(ep & 0xF); +} + +// Non Blocking receive +// Return number of bytes read +uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len) +{ + if (!_usbConfiguration) + return -1; + + LockEP lock(ep); + uint32_t n = UDD_FifoByteCount(ep & 0xF); + len = min(n,len); + n = len; + uint8_t* dst = (uint8_t*)d; + while (n--) + *dst++ = UDD_Recv8(ep & 0xF); + if (len && !UDD_FifoByteCount(ep & 0xF)) // release empty buffer + UDD_ReleaseRX(ep & 0xF); + + return len; +} + +// Recv 1 byte if ready +uint32_t USBD_Recv(uint32_t ep) +{ + uint8_t c; + if (USBD_Recv(ep & 0xF, &c, 1) != 1) + return -1; + else + return c; +} + +// Space in send EP +//uint32_t USBD_SendSpace(uint32_t ep) +//{ + //LockEP lock(ep); +//// if (!UDD_ReadWriteAllowed(ep & 0xF)) + ////{ + ////printf("pb "); // UOTGHS->UOTGHS_DEVEPTISR[%d]=0x%X\n\r", ep, UOTGHS->UOTGHS_DEVEPTISR[ep]); + ////return 0; + ////} + + //if(ep==0) return 64 - UDD_FifoByteCount(ep & 0xF); // EP0_SIZE jcb + //else return 512 - UDD_FifoByteCount(ep & 0xF); // EPX_SIZE jcb +//} + +// Blocking Send of data to an endpoint +uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len) +{ + uint32_t n; + int r = len; + const uint8_t* data = (const uint8_t*)d; + + if (!_usbConfiguration) + { + TRACE_CORE(printf("pb conf\n\r");) + return -1; + } + + while (len) + { + if(ep==0) n = EP0_SIZE; + else n = EPX_SIZE; + if (n > len) + n = len; + len -= n; +//USB PATCH to avoid dead loop + int count=0; + while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[ep & 0xF] & UOTGHS_DEVEPTISR_TXINI )) + { + count++; + if (count>10000) return len; + } + UDD_Send(ep & 0xF, data, n); + data += n; + } + //TXLED1; // light the TX LED + //TxLEDPulse = TX_RX_LED_PULSE_MS; + return r; +} + +uint16_t _cmark; +uint16_t _cend; + +void USBD_InitControl(int end) +{ + _cmark = 0; + _cend = end; +} + +// Clipped by _cmark/_cend +int USBD_SendControl(uint8_t flags __attribute__ ((unused)), const void* d, uint32_t len) +{ + const uint8_t* data = (const uint8_t*)d; + uint32_t length = len; + uint32_t sent = 0; + uint32_t pos = 0; + + TRACE_CORE(printf("=> USBD_SendControl TOTAL len=%lu\r\n", len);) + + if (_cmark < _cend) + { + while (len > 0) + { + sent = UDD_Send(EP0, data + pos, len); + TRACE_CORE(printf("=> USBD_SendControl sent=%lu\r\n", sent);) + pos += sent; + len -= sent; + } + } + + _cmark += length; + + return length; +} + +// Send a USB descriptor string. The string is stored as a +// plain ASCII string but is sent out as UTF-16 with the +// correct 2-byte prefix +static bool USB_SendStringDescriptor(const uint8_t *string, int wLength) { + if (wLength < 2) + return false; + + uint8_t buffer[wLength]; + buffer[0] = strlen((const char*)string) * 2 + 2; + buffer[1] = 0x03; + + uint8_t i; + for (i = 2; i < wLength && *string; i++) { + buffer[i++] = *string++; + if (i == wLength) break; + buffer[i] = 0; + } + + return USBD_SendControl(0, (uint8_t*)buffer, i); +} + +// Does not timeout or cross fifo boundaries +// Will only work for transfers <= 64 bytes +// TODO +int USBD_RecvControl(void* d, uint32_t len) +{ + UDD_WaitOUT(); + UDD_Recv(EP0, (uint8_t*)d, len); + UDD_ClearOUT(); + + return len; +} + +// Handle CLASS_INTERFACE requests +bool USBD_ClassInterfaceRequest(USBSetup& setup) +{ + uint8_t i = setup.wIndex; + + TRACE_CORE(printf("=> USBD_ClassInterfaceRequest\r\n");) + +#ifdef CDC_ENABLED + if (CDC_ACM_INTERFACE == i) + { + return CDC_Setup(setup); + } +#endif + +#ifdef PLUGGABLE_USB_ENABLED + return PluggableUSB().setup(setup); +#endif + + return false; +} + +uint8_t USBD_SendInterfaces(void) +{ + uint8_t interfaces = 0; + +#ifdef CDC_ENABLED + CDC_GetInterface(&interfaces); +#endif + +#ifdef PLUGGABLE_USB_ENABLED + PluggableUSB().getInterface(&interfaces); +#endif + + TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);) + return interfaces; +} + +uint8_t USBD_SendOtherInterfaces(void) +{ + uint8_t interfaces = 0; + +#ifdef CDC_ENABLED + CDC_GetOtherInterface(&interfaces); +#endif + +#ifdef PLUGGABLE_USB_ENABLED + PluggableUSB().getInterface(&interfaces); +#endif + + TRACE_CORE(printf("=> USBD_SendInterfaces, interfaces=%d\r\n", interfaces);) + return interfaces; +} + +// Construct a dynamic configuration descriptor +// This really needs dynamic endpoint allocation etc +// TODO +static bool USBD_SendConfiguration(int maxlen) +{ + // Count and measure interfaces + USBD_InitControl(0); + //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);) + uint8_t interfaces = USBD_SendInterfaces(); + //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);) + //TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));) + +_Pragma("pack(1)") + ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); +_Pragma("pack()") + //TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);) + + //TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);) + + // Now send them + USBD_InitControl(maxlen); + USBD_SendControl(0,&config,sizeof(ConfigDescriptor)); + USBD_SendInterfaces(); + return true; +} + +static bool USBD_SendOtherConfiguration(int maxlen) +{ + // Count and measure interfaces + USBD_InitControl(0); + //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);) + uint8_t interfaces = USBD_SendOtherInterfaces(); + //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);) + //TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));) + +_Pragma("pack(1)") + ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); +_Pragma("pack()") + //TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);) + + //TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);) + + // Now send them + USBD_InitControl(maxlen); + USBD_SendControl(0,&config,sizeof(ConfigDescriptor)); + USBD_SendOtherInterfaces(); + return true; +} + +static bool USBD_SendDescriptor(USBSetup& setup) +{ + uint8_t t = setup.wValueH; + uint8_t desc_length = 0; + int ret = 0; + const uint8_t* desc_addr = 0; + + if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) + { + TRACE_CORE(printf("=> USBD_SendDescriptor : USB_CONFIGURATION_DESCRIPTOR_TYPE length=%d\r\n", setup.wLength);) + return USBD_SendConfiguration(setup.wLength); + } + + USBD_InitControl(setup.wLength); + +#ifdef PLUGGABLE_USB_ENABLED + ret = PluggableUSB().getDescriptor(setup); + if (ret != 0) { + return (ret > 0 ? true : false); + } +#endif + + if (USB_DEVICE_DESCRIPTOR_TYPE == t) + { + TRACE_CORE(puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n");) + if (setup.wLength == 8) + { + _cdcComposite = 1; + } + desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor; + if( *desc_addr > setup.wLength ) { + desc_length = setup.wLength; + } + } + else if (USB_STRING_DESCRIPTOR_TYPE == t) + { + TRACE_CORE(puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n");) + if (setup.wValueL == 0) { + desc_addr = (const uint8_t*)&STRING_LANGUAGE; + } + else if (setup.wValueL == IPRODUCT) { + return USB_SendStringDescriptor(STRING_PRODUCT, setup.wLength); + } + else if (setup.wValueL == IMANUFACTURER) { + return USB_SendStringDescriptor(STRING_MANUFACTURER, setup.wLength); + } + else if (setup.wValueL == ISERIAL) { +#ifdef PLUGGABLE_USB_ENABLED + char name[ISERIAL_MAX_LEN]; + PluggableUSB().getShortName(name); + return USB_SendStringDescriptor((uint8_t*)name, setup.wLength); +#endif + } + else { + return false; + } + if( *desc_addr > setup.wLength ) { + desc_length = setup.wLength; + } + } + else if (USB_DEVICE_QUALIFIER == t) + { + // Device qualifier descriptor requested + desc_addr = (const uint8_t*)&USB_DeviceQualifier; + if( *desc_addr > setup.wLength ) { + desc_length = setup.wLength; + } + } + else if (USB_OTHER_SPEED_CONFIGURATION == t) + { + // Other configuration descriptor requested + return USBD_SendOtherConfiguration(setup.wLength); + } + else + { + //printf("Device ERROR"); + } + + if (desc_addr == 0) + { + return false; + } + + if (desc_length == 0) + { + desc_length = *desc_addr; + } + + TRACE_CORE(printf("=> USBD_SendDescriptor : desc_addr=%p desc_length=%d\r\n", desc_addr, desc_length);) + USBD_SendControl(0, desc_addr, desc_length); + + return true; +} + + +static void USB_SendZlp( void ) +{ + while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[0] & UOTGHS_DEVEPTISR_TXINI ) ) + { + if((UOTGHS->UOTGHS_DEVISR & UOTGHS_DEVISR_SUSP) == UOTGHS_DEVISR_SUSP) + { + return; + } + } + UOTGHS->UOTGHS_DEVEPTICR[0] = UOTGHS_DEVEPTICR_TXINIC; +} + + +static void Test_Mode_Support( uint8_t wIndex ) +{ + uint8_t i; + uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(2); + + switch( wIndex ) + { + case 4: + //Test mode Test_Packet: + //Upon command, a port must repetitively transmit the following test packet until + //the exit action is taken. This enables the testing of rise and fall times, eye + //patterns, jitter, and any other dynamic waveform specifications. + //The test packet is made up by concatenating the following strings. + //(Note: For J/K NRZI data, and for NRZ data, the bit on the left is the first one + //transmitted. "S" indicates that a bit stuff occurs, which inserts an "extra" NRZI data bit. + //"* N" is used to indicate N occurrences of a string of bits or symbols.) + //A port in Test_Packet mode must send this packet repetitively. The inter-packet timing + //must be no less than the minimum allowable inter-packet gap as defined in Section 7.1.18 and + //no greater than 125 us. + + // Send ZLP + USB_SendZlp(); + + UOTGHS->UOTGHS_DEVDMA[0].UOTGHS_DEVDMACONTROL = 0; // raz + UOTGHS->UOTGHS_DEVDMA[1].UOTGHS_DEVDMACONTROL = 0; // raz + + // Configure endpoint 2, 64 bytes, direction IN, type BULK, 1 bank + UOTGHS->UOTGHS_DEVEPTCFG[2] = UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE + | UOTGHS_DEVEPTCFG_EPDIR_IN + | UOTGHS_DEVEPTCFG_EPTYPE_BLK + | UOTGHS_DEVEPTCFG_EPBK_1_BANK; + // Check if the configuration is ok + UOTGHS->UOTGHS_DEVEPTCFG[2] |= UOTGHS_DEVEPTCFG_ALLOC; + while((UOTGHS->UOTGHS_DEVEPTISR[2]&UOTGHS_DEVEPTISR_CFGOK)==0) {} + UOTGHS->UOTGHS_DEVEPT |= UOTGHS_DEVEPT_EPEN2; + // Write FIFO + for( i=0; iUOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTPCKT; + // Send packet + UOTGHS->UOTGHS_DEVEPTICR[2] = UOTGHS_DEVEPTICR_TXINIC; + UOTGHS->UOTGHS_DEVEPTIDR[2] = UOTGHS_DEVEPTIDR_FIFOCONC; + for(;;); +// break; + + case 1: + //Test mode Test_J: + //Upon command, a port's transceiver must enter the high-speed J state and remain in that + //state until the exit action is taken. This enables the testing of the high output drive + //level on the D+ line. + // Send a ZLP + USB_SendZlp(); + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTJ; + for(;;); +// break; + + case 2: + //Test mode Test_K: + //Upon command, a port's transceiver must enter the high-speed K state and remain in + //that state until the exit action is taken. This enables the testing of the high output drive + //level on the D- line. + // Send a ZLP + USB_SendZlp(); + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTK; + for(;;); +// break; + + case 3: + //Test mode Test_SE0_NAK: + //Upon command, a port's transceiver must enter the high-speed receive mode + //and remain in that mode until the exit action is taken. This enables the testing + //of output impedance, low level output voltage, and loading characteristics. + //In addition, while in this mode, upstream facing ports (and only upstream facing ports) + //must respond to any IN token packet with a NAK handshake (only if the packet CRC is + //determined to be correct) within the normal allowed device response time. This enables testing of + //the device squelch level circuitry and, additionally, provides a general purpose stimulus/response + //test for basic functional testing. + + // Send a ZLP + USB_SendZlp(); + UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC + | UOTGHS_DEVIDR_MSOFEC + | UOTGHS_DEVIDR_SOFEC + | UOTGHS_DEVIDR_EORSTEC + | UOTGHS_DEVIDR_WAKEUPEC + | UOTGHS_DEVIDR_EORSMEC + | UOTGHS_DEVIDR_UPRSMEC + | UOTGHS_DEVIDR_PEP_0 + | UOTGHS_DEVIDR_PEP_1 + | UOTGHS_DEVIDR_PEP_2 + | UOTGHS_DEVIDR_PEP_3 + | UOTGHS_DEVIDR_PEP_4 + | UOTGHS_DEVIDR_PEP_5 + | UOTGHS_DEVIDR_PEP_6 + | UOTGHS_DEVIDR_DMA_1 + | UOTGHS_DEVIDR_DMA_2 + | UOTGHS_DEVIDR_DMA_3 + | UOTGHS_DEVIDR_DMA_4 + | UOTGHS_DEVIDR_DMA_5 + | UOTGHS_DEVIDR_DMA_6; + for(;;); +// break; + } +} + + +//unsigned int iii=0; +// Endpoint 0 interrupt +static void USB_ISR(void) +{ +// printf("ISR=0x%X\n\r", UOTGHS->UOTGHS_DEVISR); // jcb +// if( iii++ > 1500 ) while(1); // jcb + // End of bus reset + if (Is_udd_reset()) + { + TRACE_CORE(printf(">>> End of Reset\r\n");) + + // Reset USB address to 0 + udd_configure_address(0); + udd_enable_address(); + + // Configure EP 0 + UDD_InitEP(0, EP_TYPE_CONTROL); + udd_enable_setup_received_interrupt(0); + udd_enable_endpoint_interrupt(0); + + _usbConfiguration = 0; + udd_ack_reset(); + } + +#ifdef CDC_ENABLED + if (Is_udd_endpoint_interrupt(CDC_RX)) + { + udd_ack_out_received(CDC_RX); + + // Handle received bytes + if (USBD_Available(CDC_RX)) + SerialUSB.accept(); + } + + if (Is_udd_sof()) + { + udd_ack_sof(); + // USBD_Flush(CDC_TX); // jcb + } +#endif + + // EP 0 Interrupt + if (Is_udd_endpoint_interrupt(0) ) + { + if (!UDD_ReceivedSetupInt()) + { + return; + } + + USBSetup setup; + UDD_Recv(EP0, (uint8_t*)&setup, 8); + UDD_ClearSetupInt(); + + uint8_t requestType = setup.bmRequestType; + if (requestType & REQUEST_DEVICETOHOST) + { + TRACE_CORE(puts(">>> EP0 Int: IN Request\r\n");) + UDD_WaitIN(); + } + else + { + TRACE_CORE(puts(">>> EP0 Int: OUT Request\r\n");) + UDD_ClearIN(); + } + + bool ok = true; + if (REQUEST_STANDARD == (requestType & REQUEST_TYPE)) + { + // Standard Requests + uint8_t r = setup.bRequest; + if (GET_STATUS == r) + { + if( setup.bmRequestType == 0 ) // device + { + // Send the device status + TRACE_CORE(puts(">>> EP0 Int: GET_STATUS\r\n");) + // Check current configuration for power mode (if device is configured) + // TODO + // Check if remote wake-up is enabled + // TODO + UDD_Send8(EP0, 0); // TODO + UDD_Send8(EP0, 0); + } + // if( setup.bmRequestType == 2 ) // Endpoint: + else + { + // Send the endpoint status + // Check if the endpoint if currently halted + if( isEndpointHalt == 1 ) + UDD_Send8(EP0, 1); // TODO + else + UDD_Send8(EP0, 0); // TODO + UDD_Send8(EP0, 0); + } + } + else if (CLEAR_FEATURE == r) + { + // Check which is the selected feature + if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP + { + // Enable remote wake-up and send a ZLP + if( isRemoteWakeUpEnabled == 1 ) + UDD_Send8(EP0, 1); + else + UDD_Send8(EP0, 0); + UDD_Send8(EP0, 0); + } + else // if( setup.wValueL == 0) // ENDPOINTHALT + { + isEndpointHalt = 0; // TODO + UDD_Send8(EP0, 0); + UDD_Send8(EP0, 0); + } + + } + else if (SET_FEATURE == r) + { + // Check which is the selected feature + if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP + { + // Enable remote wake-up and send a ZLP + isRemoteWakeUpEnabled = 1; + UDD_Send8(EP0, 0); + } + if( setup.wValueL == 0) // ENDPOINTHALT + { + // Halt endpoint + isEndpointHalt = 1; + //USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest)); + UDD_Send8(EP0, 0); + } + if( setup.wValueL == 2) // TEST_MODE + { + // 7.1.20 Test Mode Support, 9.4.9 SetFeature + if( (setup.bmRequestType == 0 /*USBGenericRequest_DEVICE*/) && + ((setup.wIndex & 0x000F) == 0) ) + { + // the lower byte of wIndex must be zero + // the most significant byte of wIndex is used to specify the specific test mode + + UOTGHS->UOTGHS_DEVIDR &= ~UOTGHS_DEVIDR_SUSPEC; + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; // remove suspend ? + + Test_Mode_Support( (setup.wIndex & 0xFF00)>>8 ); + } + } + } + else if (SET_ADDRESS == r) + { + TRACE_CORE(puts(">>> EP0 Int: SET_ADDRESS\r\n");) + UDD_WaitIN(); + UDD_SetAddress(setup.wValueL); + } + else if (GET_DESCRIPTOR == r) + { + TRACE_CORE(puts(">>> EP0 Int: GET_DESCRIPTOR\r\n");) + ok = USBD_SendDescriptor(setup); + } + else if (SET_DESCRIPTOR == r) + { + TRACE_CORE(puts(">>> EP0 Int: SET_DESCRIPTOR\r\n");) + ok = false; + } + else if (GET_CONFIGURATION == r) + { + TRACE_CORE(puts(">>> EP0 Int: GET_CONFIGURATION\r\n");) + UDD_Send8(EP0, _usbConfiguration); + } + else if (SET_CONFIGURATION == r) + { + if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT)) + { + TRACE_CORE(printf(">>> EP0 Int: SET_CONFIGURATION REQUEST_DEVICE %d\r\n", setup.wValueL);) + + uint32_t num_endpoints = 0; + while (EndPoints[num_endpoints] != 0) { + num_endpoints++; + } + UDD_InitEndpoints(EndPoints, num_endpoints); + _usbConfiguration = setup.wValueL; + +#ifdef CDC_ENABLED + // Enable interrupt for CDC reception from host (OUT packet) + udd_enable_out_received_interrupt(CDC_RX); + udd_enable_endpoint_interrupt(CDC_RX); +#endif + } + else + { + TRACE_CORE(puts(">>> EP0 Int: SET_CONFIGURATION failed!\r\n");) + ok = false; + } + } + else if (GET_INTERFACE == r) + { + TRACE_CORE(puts(">>> EP0 Int: GET_INTERFACE\r\n");) + UDD_Send8(EP0, _usbSetInterface); + } + else if (SET_INTERFACE == r) + { + _usbSetInterface = setup.wValueL; + TRACE_CORE(puts(">>> EP0 Int: SET_INTERFACE\r\n");) + } + } + else + { + TRACE_CORE(puts(">>> EP0 Int: ClassInterfaceRequest\r\n");) + + UDD_WaitIN(); // Workaround: need tempo here, else CDC serial won't open correctly + + USBD_InitControl(setup.wLength); // Max length of transfer + ok = USBD_ClassInterfaceRequest(setup); + } + + if (ok) + { + TRACE_CORE(puts(">>> EP0 Int: Send packet\r\n");) + UDD_ClearIN(); + } + else + { + TRACE_CORE(puts(">>> EP0 Int: Stall\r\n");) + UDD_Stall(); + } + } +} + +void USBD_Flush(uint32_t ep) +{ + if (UDD_FifoByteCount(ep)) + UDD_ReleaseTX(ep); +} + +// VBUS or counting frames +// Any frame counting? +uint32_t USBD_Connected(void) +{ + uint8_t f = UDD_GetFrameNumber(); + + delay(3); + + return f != UDD_GetFrameNumber(); +} + + +//======================================================================= +//======================================================================= + +USBDevice_ USBDevice; + +USBDevice_::USBDevice_() +{ + UDD_SetStack(&USB_ISR); + + if (UDD_Init() == 0UL) + { + _usbInitialized=1UL; + } +} + +bool USBDevice_::attach(void) +{ + if (_usbInitialized != 0UL) + { + UDD_Attach(); + _usbConfiguration = 0; + return true; + } + else + { + return false; + } +} + +bool USBDevice_::detach(void) +{ + if (_usbInitialized != 0UL) + { + UDD_Detach(); + return true; + } + else + { + return false; + } +} + +// Check for interrupts +// TODO: VBUS detection +bool USBDevice_::configured() +{ + return _usbConfiguration; +} + +void USBDevice_::poll() +{ +} diff --git a/PIOPatches/variant.cpp b/PIOPatches/variant.cpp new file mode 100644 index 0000000..3065366 --- /dev/null +++ b/PIOPatches/variant.cpp @@ -0,0 +1,497 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" +//For Davinci Printer +/* + * DUE Board pin | PORT | Label + * ----------------+--------+------- + * 0 | PA8 | "RX0" + * 1 | PA9 | "TX0" + * 2 TIOA0 | PB25 | + * 3 TIOA7 | PC28 | + * 4 NPCS1 | PA29 | + * TIOB6 | PC26 | + * 5 TIOA6 | PC25 | + * 6 PWML7 | PC24 | + * 7 PWML6 | PC23 | + * 8 PWML5 | PC22 | + * 9 PWML4 | PC21 | + * 10 NPCS0 | PA28 | + * TIOB7 | PC29 | + * 11 TIOA8 | PD7 | + * 12 TIOB8 | PD8 | + * 13 TIOB0 | PB27 | LED AMBER "L" + * 14 TXD3 | PD4 | "TX3" + * 15 RXD3 | PD5 | "RX3" + * 16 TXD1 | PA13 | "TX2" + * 17 RXD1 | PA12 | "RX2" + * 18 TXD0 | PA11 | "TX1" + * 19 RXD0 | PA10 | "RX1" + * 20 | PB12 | "SDA" + * 21 | PB13 | "SCL" + * 22 | PB26 | + * 23 | PA14 | + * 24 | PA15 | + * 25 | PD0 | + * 26 | PD1 | + * 27 | PD2 | + * 28 | PD3 | + * 29 | PD6 | + * 30 | PD9 | + * 31 | PA7 | + * 32 | PD10 | + * 33 | PC1 | + * 34 | PC2 | + * 35 | PC3 | + * 36 | PC4 | + * 37 | PC5 | + * 38 | PC6 | + * 39 | PC7 | + * 40 | PC8 | + * 41 | PC9 | + * 42 | PA19 | + * 43 | PA20 | + * 44 | PC19 | + * 45 | PC18 | + * 46 | PC17 | + * 47 | PC16 | + * 48 | PC15 | + * 49 | PC14 | + * 50 | PC13 | + * 51 | PC12 | + * 52 NPCS2 | PB21 | + * 53 | PB14 | + * 54 | PA16 | "A0" + * 55 | PA24 | "A1" + * 56 | PA23 | "A2" + * 57 | PA22 | "A3" + * 58 TIOB2 | PA6 | "A4" + * 69 | PA4 | "A5" + * 60 TIOB1 | PA3 | "A6" + * 61 TIOA1 | PA2 | "A7" + * 62 | PB17 | "A8" + * 63 | PB18 | "A9" + * 64 | PB19 | "A10" + * 65 | PB20 | "A11" + * 66 | PB15 | "DAC0" + * 67 | PB16 | "DAC1" + * 68 | PA1 | "CANRX" + * 69 | PA0 | "CANTX" + * 70 | PA17 | "SDA1" + * 71 | PA18 | "SCL1" + * 72 | PC30 | LED AMBER "RX" + * 73 | PA21 | LED AMBER "TX" + * 74 MISO | PA25 | + * 75 MOSI | PA26 | + * 76 SCLK | PA27 | + * 77 NPCS0 | PA28 | + * 78 NPCS3 | PB23 | unconnected! + * + * USB pin | PORT + * ----------------+-------- + * ID | PB11 + * VBOF | PB10 + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Pins descriptions + */ +extern const PinDescription g_APinDescription[]= +{ + // 0 .. 53 - Digital pins + // ---------------------- + // 0/1 - UART (Serial) + { PIOA, PIO_PA8A_URXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // URXD + { PIOA, PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // UTXD + + // 2 + { PIOB, PIO_PB25B_TIOA0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHA0 }, // TIOA0 + { PIOC, PIO_PC28B_TIOA7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA7 }, // TIOA7 + { PIOC, PIO_PC26B_TIOB6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB6 }, // TIOB6 + + // 5 + { PIOC, PIO_PC25B_TIOA6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA6 }, // TIOA6 + { PIOC, PIO_PC24B_PWML7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH7, NOT_ON_TIMER }, // PWML7 + { PIOC, PIO_PC23B_PWML6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH6, NOT_ON_TIMER }, // PWML6 + { PIOC, PIO_PC22B_PWML5, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH5, NOT_ON_TIMER }, // PWML5 + { PIOC, PIO_PC21B_PWML4, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH4, NOT_ON_TIMER }, // PWML4 + // 10 + { PIOC, PIO_PC29B_TIOB7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB7 }, // TIOB7 + { PIOD, PIO_PD7B_TIOA8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA8 }, // TIOA8 + { PIOD, PIO_PD8B_TIOB8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB8 }, // TIOB8 + + // 13 - AMBER LED + { PIOB, PIO_PB27B_TIOB0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHB0 }, // TIOB0 + + // 14/15 - USART3 (Serial3) + { PIOD, PIO_PD4B_TXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD3 + { PIOD, PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD3 + + // 16/17 - USART1 (Serial2) + { PIOA, PIO_PA13A_TXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD1 + { PIOA, PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD1 + + // 18/19 - USART0 (Serial1) + { PIOA, PIO_PA11A_TXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD0 + { PIOA, PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD0 + + // 20/21 - TWI1 + { PIOB, PIO_PB12A_TWD1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD1 - SDA0 + { PIOB, PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK1 - SCL0 + + // 22 + { PIOB, PIO_PB26, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 22 + { PIOA, PIO_PA14, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 23 + { PIOA, PIO_PA15, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 24 + { PIOD, PIO_PD0, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 25 + + // 26 + { PIOD, PIO_PD1, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 26 + { PIOD, PIO_PD2, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 27 + { PIOD, PIO_PD3, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 28 + { PIOD, PIO_PD6, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 29 + + // 30 + { PIOD, PIO_PD9, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 30 + { PIOA, PIO_PA7, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 31 + { PIOD, PIO_PD10, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 32 + { PIOC, PIO_PC1, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 33 + + // 34 + { PIOC, PIO_PC2, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 34 + { PIOC, PIO_PC3, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 35 + { PIOC, PIO_PC4, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 36 + { PIOC, PIO_PC5, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 37 + + // 38 + { PIOC, PIO_PC6, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 38 + { PIOC, PIO_PC7, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 39 + { PIOC, PIO_PC8, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 40 + { PIOC, PIO_PC9, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 41 + + // 42 + { PIOA, PIO_PA19, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 42 + { PIOA, PIO_PA20, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 43 + { PIOC, PIO_PC19, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 44 + { PIOC, PIO_PC18, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 45 + + // 46 + { PIOC, PIO_PC17, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 46 + { PIOC, PIO_PC16, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 47 + { PIOC, PIO_PC15, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 48 + { PIOC, PIO_PC14, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 49 + + // 50 + { PIOC, PIO_PC13, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 50 + { PIOC, PIO_PC12, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 51 + { PIOB, PIO_PB21, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 52 + { PIOB, PIO_PB14, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 53 + + + // 54 .. 65 - Analog pins + // ---------------------- + { PIOA, PIO_PA16X1_AD7, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC7, NOT_ON_PWM, NOT_ON_TIMER }, // AD0 + { PIOA, PIO_PA24X1_AD6, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC1, ADC6, NOT_ON_PWM, NOT_ON_TIMER }, // AD1 + { PIOA, PIO_PA23X1_AD5, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC2, ADC5, NOT_ON_PWM, NOT_ON_TIMER }, // AD2 + { PIOA, PIO_PA22X1_AD4, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC3, ADC4, NOT_ON_PWM, NOT_ON_TIMER }, // AD3 + // 58 + { PIOA, PIO_PA6X1_AD3, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC4, ADC3, NOT_ON_PWM, TC0_CHB2 }, // AD4 + { PIOA, PIO_PA4X1_AD2, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC5, ADC2, NOT_ON_PWM, NOT_ON_TIMER }, // AD5 + { PIOA, PIO_PA3X1_AD1, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC6, ADC1, NOT_ON_PWM, TC0_CHB1 }, // AD6 + { PIOA, PIO_PA2X1_AD0, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC7, ADC0, NOT_ON_PWM, TC0_CHA1 }, // AD7 + // 62 + { PIOB, PIO_PB17X1_AD10, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC8, ADC10, NOT_ON_PWM, NOT_ON_TIMER }, // AD8 + { PIOB, PIO_PB18X1_AD11, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC9, ADC11, NOT_ON_PWM, NOT_ON_TIMER }, // AD9 + { PIOB, PIO_PB19X1_AD12, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC10, ADC12, NOT_ON_PWM, NOT_ON_TIMER }, // AD10 + { PIOB, PIO_PB20X1_AD13, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC11, ADC13, NOT_ON_PWM, NOT_ON_TIMER }, // AD11 + + // 66/67 - DAC0/DAC1 + { PIOB, PIO_PB15X1_DAC0, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC12, DA0, NOT_ON_PWM, NOT_ON_TIMER }, // DAC0 + { PIOB, PIO_PB16X1_DAC1, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC13, DA1, NOT_ON_PWM, NOT_ON_TIMER }, // DAC1 + + // 68/69 - CANRX0/CANTX0 + { PIOA, PIO_PA1A_CANRX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC14, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX + { PIOA, PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC15, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX + + // 70/71 - TWI0 + { PIOA, PIO_PA17A_TWD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD0 - SDA1 + { PIOA, PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK0 - SCL1 + + // 72/73 - LEDs + { PIOC, PIO_PC30, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER RXL + { PIOA, PIO_PA21, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER TXL + + // 74/75/76 - SPI + { PIOA, PIO_PA25A_SPI0_MISO,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MISO + { PIOA, PIO_PA26A_SPI0_MOSI,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI + { PIOA, PIO_PA27A_SPI0_SPCK,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // SPCK + + // 77 - SPI CS0 + { PIOA, PIO_PA28A_SPI0_NPCS0,ID_PIOA,PIO_PERIPH_A,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS0 + + // 78 - SPI CS3 (unconnected) + { PIOB, PIO_PB23B_SPI0_NPCS3,ID_PIOB,PIO_PERIPH_B,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS3 + + // 79 .. 84 - "All pins" masks + + // 79 - TWI0 all pins + { PIOA, PIO_PA17A_TWD0|PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 80 - TWI1 all pins + { PIOB, PIO_PB12A_TWD1|PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 81 - UART (Serial) all pins + { PIOA, PIO_PA8A_URXD|PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 82 - USART0 (Serial1) all pins + { PIOA, PIO_PA11A_TXD0|PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 83 - USART1 (Serial2) all pins + { PIOA, PIO_PA13A_TXD1|PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 84 - USART3 (Serial3) all pins + { PIOD, PIO_PD4B_TXD3|PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + + // 85 - USB + //{ PIOB, PIO_PB11A_UOTGID|PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF + { PIOB, PIO_PB11A_UOTGID, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF + // 86 - SPI CS2 + { PIOB, PIO_PB21B_SPI0_NPCS2, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS2 + + // 87 - SPI CS1 + { PIOA, PIO_PA29A_SPI0_NPCS1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS1 + + // 88/89 - CANRX1/CANTX1 (same physical pin for 66/53) + { PIOB, PIO_PB15A_CANRX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX1 + { PIOB, PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX1 + + // 90 .. 91 - "All CAN pins" masks + // 90 - CAN0 all pins + { PIOA, PIO_PA1A_CANRX0|PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 91 - CAN1 all pins + { PIOB, PIO_PB15A_CANRX1|PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + + // 92 .. 99 placeholders, future-proofing. + // { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + { PIOB, PIO_PB22, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 92 - PB22 E1 Enabled + { PIOB, PIO_PB10, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID 9 + { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 100 - 108 extra SAM3X8E pins, not wired on Due + { PIOA, PIO_PA5, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 100 + { PIOC, PIO_PC27, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 101 + { PIOA, PIO_PA0, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 102 + { PIOA, PIO_PA1, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 103 + { PIOC, PIO_PC11, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 104 + { PIOC, PIO_PC8B_PWML3, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH3, NOT_ON_TIMER }, // PWM 105 + { PIOC, PIO_PC2B_PWML0, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH0, NOT_ON_TIMER }, // PWM 106 + { PIOC, PIO_PC6B_PWML2, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH2, NOT_ON_TIMER }, //PWM 107 + { PIOC, PIO_PC20, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, //PWM 108 + // 109 .. 114 + { PIOA, PIO_PA20A_MCCDA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCCDA_GPIO 109 + { PIOA, PIO_PA19A_MCCK, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCCK_GPIO 110 + { PIOA, PIO_PA21A_MCDA0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA0_GPIO 111 + { PIOA, PIO_PA22A_MCDA1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA1_GPIO 112 + { PIOA, PIO_PA23A_MCDA2, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA2_GPIO 113 + { PIOA, PIO_PA24A_MCDA3, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA3_GPIO 114 + // 115 .. 124 - ETHERNET MAC + { PIOB, PIO_PB0A_ETXCK, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETXCK 115 + { PIOB, PIO_PB1A_ETXEN, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETXEN 116 + { PIOB, PIO_PB2A_ETX0, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETX0 117 + { PIOB, PIO_PB3A_ETX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETX1 118 + { PIOB, PIO_PB4A_ECRSDV, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ECRSDV 119 + { PIOB, PIO_PB5A_ERX0, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ERX0 120 + { PIOB, PIO_PB6A_ERX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ERX1 121 + { PIOB, PIO_PB7A_ERXER, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ERXER 122 + { PIOB, PIO_PB8A_EMDC, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // EMDC 123 + { PIOB, PIO_PB9A_EMDIO, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // EMDIO 124 + // 125 + { PIOB, PIO_PB24, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 125 + { PIOB, PIO_PB21X1_AD14, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC14, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 126 - PB21 with enabled ADC + { PIOB, PIO_PB13X1_AD9, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC9, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 127 - PB13 with enabled ACD AD9 + + // END + { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER } +} ; + + +uint8_t g_pinStatus[PINS_COUNT] = {0}; + +#ifdef __cplusplus +} +#endif + +/* + * UART objects + */ +RingBuffer rx_buffer1; +RingBuffer tx_buffer1; + +UARTClass Serial(UART, UART_IRQn, ID_UART, &rx_buffer1, &tx_buffer1); +void serialEvent() __attribute__((weak)); +void serialEvent() { } + +// IT handlers +void UART_Handler(void) +{ + Serial.IrqHandler(); +} + +// ---------------------------------------------------------------------------- +/* + * USART objects + */ +RingBuffer rx_buffer2; +RingBuffer rx_buffer3; +RingBuffer rx_buffer4; +RingBuffer tx_buffer2; +RingBuffer tx_buffer3; +RingBuffer tx_buffer4; + +USARTClass Serial1(USART0, USART0_IRQn, ID_USART0, &rx_buffer2, &tx_buffer2); +void serialEvent1() __attribute__((weak)); +void serialEvent1() { } +USARTClass Serial2(USART1, USART1_IRQn, ID_USART1, &rx_buffer3, &tx_buffer3); +void serialEvent2() __attribute__((weak)); +void serialEvent2() { } +USARTClass Serial3(USART3, USART3_IRQn, ID_USART3, &rx_buffer4, &tx_buffer4); +void serialEvent3() __attribute__((weak)); +void serialEvent3() { } + +// IT handlers +void USART0_Handler(void) +{ + Serial1.IrqHandler(); +} + +void USART1_Handler(void) +{ + Serial2.IrqHandler(); +} + +void USART3_Handler(void) +{ + Serial3.IrqHandler(); +} + +// ---------------------------------------------------------------------------- + +void serialEventRun(void) +{ + if (Serial.available()) serialEvent(); + if (Serial1.available()) serialEvent1(); + if (Serial2.available()) serialEvent2(); + if (Serial3.available()) serialEvent3(); +} + +// ---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +void __libc_init_array(void); + +void init( void ) +{ + SystemInit(); + + // Set Systick to 1ms interval, common to all SAM3 variants + if (SysTick_Config(SystemCoreClock / 1000)) + { + // Capture error + while (true); + } + + // Initialize C library + __libc_init_array(); + + // Disable pull-up on every pin + for (unsigned i = 0; i < PINS_COUNT; i++) + digitalWrite(i, LOW); + + // Enable parallel access on PIO output data registers + PIOA->PIO_OWER = 0xFFFFFFFF; + PIOB->PIO_OWER = 0xFFFFFFFF; + PIOC->PIO_OWER = 0xFFFFFFFF; + PIOD->PIO_OWER = 0xFFFFFFFF; + + // Initialize Serial port U(S)ART pins + PIO_Configure( + g_APinDescription[PINS_UART].pPort, + g_APinDescription[PINS_UART].ulPinType, + g_APinDescription[PINS_UART].ulPin, + g_APinDescription[PINS_UART].ulPinConfiguration); + digitalWrite(0, HIGH); // Enable pullup for RX0 + PIO_Configure( + g_APinDescription[PINS_USART0].pPort, + g_APinDescription[PINS_USART0].ulPinType, + g_APinDescription[PINS_USART0].ulPin, + g_APinDescription[PINS_USART0].ulPinConfiguration); + PIO_Configure( + g_APinDescription[PINS_USART1].pPort, + g_APinDescription[PINS_USART1].ulPinType, + g_APinDescription[PINS_USART1].ulPin, + g_APinDescription[PINS_USART1].ulPinConfiguration); + PIO_Configure( + g_APinDescription[PINS_USART3].pPort, + g_APinDescription[PINS_USART3].ulPinType, + g_APinDescription[PINS_USART3].ulPin, + g_APinDescription[PINS_USART3].ulPinConfiguration); + + // Initialize USB pins + PIO_Configure( + g_APinDescription[PINS_USB].pPort, + g_APinDescription[PINS_USB].ulPinType, + g_APinDescription[PINS_USB].ulPin, + g_APinDescription[PINS_USB].ulPinConfiguration); + + // Initialize CAN pins + PIO_Configure( + g_APinDescription[PINS_CAN0].pPort, + g_APinDescription[PINS_CAN0].ulPinType, + g_APinDescription[PINS_CAN0].ulPin, + g_APinDescription[PINS_CAN0].ulPinConfiguration); + PIO_Configure( + g_APinDescription[PINS_CAN1].pPort, + g_APinDescription[PINS_CAN1].ulPinType, + g_APinDescription[PINS_CAN1].ulPin, + g_APinDescription[PINS_CAN1].ulPinConfiguration); + + // Initialize Analog Controller + pmc_enable_periph_clk(ID_ADC); + adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST); + adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1); + adc_configure_trigger(ADC, ADC_TRIG_SW, 0); // Disable hardware trigger. + adc_disable_interrupt(ADC, 0xFFFFFFFF); // Disable all ADC interrupts. + adc_disable_all_channel(ADC); + + // Initialize analogOutput module + analogOutputInit(); +} + +#ifdef __cplusplus +} +#endif + diff --git a/apply_patches.py b/apply_patches.py new file mode 100644 index 0000000..d289480 --- /dev/null +++ b/apply_patches.py @@ -0,0 +1,29 @@ +from os.path import join, isfile +from shutil import copyfile + + +Import("env") +# access to global construction environment +ROOT_DIR = env['PROJECT_DIR'] +FRAMEWORK_DIR = env.PioPlatform().get_package_dir("framework-arduino-sam") +patchflag_path = join(FRAMEWORK_DIR, ".patching-done") + +# patch file only if we didn't do it before +if not isfile(join(FRAMEWORK_DIR, ".patching-done")): + print("Patching files") + target_file = join(FRAMEWORK_DIR, "cores","arduino","USB", "USBCore.cpp") + patched_file = join(ROOT_DIR, "PIOPatches", "USBCore.cpp") + assert isfile(target_file) and isfile(patched_file) + copyfile(patched_file, target_file) + target_file = join(FRAMEWORK_DIR, "variants", "arduino_due_x", "variant.cpp") + patched_file = join(ROOT_DIR, "PIOPatches", "variant.cpp") + assert isfile(target_file) and isfile(patched_file) + copyfile(patched_file, target_file) + + def _touch(path): + with open(path, "w") as fp: + fp.write("") + + env.Execute(lambda *args, **kwargs: _touch(patchflag_path)) +else: + print("Files already patched") \ No newline at end of file diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..26b730f --- /dev/null +++ b/platformio.ini @@ -0,0 +1,36 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[platformio] +src_dir = src\ArduinoDUE\Repetier +build_dir = .pioenvs +lib_dir = libraries +libdeps_dir = .piolibdeps +default_envs = davinci + +[env:davinci] +platform = atmelsam@6.0.1 +framework = arduino +;Native port +board = dueUSB +upload_protocol = sam-ba +;microcontroller +board_build.mcu = at91sam3x8e +;MCU frequency +board_build.f_cpu = 84000000L +extra_scripts = pre:apply_patches.py +monitor_speed = 115200 +monitor_flags = --echo +monitor_filters = send_on_enter, colorize + +;build_flags = -DDAVINCI=1 -DMODEL=0 + + +