forked from mfulz_github/qmk_firmware
Break device mode class driver interfaces into seperate config and state structs which are then combined, for clarity. Move device mode class driver interfaces back into the device mode class driver headers from the common class headers to make room for host class interfaces.
This commit is contained in:
parent
e338cb6f32
commit
f896c00c48
|
@ -40,12 +40,20 @@
|
|||
* passed to all Audio Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_Audio_t Microphone_Audio_Interface =
|
||||
USB_ClassInfo_Audio_Device_t Microphone_Audio_Interface =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
.Config =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
|
||||
.DataINEndpointNumber = AUDIO_STREAM_EPNUM,
|
||||
.DataINEndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
.DataINEndpointNumber = AUDIO_STREAM_EPNUM,
|
||||
.DataINEndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -59,7 +67,7 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
if (Microphone_Audio_Interface.InterfaceEnabled)
|
||||
if (Microphone_Audio_Interface.State.InterfaceEnabled)
|
||||
ProcessNextSample();
|
||||
|
||||
Audio_Device_USBTask(&Microphone_Audio_Interface);
|
||||
|
|
|
@ -40,12 +40,20 @@
|
|||
* passed to all Audio Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_Audio_t Speaker_Audio_Interface =
|
||||
USB_ClassInfo_Audio_Device_t Speaker_Audio_Interface =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
.Config =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
|
||||
.DataOUTEndpointNumber = AUDIO_STREAM_EPNUM,
|
||||
.DataOUTEndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
.DataINEndpointNumber = AUDIO_STREAM_EPNUM,
|
||||
.DataINEndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -59,7 +67,7 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
if (Speaker_Audio_Interface.InterfaceEnabled)
|
||||
if (Speaker_Audio_Interface.State.InterfaceEnabled)
|
||||
ProcessNextSample();
|
||||
|
||||
Audio_Device_USBTask(&Speaker_Audio_Interface);
|
||||
|
|
|
@ -40,18 +40,26 @@
|
|||
* passed to all CDC Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface =
|
||||
USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = CDC_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataINEndpointNumber = CDC_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.DataOUTEndpointNumber = CDC_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataOUTEndpointNumber = CDC_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
|
|
@ -41,18 +41,26 @@
|
|||
* within a device can be differentiated from one another. This is for the first CDC interface,
|
||||
* which sends strings to the host for each joystick movement.
|
||||
*/
|
||||
USB_ClassInfo_CDC_t VirtualSerial1_CDC_Interface =
|
||||
USB_ClassInfo_CDC_Device_t VirtualSerial1_CDC_Interface =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = CDC1_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataINEndpointNumber = CDC1_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.DataOUTEndpointNumber = CDC1_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataOUTEndpointNumber = CDC1_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** LUFA CDC Class driver interface configuration and state information. This structure is
|
||||
|
@ -60,18 +68,26 @@ USB_ClassInfo_CDC_t VirtualSerial1_CDC_Interface =
|
|||
* within a device can be differentiated from one another. This is for the second CDC interface,
|
||||
* which echos back all received data from the host.
|
||||
*/
|
||||
USB_ClassInfo_CDC_t VirtualSerial2_CDC_Interface =
|
||||
USB_ClassInfo_CDC_Device_t VirtualSerial2_CDC_Interface =
|
||||
{
|
||||
.ControlInterfaceNumber = 2,
|
||||
.Config =
|
||||
{
|
||||
.ControlInterfaceNumber = 2,
|
||||
|
||||
.DataINEndpointNumber = CDC2_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataINEndpointNumber = CDC2_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.DataOUTEndpointNumber = CDC2_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataOUTEndpointNumber = CDC2_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
|
|
@ -40,16 +40,22 @@
|
|||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_t Generic_HID_Interface =
|
||||
USB_ClassInfo_HID_Device_t Generic_HID_Interface =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = GENERIC_IN_EPNUM,
|
||||
.ReportINEndpointSize = GENERIC_EPSIZE,
|
||||
|
||||
.ReportINBufferSize = GENERIC_REPORT_SIZE,
|
||||
.ReportINEndpointNumber = GENERIC_IN_EPNUM,
|
||||
.ReportINEndpointSize = GENERIC_EPSIZE,
|
||||
|
||||
.ReportINBufferSize = GENERIC_REPORT_SIZE,
|
||||
},
|
||||
|
||||
.UsingReportProtocol = true,
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -119,8 +125,8 @@ void EVENT_USB_UnhandledControlPacket(void)
|
|||
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
|
||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
||||
{
|
||||
if (Generic_HID_Interface.IdleMSRemaining)
|
||||
Generic_HID_Interface.IdleMSRemaining--;
|
||||
if (Generic_HID_Interface.State.IdleMSRemaining)
|
||||
Generic_HID_Interface.State.IdleMSRemaining--;
|
||||
}
|
||||
|
||||
/** HID class driver callback function for the creation of HID reports to the host.
|
||||
|
@ -131,7 +137,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
|||
*
|
||||
* \return Number of bytes written in the report (or zero if no report is to be sent
|
||||
*/
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
{
|
||||
// Create generic HID report here
|
||||
|
||||
|
@ -145,7 +151,7 @@ uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceIn
|
|||
* \param ReportData Pointer to a buffer where the created report has been stored
|
||||
* \param ReportSize Size in bytes of the received HID report
|
||||
*/
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize)
|
||||
{
|
||||
// Process received generic HID report here
|
||||
|
|
|
@ -72,8 +72,9 @@
|
|||
void EVENT_USB_ConfigurationChanged(void);
|
||||
void EVENT_USB_UnhandledControlPacket(void);
|
||||
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID,
|
||||
void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,16 +40,22 @@
|
|||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_t Joystick_HID_Interface =
|
||||
USB_ClassInfo_HID_Device_t Joystick_HID_Interface =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = JOYSTICK_EPNUM,
|
||||
.ReportINEndpointSize = JOYSTICK_EPSIZE,
|
||||
|
||||
.ReportINBufferSize = sizeof(USB_JoystickReport_Data_t),
|
||||
|
||||
.UsingReportProtocol = true,
|
||||
.ReportINEndpointNumber = JOYSTICK_EPNUM,
|
||||
.ReportINEndpointSize = JOYSTICK_EPSIZE,
|
||||
|
||||
.ReportINBufferSize = sizeof(USB_JoystickReport_Data_t),
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -121,8 +127,8 @@ void EVENT_USB_UnhandledControlPacket(void)
|
|||
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
|
||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
||||
{
|
||||
if (Joystick_HID_Interface.IdleMSRemaining)
|
||||
Joystick_HID_Interface.IdleMSRemaining--;
|
||||
if (Joystick_HID_Interface.State.IdleMSRemaining)
|
||||
Joystick_HID_Interface.State.IdleMSRemaining--;
|
||||
}
|
||||
|
||||
/** HID class driver callback function for the creation of HID reports to the host.
|
||||
|
@ -133,7 +139,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
|||
*
|
||||
* \return Number of bytes written in the report (or zero if no report is to be sent
|
||||
*/
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
{
|
||||
USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData;
|
||||
|
||||
|
@ -166,7 +172,7 @@ uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceIn
|
|||
* \param ReportData Pointer to a buffer where the created report has been stored
|
||||
* \param ReportSize Size in bytes of the received HID report
|
||||
*/
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize)
|
||||
{
|
||||
// Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
|
||||
|
|
|
@ -83,8 +83,9 @@
|
|||
void EVENT_USB_ConfigurationChanged(void);
|
||||
void EVENT_USB_UnhandledControlPacket(void);
|
||||
|
||||
uint16_t CALLBACK_HID_Device_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
uint16_t CALLBACK_HID_Device_CreateNextHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID,
|
||||
void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessReceivedHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,16 +41,22 @@
|
|||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_t Keyboard_HID_Interface =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = KEYBOARD_EPNUM,
|
||||
.ReportINEndpointSize = KEYBOARD_EPSIZE,
|
||||
.ReportINEndpointNumber = KEYBOARD_EPNUM,
|
||||
.ReportINEndpointSize = KEYBOARD_EPSIZE,
|
||||
|
||||
.ReportINBufferSize = sizeof(USB_KeyboardReport_Data_t),
|
||||
|
||||
.IdleCount = 500,
|
||||
.ReportINBufferSize = sizeof(USB_KeyboardReport_Data_t),
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
.IdleCount = 500,
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -122,8 +128,8 @@ void EVENT_USB_UnhandledControlPacket(void)
|
|||
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
|
||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
||||
{
|
||||
if (Keyboard_HID_Interface.IdleMSRemaining)
|
||||
Keyboard_HID_Interface.IdleMSRemaining--;
|
||||
if (Keyboard_HID_Interface.State.IdleMSRemaining)
|
||||
Keyboard_HID_Interface.State.IdleMSRemaining--;
|
||||
}
|
||||
|
||||
/** HID class driver callback function for the creation of HID reports to the host.
|
||||
|
@ -134,7 +140,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
|||
*
|
||||
* \return Number of bytes written in the report (or zero if no report is to be sent
|
||||
*/
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
{
|
||||
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
|
||||
|
||||
|
@ -167,7 +173,7 @@ uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceIn
|
|||
* \param ReportData Pointer to a buffer where the created report has been stored
|
||||
* \param ReportSize Size in bytes of the received HID report
|
||||
*/
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize)
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
|
|
@ -86,8 +86,9 @@
|
|||
void EVENT_USB_ConfigurationChanged(void);
|
||||
void EVENT_USB_UnhandledControlPacket(void);
|
||||
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID,
|
||||
void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,16 +42,22 @@
|
|||
* within a device can be differentiated from one another. This is for the keyboard HID
|
||||
* interface within the device.
|
||||
*/
|
||||
USB_ClassInfo_HID_t Keyboard_HID_Interface =
|
||||
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = KEYBOARD_IN_EPNUM,
|
||||
.ReportINEndpointSize = HID_EPSIZE,
|
||||
|
||||
.ReportINBufferSize = sizeof(USB_KeyboardReport_Data_t),
|
||||
.ReportINEndpointNumber = KEYBOARD_IN_EPNUM,
|
||||
.ReportINEndpointSize = HID_EPSIZE,
|
||||
|
||||
.ReportINBufferSize = sizeof(USB_KeyboardReport_Data_t),
|
||||
},
|
||||
|
||||
.IdleCount = 500,
|
||||
.State =
|
||||
{
|
||||
.IdleCount = 500,
|
||||
}
|
||||
};
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
|
@ -59,14 +65,22 @@ USB_ClassInfo_HID_t Keyboard_HID_Interface =
|
|||
* within a device can be differentiated from one another. This is for the mouse HID
|
||||
* interface within the device.
|
||||
*/
|
||||
USB_ClassInfo_HID_t Mouse_HID_Interface =
|
||||
USB_ClassInfo_HID_Device_t Mouse_HID_Interface =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = MOUSE_IN_EPNUM,
|
||||
.ReportINEndpointSize = HID_EPSIZE,
|
||||
.ReportINEndpointNumber = MOUSE_IN_EPNUM,
|
||||
.ReportINEndpointSize = HID_EPSIZE,
|
||||
|
||||
.ReportINBufferSize = sizeof(USB_MouseReport_Data_t),
|
||||
.ReportINBufferSize = sizeof(USB_MouseReport_Data_t),
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -142,11 +156,11 @@ void EVENT_USB_UnhandledControlPacket(void)
|
|||
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
|
||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
||||
{
|
||||
if (Keyboard_HID_Interface.IdleMSRemaining)
|
||||
Keyboard_HID_Interface.IdleMSRemaining--;
|
||||
if (Keyboard_HID_Interface.State.IdleMSRemaining)
|
||||
Keyboard_HID_Interface.State.IdleMSRemaining--;
|
||||
|
||||
if (Mouse_HID_Interface.IdleMSRemaining)
|
||||
Mouse_HID_Interface.IdleMSRemaining--;
|
||||
if (Mouse_HID_Interface.State.IdleMSRemaining)
|
||||
Mouse_HID_Interface.State.IdleMSRemaining--;
|
||||
}
|
||||
|
||||
/** HID class driver callback function for the creation of HID reports to the host.
|
||||
|
@ -157,7 +171,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
|||
*
|
||||
* \return Number of bytes written in the report (or zero if no report is to be sent
|
||||
*/
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
{
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
|
||||
|
@ -217,7 +231,7 @@ uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceIn
|
|||
* \param ReportData Pointer to a buffer where the created report has been stored
|
||||
* \param ReportSize Size in bytes of the received HID report
|
||||
*/
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize)
|
||||
{
|
||||
if (HIDInterfaceInfo == &Keyboard_HID_Interface)
|
||||
|
|
|
@ -90,8 +90,9 @@
|
|||
void EVENT_USB_ConfigurationChanged(void);
|
||||
void EVENT_USB_UnhandledControlPacket(void);
|
||||
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID,
|
||||
void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,15 +40,23 @@
|
|||
* passed to all MIDI Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_MIDI_t Keyboard_MIDI_Interface =
|
||||
USB_ClassInfo_MIDI_Device_t Keyboard_MIDI_Interface =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
.Config =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
|
||||
.DataINEndpointNumber = MIDI_STREAM_IN_EPNUM,
|
||||
.DataINEndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.DataINEndpointNumber = MIDI_STREAM_IN_EPNUM,
|
||||
.DataINEndpointSize = MIDI_STREAM_EPSIZE,
|
||||
|
||||
.DataOUTEndpointNumber = MIDI_STREAM_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.DataOUTEndpointNumber = MIDI_STREAM_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MIDI_STREAM_EPSIZE,
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
* \param BlockAddress Data block starting address for the write sequence
|
||||
* \param TotalBlocks Number of blocks of data to write
|
||||
*/
|
||||
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
|
||||
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
|
||||
{
|
||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
|
@ -143,7 +143,7 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uin
|
|||
BytesInBlockDiv16++;
|
||||
|
||||
/* Check if the current command is being aborted by the host */
|
||||
if (MSInterfaceInfo->IsMassStoreReset)
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uin
|
|||
* \param BlockAddress Data block starting address for the read sequence
|
||||
* \param TotalBlocks Number of blocks of data to read
|
||||
*/
|
||||
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
|
||||
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
|
||||
{
|
||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
|
@ -252,7 +252,7 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint
|
|||
BytesInBlockDiv16++;
|
||||
|
||||
/* Check if the current command is being aborted by the host */
|
||||
if (MSInterfaceInfo->IsMassStoreReset)
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,9 +64,9 @@
|
|||
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress,
|
||||
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress,
|
||||
uint16_t TotalBlocks);
|
||||
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress,
|
||||
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress,
|
||||
uint16_t TotalBlocks);
|
||||
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
|
||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
|
|
@ -86,12 +86,12 @@ SCSI_Request_Sense_Response_t SenseData =
|
|||
*
|
||||
* \param MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
||||
*/
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
bool CommandSuccess = false;
|
||||
|
||||
/* Run the appropriate SCSI command hander function based on the passed command */
|
||||
switch (MSInterfaceInfo->CommandBlock.SCSICommandData[0])
|
||||
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
|
||||
{
|
||||
case SCSI_CMD_INQUIRY:
|
||||
CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);
|
||||
|
@ -116,7 +116,7 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
case SCSI_CMD_VERIFY_10:
|
||||
/* These commands should just succeed, no handling required */
|
||||
CommandSuccess = true;
|
||||
MSInterfaceInfo->CommandBlock.DataTransferLength = 0;
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
break;
|
||||
default:
|
||||
/* Update the SENSE key to reflect the invalid command */
|
||||
|
@ -146,16 +146,16 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
*
|
||||
* \return Boolean true if the command completed successfully, false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->CommandBlock.SCSICommandData[3] << 8) |
|
||||
MSInterfaceInfo->CommandBlock.SCSICommandData[4]);
|
||||
uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) |
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]);
|
||||
uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength :
|
||||
sizeof(InquiryData);
|
||||
|
||||
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
|
||||
if ((MSInterfaceInfo->CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
|
||||
MSInterfaceInfo->CommandBlock.SCSICommandData[2])
|
||||
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
|
||||
{
|
||||
/* Optional but unsupported bits set - update the SENSE key and fail the request */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
|
@ -176,7 +176,7 @@ static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -188,9 +188,9 @@ static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
*
|
||||
* \return Boolean true if the command completed successfully, false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint8_t AllocationLength = MSInterfaceInfo->CommandBlock.SCSICommandData[4];
|
||||
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
||||
uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);
|
||||
|
||||
uint8_t PadBytes[AllocationLength - BytesTransferred];
|
||||
|
@ -200,7 +200,7 @@ static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
*
|
||||
* \return Boolean true if the command completed successfully, false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint32_t TotalLUNs = (LUN_MEDIA_BLOCKS - 1);
|
||||
uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
|
||||
|
@ -222,7 +222,7 @@ static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->CommandBlock.DataTransferLength -= 8;
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -235,12 +235,12 @@ static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
*
|
||||
* \return Boolean true if the command completed successfully, false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint8_t ReturnByte;
|
||||
|
||||
/* Check to see if the SELF TEST bit is not set */
|
||||
if (!(MSInterfaceInfo->CommandBlock.SCSICommandData[1] & (1 << 2)))
|
||||
if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
|
||||
{
|
||||
/* Only self-test supported - update SENSE key and fail the command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
|
@ -287,7 +287,7 @@ static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
#endif
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->CommandBlock.DataTransferLength = 0;
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -301,20 +301,20 @@ static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
*
|
||||
* \return Boolean true if the command completed successfully, false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const bool IsDataRead)
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead)
|
||||
{
|
||||
uint32_t BlockAddress;
|
||||
uint16_t TotalBlocks;
|
||||
|
||||
/* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */
|
||||
((uint8_t*)&BlockAddress)[3] = MSInterfaceInfo->CommandBlock.SCSICommandData[2];
|
||||
((uint8_t*)&BlockAddress)[2] = MSInterfaceInfo->CommandBlock.SCSICommandData[3];
|
||||
((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->CommandBlock.SCSICommandData[4];
|
||||
((uint8_t*)&BlockAddress)[0] = MSInterfaceInfo->CommandBlock.SCSICommandData[5];
|
||||
((uint8_t*)&BlockAddress)[3] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[2];
|
||||
((uint8_t*)&BlockAddress)[2] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[3];
|
||||
((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
||||
((uint8_t*)&BlockAddress)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[5];
|
||||
|
||||
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */
|
||||
((uint8_t*)&TotalBlocks)[1] = MSInterfaceInfo->CommandBlock.SCSICommandData[7];
|
||||
((uint8_t*)&TotalBlocks)[0] = MSInterfaceInfo->CommandBlock.SCSICommandData[8];
|
||||
((uint8_t*)&TotalBlocks)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[7];
|
||||
((uint8_t*)&TotalBlocks)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[8];
|
||||
|
||||
/* Check if the block address is outside the maximum allowable value for the LUN */
|
||||
if (BlockAddress >= LUN_MEDIA_BLOCKS)
|
||||
|
@ -329,7 +329,7 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const
|
|||
|
||||
#if (TOTAL_LUNS > 1)
|
||||
/* Adjust the given block address to the real media address based on the selected LUN */
|
||||
BlockAddress += ((uint32_t)MSInterfaceInfo->CommandBlock.LUN * LUN_MEDIA_BLOCKS);
|
||||
BlockAddress += ((uint32_t)MSInterfaceInfo->State.CommandBlock.LUN * LUN_MEDIA_BLOCKS);
|
||||
#endif
|
||||
|
||||
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
|
||||
|
@ -339,7 +339,7 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const
|
|||
DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
||||
|
||||
/* Update the bytes transferred counter and succeed the command */
|
||||
MSInterfaceInfo->CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -135,14 +135,14 @@
|
|||
} SCSI_Request_Sense_Response_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
#if defined(INCLUDE_FROM_SCSI_C)
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const bool IsDataRead);
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,17 +40,25 @@
|
|||
* passed to all Mass Storage Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_MS_t Disk_MS_Interface =
|
||||
USB_ClassInfo_MS_Device_t Disk_MS_Interface =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
|
||||
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
|
||||
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
|
||||
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
|
||||
.TotalLUNs = TOTAL_LUNS,
|
||||
.TotalLUNs = TOTAL_LUNS,
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -119,7 +127,7 @@ void EVENT_USB_UnhandledControlPacket(void)
|
|||
*
|
||||
* \param MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced
|
||||
*/
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
bool CommandSuccess;
|
||||
|
||||
|
|
|
@ -83,6 +83,6 @@
|
|||
void EVENT_USB_ConfigurationChanged(void);
|
||||
void EVENT_USB_UnhandledControlPacket(void);
|
||||
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,14 +40,22 @@
|
|||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_t Mouse_HID_Interface =
|
||||
USB_ClassInfo_HID_Device_t Mouse_HID_Interface =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = MOUSE_EPNUM,
|
||||
.ReportINEndpointSize = MOUSE_EPSIZE,
|
||||
.ReportINEndpointNumber = MOUSE_EPNUM,
|
||||
.ReportINEndpointSize = MOUSE_EPSIZE,
|
||||
|
||||
.ReportINBufferSize = sizeof(USB_MouseReport_Data_t),
|
||||
.ReportINBufferSize = sizeof(USB_MouseReport_Data_t),
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -119,8 +127,8 @@ void EVENT_USB_UnhandledControlPacket(void)
|
|||
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
|
||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
||||
{
|
||||
if (Mouse_HID_Interface.IdleMSRemaining)
|
||||
Mouse_HID_Interface.IdleMSRemaining--;
|
||||
if (Mouse_HID_Interface.State.IdleMSRemaining)
|
||||
Mouse_HID_Interface.State.IdleMSRemaining--;
|
||||
}
|
||||
|
||||
/** HID class driver callback function for the creation of HID reports to the host.
|
||||
|
@ -131,7 +139,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
|||
*
|
||||
* \return Number of bytes written in the report (or zero if no report is to be sent
|
||||
*/
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
|
||||
{
|
||||
USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
|
||||
|
||||
|
@ -164,7 +172,7 @@ uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceIn
|
|||
* \param ReportData Pointer to a buffer where the created report has been stored
|
||||
* \param ReportSize Size in bytes of the received HID report
|
||||
*/
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize)
|
||||
{
|
||||
// Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
|
||||
|
|
|
@ -85,8 +85,9 @@
|
|||
void EVENT_USB_ConfigurationChanged(void);
|
||||
void EVENT_USB_UnhandledControlPacket(void);
|
||||
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID,
|
||||
void* ReportData);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID,
|
||||
void* ReportData, uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -56,7 +56,7 @@ TCP_ConnectionState_t ConnectionStateTable[MAX_TCP_CONNECTIONS];
|
|||
* level. If an application produces a response, this task constructs the appropriate Ethernet frame and places it into the Ethernet OUT
|
||||
* buffer for later transmission.
|
||||
*/
|
||||
void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
||||
void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo)
|
||||
{
|
||||
/* Task to hand off TCP packets to and from the listening applications. */
|
||||
|
||||
|
@ -76,7 +76,7 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
|||
}
|
||||
|
||||
/* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */
|
||||
if (RNDISInterfaceInfo->FrameOUT.FrameInBuffer)
|
||||
if (RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer)
|
||||
return;
|
||||
|
||||
/* Send response packets from each application as the TCP packet buffers are filled by the applications */
|
||||
|
@ -86,11 +86,11 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
|||
if ((ConnectionStateTable[CSTableEntry].Info.Buffer.Direction == TCP_PACKETDIR_OUT) &&
|
||||
(ConnectionStateTable[CSTableEntry].Info.Buffer.Ready))
|
||||
{
|
||||
Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData;
|
||||
IP_Header_t* IPHeaderOUT = (IP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];
|
||||
TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
|
||||
Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&RNDISInterfaceInfo->State.FrameOUT.FrameData;
|
||||
IP_Header_t* IPHeaderOUT = (IP_Header_t*)&RNDISInterfaceInfo->State.FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];
|
||||
TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)&RNDISInterfaceInfo->State.FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
|
||||
sizeof(IP_Header_t)];
|
||||
void* TCPDataOUT = &RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
|
||||
void* TCPDataOUT = &RNDISInterfaceInfo->State.FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
|
||||
sizeof(IP_Header_t) +
|
||||
sizeof(TCP_Header_t)];
|
||||
|
||||
|
@ -145,8 +145,8 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
|||
PacketSize += sizeof(Ethernet_Frame_Header_t);
|
||||
|
||||
/* Set the response length in the buffer and indicate that a response is ready to be sent */
|
||||
RNDISInterfaceInfo->FrameOUT.FrameLength = PacketSize;
|
||||
RNDISInterfaceInfo->FrameOUT.FrameInBuffer = true;
|
||||
RNDISInterfaceInfo->State.FrameOUT.FrameLength = PacketSize;
|
||||
RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer = true;
|
||||
|
||||
ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false;
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@
|
|||
TCP_PortState_t PortStateTable[MAX_OPEN_TCP_PORTS];
|
||||
|
||||
/* Function Prototypes: */
|
||||
void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
|
||||
void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo);
|
||||
void TCP_Init(void);
|
||||
bool TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*));
|
||||
uint8_t TCP_GetPortState(uint16_t Port);
|
||||
|
|
|
@ -40,21 +40,29 @@
|
|||
* passed to all RNDIS Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_RNDIS_t Ethernet_RNDIS_Interface =
|
||||
USB_ClassInfo_RNDIS_Device_t Ethernet_RNDIS_Interface =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = CDC_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataINEndpointNumber = CDC_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.DataOUTEndpointNumber = CDC_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataOUTEndpointNumber = CDC_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
|
||||
.AdapterVendorDescription = "LUFA RNDIS Demo Adapter",
|
||||
.AdapterMACAddress = {ADAPTER_MAC_ADDRESS},
|
||||
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
|
||||
.AdapterVendorDescription = "LUFA RNDIS Demo Adapter",
|
||||
.AdapterMACAddress = {ADAPTER_MAC_ADDRESS},
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -73,10 +81,10 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
if (Ethernet_RNDIS_Interface.FrameIN.FrameInBuffer)
|
||||
if (Ethernet_RNDIS_Interface.State.FrameIN.FrameInBuffer)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
Ethernet_ProcessPacket(&Ethernet_RNDIS_Interface.FrameIN, &Ethernet_RNDIS_Interface.FrameOUT);
|
||||
Ethernet_ProcessPacket(&Ethernet_RNDIS_Interface.State.FrameIN, &Ethernet_RNDIS_Interface.State.FrameOUT);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,18 +46,26 @@ RingBuff_t Tx_Buffer;
|
|||
* passed to all CDC Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface =
|
||||
USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
.Config =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = CDC_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataINEndpointNumber = CDC_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.DataOUTEndpointNumber = CDC_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataOUTEndpointNumber = CDC_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
},
|
||||
|
||||
.State =
|
||||
{
|
||||
// Leave all state values to their defaults
|
||||
}
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
|
@ -152,27 +160,38 @@ ISR(USART1_RX_vect, ISR_BLOCK)
|
|||
*
|
||||
* \param CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
|
||||
*/
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
|
||||
{
|
||||
uint8_t ConfigMask = 0;
|
||||
|
||||
if (CDCInterfaceInfo->LineEncoding.ParityType == CDC_PARITY_Odd)
|
||||
ConfigMask = ((1 << UPM11) | (1 << UPM10));
|
||||
else if (CDCInterfaceInfo->LineEncoding.ParityType == CDC_PARITY_Even)
|
||||
ConfigMask = (1 << UPM11);
|
||||
switch (CDCInterfaceInfo->State.LineEncoding.ParityType)
|
||||
{
|
||||
case CDC_PARITY_Odd:
|
||||
ConfigMask = ((1 << UPM11) | (1 << UPM10));
|
||||
break;
|
||||
case CDC_PARITY_Even:
|
||||
ConfigMask = (1 << UPM11);
|
||||
break;
|
||||
}
|
||||
|
||||
if (CDCInterfaceInfo->LineEncoding.CharFormat == CDC_LINEENCODING_TwoStopBits)
|
||||
if (CDCInterfaceInfo->State.LineEncoding.CharFormat == CDC_LINEENCODING_TwoStopBits)
|
||||
ConfigMask |= (1 << USBS1);
|
||||
|
||||
if (CDCInterfaceInfo->LineEncoding.DataBits == 6)
|
||||
ConfigMask |= (1 << UCSZ10);
|
||||
else if (CDCInterfaceInfo->LineEncoding.DataBits == 7)
|
||||
ConfigMask |= (1 << UCSZ11);
|
||||
else if (CDCInterfaceInfo->LineEncoding.DataBits == 8)
|
||||
ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
|
||||
switch (CDCInterfaceInfo->State.LineEncoding.DataBits)
|
||||
{
|
||||
case 6:
|
||||
ConfigMask |= (1 << UCSZ10);
|
||||
break;
|
||||
case 7:
|
||||
ConfigMask |= (1 << UCSZ11);
|
||||
break;
|
||||
case 8:
|
||||
ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
|
||||
break;
|
||||
}
|
||||
|
||||
UCSR1A = (1 << U2X1);
|
||||
UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
|
||||
UCSR1C = ConfigMask;
|
||||
UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)CDCInterfaceInfo->LineEncoding.BaudRateBPS);
|
||||
UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
|
||||
}
|
||||
|
|
|
@ -74,6 +74,6 @@
|
|||
void EVENT_USB_ConfigurationChanged(void);
|
||||
void EVENT_USB_UnhandledControlPacket(void);
|
||||
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,8 +40,13 @@
|
|||
* passed to all CDC Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface;
|
||||
|
||||
USB_ClassInfo_CDC_Host_t VirtualSerial_CDC_Interface =
|
||||
{
|
||||
.DataINPipeNumber = 1,
|
||||
.DataOUTPipeNumber = 2,
|
||||
.NotificationPipeNumber = 3,
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine configures the hardware required by the application, then
|
||||
* starts the scheduler to run the application tasks.
|
||||
*/
|
||||
|
@ -56,6 +61,7 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
CDC_Host_USBTask(&VirtualSerial_CDC_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,30 +81,36 @@
|
|||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
|
||||
const struct
|
||||
{
|
||||
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
|
||||
|
||||
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
|
||||
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
|
||||
|
||||
uint8_t ControlLineState; /**< Current control line states, as set by the host */
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
|
||||
|
||||
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
|
||||
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
|
||||
} Config;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
|
||||
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
|
||||
* CDCDevice_CDC_LineCodingFormats_t enum
|
||||
*/
|
||||
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
|
||||
* CDCDevice_LineCodingParity_t enum
|
||||
*/
|
||||
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
|
||||
} LineEncoding;
|
||||
uint8_t ControlLineState; /**< Current control line states, as set by the host */
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
|
||||
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
|
||||
* CDCDevice_CDC_LineCodingFormats_t enum
|
||||
*/
|
||||
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
|
||||
* CDCDevice_LineCodingParity_t enum
|
||||
*/
|
||||
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
|
||||
} LineEncoding;
|
||||
} State;
|
||||
} USB_ClassInfo_CDC_Host_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -349,27 +349,7 @@
|
|||
|
||||
uint8_t LockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification */
|
||||
uint16_t LockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry */
|
||||
} USB_AudioStreamEndpoint_Spc_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each Audio interface
|
||||
* within the user application, and passed to each of the Audio class driver functions as the
|
||||
* AudioInterfaceInfo parameter. The contents of this structure should be set to their correct
|
||||
* values when used, or ommitted to force the library to use default values.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the incomming Audio Streaming data, if available (zero if unused) */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the incomming Audio Streaming data endpoint, if available (zero if unused) */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing Audio Streaming data, if available (zero if unused) */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing Audio Streaming data endpoint, if available (zero if unused) */
|
||||
|
||||
bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints
|
||||
* of the Audio Streaming interface
|
||||
*/
|
||||
} USB_ClassInfo_Audio_t;
|
||||
} USB_AudioStreamEndpoint_Spc_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -140,40 +140,6 @@
|
|||
CDC_PARITY_Space = 4, /**< Space parity bit mode on each frame */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** Class state structure. An instance of this structure should be made for each CDC interface
|
||||
* within the user application, and passed to each of the CDC class driver functions as the
|
||||
* CDCInterfaceInfo parameter. The contents of this structure should be set to their correct
|
||||
* values when used, or ommitted to force the library to use default values.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
|
||||
|
||||
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
|
||||
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
|
||||
|
||||
uint8_t ControlLineState; /**< Current control line states, as set by the host */
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
|
||||
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
|
||||
* CDCDevice_CDC_LineCodingFormats_t enum
|
||||
*/
|
||||
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
|
||||
* CDCDevice_LineCodingParity_t enum
|
||||
*/
|
||||
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
|
||||
} LineEncoding;
|
||||
} USB_ClassInfo_CDC_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -71,42 +71,20 @@
|
|||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header;
|
||||
USB_Descriptor_Header_t Header;
|
||||
|
||||
uint16_t HIDSpec;
|
||||
uint8_t CountryCode;
|
||||
uint16_t HIDSpec;
|
||||
uint8_t CountryCode;
|
||||
|
||||
uint8_t TotalReportDescriptors;
|
||||
uint8_t TotalReportDescriptors;
|
||||
|
||||
uint8_t HIDReportType;
|
||||
uint16_t HIDReportLength;
|
||||
uint8_t HIDReportType;
|
||||
uint16_t HIDReportLength;
|
||||
} USB_Descriptor_HID_t;
|
||||
|
||||
/** Type define for the data type used to store HID report descriptor elements. */
|
||||
typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each HID interface
|
||||
* within the user application, and passed to each of the HID class driver functions as the
|
||||
* HIDInterfaceInfo parameter. The contents of this structure should be set to their correct
|
||||
* values when used, or ommitted to force the library to use default values.
|
||||
*
|
||||
* Note that for the HID class driver, host-to-device reports are received via HID class requests
|
||||
* rather than a dedicated endpoint to simplify the driver and its interface.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device */
|
||||
|
||||
uint8_t ReportINEndpointNumber; /**< Endpoint number of the HID interface's IN report endpoint */
|
||||
uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint */
|
||||
|
||||
uint8_t ReportINBufferSize; /**< Size of the largest possible report to send to the host, for buffer allocation purposes */
|
||||
|
||||
bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode */
|
||||
uint16_t IdleCount; /**< Report idle period, in ms, set by the host */
|
||||
uint16_t IdleMSRemaining; /**< Total number of ms remaining before the idle period elapses */
|
||||
} USB_ClassInfo_HID_t;
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -145,22 +145,6 @@
|
|||
uint8_t Data3; /**< Third byte of data in the MIDI event */
|
||||
} USB_MIDI_EventPacket_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each MIDI interface
|
||||
* within the user application, and passed to each of the MIDI class driver functions as the
|
||||
* MIDIInterfaceInfo parameter. The contents of this structure should be set to their correct
|
||||
* values when used, or ommitted to force the library to use default values.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the incomming MIDI data, if available (zero if unused) */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the incomming MIDI data endpoint, if available (zero if unused) */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing MIDI data, if available (zero if unused) */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing MIDI data endpoint, if available (zero if unused) */
|
||||
} USB_ClassInfo_MIDI_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -94,36 +94,6 @@
|
|||
SCSI_Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */
|
||||
SCSI_Phase_Error = 2 /**< Command failed due to being invalid in the current phase */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** Class state structure. An instance of this structure should be made for each Mass Storage interface
|
||||
* within the user application, and passed to each of the Mass Storage class driver functions as the
|
||||
* MSInterfaceInfo parameter. The contents of this structure should be set to their correct
|
||||
* values when used, or ommitted to force the library to use default values.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the Mass Storage interface's IN data endpoint */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the Mass Storage interface's IN data endpoint */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the Mass Storage interface's OUT data endpoint */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the Mass Storage interface's OUT data endpoint */
|
||||
|
||||
uint8_t TotalLUNs; /**< Total number of logical drives in the Mass Storage interface */
|
||||
|
||||
CommandBlockWrapper_t CommandBlock; /**< Mass Storage class command block structure, used internally
|
||||
* by the class driver
|
||||
*/
|
||||
CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, used internally
|
||||
* by the class driver
|
||||
*/
|
||||
|
||||
bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset
|
||||
* and that all current Mass Storage operations should immediately abort
|
||||
*/
|
||||
} USB_ClassInfo_MS_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -228,41 +228,6 @@
|
|||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
} RNDIS_QUERY_CMPLT_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each RNDIS interface
|
||||
* within the user application, and passed to each of the RNDIS class driver functions as the
|
||||
* RNDISInterfaceInfo parameter. The contents of this structure should be set to their correct
|
||||
* values when used, or ommitted to force the library to use default values.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
|
||||
|
||||
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
|
||||
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
|
||||
|
||||
char* AdapterVendorDescription; /**< String description of the adapter vendor */
|
||||
MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter */
|
||||
|
||||
uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE]; /**< Buffer to hold RNDIS messages to and from the host,
|
||||
* managed by the class driver
|
||||
*/
|
||||
bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host */
|
||||
uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the RNDIS_States_t enum */
|
||||
uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver */
|
||||
Ethernet_Frame_Info_t FrameIN; /**< Structure holding the last received Ethernet frame from the host, for user
|
||||
* processing
|
||||
*/
|
||||
Ethernet_Frame_Info_t FrameOUT; /**< Structure holding the next Ethernet frame to send to the host, populated by the
|
||||
* user application
|
||||
*/
|
||||
} USB_ClassInfo_RNDIS_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -33,12 +33,12 @@
|
|||
|
||||
#include "Audio.h"
|
||||
|
||||
void Audio_Device_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
|
||||
void Audio_Device_ProcessControlPacket(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != AudioInterfaceInfo->StreamingInterfaceNumber)
|
||||
if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
|
@ -48,7 +48,7 @@ void Audio_Device_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
AudioInterfaceInfo->InterfaceEnabled = (USB_ControlRequest.wValue != 0);
|
||||
AudioInterfaceInfo->State.InterfaceEnabled = (USB_ControlRequest.wValue != 0);
|
||||
|
||||
while (!(Endpoint_IsINReady()));
|
||||
Endpoint_ClearIN();
|
||||
|
@ -58,22 +58,22 @@ void Audio_Device_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo
|
|||
}
|
||||
}
|
||||
|
||||
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
|
||||
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo)
|
||||
{
|
||||
if (AudioInterfaceInfo->DataINEndpointNumber)
|
||||
if (AudioInterfaceInfo->Config.DataINEndpointNumber)
|
||||
{
|
||||
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataINEndpointNumber, EP_TYPE_ISOCHRONOUS,
|
||||
ENDPOINT_DIR_IN, AudioInterfaceInfo->DataINEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_ISOCHRONOUS,
|
||||
ENDPOINT_DIR_IN, AudioInterfaceInfo->Config.DataINEndpointSize,
|
||||
ENDPOINT_BANK_DOUBLE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (AudioInterfaceInfo->DataOUTEndpointNumber)
|
||||
if (AudioInterfaceInfo->Config.DataOUTEndpointNumber)
|
||||
{
|
||||
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_ISOCHRONOUS,
|
||||
ENDPOINT_DIR_OUT, AudioInterfaceInfo->DataOUTEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_ISOCHRONOUS,
|
||||
ENDPOINT_DIR_OUT, AudioInterfaceInfo->Config.DataOUTEndpointSize,
|
||||
ENDPOINT_BANK_DOUBLE)))
|
||||
{
|
||||
return false;
|
||||
|
@ -83,7 +83,7 @@ bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
|
|||
return true;
|
||||
}
|
||||
|
||||
void Audio_Device_USBTask(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
|
||||
void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -149,15 +149,15 @@ void Audio_Device_WriteSample24(int32_t Sample)
|
|||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
|
||||
bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo)
|
||||
{
|
||||
Endpoint_SelectEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
return Endpoint_IsOUTReceived();
|
||||
}
|
||||
|
||||
bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
|
||||
bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo)
|
||||
{
|
||||
Endpoint_SelectEndpoint(AudioInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataINEndpointNumber);
|
||||
return Endpoint_IsINReady();
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,57 @@
|
|||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** Configuration information structure for \ref USB_ClassInfo_Audio_Device_t Audio device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this
|
||||
* structure controls.
|
||||
*/
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the incomming Audio Streaming data, if available
|
||||
* (zero if unused).
|
||||
*/
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the incomming Audio Streaming data endpoint, if available
|
||||
* (zero if unused).
|
||||
*/
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing Audio Streaming data, if available
|
||||
* (zero if unused).
|
||||
*/
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing Audio Streaming data endpoint, if available
|
||||
* (zero if unused).
|
||||
*/
|
||||
} USB_ClassInfo_Audio_Device_Config_t;
|
||||
|
||||
/** Current State information structure for \ref USB_ClassInfo_Audio_Device_t Audio device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints
|
||||
* of the Audio Streaming interface.
|
||||
*/
|
||||
} USB_ClassInfo_Audio_Device_State_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each Audio interface
|
||||
* within the user application, and passed to each of the Audio class driver functions as the
|
||||
* AudioInterfaceInfo parameter. This stores each Audio interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const USB_ClassInfo_Audio_Device_Config_t Config; /**< Config data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail
|
||||
* to enumerate and operate correctly.
|
||||
*/
|
||||
|
||||
USB_ClassInfo_Audio_Device_State_t State; /**< State data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may
|
||||
* also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_Audio_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given Audio interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
|
||||
|
@ -61,21 +112,21 @@
|
|||
*
|
||||
* \return Boolean true if the endpoints were sucessfully configured, false otherwise
|
||||
*/
|
||||
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
|
||||
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo);
|
||||
|
||||
/** Processes incomming control requests from the host, that are directed to the given Audio class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_UnhandledControlPacket() event.
|
||||
*
|
||||
* \param AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*/
|
||||
void Audio_Device_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
|
||||
void Audio_Device_ProcessControlPacket(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo);
|
||||
|
||||
/** General management task for a given Audio class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*/
|
||||
void Audio_Device_USBTask(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
|
||||
void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo);
|
||||
|
||||
/** Reads the next 8-bit audio sample from the current audio interface.
|
||||
*
|
||||
|
@ -137,7 +188,7 @@
|
|||
*
|
||||
* \return Boolean true if the given Audio interface has a sample to be read, false otherwise
|
||||
*/
|
||||
bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
|
||||
bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo);
|
||||
|
||||
/** Determines if the given audio interface is ready to accept the next sample to be written to it.
|
||||
*
|
||||
|
@ -145,7 +196,7 @@
|
|||
*
|
||||
* \return Boolean true if the given Audio interface is ready to accept the next sample, false otherwise
|
||||
*/
|
||||
bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
|
||||
bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo);
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -39,12 +39,12 @@ void CDC_Device_Event_Stub(void)
|
|||
|
||||
}
|
||||
|
||||
void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
||||
void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != CDCInterfaceInfo->ControlInterfaceNumber)
|
||||
if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
|
@ -53,7 +53,7 @@ void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
|||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_Write_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));
|
||||
Endpoint_Write_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding));
|
||||
Endpoint_ClearOUT();
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
|||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));
|
||||
Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding));
|
||||
Endpoint_ClearIN();
|
||||
|
||||
EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo);
|
||||
|
@ -74,7 +74,7 @@ void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
CDCInterfaceInfo->ControlLineState = USB_ControlRequest.wValue;
|
||||
CDCInterfaceInfo->State.ControlLineState = USB_ControlRequest.wValue;
|
||||
|
||||
EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
|
||||
|
||||
|
@ -86,24 +86,24 @@ void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
|||
}
|
||||
}
|
||||
|
||||
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
||||
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_IN, CDCInterfaceInfo->DataINEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_IN, CDCInterfaceInfo->Config.DataINEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_OUT, CDCInterfaceInfo->DataOUTEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_OUT, CDCInterfaceInfo->Config.DataOUTEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,
|
||||
ENDPOINT_DIR_IN, CDCInterfaceInfo->NotificationEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber, EP_TYPE_INTERRUPT,
|
||||
ENDPOINT_DIR_IN, CDCInterfaceInfo->Config.NotificationEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
|
@ -112,12 +112,12 @@ bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
|||
return true;
|
||||
}
|
||||
|
||||
void CDC_Device_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
||||
void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
|
||||
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
return;
|
||||
|
@ -131,21 +131,21 @@ void CDC_Device_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
|||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
void CDC_Device_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length)
|
||||
void CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, char* Data, uint16_t Length)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
|
||||
Endpoint_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
|
||||
}
|
||||
|
||||
void CDC_Device_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data)
|
||||
void CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, uint8_t Data)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
|
||||
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
|
@ -156,19 +156,19 @@ void CDC_Device_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data)
|
|||
Endpoint_Write_Byte(Data);
|
||||
}
|
||||
|
||||
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
||||
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
|
||||
{
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
|
||||
return Endpoint_BytesInEndpoint();
|
||||
}
|
||||
|
||||
uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
||||
uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return 0;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
|
||||
uint8_t DataByte = Endpoint_Read_Byte();
|
||||
|
||||
|
@ -178,12 +178,12 @@ uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
|||
return DataByte;
|
||||
}
|
||||
|
||||
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask)
|
||||
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, uint16_t LineStateMask)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->NotificationEndpointNumber);
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber);
|
||||
|
||||
USB_Request_Header_t Notification = (USB_Request_Header_t)
|
||||
{
|
||||
|
|
|
@ -52,6 +52,60 @@
|
|||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** Configuration information structure for \ref USB_ClassInfo_CDC_Device_t CDC device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
|
||||
|
||||
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
|
||||
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
|
||||
} USB_ClassInfo_CDC_Device_Config_t;
|
||||
|
||||
/** Current State information structure for \ref USB_ClassInfo_CDC_Device_t CDC device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ControlLineState; /**< Current control line states, as set by the host */
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
|
||||
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
|
||||
* CDCDevice_CDC_LineCodingFormats_t enum
|
||||
*/
|
||||
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
|
||||
* CDCDevice_LineCodingParity_t enum
|
||||
*/
|
||||
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
|
||||
} LineEncoding;
|
||||
} USB_ClassInfo_CDC_Device_State_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each CDC interface
|
||||
* within the user application, and passed to each of the CDC class driver functions as the
|
||||
* CDCInterfaceInfo parameter. This stores each CDC interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const USB_ClassInfo_CDC_Device_Config_t Config; /**< Config data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail
|
||||
* to enumerate and operate correctly.
|
||||
*/
|
||||
|
||||
USB_ClassInfo_CDC_Device_State_t State; /**< State data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may
|
||||
* also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_CDC_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given CDC interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
|
||||
|
@ -61,21 +115,21 @@
|
|||
*
|
||||
* \return Boolean true if the endpoints were sucessfully configured, false otherwise
|
||||
*/
|
||||
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
|
||||
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
|
||||
|
||||
/** Processes incomming control requests from the host, that are directed to the given CDC class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_UnhandledControlPacket() event.
|
||||
*
|
||||
* \param CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*/
|
||||
void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
|
||||
void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
|
||||
|
||||
/** General management task for a given CDC class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*/
|
||||
void CDC_Device_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
|
||||
void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
|
||||
|
||||
/** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a
|
||||
* line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the
|
||||
|
@ -84,7 +138,7 @@
|
|||
*
|
||||
* \param CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*/
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
|
||||
|
||||
/** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
|
||||
* control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the
|
||||
|
@ -94,7 +148,7 @@
|
|||
*
|
||||
* \param CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*/
|
||||
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
|
||||
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
|
||||
|
||||
/** Sends a given string to the attached USB host, if connected. If a host is not connected when the function is called, the
|
||||
* string is discarded.
|
||||
|
@ -103,7 +157,7 @@
|
|||
* \param Data Pointer to the string to send to the host
|
||||
* \param Length Size in bytes of the string to send to the host
|
||||
*/
|
||||
void CDC_Device_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length);
|
||||
void CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, char* Data, uint16_t Length);
|
||||
|
||||
/** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
|
||||
* byte is discarded.
|
||||
|
@ -111,7 +165,7 @@
|
|||
* \param CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param Data Byte of data to send to the host
|
||||
*/
|
||||
void CDC_Device_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data);
|
||||
void CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, uint8_t Data);
|
||||
|
||||
/** Determines the number of bytes received by the CDC interface from the host, waiting to be read.
|
||||
*
|
||||
|
@ -119,7 +173,7 @@
|
|||
*
|
||||
* \return Total number of buffered bytes received from the host
|
||||
*/
|
||||
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
|
||||
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
|
||||
|
||||
/** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
|
||||
* returns 0. The USB_CDC_BytesReceived() function should be queried before data is recieved to ensure that no data
|
||||
|
@ -129,7 +183,7 @@
|
|||
*
|
||||
* \return Next received byte from the host, or 0 if no data received
|
||||
*/
|
||||
uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
|
||||
uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
|
||||
|
||||
/** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial control
|
||||
* lines (DCD, DSR, etc.) have changed states, or to give BREAK notfications to the host. Line states persist until they are
|
||||
|
@ -138,16 +192,16 @@
|
|||
* \param CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param LineStateMask Mask of CDC_CONTROL_LINE_IN_* masks giving the current control line states
|
||||
*/
|
||||
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask);
|
||||
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, uint16_t LineStateMask);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(INCLUDE_FROM_CDC_CLASS_DEVICE_C)
|
||||
void CDC_Device_Event_Stub(void);
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
|
||||
ATTR_WEAK ATTR_ALIAS(CDC_Device_Event_Stub);
|
||||
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
|
||||
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
|
||||
ATTR_WEAK ATTR_ALIAS(CDC_Device_Event_Stub);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -33,12 +33,12 @@
|
|||
|
||||
#include "HID.h"
|
||||
|
||||
void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
||||
void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != HIDInterfaceInfo->InterfaceNumber)
|
||||
if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
|
@ -48,7 +48,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
uint8_t ReportINData[HIDInterfaceInfo->ReportINBufferSize];
|
||||
uint8_t ReportINData[HIDInterfaceInfo->Config.ReportINBufferSize];
|
||||
uint16_t ReportINSize;
|
||||
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
|
||||
|
||||
|
@ -82,7 +82,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
Endpoint_Write_Byte(HIDInterfaceInfo->UsingReportProtocol);
|
||||
Endpoint_Write_Byte(HIDInterfaceInfo->State.UsingReportProtocol);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
while (!(Endpoint_IsOUTReceived()));
|
||||
|
@ -95,7 +95,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
HIDInterfaceInfo->UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);
|
||||
HIDInterfaceInfo->State.UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);
|
||||
|
||||
while (!(Endpoint_IsINReady()));
|
||||
Endpoint_ClearIN();
|
||||
|
@ -107,7 +107,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
HIDInterfaceInfo->IdleCount = ((USB_ControlRequest.wValue >> 8) << 2);
|
||||
HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue >> 8) << 2);
|
||||
|
||||
while (!(Endpoint_IsINReady()));
|
||||
Endpoint_ClearIN();
|
||||
|
@ -119,7 +119,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
Endpoint_Write_Byte(HIDInterfaceInfo->IdleCount >> 2);
|
||||
Endpoint_Write_Byte(HIDInterfaceInfo->State.IdleCount >> 2);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
while (!(Endpoint_IsOUTReceived()));
|
||||
|
@ -130,12 +130,12 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
|||
}
|
||||
}
|
||||
|
||||
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
||||
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo)
|
||||
{
|
||||
HIDInterfaceInfo->UsingReportProtocol = true;
|
||||
HIDInterfaceInfo->State.UsingReportProtocol = true;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->ReportINEndpointNumber, EP_TYPE_INTERRUPT,
|
||||
ENDPOINT_DIR_IN, HIDInterfaceInfo->ReportINEndpointSize, ENDPOINT_BANK_SINGLE)))
|
||||
if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber, EP_TYPE_INTERRUPT,
|
||||
ENDPOINT_DIR_IN, HIDInterfaceInfo->Config.ReportINEndpointSize, ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -143,20 +143,20 @@ bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
|||
return true;
|
||||
}
|
||||
|
||||
void HID_Device_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo)
|
||||
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(HIDInterfaceInfo->ReportINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
|
||||
|
||||
if (Endpoint_IsReadWriteAllowed() &&
|
||||
!(HIDInterfaceInfo->IdleCount && HIDInterfaceInfo->IdleMSRemaining))
|
||||
!(HIDInterfaceInfo->State.IdleCount && HIDInterfaceInfo->State.IdleMSRemaining))
|
||||
{
|
||||
if (HIDInterfaceInfo->IdleCount && !(HIDInterfaceInfo->IdleMSRemaining))
|
||||
HIDInterfaceInfo->IdleMSRemaining = HIDInterfaceInfo->IdleCount;
|
||||
if (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining))
|
||||
HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;
|
||||
|
||||
uint8_t ReportINData[HIDInterfaceInfo->ReportINBufferSize];
|
||||
uint8_t ReportINData[HIDInterfaceInfo->Config.ReportINBufferSize];
|
||||
uint16_t ReportINSize;
|
||||
uint8_t ReportID = 0;
|
||||
|
||||
|
|
|
@ -52,6 +52,48 @@
|
|||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** Configuration information structure for \ref USB_ClassInfo_HID_Device_t HID device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device */
|
||||
|
||||
uint8_t ReportINEndpointNumber; /**< Endpoint number of the HID interface's IN report endpoint */
|
||||
uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint */
|
||||
|
||||
uint8_t ReportINBufferSize; /**< Size of the largest possible report to send to the host, for
|
||||
* buffer allocation purposes
|
||||
*/
|
||||
} USB_ClassInfo_HID_Device_Config_t;
|
||||
|
||||
/** Current State information structure for \ref USB_ClassInfo_HID_Device_t HID device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode */
|
||||
uint16_t IdleCount; /**< Report idle period, in ms, set by the host */
|
||||
uint16_t IdleMSRemaining; /**< Total number of ms remaining before the idle period elapses */
|
||||
} USB_ClassInfo_HID_Device_State_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each HID interface
|
||||
* within the user application, and passed to each of the HID class driver functions as the
|
||||
* HIDInterfaceInfo parameter. This stores each HID interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const USB_ClassInfo_HID_Device_Config_t Config; /**< Config data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail
|
||||
* to enumerate and operate correctly.
|
||||
*/
|
||||
|
||||
USB_ClassInfo_HID_Device_State_t State; /**< State data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may
|
||||
* also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_HID_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given HID interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_ConfigurationChanged() event so that the endpoints are configured when the configuration
|
||||
|
@ -61,21 +103,21 @@
|
|||
*
|
||||
* \return Boolean true if the endpoints were sucessfully configured, false otherwise
|
||||
*/
|
||||
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo);
|
||||
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
|
||||
|
||||
/** Processes incomming control requests from the host, that are directed to the given HID class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_UnhandledControlPacket() event.
|
||||
*
|
||||
* \param HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
|
||||
*/
|
||||
void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo);
|
||||
void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
|
||||
|
||||
/** General management task for a given HID class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
|
||||
*/
|
||||
void HID_Device_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo);
|
||||
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
|
||||
|
||||
/** HID class driver callback for the user creation of a HID input report. This callback may fire in response to either
|
||||
* HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the
|
||||
|
@ -89,7 +131,7 @@
|
|||
*
|
||||
* \return Number of bytes in the generated input report, or zero if no report is to be sent
|
||||
*/
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
|
||||
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
|
||||
|
||||
/** HID class driver callback for the user processing of a received HID input report. This callback may fire in response to
|
||||
* either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback
|
||||
|
@ -101,7 +143,7 @@
|
|||
* \param ReportData Pointer to a buffer where the received HID report is stored.
|
||||
* \param ReportSize Size in bytes of the received report from the host.
|
||||
*/
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID, void* ReportData,
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo, uint8_t ReportID, void* ReportData,
|
||||
uint16_t ReportSize);
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
|
|
|
@ -33,27 +33,27 @@
|
|||
|
||||
#include "MIDI.h"
|
||||
|
||||
void MIDI_Device_ProcessControlPacket(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo)
|
||||
void MIDI_Device_ProcessControlPacket(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo)
|
||||
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo)
|
||||
{
|
||||
if (MIDIInterfaceInfo->DataINEndpointNumber)
|
||||
if (MIDIInterfaceInfo->Config.DataINEndpointNumber)
|
||||
{
|
||||
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_IN, MIDIInterfaceInfo->DataINEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_IN, MIDIInterfaceInfo->Config.DataINEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (MIDIInterfaceInfo->DataOUTEndpointNumber)
|
||||
if (MIDIInterfaceInfo->Config.DataOUTEndpointNumber)
|
||||
{
|
||||
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_OUT, MIDIInterfaceInfo->DataOUTEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_OUT, MIDIInterfaceInfo->Config.DataOUTEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
|
@ -63,17 +63,17 @@ bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo)
|
|||
return true;
|
||||
}
|
||||
|
||||
void MIDI_Device_USBTask(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo)
|
||||
void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo, USB_MIDI_EventPacket_t* Event)
|
||||
void MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo, USB_MIDI_EventPacket_t* Event)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(MIDIInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);
|
||||
|
||||
if (Endpoint_IsReadWriteAllowed());
|
||||
{
|
||||
|
@ -82,12 +82,12 @@ void MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo, USB_MI
|
|||
}
|
||||
}
|
||||
|
||||
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo, USB_MIDI_EventPacket_t* Event)
|
||||
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo, USB_MIDI_EventPacket_t* Event)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return false;
|
||||
|
||||
Endpoint_SelectEndpoint(MIDIInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
return false;
|
||||
|
|
|
@ -53,6 +53,45 @@
|
|||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Define: */
|
||||
/** Configuration information structure for \ref USB_ClassInfo_MIDI_Device_t MIDI device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the incomming MIDI data, if available (zero if unused) */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the incomming MIDI data endpoint, if available (zero if unused) */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing MIDI data, if available (zero if unused) */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing MIDI data endpoint, if available (zero if unused) */
|
||||
} USB_ClassInfo_MIDI_Device_Config_t;
|
||||
|
||||
/** Current State information structure for \ref USB_ClassInfo_MIDI_Device_t MIDI device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
|
||||
} USB_ClassInfo_MIDI_Device_State_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each MIDI interface
|
||||
* within the user application, and passed to each of the MIDI class driver functions as the
|
||||
* MIDIInterfaceInfo parameter. This stores each MIDI interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const USB_ClassInfo_MIDI_Device_Config_t Config; /**< Config data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail
|
||||
* to enumerate and operate correctly.
|
||||
*/
|
||||
|
||||
USB_ClassInfo_MIDI_Device_State_t State; /**< State data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may
|
||||
* also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_MIDI_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given MIDI interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_ConfigurationChanged() event so that the endpoints are configured when the configuration
|
||||
|
@ -62,28 +101,28 @@
|
|||
*
|
||||
* \return Boolean true if the endpoints were sucessfully configured, false otherwise
|
||||
*/
|
||||
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo);
|
||||
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo);
|
||||
|
||||
/** Processes incomming control requests from the host, that are directed to the given MIDI class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_UnhandledControlPacket() event.
|
||||
*
|
||||
* \param MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
*/
|
||||
void MIDI_Device_ProcessControlPacket(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo);
|
||||
void MIDI_Device_ProcessControlPacket(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo);
|
||||
|
||||
/** General management task for a given MIDI class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
*/
|
||||
void MIDI_Device_USBTask(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo);
|
||||
void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo);
|
||||
|
||||
/** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded.
|
||||
*
|
||||
* \param MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
* \param Event Pointer to a populated USB_MIDI_EventPacket_t structure containing the MIDI event to send
|
||||
*/
|
||||
void MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo, USB_MIDI_EventPacket_t* Event);
|
||||
void MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo, USB_MIDI_EventPacket_t* Event);
|
||||
|
||||
/** Receives a MIDI event packet from the host.
|
||||
*
|
||||
|
@ -92,7 +131,7 @@
|
|||
*
|
||||
* \return Boolean true if a MIDI event packet was received, false otherwise
|
||||
*/
|
||||
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_t* MIDIInterfaceInfo, USB_MIDI_EventPacket_t* Event);
|
||||
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* MIDIInterfaceInfo, USB_MIDI_EventPacket_t* Event);
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -34,14 +34,14 @@
|
|||
#define INCLUDE_FROM_MS_CLASS_DEVICE_C
|
||||
#include "MassStorage.h"
|
||||
|
||||
static USB_ClassInfo_MS_t* CallbackMSInterfaceInfo;
|
||||
static USB_ClassInfo_MS_Device_t* CallbackMSInterfaceInfo;
|
||||
|
||||
void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != MSInterfaceInfo->InterfaceNumber)
|
||||
if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
|
@ -51,7 +51,7 @@ void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
MSInterfaceInfo->IsMassStoreReset = true;
|
||||
MSInterfaceInfo->State.IsMassStoreReset = true;
|
||||
|
||||
while (!(Endpoint_IsINReady()));
|
||||
Endpoint_ClearIN();
|
||||
|
@ -63,7 +63,7 @@ void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
Endpoint_Write_Byte(MSInterfaceInfo->TotalLUNs - 1);
|
||||
Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1);
|
||||
|
||||
Endpoint_ClearIN();
|
||||
|
||||
|
@ -75,17 +75,17 @@ void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
}
|
||||
}
|
||||
|
||||
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_IN, MSInterfaceInfo->DataINEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_IN, MSInterfaceInfo->Config.DataINEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_OUT, MSInterfaceInfo->DataOUTEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_OUT, MSInterfaceInfo->Config.DataOUTEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
|
@ -94,109 +94,112 @@ bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
|||
return true;
|
||||
}
|
||||
|
||||
void MS_Device_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
|
||||
if (Endpoint_IsReadWriteAllowed())
|
||||
{
|
||||
if (MS_Device_ReadInCommandBlock(MSInterfaceInfo))
|
||||
{
|
||||
if (MSInterfaceInfo->CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
|
||||
if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
|
||||
|
||||
MSInterfaceInfo->CommandStatus.Status = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo) ?
|
||||
SCSI_Command_Pass : SCSI_Command_Fail;
|
||||
MSInterfaceInfo->CommandStatus.Signature = MS_CSW_SIGNATURE;
|
||||
MSInterfaceInfo->CommandStatus.Tag = MSInterfaceInfo->CommandBlock.Tag;
|
||||
MSInterfaceInfo->CommandStatus.DataTransferResidue = MSInterfaceInfo->CommandBlock.DataTransferLength;
|
||||
MSInterfaceInfo->State.CommandStatus.Status = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo) ?
|
||||
SCSI_Command_Pass : SCSI_Command_Fail;
|
||||
MSInterfaceInfo->State.CommandStatus.Signature = MS_CSW_SIGNATURE;
|
||||
MSInterfaceInfo->State.CommandStatus.Tag = MSInterfaceInfo->State.CommandBlock.Tag;
|
||||
MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength;
|
||||
|
||||
if ((MSInterfaceInfo->CommandStatus.Status == SCSI_Command_Fail) && (MSInterfaceInfo->CommandStatus.DataTransferResidue))
|
||||
Endpoint_StallTransaction();
|
||||
if ((MSInterfaceInfo->State.CommandStatus.Status == SCSI_Command_Fail) &&
|
||||
(MSInterfaceInfo->State.CommandStatus.DataTransferResidue))
|
||||
{
|
||||
Endpoint_StallTransaction();
|
||||
}
|
||||
|
||||
MS_Device_ReturnCommandStatus(MSInterfaceInfo);
|
||||
|
||||
if (MSInterfaceInfo->IsMassStoreReset)
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
{
|
||||
Endpoint_ResetFIFO(MSInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_ResetFIFO(MSInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_ResetFIFO(MSInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
Endpoint_ResetFIFO(MSInterfaceInfo->Config.DataINEndpointNumber);
|
||||
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
Endpoint_ClearStall();
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
|
||||
Endpoint_ClearStall();
|
||||
|
||||
MSInterfaceInfo->IsMassStoreReset = false;
|
||||
MSInterfaceInfo->State.IsMassStoreReset = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
|
||||
CallbackMSInterfaceInfo = MSInterfaceInfo;
|
||||
Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock,
|
||||
Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock,
|
||||
(sizeof(CommandBlockWrapper_t) - 16),
|
||||
StreamCallback_MS_Device_AbortOnMassStoreReset);
|
||||
|
||||
if ((MSInterfaceInfo->CommandBlock.Signature != MS_CBW_SIGNATURE) ||
|
||||
(MSInterfaceInfo->CommandBlock.LUN >= MSInterfaceInfo->TotalLUNs) ||
|
||||
(MSInterfaceInfo->CommandBlock.SCSICommandLength > 16))
|
||||
if ((MSInterfaceInfo->State.CommandBlock.Signature != MS_CBW_SIGNATURE) ||
|
||||
(MSInterfaceInfo->State.CommandBlock.LUN >= MSInterfaceInfo->Config.TotalLUNs) ||
|
||||
(MSInterfaceInfo->State.CommandBlock.SCSICommandLength > 16))
|
||||
{
|
||||
Endpoint_StallTransaction();
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
|
||||
Endpoint_StallTransaction();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CallbackMSInterfaceInfo = MSInterfaceInfo;
|
||||
Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock.SCSICommandData,
|
||||
MSInterfaceInfo->CommandBlock.SCSICommandLength,
|
||||
Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock.SCSICommandData,
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandLength,
|
||||
StreamCallback_MS_Device_AbortOnMassStoreReset);
|
||||
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
if (MSInterfaceInfo->IsMassStoreReset)
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo)
|
||||
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
|
||||
while (Endpoint_IsStalled())
|
||||
{
|
||||
USB_USBTask();
|
||||
|
||||
if (MSInterfaceInfo->IsMassStoreReset)
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
|
||||
|
||||
while (Endpoint_IsStalled())
|
||||
{
|
||||
USB_USBTask();
|
||||
|
||||
if (MSInterfaceInfo->IsMassStoreReset)
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
CallbackMSInterfaceInfo = MSInterfaceInfo;
|
||||
Endpoint_Write_Stream_LE(&MSInterfaceInfo->CommandStatus, sizeof(CommandStatusWrapper_t),
|
||||
Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus, sizeof(CommandStatusWrapper_t),
|
||||
StreamCallback_MS_Device_AbortOnMassStoreReset);
|
||||
|
||||
Endpoint_ClearIN();
|
||||
|
||||
if (MSInterfaceInfo->IsMassStoreReset)
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -204,7 +207,7 @@ static uint8_t StreamCallback_MS_Device_AbortOnMassStoreReset(void)
|
|||
{
|
||||
MS_Device_USBTask(CallbackMSInterfaceInfo);
|
||||
|
||||
if (CallbackMSInterfaceInfo->IsMassStoreReset)
|
||||
if (CallbackMSInterfaceInfo->State.IsMassStoreReset)
|
||||
return STREAMCALLBACK_Abort;
|
||||
else
|
||||
return STREAMCALLBACK_Continue;
|
||||
|
|
|
@ -52,6 +52,56 @@
|
|||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** Configuration information structure for \ref USB_ClassInfo_MS_Device_t Mass Storage device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the Mass Storage interface's IN data endpoint */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the Mass Storage interface's IN data endpoint */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the Mass Storage interface's OUT data endpoint */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the Mass Storage interface's OUT data endpoint */
|
||||
|
||||
uint8_t TotalLUNs; /**< Total number of logical drives in the Mass Storage interface */
|
||||
} USB_ClassInfo_MS_Device_Config_t;
|
||||
|
||||
/** Current State information structure for \ref USB_ClassInfo_MS_Device_t Mass Storage device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
CommandBlockWrapper_t CommandBlock; /**< Mass Storage class command block structure, used internally
|
||||
* by the class driver
|
||||
*/
|
||||
CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, used internally
|
||||
* by the class driver
|
||||
*/
|
||||
|
||||
bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset
|
||||
* and that all current Mass Storage operations should immediately abort
|
||||
*/
|
||||
} USB_ClassInfo_MS_Device_State_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each Mass Storage interface
|
||||
* within the user application, and passed to each of the Mass Storage class driver functions as the
|
||||
* MSInterfaceInfo parameter. This stores each Mass Storage interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const USB_ClassInfo_MS_Device_Config_t Config; /**< Config data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail
|
||||
* to enumerate and operate correctly.
|
||||
*/
|
||||
|
||||
USB_ClassInfo_MS_Device_State_t State; /**< State data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may
|
||||
* also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_MS_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given Mass Storage interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_ConfigurationChanged() event so that the endpoints are configured when the configuration
|
||||
|
@ -61,21 +111,21 @@
|
|||
*
|
||||
* \return Boolean true if the endpoints were sucessfully configured, false otherwise
|
||||
*/
|
||||
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
/** Processes incomming control requests from the host, that are directed to the given Mass Storage class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_UnhandledControlPacket() event.
|
||||
*
|
||||
* \param MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
|
||||
*/
|
||||
void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
/** General management task for a given Mass Storage class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param MSInterfaceInfo Pointer to a structure containing a Mass Storage configuration and state.
|
||||
*/
|
||||
void MS_Device_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
/** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the
|
||||
* host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible
|
||||
|
@ -86,14 +136,14 @@
|
|||
*
|
||||
* \return Boolean true if the SCSI command was successfully processed, false otherwise
|
||||
*/
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(INCLUDE_FROM_MS_CLASS_DEVICE_C)
|
||||
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo);
|
||||
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
static uint8_t StreamCallback_MS_Device_AbortOnMassStoreReset(void);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -65,12 +65,12 @@ static const uint32_t PROGMEM AdapterSupportedOIDList[] =
|
|||
OID_802_3_XMIT_MORE_COLLISIONS,
|
||||
};
|
||||
|
||||
void RNDIS_Device_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
||||
void RNDIS_Device_ProcessControlPacket(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->ControlInterfaceNumber)
|
||||
if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
|
@ -80,7 +80,7 @@ void RNDIS_Device_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, USB_ControlRequest.wLength);
|
||||
Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo);
|
||||
|
@ -92,15 +92,15 @@ void RNDIS_Device_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
|
||||
if (!(MessageHeader->MessageLength))
|
||||
{
|
||||
RNDISInterfaceInfo->RNDISMessageBuffer[0] = 0;
|
||||
RNDISInterfaceInfo->State.RNDISMessageBuffer[0] = 0;
|
||||
MessageHeader->MessageLength = 1;
|
||||
}
|
||||
|
||||
Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, MessageHeader->MessageLength);
|
||||
Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, MessageHeader->MessageLength);
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
MessageHeader->MessageLength = 0;
|
||||
|
@ -110,24 +110,24 @@ void RNDIS_Device_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo
|
|||
}
|
||||
}
|
||||
|
||||
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
||||
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_IN, RNDISInterfaceInfo->DataINEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_IN, RNDISInterfaceInfo->Config.DataINEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_OUT, RNDISInterfaceInfo->DataOUTEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_OUT, RNDISInterfaceInfo->Config.DataOUTEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,
|
||||
ENDPOINT_DIR_IN, RNDISInterfaceInfo->NotificationEndpointSize,
|
||||
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.NotificationEndpointNumber, EP_TYPE_INTERRUPT,
|
||||
ENDPOINT_DIR_IN, RNDISInterfaceInfo->Config.NotificationEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE)))
|
||||
{
|
||||
return false;
|
||||
|
@ -136,16 +136,16 @@ bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
|||
return true;
|
||||
}
|
||||
|
||||
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
||||
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo)
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return;
|
||||
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber);
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpointNumber);
|
||||
|
||||
if (Endpoint_IsINReady() && RNDISInterfaceInfo->ResponseReady)
|
||||
if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady)
|
||||
{
|
||||
USB_Request_Header_t Notification = (USB_Request_Header_t)
|
||||
{
|
||||
|
@ -160,16 +160,16 @@ void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
|||
|
||||
Endpoint_ClearIN();
|
||||
|
||||
RNDISInterfaceInfo->ResponseReady = false;
|
||||
RNDISInterfaceInfo->State.ResponseReady = false;
|
||||
}
|
||||
|
||||
if ((RNDISInterfaceInfo->CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
|
||||
if ((RNDISInterfaceInfo->State.CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
|
||||
{
|
||||
RNDIS_PACKET_MSG_t RNDISPacketHeader;
|
||||
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber);
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||
|
||||
if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->FrameIN.FrameInBuffer))
|
||||
if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->State.FrameIN.FrameInBuffer))
|
||||
{
|
||||
Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);
|
||||
|
||||
|
@ -179,49 +179,49 @@ void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
|||
return;
|
||||
}
|
||||
|
||||
Endpoint_Read_Stream_LE(RNDISInterfaceInfo->FrameIN.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
|
||||
Endpoint_Read_Stream_LE(RNDISInterfaceInfo->State.FrameIN.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
|
||||
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
RNDISInterfaceInfo->FrameIN.FrameLength = RNDISPacketHeader.DataLength;
|
||||
RNDISInterfaceInfo->State.FrameIN.FrameLength = RNDISPacketHeader.DataLength;
|
||||
|
||||
RNDISInterfaceInfo->FrameIN.FrameInBuffer = true;
|
||||
RNDISInterfaceInfo->State.FrameIN.FrameInBuffer = true;
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataINEndpointNumber);
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber);
|
||||
|
||||
if (Endpoint_IsINReady() && RNDISInterfaceInfo->FrameOUT.FrameInBuffer)
|
||||
if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer)
|
||||
{
|
||||
memset(&RNDISPacketHeader, 0, sizeof(RNDIS_PACKET_MSG_t));
|
||||
|
||||
RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG;
|
||||
RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + RNDISInterfaceInfo->FrameOUT.FrameLength);
|
||||
RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + RNDISInterfaceInfo->State.FrameOUT.FrameLength);
|
||||
RNDISPacketHeader.DataOffset = (sizeof(RNDIS_PACKET_MSG_t) - sizeof(RNDIS_Message_Header_t));
|
||||
RNDISPacketHeader.DataLength = RNDISInterfaceInfo->FrameOUT.FrameLength;
|
||||
RNDISPacketHeader.DataLength = RNDISInterfaceInfo->State.FrameOUT.FrameLength;
|
||||
|
||||
Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_LE(RNDISInterfaceInfo->FrameOUT.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_LE(RNDISInterfaceInfo->State.FrameOUT.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
RNDISInterfaceInfo->FrameOUT.FrameInBuffer = false;
|
||||
RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
||||
void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo)
|
||||
{
|
||||
/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
|
||||
this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
|
||||
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
|
||||
switch (MessageHeader->MessageType)
|
||||
{
|
||||
case REMOTE_NDIS_INITIALIZE_MSG:
|
||||
RNDISInterfaceInfo->ResponseReady = true;
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_INITIALIZE_MSG_t* INITIALIZE_Message = (RNDIS_INITIALIZE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_INITIALIZE_MSG_t* INITIALIZE_Message = (RNDIS_INITIALIZE_MSG_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
|
||||
INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
|
||||
INITIALIZE_Response->MessageLength = sizeof(RNDIS_INITIALIZE_CMPLT_t);
|
||||
|
@ -238,26 +238,26 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfa
|
|||
INITIALIZE_Response->AFListOffset = 0;
|
||||
INITIALIZE_Response->AFListSize = 0;
|
||||
|
||||
RNDISInterfaceInfo->CurrRNDISState = RNDIS_Initialized;
|
||||
RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_HALT_MSG:
|
||||
RNDISInterfaceInfo->ResponseReady = false;
|
||||
RNDISInterfaceInfo->State.ResponseReady = false;
|
||||
MessageHeader->MessageLength = 0;
|
||||
|
||||
RNDISInterfaceInfo->CurrRNDISState = RNDIS_Uninitialized;
|
||||
RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_QUERY_MSG:
|
||||
RNDISInterfaceInfo->ResponseReady = true;
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_QUERY_MSG_t* QUERY_Message = (RNDIS_QUERY_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_QUERY_MSG_t* QUERY_Message = (RNDIS_QUERY_MSG_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
uint32_t Query_Oid = QUERY_Message->Oid;
|
||||
|
||||
void* QueryData = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
void* QueryData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
QUERY_Message->InformationBufferOffset];
|
||||
void* ResponseData = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];
|
||||
void* ResponseData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];
|
||||
uint16_t ResponseSize;
|
||||
|
||||
QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
|
@ -282,17 +282,17 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfa
|
|||
|
||||
break;
|
||||
case REMOTE_NDIS_SET_MSG:
|
||||
RNDISInterfaceInfo->ResponseReady = true;
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_SET_MSG_t* SET_Message = (RNDIS_SET_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_SET_MSG_t* SET_Message = (RNDIS_SET_MSG_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
uint32_t SET_Oid = SET_Message->Oid;
|
||||
|
||||
SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
SET_Response->MessageLength = sizeof(RNDIS_SET_CMPLT_t);
|
||||
SET_Response->RequestId = SET_Message->RequestId;
|
||||
|
||||
void* SetData = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
void* SetData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
SET_Message->InformationBufferOffset];
|
||||
|
||||
if (RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData, SET_Message->InformationBufferLength))
|
||||
|
@ -302,9 +302,9 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfa
|
|||
|
||||
break;
|
||||
case REMOTE_NDIS_RESET_MSG:
|
||||
RNDISInterfaceInfo->ResponseReady = true;
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
|
||||
RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
|
||||
RESET_Response->MessageLength = sizeof(RNDIS_RESET_CMPLT_t);
|
||||
|
@ -313,10 +313,10 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfa
|
|||
|
||||
break;
|
||||
case REMOTE_NDIS_KEEPALIVE_MSG:
|
||||
RNDISInterfaceInfo->ResponseReady = true;
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_KEEPALIVE_MSG_t* KEEPALIVE_Message = (RNDIS_KEEPALIVE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
|
||||
RNDIS_KEEPALIVE_MSG_t* KEEPALIVE_Message = (RNDIS_KEEPALIVE_MSG_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
|
||||
|
||||
KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
|
||||
KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KEEPALIVE_CMPLT_t);
|
||||
|
@ -327,7 +327,7 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfa
|
|||
}
|
||||
}
|
||||
|
||||
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo,
|
||||
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo,
|
||||
uint32_t OId, void* QueryData, uint16_t QuerySize,
|
||||
void* ResponseData, uint16_t* ResponseSize)
|
||||
{
|
||||
|
@ -375,9 +375,9 @@ static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceI
|
|||
|
||||
return true;
|
||||
case OID_GEN_VENDOR_DESCRIPTION:
|
||||
*ResponseSize = (strlen(RNDISInterfaceInfo->AdapterVendorDescription) + 1);
|
||||
*ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1);
|
||||
|
||||
memcpy(ResponseData, RNDISInterfaceInfo->AdapterVendorDescription, *ResponseSize);
|
||||
memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize);
|
||||
|
||||
return true;
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
|
@ -397,7 +397,7 @@ static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceI
|
|||
case OID_802_3_CURRENT_ADDRESS:
|
||||
*ResponseSize = sizeof(MAC_Address_t);
|
||||
|
||||
memcpy(ResponseData, &RNDISInterfaceInfo->AdapterMACAddress, sizeof(MAC_Address_t));
|
||||
memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t));
|
||||
|
||||
return true;
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
|
@ -410,7 +410,7 @@ static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceI
|
|||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
*((uint32_t*)ResponseData) = RNDISInterfaceInfo->CurrPacketFilter;
|
||||
*((uint32_t*)ResponseData) = RNDISInterfaceInfo->State.CurrPacketFilter;
|
||||
|
||||
return true;
|
||||
case OID_GEN_XMIT_OK:
|
||||
|
@ -439,13 +439,14 @@ static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceI
|
|||
}
|
||||
}
|
||||
|
||||
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId, void* SetData, uint16_t SetSize)
|
||||
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo, uint32_t OId, void* SetData,
|
||||
uint16_t SetSize)
|
||||
{
|
||||
switch (OId)
|
||||
{
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
RNDISInterfaceInfo->CurrPacketFilter = *((uint32_t*)SetData);
|
||||
RNDISInterfaceInfo->CurrRNDISState = ((RNDISInterfaceInfo->CurrPacketFilter) ?
|
||||
RNDISInterfaceInfo->State.CurrPacketFilter = *((uint32_t*)SetData);
|
||||
RNDISInterfaceInfo->State.CurrRNDISState = ((RNDISInterfaceInfo->State.CurrPacketFilter) ?
|
||||
RNDIS_Data_Initialized : RNDIS_Data_Initialized);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -53,6 +53,62 @@
|
|||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** Configuration information structure for \ref USB_ClassInfo_RNDIS_Device_t RNDIS device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
|
||||
|
||||
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
|
||||
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
|
||||
|
||||
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
|
||||
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
|
||||
|
||||
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
|
||||
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
|
||||
|
||||
char* AdapterVendorDescription; /**< String description of the adapter vendor */
|
||||
MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter */
|
||||
} USB_ClassInfo_MS_Device_Config_t;
|
||||
|
||||
/** Current State information structure for \ref USB_ClassInfo_RNDIS_Device_t RNDIS device interface structures. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE]; /**< Buffer to hold RNDIS messages to and from the host,
|
||||
* managed by the class driver
|
||||
*/
|
||||
bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host */
|
||||
uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the RNDIS_States_t enum */
|
||||
uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver */
|
||||
Ethernet_Frame_Info_t FrameIN; /**< Structure holding the last received Ethernet frame from the host, for user
|
||||
* processing
|
||||
*/
|
||||
Ethernet_Frame_Info_t FrameOUT; /**< Structure holding the next Ethernet frame to send to the host, populated by the
|
||||
* user application
|
||||
*/
|
||||
} USB_ClassInfo_MS_Device_State_t;
|
||||
|
||||
/** Class state structure. An instance of this structure should be made for each RNDIS interface
|
||||
* within the user application, and passed to each of the RNDIS class driver functions as the
|
||||
* RNDISInterfaceInfo parameter. This stores each RNDIS interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const USB_ClassInfo_MS_Device_Config_t Config; /**< Config data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail
|
||||
* to enumerate and operate correctly.
|
||||
*/
|
||||
|
||||
USB_ClassInfo_MS_Device_State_t State; /**< State data for the USB class interface within
|
||||
* the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may
|
||||
* also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_RNDIS_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given RNDIS interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_ConfigurationChanged() event so that the endpoints are configured when the configuration
|
||||
|
@ -62,31 +118,31 @@
|
|||
*
|
||||
* \return Boolean true if the endpoints were sucessfully configured, false otherwise
|
||||
*/
|
||||
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
|
||||
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo);
|
||||
|
||||
/** Processes incomming control requests from the host, that are directed to the given RNDIS class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_UnhandledControlPacket() event.
|
||||
*
|
||||
* \param RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
|
||||
*/
|
||||
void RNDIS_Device_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
|
||||
void RNDIS_Device_ProcessControlPacket(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo);
|
||||
|
||||
/** General management task for a given HID class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
|
||||
*/
|
||||
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
|
||||
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(INCLUDE_FROM_RNDIS_CLASS_DEVICE_C)
|
||||
static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
|
||||
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo,
|
||||
static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo);
|
||||
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo,
|
||||
uint32_t OId, void* QueryData, uint16_t QuerySize,
|
||||
void* ResponseData, uint16_t* ResponseSize);
|
||||
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId,
|
||||
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo, uint32_t OId,
|
||||
void* SetData, uint16_t SetSize);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -41,22 +41,22 @@ static uint8_t CDC_Host_ProcessConfigDescriptor(void)
|
|||
uint8_t FoundEndpoints = 0;
|
||||
|
||||
if (USB_GetDeviceConfigDescriptor(&ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
|
||||
return ControlError;
|
||||
return CDC_ENUMERROR_ControlError;
|
||||
|
||||
if (ConfigDescriptorSize > 512)
|
||||
return DescriptorTooLarge;
|
||||
return CDC_ENUMERROR_DescriptorTooLarge;
|
||||
|
||||
ConfigDescriptorData = alloca(ConfigDescriptorSize);
|
||||
|
||||
USB_GetDeviceConfigDescriptor(&ConfigDescriptorSize, ConfigDescriptorData);
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return InvalidConfigDataReturned;
|
||||
return CDC_ENUMERROR_InvalidConfigDataReturned;
|
||||
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DComp_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return NoCDCInterfaceFound;
|
||||
return CDC_ENUMERROR_NoCDCInterfaceFound;
|
||||
}
|
||||
|
||||
while (FoundEndpoints != ((1 << CDC_NOTIFICATIONPIPE) | (1 << CDC_DATAPIPE_IN) | (1 << CDC_DATAPIPE_OUT)))
|
||||
|
@ -72,7 +72,7 @@ static uint8_t CDC_Host_ProcessConfigDescriptor(void)
|
|||
DComp_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
/* Descriptor not found, error out */
|
||||
return NoCDCInterfaceFound;
|
||||
return CDC_ENUMERROR_NoCDCInterfaceFound;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -89,14 +89,14 @@ static uint8_t CDC_Host_ProcessConfigDescriptor(void)
|
|||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DComp_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return NoCDCInterfaceFound;
|
||||
return CDC_ENUMERROR_NoCDCInterfaceFound;
|
||||
}
|
||||
}
|
||||
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DComp_CDC_Host_NextInterfaceCDCDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return NoEndpointFound;
|
||||
return CDC_ENUMERROR_NoEndpointFound;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ static uint8_t CDC_Host_ProcessConfigDescriptor(void)
|
|||
}
|
||||
}
|
||||
|
||||
return SuccessfulConfigRead;
|
||||
return CDC_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* CurrentDescriptor)
|
||||
|
@ -192,25 +192,19 @@ static uint8_t DComp_CDC_Host_NextInterfaceCDCDataEndpoint(void* CurrentDescript
|
|||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
void CDC_Host_Task(void)
|
||||
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_SetConfiguration,
|
||||
.wValue = 1,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
if ((ErrorCode = CDC_Host_ProcessConfigDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
}
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
}
|
||||
|
@ -218,10 +212,6 @@ void CDC_Host_Task(void)
|
|||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
if ((ErrorCode = CDC_Host_ProcessConfigDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
}
|
||||
|
||||
USB_HostState = HOST_STATE_Ready;
|
||||
break;
|
||||
|
|
|
@ -53,8 +53,6 @@
|
|||
/* Type Defines: */
|
||||
typedef struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if this class driver is currently attached to the device */
|
||||
|
||||
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
|
||||
|
||||
uint8_t DataINPipeNumber; /**< Pipe number of the CDC interface's IN data pipe */
|
||||
|
@ -63,8 +61,8 @@
|
|||
uint8_t DataOUTPipeNumber; /**< Pipe number of the CDC interface's OUT data pipe */
|
||||
uint16_t DataOUTPipeSize; /**< Size in bytes of the CDC interface's OUT data pipe */
|
||||
|
||||
uint8_t NotificationEndpointNumber; /**< Pipe number of the CDC interface's IN notification endpoint, if used */
|
||||
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
|
||||
uint8_t NotificationPipeNumber; /**< Pipe number of the CDC interface's IN notification endpoint, if used */
|
||||
uint16_t NotificationPipeSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
|
||||
|
||||
uint8_t ControlLineState; /**< Current control line states */
|
||||
|
||||
|
@ -80,9 +78,20 @@
|
|||
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
|
||||
} LineEncoding;
|
||||
} USB_ClassInfo_CDC_Host_t;
|
||||
|
||||
/* Enums: */
|
||||
typedef enum
|
||||
{
|
||||
CDC_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
|
||||
CDC_ENUMERROR_ControlError = 1, /**< A control request to the device failed to complete successfully */
|
||||
CDC_ENUMERROR_DescriptorTooLarge = 2, /**< The device's Configuration Descriptor is too large to process */
|
||||
CDC_ENUMERROR_InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */
|
||||
CDC_ENUMERROR_NoCDCInterfaceFound = 4, /**< A compatible CDC interface was not found in the device's Configuration Descriptor */
|
||||
CDC_ENUMERROR_NoEndpointFound = 5, /**< Compatible CDC endpoints were not found in the device's CDC interface */
|
||||
} CDCHost_EnumerationFailure_ErrorCodes_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void CDC_Host_Task(void);
|
||||
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
|
|
@ -22,6 +22,5 @@
|
|||
* - Remake AVRStudio project files
|
||||
* - Master LUFA include file
|
||||
* - Debug mode for pipe/endpoint calls
|
||||
* - Device descriptor get routines
|
||||
* - Add ClearPipeStall host function
|
||||
* - Add hub support to match Atmel's stack (thanks to the Atmel engineer who said it wasn't possible :P)
|
||||
*/
|
||||
|
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim 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, 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.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* USB Device Configuration Descriptor processing routines, to determine the correct pipe configurations
|
||||
* needed to communication with an attached USB device. Descriptors are special computer-readable structures
|
||||
* which the host requests upon device enumeration, to determine the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "ConfigDescriptor.h"
|
||||
|
||||
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This
|
||||
* routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate
|
||||
* with compatible devices.
|
||||
*
|
||||
* This routine searches for a HID interface descriptor containing at least one Interrupt type IN endpoint.
|
||||
*
|
||||
* \return An error code from the GenericHIDHost_GetConfigDescriptorDataCodes_t enum.
|
||||
*/
|
||||
uint8_t ProcessConfigurationDescriptor(void)
|
||||
{
|
||||
uint8_t* ConfigDescriptorData;
|
||||
uint16_t ConfigDescriptorSize;
|
||||
|
||||
uint8_t FoundEndpoints = 0;
|
||||
|
||||
/* Get Configuration Descriptor size from the device */
|
||||
if (USB_GetDeviceConfigDescriptor(&ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
|
||||
return ControlError;
|
||||
|
||||
/* Ensure that the Configuration Descriptor isn't too large */
|
||||
if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
|
||||
return DescriptorTooLarge;
|
||||
|
||||
/* Allocate enough memory for the entire config descriptor */
|
||||
ConfigDescriptorData = alloca(ConfigDescriptorSize);
|
||||
|
||||
/* Retrieve the entire configuration descriptor into the allocated buffer */
|
||||
USB_GetDeviceConfigDescriptor(&ConfigDescriptorSize, ConfigDescriptorData);
|
||||
|
||||
/* Validate returned data - ensure first entry is a configuration header descriptor */
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return InvalidConfigDataReturned;
|
||||
|
||||
/* Get the HID interface from the configuration descriptor */
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DComp_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
/* Descriptor not found, error out */
|
||||
return NoHIDInterfaceFound;
|
||||
}
|
||||
|
||||
while (FoundEndpoints != ((1 << HID_DATA_IN_PIPE) | (1 << HID_DATA_OUT_PIPE)))
|
||||
{
|
||||
/* Get the next HID interface's data endpoint descriptor */
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DComp_NextInterfaceHIDDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
/* Not all HID devices have an OUT endpoint - if we've reached the end of the HID descriptor
|
||||
* but only found the mandatory IN endpoint, it's safe to continue with the device enumeration */
|
||||
if (FoundEndpoints == (1 << HID_DATA_IN_PIPE))
|
||||
break;
|
||||
|
||||
/* Descriptor not found, error out */
|
||||
return NoEndpointFound;
|
||||
}
|
||||
|
||||
/* Retrieve the endpoint address from the endpoint descriptor */
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
/* If the endpoint is a IN type endpoint */
|
||||
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
|
||||
{
|
||||
/* Configure the HID data IN pipe */
|
||||
Pipe_ConfigurePipe(HID_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
|
||||
|
||||
Pipe_SetInfiniteINRequests();
|
||||
|
||||
FoundEndpoints |= (1 << HID_DATA_IN_PIPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Configure the HID data OUT pipe */
|
||||
Pipe_ConfigurePipe(HID_DATA_OUT_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
|
||||
|
||||
FoundEndpoints |= (1 << HID_DATA_OUT_PIPE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Valid data found, return success */
|
||||
return SuccessfulConfigRead;
|
||||
}
|
||||
|
||||
/** Descriptor comparator function. This comparator function is can be called while processing an attached USB device's
|
||||
* configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
|
||||
* descriptor processing if an incompatible descriptor configuration is found.
|
||||
*
|
||||
* This comparator searches for the next Interface descriptor of the correct HID Class value.
|
||||
*
|
||||
* \return A value from the DSEARCH_Return_ErrorCodes_t enum
|
||||
*/
|
||||
uint8_t DComp_NextHIDInterface(void* CurrentDescriptor)
|
||||
{
|
||||
/* Determine if the current descriptor is an interface descriptor */
|
||||
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
|
||||
{
|
||||
/* Check the HID descriptor class and protocol, break out if correct class/protocol interface found */
|
||||
if (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class == HID_CLASS)
|
||||
{
|
||||
/* Indicate that the descriptor being searched for has been found */
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
/* Current descriptor does not match what this comparator is looking for */
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
/** Descriptor comparator function. This comparator function is can be called while processing an attached USB device's
|
||||
* configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
|
||||
* descriptor processing if an incompatible descriptor configuration is found.
|
||||
*
|
||||
* This comparator searches for the next Endpoint descriptor inside the current interface descriptor,
|
||||
* aborting the search if another interface descriptor is found before the required endpoint.
|
||||
*
|
||||
* \return A value from the DSEARCH_Return_ErrorCodes_t enum
|
||||
*/
|
||||
uint8_t DComp_NextInterfaceHIDDataEndpoint(void* CurrentDescriptor)
|
||||
{
|
||||
/* Determine the type of the current descriptor */
|
||||
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
|
||||
{
|
||||
/* Indicate that the descriptor being searched for has been found */
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
|
||||
{
|
||||
/* Indicate that the search has failed prematurely and should be aborted */
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
/* Current descriptor does not match what this comparator is looking for */
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim 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, 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.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for ConfigDescriptor.c.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIGDESCRIPTOR_H_
|
||||
#define _CONFIGDESCRIPTOR_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include "MissileLauncher.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Interface Class value for the Human Interface Device class */
|
||||
#define HID_CLASS 0x03
|
||||
|
||||
/** Maximum size of a device configuration descriptor which can be processed by the host, in bytes */
|
||||
#define MAX_CONFIG_DESCRIPTOR_SIZE 512
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible return codes of the ProcessConfigurationDescriptor() function. */
|
||||
enum GenericHIDHost_GetConfigDescriptorDataCodes_t
|
||||
{
|
||||
SuccessfulConfigRead = 0, /**< Configuration Descriptor was processed successfully */
|
||||
ControlError = 1, /**< A control request to the device failed to complete successfully */
|
||||
DescriptorTooLarge = 2, /**< The device's Configuration Descriptor is too large to process */
|
||||
InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */
|
||||
NoHIDInterfaceFound = 4, /**< A compatible HID interface was not found in the device's Configuration Descriptor */
|
||||
NoEndpointFound = 5, /**< A compatible HID IN endpoint was not found in the device's HID interface */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
uint8_t ProcessConfigurationDescriptor(void);
|
||||
|
||||
uint8_t DComp_NextHIDInterface(void* CurrentDescriptor);
|
||||
uint8_t DComp_NextInterfaceHIDDataEndpoint(void* CurrentDescriptor);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,346 +0,0 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
USB Missle Launcher Demo
|
||||
Copyright (C) Dave Fletcher, 2009.
|
||||
fletch at fletchtronics dot net
|
||||
|
||||
Based on research by Scott Weston at
|
||||
http://code.google.com/p/pymissle
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2009 Dave Fletcher (fletch [at] fletchtronics [dot] net)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim 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, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Missle Launcher host. This is a host driver for the popular USB-controller table top toy missle launchers,
|
||||
* which can typically aim and fire small foam "missles" from a spring-loaded turret. This project controls the
|
||||
* launcher via a joystick and button to aim and fire missles at targets without a PC.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the MissileLauncher application. This file contains the main tasks of
|
||||
* the application and is responsible for the initial application hardware configuration as well
|
||||
* as the sending of commands to the attached launcher toy.
|
||||
*/
|
||||
|
||||
#include "MissileLauncher.h"
|
||||
|
||||
/** Launcher first init command report data sequence */
|
||||
static const uint8_t CMD_INITA[8] = { 85, 83, 66, 67, 0, 0, 4, 0 };
|
||||
|
||||
/** Launcher second init command report data sequence */
|
||||
static const uint8_t CMD_INITB[8] = { 85, 83, 66, 67, 0, 64, 2, 0 };
|
||||
|
||||
/** Launcher command report data sequence to stop all movement */
|
||||
static const uint8_t CMD_STOP[8] = { 0, 0, 0, 0, 0, 0, 8, 8 };
|
||||
|
||||
/** Launcher command report data sequence to move left */
|
||||
static const uint8_t CMD_LEFT[8] = { 0, 1, 0, 0, 0, 0, 8, 8 };
|
||||
|
||||
/** Launcher command report data sequence to move right */
|
||||
static const uint8_t CMD_RIGHT[8] = { 0, 0, 1, 0, 0, 0, 8, 8 };
|
||||
|
||||
/** Launcher command report data sequence to move up */
|
||||
static const uint8_t CMD_UP[8] = { 0, 0, 0, 1, 0, 0, 8, 8 };
|
||||
|
||||
/** Launcher command report data sequence to move down */
|
||||
static const uint8_t CMD_DOWN[8] = { 0, 0, 0, 0, 1, 0, 8, 8 };
|
||||
|
||||
/** Launcher command report data sequence to move left and up */
|
||||
static const uint8_t CMD_LEFTUP[8] = { 0, 1, 0, 1, 0, 0, 8, 8 };
|
||||
|
||||
/** Launcher command report data sequence to move right and up */
|
||||
static const uint8_t CMD_RIGHTUP[8] = { 0, 0, 1, 1, 0, 0, 8, 8 };
|
||||
|
||||
/** Launcher command report data sequence to move left and down */
|
||||
static const uint8_t CMD_LEFTDOWN[8] = { 0, 1, 0, 0, 1, 0, 8, 8 };
|
||||
|
||||
/** Launcher command report data sequence to move right and down */
|
||||
static const uint8_t CMD_RIGHTDOWN[8] = { 0, 0, 1, 0, 1, 0, 8, 8 };
|
||||
|
||||
/** Launcher command report data sequence to fire a missle */
|
||||
static const uint8_t CMD_FIRE[8] = { 0, 0, 0, 0, 0, 1, 8, 8 };
|
||||
|
||||
/** Last command sent to the launcher, to determine what new command (if any) must be sent */
|
||||
uint8_t* CmdState;
|
||||
|
||||
/** Buffer to hold a command to send to the launcher */
|
||||
uint8_t CmdBuffer[LAUNCHER_CMD_BUFFER_SIZE];
|
||||
|
||||
|
||||
/** Main program entry point. This routine configures the hardware required by the application, then
|
||||
* starts the scheduler to run the application tasks.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
|
||||
CmdState = CMD_STOP;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Read_Joystick_Status();
|
||||
|
||||
HID_Host_Task();
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
Joystick_Init();
|
||||
Buttons_Init();
|
||||
}
|
||||
|
||||
/** Reads the joystick and button status, sending commands to the launcher as needed. */
|
||||
void Read_Joystick_Status(void)
|
||||
{
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
|
||||
if (BUTTONS_BUTTON1 && Buttons_GetStatus())
|
||||
Send_Command(CMD_FIRE);
|
||||
else if (JoyStatus_LCL & JOY_UP)
|
||||
Send_Command(CMD_UP);
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
Send_Command(CMD_DOWN);
|
||||
else if (JoyStatus_LCL & JOY_LEFT)
|
||||
Send_Command(CMD_LEFT);
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
Send_Command(CMD_RIGHT);
|
||||
else if (CmdState != CMD_STOP)
|
||||
Send_Command(CMD_STOP);
|
||||
}
|
||||
|
||||
/** Lower level send routine, copies report into a larger buffer and sends.
|
||||
*
|
||||
* \param Report Report data to send.
|
||||
* \param ReportSize Report length in bytes.
|
||||
*/
|
||||
void Send_Command_Report(uint8_t *Report, uint16_t ReportSize)
|
||||
{
|
||||
memcpy(CmdBuffer, Report, 8);
|
||||
WriteNextReport(CmdBuffer, ReportSize);
|
||||
}
|
||||
|
||||
/** Send one of the CMD_* command constants listed above.
|
||||
*
|
||||
* \param Command One of the command constants.
|
||||
*/
|
||||
void Send_Command(uint8_t* Command)
|
||||
{
|
||||
if ((CmdState == CMD_STOP && Command != CMD_STOP) ||
|
||||
(CmdState != CMD_STOP && Command == CMD_STOP))
|
||||
{
|
||||
LEDs_ChangeLEDs(LEDS_LED4, ~LEDs_GetLEDs() & LEDS_LED4);
|
||||
|
||||
Send_Command_Report(CMD_INITA, 8);
|
||||
Send_Command_Report(CMD_INITB, 8);
|
||||
Send_Command_Report(Command, LAUNCHER_CMD_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
CmdState = Command;
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
void EVENT_USB_DeviceAttached(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
|
||||
* stops the library USB task management process.
|
||||
*/
|
||||
void EVENT_USB_DeviceUnattached(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
|
||||
* enumerated by the host and is now ready to be used by the application.
|
||||
*/
|
||||
void EVENT_USB_DeviceEnumerationComplete(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
|
||||
void EVENT_USB_HostError(const uint8_t ErrorCode)
|
||||
{
|
||||
USB_ShutDown();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
|
||||
* enumerating an attached USB device.
|
||||
*/
|
||||
void EVENT_USB_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Reads in and discards the next report from the attached device. */
|
||||
void DiscardNextReport(void)
|
||||
{
|
||||
/* Select and unfreeze HID data IN pipe */
|
||||
Pipe_SelectPipe(HID_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (!(Pipe_IsINReceived()))
|
||||
{
|
||||
/* Refreeze HID data IN pipe */
|
||||
Pipe_Freeze();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
|
||||
/* Refreeze HID data IN pipe */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Writes a report to the attached device.
|
||||
*
|
||||
* \param ReportOUTData Buffer containing the report to send to the device
|
||||
* \param ReportLength Length of the report to send
|
||||
*/
|
||||
void WriteNextReport(uint8_t* ReportOUTData, uint16_t ReportLength)
|
||||
{
|
||||
/* Select and unfreeze HID data OUT pipe */
|
||||
Pipe_SelectPipe(HID_DATA_OUT_PIPE);
|
||||
|
||||
/* Not all HID devices have an OUT endpoint (some require OUT reports to be sent over the
|
||||
* control endpoint instead) - check to see if the OUT endpoint has been initialized */
|
||||
if (Pipe_IsConfigured())
|
||||
{
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Ensure pipe is ready to be written to before continuing */
|
||||
if (!(Pipe_IsOUTReady()))
|
||||
{
|
||||
/* Refreeze the data OUT pipe */
|
||||
Pipe_Freeze();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write out HID report data */
|
||||
Pipe_Write_Stream_LE(ReportOUTData, ReportLength);
|
||||
|
||||
/* Clear the OUT endpoint, send last data packet */
|
||||
Pipe_ClearOUT();
|
||||
|
||||
/* Refreeze the data OUT pipe */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Class specific request to send a HID report to the device */
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = 0x21,
|
||||
.bRequest = 0x09,
|
||||
.wValue = 0x02,
|
||||
.wIndex = 0x01,
|
||||
.wLength = ReportLength,
|
||||
};
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Send the request to the device */
|
||||
USB_Host_SendControlRequest(ReportOUTData);
|
||||
}
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* HID reports from the device and to send reports if desired.
|
||||
*/
|
||||
void HID_Host_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
while (USB_IsConnected);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
while (USB_IsConnected);
|
||||
break;
|
||||
}
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
USB_HostState = HOST_STATE_Ready;
|
||||
break;
|
||||
case HOST_STATE_Ready:
|
||||
DiscardNextReport();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim 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, 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.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for MissleLauncher.c.
|
||||
*/
|
||||
|
||||
#ifndef _MISSLELAUNCHER_HOST_H_
|
||||
#define _MISSLELAUNCHER_HOST_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/power.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
|
||||
#include "ConfigDescriptor.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Pipe number for the HID data IN pipe */
|
||||
#define HID_DATA_IN_PIPE 1
|
||||
|
||||
/** Pipe number for the HID data OUT pipe */
|
||||
#define HID_DATA_OUT_PIPE 2
|
||||
|
||||
/** HID Class specific request to send a HID report to the device. */
|
||||
#define REQ_SetReport 0x09
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/** Size of the Launcher report command buffer */
|
||||
#define LAUNCHER_CMD_BUFFER_SIZE 64
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void Read_Joystick_Status(void);
|
||||
void Send_Command_Report(uint8_t* Report, uint16_t ReportSize);
|
||||
void Send_Command(uint8_t* Command);
|
||||
|
||||
void HID_Host_Task(void);
|
||||
|
||||
void EVENT_USB_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_DeviceAttached(void);
|
||||
void EVENT_USB_DeviceUnattached(void);
|
||||
void EVENT_USB_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode);
|
||||
void EVENT_USB_DeviceEnumerationComplete(void);
|
||||
|
||||
void DiscardNextReport(void);
|
||||
void WriteNextReport(uint8_t* ReportOUTData, uint16_t ReportLength);
|
||||
|
||||
#endif
|
|
@ -1,53 +0,0 @@
|
|||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Missle Launcher
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Host</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification, USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode, Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Missle Launcher host. This is a host driver for the popular USB-controller table top toy missle launchers,
|
||||
* which can typically aim and fire small foam "missles" from a spring-loaded turret. This project controls the
|
||||
* launcher via a joystick and button to aim and fire missles at targets without a PC.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
|
@ -1,733 +0,0 @@
|
|||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#----------------------------------------------------------------------------
|
||||
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
|
||||
# >> Modified for use with the LUFA project. <<
|
||||
#
|
||||
# Released to the Public Domain
|
||||
#
|
||||
# Additional material for this makefile was written by:
|
||||
# Peter Fleury
|
||||
# Tim Henigan
|
||||
# Colin O'Flynn
|
||||
# Reiner Patommel
|
||||
# Markus Pfaff
|
||||
# Sander Pool
|
||||
# Frederik Rouleau
|
||||
# Carlos Lamas
|
||||
# Dean Camera
|
||||
# Opendous Inc.
|
||||
# Denver Gingerich
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# make coff = Convert ELF to AVR COFF.
|
||||
#
|
||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
||||
#
|
||||
# make program = Download the hex file to the device, using avrdude.
|
||||
# Please customize the avrdude settings below first!
|
||||
#
|
||||
# make dfu = Download the hex file to the device, using dfu-programmer (must
|
||||
# have dfu-programmer installed).
|
||||
#
|
||||
# make flip = Download the hex file to the device, using Atmel FLIP (must
|
||||
# have Atmel FLIP installed).
|
||||
#
|
||||
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
|
||||
# (must have dfu-programmer installed).
|
||||
#
|
||||
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
|
||||
# (must have Atmel FLIP installed).
|
||||
#
|
||||
# make doxygen = Generate DoxyGen documentation for the project (must have
|
||||
# DoxyGen installed)
|
||||
#
|
||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
||||
# with avr-gdb or avr-insight as the front end for debugging.
|
||||
#
|
||||
# make filename.s = Just compile filename.c into the assembler code only.
|
||||
#
|
||||
# make filename.i = Create a preprocessed source file for use in submitting
|
||||
# bug reports to the GCC project.
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# MCU name
|
||||
MCU = at90usb1287
|
||||
|
||||
|
||||
# Target board (see library "Board Types" documentation, USER or blank for projects not requiring
|
||||
# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
|
||||
# "Board" inside the application directory.
|
||||
BOARD = USBKEY
|
||||
|
||||
|
||||
# Processor frequency.
|
||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
||||
# processor frequency. You can then use this symbol in your source code to
|
||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
||||
# automatically to create a 32-bit value in your source code.
|
||||
# Typical values are:
|
||||
# F_CPU = 1000000
|
||||
# F_CPU = 1843200
|
||||
# F_CPU = 2000000
|
||||
# F_CPU = 3686400
|
||||
# F_CPU = 4000000
|
||||
# F_CPU = 7372800
|
||||
# F_CPU = 8000000
|
||||
# F_CPU = 11059200
|
||||
# F_CPU = 14745600
|
||||
# F_CPU = 16000000
|
||||
# F_CPU = 18432000
|
||||
# F_CPU = 20000000
|
||||
F_CPU = 8000000
|
||||
|
||||
|
||||
# Input clock frequency.
|
||||
# This will define a symbol, F_CLOCK, in all source code files equal to the
|
||||
# input clock frequency (before any prescaling is performed). This value may
|
||||
# differ from F_CPU if prescaling is used on the latter, and is required as the
|
||||
# raw input clock is fed directly to the PLL sections of the AVR for high speed
|
||||
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
|
||||
# at the end, this will be done automatically to create a 32-bit value in your
|
||||
# source code.
|
||||
#
|
||||
# If no clock division is performed on the input clock inside the AVR (via the
|
||||
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
|
||||
F_CLOCK = 8000000
|
||||
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = ihex
|
||||
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = MissileLauncher
|
||||
|
||||
|
||||
# Object files directory
|
||||
# To put object files in current directory, use a dot (.), do NOT make
|
||||
# this an empty or blank macro!
|
||||
OBJDIR = .
|
||||
|
||||
|
||||
# Path to the LUFA library
|
||||
LUFA_PATH = ../..
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = $(TARGET).c \
|
||||
ConfigDescriptor.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/HostChapter9.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/LowLevel.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Pipe.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/Events.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/HIDParser.c \
|
||||
|
||||
|
||||
# List C++ source files here. (C dependencies are automatically generated.)
|
||||
CPPSRC =
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC =
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
OPT = s
|
||||
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
|
||||
# AVR Studio 4.10 requires dwarf-2.
|
||||
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
|
||||
DEBUG = dwarf-2
|
||||
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRAINCDIRS = $(LUFA_PATH)/
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 = "ANSI" C
|
||||
# gnu89 = c89 plus GCC extensions
|
||||
# c99 = ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 = c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
|
||||
|
||||
# Place -D or -U options here for C sources
|
||||
CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
|
||||
CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_HOST_ONLY
|
||||
CDEFS += -DUSE_STATIC_OPTIONS="(USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
|
||||
|
||||
# Place -D or -U options here for ASM sources
|
||||
ADEFS = -DF_CPU=$(F_CPU)
|
||||
|
||||
|
||||
# Place -D or -U options here for C++ sources
|
||||
CPPDEFS = -DF_CPU=$(F_CPU)UL
|
||||
#CPPDEFS += -D__STDC_LIMIT_MACROS
|
||||
#CPPDEFS += -D__STDC_CONSTANT_MACROS
|
||||
|
||||
|
||||
|
||||
#---------------- Compiler Options C ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += -funsigned-char
|
||||
CFLAGS += -funsigned-bitfields
|
||||
CFLAGS += -ffunction-sections
|
||||
CFLAGS += -fpack-struct
|
||||
CFLAGS += -fshort-enums
|
||||
CFLAGS += -finline-limit=20
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
CFLAGS += -Wundef
|
||||
#CFLAGS += -fno-unit-at-a-time
|
||||
#CFLAGS += -Wunreachable-code
|
||||
#CFLAGS += -Wsign-compare
|
||||
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
CFLAGS += $(CSTANDARD)
|
||||
|
||||
|
||||
#---------------- Compiler Options C++ ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CPPFLAGS = -g$(DEBUG)
|
||||
CPPFLAGS += $(CPPDEFS)
|
||||
CPPFLAGS += -O$(OPT)
|
||||
CPPFLAGS += -funsigned-char
|
||||
CPPFLAGS += -funsigned-bitfields
|
||||
CPPFLAGS += -fpack-struct
|
||||
CPPFLAGS += -fshort-enums
|
||||
CPPFLAGS += -fno-exceptions
|
||||
CPPFLAGS += -Wall
|
||||
CFLAGS += -Wundef
|
||||
#CPPFLAGS += -mshort-calls
|
||||
#CPPFLAGS += -fno-unit-at-a-time
|
||||
#CPPFLAGS += -Wstrict-prototypes
|
||||
#CPPFLAGS += -Wunreachable-code
|
||||
#CPPFLAGS += -Wsign-compare
|
||||
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
|
||||
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
#CPPFLAGS += $(CSTANDARD)
|
||||
|
||||
|
||||
#---------------- Assembler Options ----------------
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns: create listing
|
||||
# -gstabs: have the assembler create line number information; note that
|
||||
# for use in COFF files, additional information about filenames
|
||||
# and function names needs to be present in the assembler source
|
||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
|
||||
# dump that will be displayed for a given single line of source input.
|
||||
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
|
||||
|
||||
|
||||
#---------------- Library Options ----------------
|
||||
# Minimalistic printf version
|
||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
||||
|
||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard printf version.
|
||||
PRINTF_LIB =
|
||||
#PRINTF_LIB = $(PRINTF_LIB_MIN)
|
||||
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
|
||||
|
||||
|
||||
# Minimalistic scanf version
|
||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
||||
|
||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard scanf version.
|
||||
SCANF_LIB =
|
||||
#SCANF_LIB = $(SCANF_LIB_MIN)
|
||||
#SCANF_LIB = $(SCANF_LIB_FLOAT)
|
||||
|
||||
|
||||
MATH_LIB = -lm
|
||||
|
||||
|
||||
# List any extra directories to look for libraries here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRALIBDIRS =
|
||||
|
||||
|
||||
|
||||
#---------------- External Memory Options ----------------
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# used for variables (.data/.bss) and heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# only used for heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
EXTMEMOPTS =
|
||||
|
||||
|
||||
|
||||
#---------------- Linker Options ----------------
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS += -Wl,--relax
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
LDFLAGS += $(EXTMEMOPTS)
|
||||
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
|
||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
||||
#LDFLAGS += -T linker_script.x
|
||||
|
||||
|
||||
|
||||
#---------------- Programming Options (avrdude) ----------------
|
||||
|
||||
# Programming hardware: alf avr910 avrisp bascom bsd
|
||||
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
|
||||
#
|
||||
# Type: avrdude -c ?
|
||||
# to get a full listing.
|
||||
#
|
||||
AVRDUDE_PROGRAMMER = jtagmkII
|
||||
|
||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
||||
AVRDUDE_PORT = usb
|
||||
|
||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
||||
|
||||
|
||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
||||
# Note that this counter needs to be initialized first using -Yn,
|
||||
# see avrdude manual.
|
||||
#AVRDUDE_ERASE_COUNTER = -y
|
||||
|
||||
# Uncomment the following if you do /not/ wish a verification to be
|
||||
# performed after programming the device.
|
||||
#AVRDUDE_NO_VERIFY = -V
|
||||
|
||||
# Increase verbosity level. Please use this when submitting bug
|
||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
||||
# to submit bug reports.
|
||||
#AVRDUDE_VERBOSE = -v -v
|
||||
|
||||
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
||||
|
||||
|
||||
|
||||
#---------------- Debugging Options ----------------
|
||||
|
||||
# For simulavr only - target MCU frequency.
|
||||
DEBUG_MFREQ = $(F_CPU)
|
||||
|
||||
# Set the DEBUG_UI to either gdb or insight.
|
||||
# DEBUG_UI = gdb
|
||||
DEBUG_UI = insight
|
||||
|
||||
# Set the debugging back-end to either avarice, simulavr.
|
||||
DEBUG_BACKEND = avarice
|
||||
#DEBUG_BACKEND = simulavr
|
||||
|
||||
# GDB Init Filename.
|
||||
GDBINIT_FILE = __avr_gdbinit
|
||||
|
||||
# When using avarice settings for the JTAG
|
||||
JTAG_DEV = /dev/com1
|
||||
|
||||
# Debugging port used to communicate between GDB / avarice / simulavr.
|
||||
DEBUG_PORT = 4242
|
||||
|
||||
# Debugging host used to communicate between GDB / avarice / simulavr, normally
|
||||
# just set to localhost unless doing some sort of crazy debugging when
|
||||
# avarice is running on a different computer.
|
||||
DEBUG_HOST = localhost
|
||||
|
||||
|
||||
|
||||
#============================================================================
|
||||
|
||||
|
||||
# Define programs and commands.
|
||||
SHELL = sh
|
||||
CC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
AR = avr-ar rcs
|
||||
NM = avr-nm
|
||||
AVRDUDE = avrdude
|
||||
REMOVE = rm -f
|
||||
REMOVEDIR = rm -rf
|
||||
COPY = cp
|
||||
WINSHELL = cmd
|
||||
|
||||
# Define Messages
|
||||
# English
|
||||
MSG_ERRORS_NONE = Errors: none
|
||||
MSG_BEGIN = -------- begin --------
|
||||
MSG_END = -------- end --------
|
||||
MSG_SIZE_BEFORE = Size before:
|
||||
MSG_SIZE_AFTER = Size after:
|
||||
MSG_COFF = Converting to AVR COFF:
|
||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
||||
MSG_FLASH = Creating load file for Flash:
|
||||
MSG_EEPROM = Creating load file for EEPROM:
|
||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
||||
MSG_LINKING = Linking:
|
||||
MSG_COMPILING = Compiling C:
|
||||
MSG_COMPILING_CPP = Compiling C++:
|
||||
MSG_ASSEMBLING = Assembling:
|
||||
MSG_CLEANING = Cleaning project:
|
||||
MSG_CREATING_LIBRARY = Creating library:
|
||||
|
||||
|
||||
|
||||
|
||||
# Define all object files.
|
||||
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
|
||||
|
||||
# Define all listing files.
|
||||
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
|
||||
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Default target.
|
||||
all: begin gccversion sizebefore build checkhooks checklibmode checkboard sizeafter end
|
||||
|
||||
# Change the build target to build a HEX file or a library.
|
||||
build: elf hex eep lss sym
|
||||
#build: lib
|
||||
|
||||
|
||||
elf: $(TARGET).elf
|
||||
hex: $(TARGET).hex
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
LIBNAME=lib$(TARGET).a
|
||||
lib: $(LIBNAME)
|
||||
|
||||
|
||||
|
||||
# Eye candy.
|
||||
# AVR Studio 3.x does not check make's exit code but relies on
|
||||
# the following magic strings to be generated by the compile job.
|
||||
begin:
|
||||
@echo
|
||||
@echo $(MSG_BEGIN)
|
||||
|
||||
end:
|
||||
@echo $(MSG_END)
|
||||
@echo
|
||||
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
|
||||
MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
|
||||
FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
|
||||
|
||||
sizebefore:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
|
||||
2>/dev/null; echo; fi
|
||||
|
||||
sizeafter:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
|
||||
2>/dev/null; echo; fi
|
||||
|
||||
checkhooks: build
|
||||
@echo
|
||||
@echo ------- Unhooked LUFA Events -------
|
||||
@$(shell) (grep -s '^EVENT_.*LUFA/.*\\.o' $(TARGET).map | \
|
||||
cut -d' ' -f1 | cut -d'_' -f2- | grep ".*") || \
|
||||
echo "(None)"
|
||||
@echo ------------------------------------
|
||||
|
||||
checklibmode:
|
||||
@echo
|
||||
@echo ----------- Library Mode -----------
|
||||
@$(shell) ($(CC) $(ALL_CFLAGS) -E -dM - < /dev/null \
|
||||
| grep 'USB_\(DEVICE\|HOST\)_ONLY' | cut -d' ' -f2 | grep ".*") \
|
||||
|| echo "No specific mode (both device and host mode allowable)."
|
||||
@echo ------------------------------------
|
||||
|
||||
checkboard:
|
||||
@echo
|
||||
@echo ---------- Selected Board ----------
|
||||
@echo Selected board model is $(BOARD).
|
||||
@echo ------------------------------------
|
||||
|
||||
# Display compiler version information.
|
||||
gccversion :
|
||||
@$(CC) --version
|
||||
|
||||
|
||||
|
||||
# Program the device.
|
||||
program: $(TARGET).hex $(TARGET).eep
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
||||
|
||||
flip: $(TARGET).hex
|
||||
batchisp -hardware usb -device $(MCU) -operation erase f
|
||||
batchisp -hardware usb -device $(MCU) -operation loadbuffer $(TARGET).hex program
|
||||
batchisp -hardware usb -device $(MCU) -operation start reset 0
|
||||
|
||||
dfu: $(TARGET).hex
|
||||
dfu-programmer $(MCU) erase
|
||||
dfu-programmer $(MCU) flash --debug 1 $(TARGET).hex
|
||||
dfu-programmer $(MCU) reset
|
||||
|
||||
flip-ee: $(TARGET).hex $(TARGET).eep
|
||||
copy $(TARGET).eep $(TARGET)eep.hex
|
||||
batchisp -hardware usb -device $(MCU) -operation memory EEPROM erase
|
||||
batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(TARGET)eep.hex program
|
||||
batchisp -hardware usb -device $(MCU) -operation start reset 0
|
||||
|
||||
dfu-ee: $(TARGET).hex $(TARGET).eep
|
||||
dfu-programmer $(MCU) flash-eeprom --debug 1 --suppress-bootloader-mem $(TARGET).eep
|
||||
dfu-programmer $(MCU) reset
|
||||
|
||||
|
||||
# Generate avr-gdb config/init file which does the following:
|
||||
# define the reset signal, load the target file, connect to target, and set
|
||||
# a breakpoint at main().
|
||||
gdb-config:
|
||||
@$(REMOVE) $(GDBINIT_FILE)
|
||||
@echo define reset >> $(GDBINIT_FILE)
|
||||
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
|
||||
@echo end >> $(GDBINIT_FILE)
|
||||
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
|
||||
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
|
||||
ifeq ($(DEBUG_BACKEND),simulavr)
|
||||
@echo load >> $(GDBINIT_FILE)
|
||||
endif
|
||||
@echo break main >> $(GDBINIT_FILE)
|
||||
|
||||
debug: gdb-config $(TARGET).elf
|
||||
ifeq ($(DEBUG_BACKEND), avarice)
|
||||
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
|
||||
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
|
||||
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
|
||||
@$(WINSHELL) /c pause
|
||||
|
||||
else
|
||||
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
|
||||
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
|
||||
endif
|
||||
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
|
||||
|
||||
|
||||
|
||||
|
||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
||||
COFFCONVERT = $(OBJCOPY) --debugging
|
||||
COFFCONVERT += --change-section-address .data-0x800000
|
||||
COFFCONVERT += --change-section-address .bss-0x800000
|
||||
COFFCONVERT += --change-section-address .noinit-0x800000
|
||||
COFFCONVERT += --change-section-address .eeprom-0x810000
|
||||
|
||||
|
||||
|
||||
coff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
extcoff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
|
||||
# Create final output files (.hex, .eep) from ELF output file.
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
|
||||
|
||||
%.eep: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EEPROM) $@
|
||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -z -S $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
%.sym: %.elf
|
||||
@echo
|
||||
@echo $(MSG_SYMBOL_TABLE) $@
|
||||
$(NM) -n $< > $@
|
||||
|
||||
|
||||
|
||||
# Create library from object files.
|
||||
.SECONDARY : $(TARGET).a
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.a: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_CREATING_LIBRARY) $@
|
||||
$(AR) $@ $(OBJ)
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.elf: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_LINKING) $@
|
||||
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
$(OBJDIR)/%.o : %.c
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $<
|
||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create object files from C++ source files.
|
||||
$(OBJDIR)/%.o : %.cpp
|
||||
@echo
|
||||
@echo $(MSG_COMPILING_CPP) $<
|
||||
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
%.s : %.c
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C++ source files.
|
||||
%.s : %.cpp
|
||||
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
$(OBJDIR)/%.o : %.S
|
||||
@echo
|
||||
@echo $(MSG_ASSEMBLING) $<
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Create preprocessed source for use in sending a bug report.
|
||||
%.i : %.c
|
||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list clean_binary end
|
||||
|
||||
clean_binary:
|
||||
$(REMOVE) $(TARGET).hex
|
||||
|
||||
clean_list:
|
||||
@echo $(MSG_CLEANING)
|
||||
$(REMOVE) $(TARGET).eep
|
||||
$(REMOVE) $(TARGET)eep.hex
|
||||
$(REMOVE) $(TARGET).cof
|
||||
$(REMOVE) $(TARGET).elf
|
||||
$(REMOVE) $(TARGET).map
|
||||
$(REMOVE) $(TARGET).sym
|
||||
$(REMOVE) $(TARGET).lss
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
|
||||
$(REMOVE) $(SRC:.c=.s)
|
||||
$(REMOVE) $(SRC:.c=.d)
|
||||
$(REMOVE) $(SRC:.c=.i)
|
||||
$(REMOVEDIR) .dep
|
||||
|
||||
|
||||
doxygen:
|
||||
@echo Generating Project Documentation...
|
||||
@doxygen Doxygen.conf
|
||||
@echo Documentation Generation Complete.
|
||||
|
||||
clean_doxygen:
|
||||
rm -rf Documentation
|
||||
|
||||
# Create object files directory
|
||||
$(shell mkdir $(OBJDIR) 2>/dev/null)
|
||||
|
||||
|
||||
# Include the dependency files.
|
||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all checkhooks checklibmode checkboard \
|
||||
begin finish end sizebefore sizeafter gccversion \
|
||||
build elf hex eep lss sym coff extcoff clean \
|
||||
clean_list clean_binary program debug gdb-config \
|
||||
doxygen dfu flip flip-ee dfu-ee
|
|
@ -17,8 +17,8 @@ all:
|
|||
make -C Magstripe clean
|
||||
make -C Magstripe all
|
||||
|
||||
make -C MissleLauncher clean
|
||||
make -C MissleLauncher all
|
||||
make -C MissileLauncher clean
|
||||
make -C MissileLauncher all
|
||||
|
||||
%:
|
||||
make -C Magstripe $@
|
||||
|
|
Loading…
Reference in New Issue