USB Host Shield 2.0
usbh_midi.h
Go to the documentation of this file.
1 /*
2  *******************************************************************************
3  * USB-MIDI class driver for USB Host Shield 2.0 Library
4  * Copyright (c) 2012-2021 Yuuichi Akagawa
5  *
6  * Idea from LPK25 USB-MIDI to Serial MIDI converter
7  * by Collin Cunningham - makezine.com, narbotic.com
8  *
9  * for use with USB Host Shield 2.0 from Circuitsathome.com
10  * https://github.com/felis/USB_Host_Shield_2.0
11  *******************************************************************************
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program. If not, see <http://www.gnu.org/licenses/>
24  *******************************************************************************
25  */
26 
27 #if !defined(_USBH_MIDI_H_)
28 #define _USBH_MIDI_H_
29 #include "Usb.h"
30 
31 #define USBH_MIDI_VERSION 600
32 #define MIDI_MAX_ENDPOINTS 3 //endpoint 0, bulk_IN(MIDI), bulk_OUT(MIDI)
33 #define USB_SUBCLASS_MIDISTREAMING 3
34 #define MIDI_EVENT_PACKET_SIZE 64
35 #define MIDI_MAX_SYSEX_SIZE 256
36 
37 namespace _ns_USBH_MIDI {
38 const uint8_t cin2len[] PROGMEM = {0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1};
39 const uint8_t sys2cin[] PROGMEM = {0, 2, 3, 2, 0, 0, 5, 0, 0xf, 0, 0xf, 0xf, 0xf, 0, 0xf, 0xf};
40 }
41 
42 // Endpoint Descriptor extracter Class
44 public:
45  //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0;
46  //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0;
47 
48  virtual bool EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) {
49  return true;
50  };
51 };
52 // Configuration Descriptor Parser Class
53 class MidiDescParser : public USBReadParser {
54  UsbMidiConfigXtracter *theXtractor;
55  MultiValueBuffer theBuffer;
56  MultiByteValueParser valParser;
57  ByteSkipper theSkipper;
58  uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
59 
60  uint8_t stateParseDescr; // ParseDescriptor state
61 
62  uint8_t dscrLen; // Descriptor length
63  uint8_t dscrType; // Descriptor type
64  uint8_t nEPs; // number of valid endpoint
65  bool isMidiSearch; //Configuration mode true: MIDI, false: Vendor specific
66 
67  bool isGoodInterface; // Apropriate interface flag
68  uint8_t confValue; // Configuration value
69 
70  bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn);
71 
72 public:
73  MidiDescParser(UsbMidiConfigXtracter *xtractor, bool modeMidi);
74  void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
75  inline uint8_t getConfValue() { return confValue; };
76  inline uint8_t getNumEPs() { return nEPs; };
77 };
78 
81 {
82 protected:
83  static const uint8_t epDataInIndex = 1; // DataIn endpoint index(MIDI)
84  static const uint8_t epDataOutIndex= 2; // DataOUT endpoint index(MIDI)
85 
86  /* mandatory members */
88  uint8_t bAddress;
90  uint16_t pid, vid; // ProductID, VendorID
92  /* Endpoint data structure */
94  /* MIDI Event packet buffer */
96  uint8_t readPtr;
97 
98  uint16_t countSysExDataSize(uint8_t *dataptr);
99  void setupDeviceSpecific();
100  inline uint8_t convertStatus2Cin(uint8_t status) {
101  return ((status < 0xf0) ? ((status & 0xF0) >> 4) : pgm_read_byte_near(_ns_USBH_MIDI::sys2cin + (status & 0x0F)));
102  };
103  inline uint8_t getMsgSizeFromCin(uint8_t cin) {
105  };
106 
107  /* UsbConfigXtracter implementation */
108  bool EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
109 
110 #ifdef DEBUG_USB_HOST
111  void PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr );
112 #endif
113 public:
114  USBH_MIDI(USB *p);
115  // Misc functions
116  operator bool() { return (bPollEnable); }
117  uint16_t idVendor() { return vid; }
118  uint16_t idProduct() { return pid; }
119  // Methods for recieving and sending data
120  uint8_t RecvData(uint16_t *bytes_rcvd, uint8_t *dataptr);
121  uint8_t RecvData(uint8_t *outBuf, bool isRaw=false);
122  inline uint8_t RecvRawData(uint8_t *outBuf) { return RecvData(outBuf, true); };
123  uint8_t SendData(uint8_t *dataptr, uint8_t nCable=0);
124  inline uint8_t SendRawData(uint16_t bytes_send, uint8_t *dataptr) { return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, bytes_send, dataptr); };
125  uint8_t lookupMsgSize(uint8_t midiMsg, uint8_t cin=0);
126  uint8_t SendSysEx(uint8_t *dataptr, uint16_t datasize, uint8_t nCable=0);
127  uint8_t extractSysExData(uint8_t *p, uint8_t *buf);
128  // backward compatibility functions
129  inline uint8_t RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr) { return RecvData(bytes_rcvd, dataptr); };
130  inline uint8_t RcvData(uint8_t *outBuf) { return RecvData(outBuf); };
131 
132  // USBDeviceConfig implementation
133  virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
134  virtual uint8_t Release();
135  virtual uint8_t GetAddress() { return bAddress; };
136 
137  void attachOnInit(void (*funcOnInit)(void)) {
138  pFuncOnInit = funcOnInit;
139  };
140 private:
141  void (*pFuncOnInit)(void) = nullptr; // Pointer to function called in onInit()
142 };
143 
144 #endif //_USBH_MIDI_H_
USB::outTransfer
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
Definition: Usb.cpp:303
USBH_MIDI::attachOnInit
void attachOnInit(void(*funcOnInit)(void))
Definition: usbh_midi.h:137
USBDeviceConfig
Definition: UsbCore.h:134
_ns_USBH_MIDI::sys2cin
const uint8_t sys2cin[]
Definition: usbh_midi.h:39
USBH_MIDI::countSysExDataSize
uint16_t countSysExDataSize(uint8_t *dataptr)
Definition: usbh_midi.cpp:437
_ns_USBH_MIDI::cin2len
const uint8_t cin2len[]
Definition: usbh_midi.h:38
USBH_MIDI
Definition: usbh_midi.h:80
USBH_MIDI::pUsb
USB * pUsb
Definition: usbh_midi.h:87
USB_ENDPOINT_DESCRIPTOR
Definition: usb_ch9.h:148
UsbMidiConfigXtracter::EndpointXtract
virtual bool EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
Definition: usbh_midi.h:48
USBH_MIDI::bAddress
uint8_t bAddress
Definition: usbh_midi.h:88
USBH_MIDI::RcvData
uint8_t RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr)
Definition: usbh_midi.h:129
MidiDescParser::Parse
void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset)
Definition: usbh_midi.cpp:560
USBH_MIDI::vid
uint16_t vid
Definition: usbh_midi.h:90
USBH_MIDI::GetAddress
virtual uint8_t GetAddress()
Definition: usbh_midi.h:135
USBReadParser
Definition: UsbCore.h:205
USBH_MIDI::USBH_MIDI
USBH_MIDI(USB *p)
Definition: usbh_midi.cpp:85
USBH_MIDI::getMsgSizeFromCin
uint8_t getMsgSizeFromCin(uint8_t cin)
Definition: usbh_midi.h:103
USBH_MIDI::Init
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
Definition: usbh_midi.cpp:103
USBH_MIDI::epDataInIndex
static const uint8_t epDataInIndex
Definition: usbh_midi.h:83
UsbMidiConfigXtracter
Definition: usbh_midi.h:43
MidiDescParser::getConfValue
uint8_t getConfValue()
Definition: usbh_midi.h:75
USBH_MIDI::recvBuf
uint8_t recvBuf[MIDI_EVENT_PACKET_SIZE]
Definition: usbh_midi.h:95
USBH_MIDI::idProduct
uint16_t idProduct()
Definition: usbh_midi.h:118
USBH_MIDI::convertStatus2Cin
uint8_t convertStatus2Cin(uint8_t status)
Definition: usbh_midi.h:100
USBH_MIDI::setupDeviceSpecific
void setupDeviceSpecific()
Definition: usbh_midi.cpp:286
USBH_MIDI::lookupMsgSize
uint8_t lookupMsgSize(uint8_t midiMsg, uint8_t cin=0)
Definition: usbh_midi.cpp:428
EpInfo
Definition: address.h:39
ByteSkipper
Definition: parsetools.h:62
USBH_MIDI::SendRawData
uint8_t SendRawData(uint16_t bytes_send, uint8_t *dataptr)
Definition: usbh_midi.h:124
USBH_MIDI::idVendor
uint16_t idVendor()
Definition: usbh_midi.h:117
MIDI_MAX_ENDPOINTS
#define MIDI_MAX_ENDPOINTS
Definition: usbh_midi.h:32
USBH_MIDI::extractSysExData
uint8_t extractSysExData(uint8_t *p, uint8_t *buf)
Definition: usbh_midi.cpp:516
USBH_MIDI::SendData
uint8_t SendData(uint8_t *dataptr, uint8_t nCable=0)
Definition: usbh_midi.cpp:366
USB
Definition: UsbCore.h:210
_ns_USBH_MIDI
Definition: usbh_midi.h:37
MidiDescParser
Definition: usbh_midi.h:53
USBH_MIDI::pid
uint16_t pid
Definition: usbh_midi.h:90
USBH_MIDI::Release
virtual uint8_t Release()
Definition: usbh_midi.cpp:276
USBH_MIDI::RecvRawData
uint8_t RecvRawData(uint8_t *outBuf)
Definition: usbh_midi.h:122
USBH_MIDI::bPollEnable
bool bPollEnable
Definition: usbh_midi.h:89
Usb.h
MidiDescParser::getNumEPs
uint8_t getNumEPs()
Definition: usbh_midi.h:76
USBH_MIDI::bTransferTypeMask
uint8_t bTransferTypeMask
Definition: usbh_midi.h:91
USBH_MIDI::EndpointXtract
bool EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
Definition: usbh_midi.cpp:662
USBH_MIDI::readPtr
uint8_t readPtr
Definition: usbh_midi.h:96
MultiValueBuffer
Definition: parsetools.h:30
USBH_MIDI::SendSysEx
uint8_t SendSysEx(uint8_t *dataptr, uint16_t datasize, uint8_t nCable=0)
Definition: usbh_midi.cpp:459
MidiDescParser::MidiDescParser
MidiDescParser(UsbMidiConfigXtracter *xtractor, bool modeMidi)
Definition: usbh_midi.cpp:549
USBH_MIDI::RcvData
uint8_t RcvData(uint8_t *outBuf)
Definition: usbh_midi.h:130
MultiByteValueParser
Definition: parsetools.h:40
pgm_read_byte_near
#define pgm_read_byte_near(addr)
Definition: version_helper.h:174
MIDI_EVENT_PACKET_SIZE
#define MIDI_EVENT_PACKET_SIZE
Definition: usbh_midi.h:34
USBH_MIDI::epInfo
EpInfo epInfo[MIDI_MAX_ENDPOINTS]
Definition: usbh_midi.h:93
USBH_MIDI::epDataOutIndex
static const uint8_t epDataOutIndex
Definition: usbh_midi.h:84
USBH_MIDI::RecvData
uint8_t RecvData(uint16_t *bytes_rcvd, uint8_t *dataptr)
Definition: usbh_midi.cpp:308