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-2022 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 10000
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 
141  void attachOnRelease(void (*funcOnRelease)(void)) {
142  pFuncOnRelease = funcOnRelease;
143  };
144 private:
145  void (*pFuncOnInit)(void) = nullptr; // Pointer to function called in onInit()
146  void (*pFuncOnRelease)(void) = nullptr; // Pointer to function called in onRelease()
147 };
148 
149 #endif //_USBH_MIDI_H_
void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset)
Definition: usbh_midi.cpp:566
uint8_t getConfValue()
Definition: usbh_midi.h:75
MidiDescParser(UsbMidiConfigXtracter *xtractor, bool modeMidi)
Definition: usbh_midi.cpp:555
uint8_t getNumEPs()
Definition: usbh_midi.h:76
static const uint8_t epDataInIndex
Definition: usbh_midi.h:83
uint8_t convertStatus2Cin(uint8_t status)
Definition: usbh_midi.h:100
bool EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
Definition: usbh_midi.cpp:668
uint8_t bTransferTypeMask
Definition: usbh_midi.h:91
uint8_t RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr)
Definition: usbh_midi.h:129
static const uint8_t epDataOutIndex
Definition: usbh_midi.h:84
uint8_t SendRawData(uint16_t bytes_send, uint8_t *dataptr)
Definition: usbh_midi.h:124
bool bPollEnable
Definition: usbh_midi.h:89
void attachOnRelease(void(*funcOnRelease)(void))
Definition: usbh_midi.h:141
uint8_t SendData(uint8_t *dataptr, uint8_t nCable=0)
Definition: usbh_midi.cpp:372
USBH_MIDI(USB *p)
Definition: usbh_midi.cpp:85
uint8_t lookupMsgSize(uint8_t midiMsg, uint8_t cin=0)
Definition: usbh_midi.cpp:434
virtual uint8_t Release()
Definition: usbh_midi.cpp:277
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
Definition: usbh_midi.cpp:103
uint8_t SendSysEx(uint8_t *dataptr, uint16_t datasize, uint8_t nCable=0)
Definition: usbh_midi.cpp:465
uint16_t vid
Definition: usbh_midi.h:90
uint16_t idVendor()
Definition: usbh_midi.h:117
uint8_t recvBuf[MIDI_EVENT_PACKET_SIZE]
Definition: usbh_midi.h:95
void setupDeviceSpecific()
Definition: usbh_midi.cpp:291
uint8_t readPtr
Definition: usbh_midi.h:96
uint16_t pid
Definition: usbh_midi.h:90
uint16_t countSysExDataSize(uint8_t *dataptr)
Definition: usbh_midi.cpp:443
uint8_t extractSysExData(uint8_t *p, uint8_t *buf)
Definition: usbh_midi.cpp:522
uint16_t idProduct()
Definition: usbh_midi.h:118
EpInfo epInfo[MIDI_MAX_ENDPOINTS]
Definition: usbh_midi.h:93
uint8_t RecvData(uint16_t *bytes_rcvd, uint8_t *dataptr)
Definition: usbh_midi.cpp:314
void attachOnInit(void(*funcOnInit)(void))
Definition: usbh_midi.h:137
virtual uint8_t GetAddress()
Definition: usbh_midi.h:135
uint8_t getMsgSizeFromCin(uint8_t cin)
Definition: usbh_midi.h:103
uint8_t bAddress
Definition: usbh_midi.h:88
USB * pUsb
Definition: usbh_midi.h:87
uint8_t RecvRawData(uint8_t *outBuf)
Definition: usbh_midi.h:122
uint8_t RcvData(uint8_t *outBuf)
Definition: usbh_midi.h:130
Definition: UsbCore.h:212
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
Definition: Usb.cpp:303
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
const uint8_t sys2cin[]
Definition: usbh_midi.h:39
const uint8_t cin2len[]
Definition: usbh_midi.h:38
Definition: address.h:39
#define MIDI_EVENT_PACKET_SIZE
Definition: usbh_midi.h:34
#define MIDI_MAX_ENDPOINTS
Definition: usbh_midi.h:32
#define pgm_read_byte_near(addr)