void MIDI_IN(void) { MIDI_EventPacket_t ReceivedMIDIEvent; if (MIDI_Device_ReceiveEventPacket(&MIDI_Interface, &ReceivedMIDIEvent)) { LEDs_TurnOnLEDs(LEDMASK_RX); Serial_TxByte(ReceivedMIDIEvent.Data1); Serial_TxByte(ReceivedMIDIEvent.Data2); Serial_TxByte(ReceivedMIDIEvent.Data3); } else { LEDs_TurnOffLEDs(LEDMASK_RX); } }
static int SerialStream_TxByte(char DataByte, FILE *Stream) { (void)Stream; Serial_TxByte(DataByte); return 0; }
/** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. */ int main(void) { SetupHardware(); RingBuffer_InitBuffer(&USBtoUSART_Buffer); RingBuffer_InitBuffer(&USARTtoUSB_Buffer); sei(); for (;;) { /* Only try to read in bytes from the CDC interface if the transmit buffer is not full */ if (!(RingBuffer_IsFull(&USBtoUSART_Buffer))) { int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); /* Read bytes from the USB OUT endpoint into the USART transmit buffer */ if (!(ReceivedByte < 0)) RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte); } /* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */ RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); if ((TIFR0 & (1 << TOV0)) || (BufferCount > BUFFER_NEARLY_FULL)) { TIFR0 |= (1 << TOV0); if (USARTtoUSB_Buffer.Count) { LEDs_TurnOnLEDs(LEDMASK_TX); PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS; } /* Read bytes from the USART receive buffer into the USB IN endpoint */ while (BufferCount--) CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer)); /* Turn off TX LED(s) once the TX pulse period has elapsed */ if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse)) LEDs_TurnOffLEDs(LEDMASK_TX); /* Turn off RX LED(s) once the RX pulse period has elapsed */ if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse)) LEDs_TurnOffLEDs(LEDMASK_RX); } /* Load the next byte from the USART transmit buffer into the USART */ if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) { Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer)); LEDs_TurnOnLEDs(LEDMASK_RX); PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS; } CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); } }
void Serial_TxString(const char* StringPtr) { uint8_t CurrByte; while ((CurrByte = *StringPtr) != 0x00) { Serial_TxByte(CurrByte); StringPtr++; } }
void Serial_TxString_P(const char* FlashStringPtr) { uint8_t CurrByte; while ((CurrByte = pgm_read_byte(FlashStringPtr)) != 0x00) { Serial_TxByte(CurrByte); FlashStringPtr++; } }
/** Task to manage CDC data transmission and reception to and from the host, from and to the physical USART. */ void CDC_Task(void) { /* Device must be connected and configured for the task to run */ if (USB_DeviceState != DEVICE_STATE_Configured) return; #if 0 /* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232 handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code: */ USB_Notification_Header_t Notification = (USB_Notification_Header_t) { .NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), .Notification = NOTIF_SerialState, .wValue = 0, .wIndex = 0, .wLength = sizeof(uint16_t), }; uint16_t LineStateMask; // Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM); Endpoint_Write_Stream_LE(&Notification, sizeof(Notification)); Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask)); Endpoint_ClearIN(); #endif /* Select the Serial Rx Endpoint */ Endpoint_SelectEndpoint(CDC_RX_EPNUM); /* Check to see if a packet has been received from the host */ if (Endpoint_IsOUTReceived()) { /* Read the bytes in from the endpoint into the buffer while space is available */ while (Endpoint_BytesInEndpoint() && (Rx_Buffer.Elements != BUFF_STATICSIZE)) { /* Store each character from the endpoint */ Buffer_StoreElement(&Rx_Buffer, Endpoint_Read_Byte()); } /* Check to see if all bytes in the current packet have been read */ if (!(Endpoint_BytesInEndpoint())) { /* Clear the endpoint buffer */ Endpoint_ClearOUT(); } } /* Check if Rx buffer contains data - if so, send it */ if (Rx_Buffer.Elements) Serial_TxByte(Buffer_GetElement(&Rx_Buffer)); /* Select the Serial Tx Endpoint */ Endpoint_SelectEndpoint(CDC_TX_EPNUM); /* Check if the Tx buffer contains anything to be sent to the host */ if ((Tx_Buffer.Elements) && LineEncoding.BaudRateBPS) { /* Wait until Serial Tx Endpoint Ready for Read/Write */ Endpoint_WaitUntilReady(); /* Write the bytes from the buffer to the endpoint while space is available */ while (Tx_Buffer.Elements && Endpoint_IsReadWriteAllowed()) { /* Write each byte retreived from the buffer to the endpoint */ Endpoint_Write_Byte(Buffer_GetElement(&Tx_Buffer)); } /* Remember if the packet to send completely fills the endpoint */ bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE); /* Send the data */ Endpoint_ClearIN(); /* If no more data to send and the last packet filled the endpoint, send an empty packet to release * the buffer on the receiver (otherwise all data will be cached until a non-full packet is received) */ if (IsFull && !(Tx_Buffer.Elements)) { /* Wait until Serial Tx Endpoint Ready for Read/Write */ Endpoint_WaitUntilReady(); /* Send an empty packet to terminate the transfer */ Endpoint_ClearIN(); } } } /** ISR to handle the USART receive complete interrupt, fired each time the USART has received a character. This stores the received * character into the Tx_Buffer circular buffer for later transmission to the host. */ ISR(USART1_RX_vect, ISR_BLOCK) { uint8_t ReceivedByte = UDR1; /* Only store received characters if the USB interface is connected */ if ((USB_DeviceState == DEVICE_STATE_Configured)) {// && LineEncoding.BaudRateBPS Buffer_StoreElement(&Tx_Buffer, ReceivedByte); } }
/** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. */ int main(void) { SetupHardware(); RingBuffer_InitBuffer(&USBtoUSART_Buffer); RingBuffer_InitBuffer(&USARTtoUSB_Buffer); setupEeprom(); sei(); for (;;) { // Only try to read in bytes from the CDC interface if the transmit buffer is not full if (!(RingBuffer_IsFull(&USBtoUSART_Buffer))) { int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); // Read bytes from the USB OUT endpoint into the USART transmit buffer if (!(ReceivedByte < 0)) RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte); } // Check if the UART receive buffer flush timer has expired or the buffer is nearly full RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); if ((TIFR0 & (1 << TOV0)) || (BufferCount > BUFFER_NEARLY_FULL)) { TIFR0 |= (1 << TOV0); if (USARTtoUSB_Buffer.Count) { LEDs_TurnOnLEDs(LEDMASK_TX); PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS; } // Read bytes from the USART receive buffer into the USB IN endpoint while (BufferCount--) CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer)); // Turn off TX LED(s) once the TX pulse period has elapsed if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse)) LEDs_TurnOffLEDs(LEDMASK_TX); // Turn off RX LED(s) once the RX pulse period has elapsed if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse)) LEDs_TurnOffLEDs(LEDMASK_RX); if (ResetTimer > 0) { // SAM3X RESET/ERASE Sequence // -------------------------- if (ResetTimer == 95) { eepromInterruptDisable(); setErasePin(true); setResetPin(false); } if (ResetTimer == 35) { eepromInterruptDisable(); setErasePin(false); setResetPin(false); } if (ResetTimer == 25) { eepromInterruptDisable(); setErasePin(false); setResetPin(true); } if (ResetTimer == 1) { eepromInterruptDisable(); setErasePin(false); setResetPin(false); } ResetTimer--; } else { setErasePin(false); setResetPin(false); eepromInterruptEnable(); } } // Load the next byte from the USART transmit buffer into the USART if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) { Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer)); LEDs_TurnOnLEDs(LEDMASK_RX); PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS; } // CDC_Device_USBTask(&VirtualSerial_CDC_Interface); // USB_USBTask(); serviceEepromRequest(); CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); } }
/** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. */ int main(void) { MIDI_EventPacket_t midiEvent; struct { uint8_t command; uint8_t channel; uint8_t data2; uint8_t data3; } midiMsg; int ind; int led1_ticks = 0; int led2_ticks = 0; SetupHardware(); RingBuffer_InitBuffer(&USBtoUSART_Buffer); RingBuffer_InitBuffer(&USARTtoUSB_Buffer); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); /* See if we have a message yet */ if (BufferCount >= 4) { /* Read in the message from the serial buffer */ for (ind=0; ind<4; ind++) { ((uint8_t *)&midiMsg)[ind] = RingBuffer_Remove(&USARTtoUSB_Buffer); } /* Build a midi event to send via USB */ midiEvent.CableNumber = 0; midiEvent.Command = midiMsg.command >> 4; midiEvent.Data1 = (midiMsg.command & 0xF0) | ((midiMsg.channel-1) & 0x0F); midiEvent.Data2 = midiMsg.data2; midiEvent.Data3 = midiMsg.data3; MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &midiEvent); MIDI_Device_Flush(&Keyboard_MIDI_Interface); /* Turn on the TX led and starts its timer */ LEDs_TurnOnLEDs(LEDS_LED1); led1_ticks = LED_ON_TICKS; } /* Turn off the Tx LED when the tick count reaches zero */ if (led1_ticks) { led1_ticks--; if (led1_ticks == 0) { LEDs_TurnOffLEDs(LEDS_LED1); } } if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &midiEvent)) { RingBuff_Count_t count = RingBuffer_GetCount(&USBtoUSART_Buffer); /* Room to send a message? */ if ((BUFFER_SIZE - count) >= sizeof(midiMsg)) { midiMsg.command = midiEvent.Command << 4; midiMsg.channel = (midiEvent.Data1 & 0x0F) + 1; midiMsg.data2 = midiEvent.Data2; midiMsg.data3 = midiEvent.Data3; for (ind=0; ind<sizeof(midiMsg); ind++) { RingBuffer_Insert(&USBtoUSART_Buffer, ((uint8_t *)&midiMsg)[ind]); } /* Turn on the RX led and start its timer */ LEDs_TurnOnLEDs(LEDS_LED2); led2_ticks = LED_ON_TICKS; } else { /* Turn on the RX led and leave it on to indicate the * buffer is full and the sketch is not reading it * fast enough. */ LEDs_TurnOnLEDs(LEDS_LED2); } /* if there's no room in the serial buffer the message gets dropped */ } /* Turn off the RX LED when the tick count reaches zero */ if (led2_ticks) { led2_ticks--; if (led2_ticks == 0) { LEDs_TurnOffLEDs(LEDS_LED2); } } /* any data to send to main processor? */ if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) { Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer)); } MIDI_Device_USBTask(&Keyboard_MIDI_Interface); USB_USBTask(); } }