Merge PCB updates
[SCSI2SD.git] / software / SCSI2SD / v4 / SCSI2SD.cydsn / Generated_Source / PSoC5 / USBFS_midi.c
1 /*******************************************************************************
2 * File Name: USBFS_midi.c
3 * Version 2.60
4 *
5 * Description:
6 *  MIDI Streaming request handler.
7 *  This file contains routines for sending and receiving MIDI
8 *  messages, and handles running status in both directions.
9 *
10 ********************************************************************************
11 * Copyright 2008-2013, Cypress Semiconductor Corporation.  All rights reserved.
12 * You may use this file only in accordance with the license, terms, conditions,
13 * disclaimers, and limitations in the end user license agreement accompanying
14 * the software package with which this file was provided.
15 *******************************************************************************/
16
17 #include "USBFS.h"
18
19 #if defined(USBFS_ENABLE_MIDI_STREAMING)
20
21 #include "USBFS_midi.h"
22 #include "USBFS_pvt.h"
23
24
25 /***************************************
26 *    MIDI Constants
27 ***************************************/
28
29 #if (USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF)
30     /* The Size of the MIDI messages (MIDI Table 4-1) */
31     static const uint8 CYCODE USBFS_MIDI_SIZE[] = {
32     /*  Miscellaneous function codes(Reserved)  */ 0x03u,
33     /*  Cable events (Reserved)                 */ 0x03u,
34     /*  Two-byte System Common messages         */ 0x02u,
35     /*  Three-byte System Common messages       */ 0x03u,
36     /*  SysEx starts or continues               */ 0x03u,
37     /*  Single-byte System Common Message or
38         SysEx ends with following single byte   */ 0x01u,
39     /*  SysEx ends with following two bytes     */ 0x02u,
40     /*  SysEx ends with following three bytes   */ 0x03u,
41     /*  Note-off                                */ 0x03u,
42     /*  Note-on                                 */ 0x03u,
43     /*  Poly-KeyPress                           */ 0x03u,
44     /*  Control Change                          */ 0x03u,
45     /*  Program Change                          */ 0x02u,
46     /*  Channel Pressure                        */ 0x02u,
47     /*  PitchBend Change                        */ 0x03u,
48     /*  Single Byte                             */ 0x01u
49     };
50 #endif  /* USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF */
51
52
53
54 /***************************************
55 *  Global variables
56 ***************************************/
57
58 #if (USBFS_MIDI_IN_BUFF_SIZE > 0)
59     #if (USBFS_MIDI_IN_BUFF_SIZE >= 256)
60         volatile uint16 USBFS_midiInPointer;                            /* Input endpoint buffer pointer */
61     #else
62         volatile uint8 USBFS_midiInPointer;                             /* Input endpoint buffer pointer */
63     #endif /* End USBFS_MIDI_IN_BUFF_SIZE >=256 */
64     volatile uint8 USBFS_midi_in_ep;                                    /* Input endpoint number */
65     uint8 USBFS_midiInBuffer[USBFS_MIDI_IN_BUFF_SIZE];       /* Input endpoint buffer */
66 #endif /* USBFS_MIDI_IN_BUFF_SIZE > 0 */
67
68 #if (USBFS_MIDI_OUT_BUFF_SIZE > 0)
69     volatile uint8 USBFS_midi_out_ep;                                   /* Output endpoint number */
70     uint8 USBFS_midiOutBuffer[USBFS_MIDI_OUT_BUFF_SIZE];     /* Output endpoint buffer */
71 #endif /* USBFS_MIDI_OUT_BUFF_SIZE > 0 */
72
73 #if (USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF)
74     static USBFS_MIDI_RX_STATUS USBFS_MIDI1_Event;            /* MIDI RX status structure */
75     static volatile uint8 USBFS_MIDI1_TxRunStat;                         /* MIDI Output running status */
76     volatile uint8 USBFS_MIDI1_InqFlags;                                 /* Device inquiry flag */
77
78     #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF)
79         static USBFS_MIDI_RX_STATUS USBFS_MIDI2_Event;        /* MIDI RX status structure */
80         static volatile uint8 USBFS_MIDI2_TxRunStat;                     /* MIDI Output running status */
81         volatile uint8 USBFS_MIDI2_InqFlags;                             /* Device inquiry flag */
82     #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF */
83 #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF */
84
85
86 /***************************************
87 * Custom Declarations
88 ***************************************/
89
90 /* `#START MIDI_CUSTOM_DECLARATIONS` Place your declaration here */
91
92 /* `#END` */
93
94
95 /***************************************
96 * Optional MIDI APIs
97 ***************************************/
98 #if (USBFS_ENABLE_MIDI_API != 0u)
99
100
101 /*******************************************************************************
102 * Function Name: USBFS_MIDI_EP_Init
103 ********************************************************************************
104 *
105 * Summary:
106 *  This function initializes the MIDI interface and UART(s) to be ready to
107 *   receive data from the PC and MIDI ports.
108 *
109 * Parameters:
110 *  None
111 *
112 * Return:
113 *  None
114 *
115 * Global variables:
116 *  USBFS_midiInBuffer: This buffer is used for saving and combining
117 *    the received data from UART(s) and(or) generated internally by
118 *    PutUsbMidiIn() function messages. USBFS_MIDI_IN_EP_Service()
119 *    function transfers the data from this buffer to the PC.
120 *  USBFS_midiOutBuffer: This buffer is used by the
121 *    USBFS_MIDI_OUT_EP_Service() function for saving the received
122 *    from the PC data, then the data are parsed and transferred to UART(s)
123 *    buffer and to the internal processing by the
124 *    USBFS_callbackLocalMidiEvent function.
125 *  USBFS_midi_out_ep: Used as an OUT endpoint number.
126 *  USBFS_midi_in_ep: Used as an IN endpoint number.
127 *   USBFS_midiInPointer: Initialized to zero.
128 *
129 * Reentrant:
130 *  No
131 *
132 *******************************************************************************/
133 void USBFS_MIDI_EP_Init(void) 
134 {
135     #if (USBFS_MIDI_IN_BUFF_SIZE > 0)
136        USBFS_midiInPointer = 0u;
137     #endif  /* USBFS_MIDI_IN_BUFF_SIZE > 0 */
138
139     #if(USBFS_EP_MM == USBFS__EP_DMAAUTO)
140         #if (USBFS_MIDI_IN_BUFF_SIZE > 0)
141             /* Init DMA configurations for IN EP*/
142             USBFS_LoadInEP(USBFS_midi_in_ep, USBFS_midiInBuffer,
143                                                                                 USBFS_MIDI_IN_BUFF_SIZE);
144                                                                                 
145         #endif  /* USBFS_MIDI_IN_BUFF_SIZE > 0 */
146         #if (USBFS_MIDI_OUT_BUFF_SIZE > 0)
147             /* Init DMA configurations for OUT EP*/
148             (void)USBFS_ReadOutEP(USBFS_midi_out_ep, USBFS_midiOutBuffer,
149                                                                                 USBFS_MIDI_OUT_BUFF_SIZE);
150         #endif /*USBFS_MIDI_OUT_BUFF_SIZE > 0 */
151     #endif  /* End USBFS__EP_DMAAUTO */
152
153     #if (USBFS_MIDI_OUT_BUFF_SIZE > 0)
154         USBFS_EnableOutEP(USBFS_midi_out_ep);
155     #endif /* USBFS_MIDI_OUT_BUFF_SIZE > 0 */
156
157     /* Initialize the MIDI port(s) */
158     #if (USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF)
159         USBFS_MIDI_Init();
160     #endif /* USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF */
161 }
162
163 #if (USBFS_MIDI_OUT_BUFF_SIZE > 0)
164
165
166     /*******************************************************************************
167     * Function Name: USBFS_MIDI_OUT_EP_Service
168     ********************************************************************************
169     *
170     * Summary:
171     *  Services the USB MIDI OUT endpoints.
172     *  This function is called from OUT EP ISR. It transfers the received from PC
173     *  data to the external MIDI port(UART TX buffer) and calls the
174     *  USBFS_callbackLocalMidiEvent() function to internal process
175     *  of the MIDI data.
176     *  This function is blocked by UART, if not enough space is available in UART
177     *  TX buffer. Therefore it is recommended to use large UART TX buffer size.
178     *
179     * Parameters:
180     *  None
181     *
182     * Return:
183     *  None
184     *
185     * Global variables:
186     *  USBFS_midiOutBuffer: Used as temporary buffer between USB internal
187     *   memory and UART TX buffer.
188     *  USBFS_midi_out_ep: Used as an OUT endpoint number.
189     *
190     * Reentrant:
191     *  No
192     *
193     *******************************************************************************/
194     void USBFS_MIDI_OUT_EP_Service(void) 
195     {
196         #if USBFS_MIDI_OUT_BUFF_SIZE >= 256
197             uint16 outLength;
198             uint16 outPointer;
199         #else
200             uint8 outLength;
201             uint8 outPointer;
202         #endif /* End USBFS_MIDI_OUT_BUFF_SIZE >=256 */
203
204         uint8 dmaState = 0u;
205
206         /* Service the USB MIDI output endpoint */
207         if (USBFS_GetEPState(USBFS_midi_out_ep) == USBFS_OUT_BUFFER_FULL)
208         {
209             #if USBFS_MIDI_OUT_BUFF_SIZE >= 256
210                 outLength = USBFS_GetEPCount(USBFS_midi_out_ep);
211             #else
212                 outLength = (uint8)USBFS_GetEPCount(USBFS_midi_out_ep);
213             #endif /* End USBFS_MIDI_OUT_BUFF_SIZE >= 256 */
214             #if(USBFS_EP_MM != USBFS__EP_DMAAUTO)
215                 #if USBFS_MIDI_OUT_BUFF_SIZE >= 256
216                     outLength = USBFS_ReadOutEP(USBFS_midi_out_ep,
217                                                                     USBFS_midiOutBuffer, outLength);
218                 #else
219                     outLength = (uint8)USBFS_ReadOutEP(USBFS_midi_out_ep,
220                                                                     USBFS_midiOutBuffer, (uint16)outLength);
221                 #endif /* End USBFS_MIDI_OUT_BUFF_SIZE >= 256 */
222                 #if(USBFS_EP_MM == USBFS__EP_DMAMANUAL)
223                     do  /* wait for DMA transfer complete */
224                     {
225                         (void)CyDmaChStatus(USBFS_DmaChan[USBFS_midi_out_ep], NULL, &dmaState);
226                     }while((dmaState & (STATUS_TD_ACTIVE | STATUS_CHAIN_ACTIVE)) != 0u);
227                 #endif /* End USBFS_EP_MM == USBFS__EP_DMAMANUAL */
228             #endif  /* End USBFS_EP_MM != USBFS__EP_DMAAUTO */
229             if(dmaState != 0u)
230             {
231                 /* Suppress compiler warning */
232             }
233             if (outLength >= USBFS_EVENT_LENGTH)
234             {
235                 outPointer = 0u;
236                 while (outPointer < outLength)
237                 {
238                     /* In some OS OUT packet could be appended by nulls which could be skipped */
239                     if (USBFS_midiOutBuffer[outPointer] == 0u)
240                     {
241                         break;
242                     }
243                     /* Route USB MIDI to the External connection */
244                     #if (USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF)
245                         if ((USBFS_midiOutBuffer[outPointer] & USBFS_CABLE_MASK) ==
246                             USBFS_MIDI_CABLE_00)
247                         {
248                             USBFS_MIDI1_ProcessUsbOut(&USBFS_midiOutBuffer[outPointer]);
249                         }
250                         else if ((USBFS_midiOutBuffer[outPointer] & USBFS_CABLE_MASK) ==
251                                  USBFS_MIDI_CABLE_01)
252                         {
253                             #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF)
254                                 USBFS_MIDI2_ProcessUsbOut(&USBFS_midiOutBuffer[outPointer]);
255                             #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF */
256                         }
257                         else
258                         {
259                             /* `#START CUSTOM_MIDI_OUT_EP_SERV` Place your code here */
260
261                             /* `#END` */
262                         }
263                     #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF */
264
265                     /* Process any local MIDI output functions */
266                     USBFS_callbackLocalMidiEvent(
267                         USBFS_midiOutBuffer[outPointer] & USBFS_CABLE_MASK,
268                         &USBFS_midiOutBuffer[outPointer + USBFS_EVENT_BYTE1]);
269                     outPointer += USBFS_EVENT_LENGTH;
270                 }
271             }
272             #if(USBFS_EP_MM == USBFS__EP_DMAAUTO)
273                 /* Enable Out EP*/
274                 USBFS_EnableOutEP(USBFS_midi_out_ep);
275             #endif  /* End USBFS_EP_MM == USBFS__EP_DMAAUTO */
276         }
277     }
278
279 #endif /* #if (USBFS_MIDI_OUT_BUFF_SIZE > 0) */
280
281 #if (USBFS_MIDI_IN_BUFF_SIZE > 0)
282
283
284     /*******************************************************************************
285     * Function Name: USBFS_MIDI_IN_EP_Service
286     ********************************************************************************
287     *
288     * Summary:
289     *  Services the USB MIDI IN endpoint. Non-blocking.
290     *  Checks that previous packet was processed by HOST, otherwise service the
291     *  input endpoint on the subsequent call. It is called from the
292     *  USBFS_MIDI_IN_Service() and from the
293     *  USBFS_PutUsbMidiIn() function.
294     *
295     * Parameters:
296     *  None
297     *
298     * Return:
299     *  None
300     *
301     * Global variables:
302     *  USBFS_midi_in_ep: Used as an IN endpoint number.
303     *  USBFS_midiInBuffer: Function loads the data from this buffer to
304     *    the USB IN endpoint.
305     *   USBFS_midiInPointer: Cleared to zero when data are sent.
306     *
307     * Reentrant:
308     *  No
309     *
310     *******************************************************************************/
311     void USBFS_MIDI_IN_EP_Service(void) 
312     {
313         /* Service the USB MIDI input endpoint */
314         /* Check that previous packet was processed by HOST, otherwise service the USB later */
315         if (USBFS_midiInPointer != 0u)
316         {
317             if(USBFS_GetEPState(USBFS_midi_in_ep) == USBFS_EVENT_PENDING)
318             {
319             #if(USBFS_EP_MM != USBFS__EP_DMAAUTO)
320                 USBFS_LoadInEP(USBFS_midi_in_ep, USBFS_midiInBuffer,
321                                                                                 (uint16)USBFS_midiInPointer);
322             #else /* USBFS_EP_MM != USBFS__EP_DMAAUTO */
323                 /* rearm IN EP */
324                 USBFS_LoadInEP(USBFS_midi_in_ep, NULL, (uint16)USBFS_midiInPointer);
325             #endif /* End USBFS_EP_MM != USBFS__EP_DMAAUTO*/
326
327             /* Clear the midiInPointer. For DMA mode, clear this pointer in the ARB ISR when data are moved by DMA */
328             #if(USBFS_EP_MM == USBFS__EP_MANUAL)
329                 USBFS_midiInPointer = 0u;
330             #endif /* USBFS_EP_MM == USBFS__EP_MANUAL */
331             }
332         }
333     }
334
335
336     /*******************************************************************************
337     * Function Name: USBFS_MIDI_IN_Service
338     ********************************************************************************
339     *
340     * Summary:
341     *  Services the traffic from the MIDI input ports (RX UART) and prepare data
342     *  in USB MIDI IN endpoint buffer.
343     *  Calls the USBFS_MIDI_IN_EP_Service() function to sent the
344     *  data from buffer to PC. Non-blocking. Should be called from main foreground
345     *  task.
346     *  This function is not protected from the reentrant calls. When it is required
347     *  to use this function in UART RX ISR to guaranty low latency, care should be
348     *  taken to protect from reentrant calls.
349     *
350     * Parameters:
351     *  None
352     *
353     * Return:
354     *  None
355     *
356     * Global variables:
357     *   USBFS_midiInPointer: Cleared to zero when data are sent.
358     *
359     * Reentrant:
360     *  No
361     *
362     *******************************************************************************/
363     void USBFS_MIDI_IN_Service(void) 
364     {
365         /* Service the MIDI UART inputs until either both receivers have no more
366         *  events or until the input endpoint buffer fills up.
367         */
368         #if (USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF)
369             uint8 m1 = 0u;
370             uint8 m2 = 0u;
371             do
372             {
373                 if (USBFS_midiInPointer <= (USBFS_MIDI_IN_BUFF_SIZE - USBFS_EVENT_LENGTH))
374                 {
375                     /* Check MIDI1 input port for a complete event */
376                     m1 = USBFS_MIDI1_GetEvent();
377                     if (m1 != 0u)
378                     {
379                         USBFS_PrepareInBuffer(m1, (uint8 *)&USBFS_MIDI1_Event.msgBuff[0],
380                                                     USBFS_MIDI1_Event.size, USBFS_MIDI_CABLE_00);
381                     }
382                 }
383
384             #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF)
385                 if (USBFS_midiInPointer <= (USBFS_MIDI_IN_BUFF_SIZE - USBFS_EVENT_LENGTH))
386                 {
387                     /* Check MIDI2 input port for a complete event */
388                     m2 = USBFS_MIDI2_GetEvent();
389                     if (m2 != 0u)
390                     {
391                         USBFS_PrepareInBuffer(m2, (uint8 *)&USBFS_MIDI2_Event.msgBuff[0],
392                                                     USBFS_MIDI2_Event.size, USBFS_MIDI_CABLE_01);
393                     }
394                 }
395             #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF */
396
397             }while( (USBFS_midiInPointer <= (USBFS_MIDI_IN_BUFF_SIZE - USBFS_EVENT_LENGTH))
398                    && ((m1 != 0u) || (m2 != 0u)) );
399         #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF */
400
401         /* Service the USB MIDI input endpoint */
402         USBFS_MIDI_IN_EP_Service();
403     }
404
405
406     /*******************************************************************************
407     * Function Name: USBFS_PutUsbMidiIn
408     ********************************************************************************
409     *
410     * Summary:
411     *  Puts one MIDI messages into the USB MIDI In endpoint buffer. These are
412     *  MIDI input messages to the host. This function is only used if the device
413     *  has internal MIDI input functionality. USBMIDI_MIDI_IN_Service() function
414     *  should additionally be called to send the message from local buffer to
415     *  IN endpoint.
416     *
417     * Parameters:
418     *  ic:   0 = No message (should never happen)
419     *        1 - 3 = Complete MIDI message in midiMsg
420     *        3 - IN EP LENGTH = Complete SySEx message(without EOSEX byte) in
421     *            midiMsg. The length is limited by the max BULK EP size(64)
422     *        MIDI_SYSEX = Start or continuation of SysEx message
423     *                     (put event bytes in midiMsg buffer)
424     *        MIDI_EOSEX = End of SysEx message
425     *                     (put event bytes in midiMsg buffer)
426     *        MIDI_TUNEREQ = Tune Request message (single byte system common msg)
427     *        0xf8 - 0xff = Single byte real-time message
428     *  midiMsg: pointer to MIDI message.
429     *  cable:   cable number.
430     *
431     * Return:
432     *  USBFS_TRUE if error.
433     *  USBFS_FALSE if success.
434     *
435     * Global variables:
436     *  USBFS_midi_in_ep: MIDI IN endpoint number used for sending data.
437     *  USBFS_midiInPointer: Checked this variable to see if there is
438     *    enough free space in the IN endpoint buffer. If buffer is full, initiate
439     *    sending to PC.
440     *
441     * Reentrant:
442     *  No
443     *
444     *******************************************************************************/
445     uint8 USBFS_PutUsbMidiIn(uint8 ic, const uint8 midiMsg[], uint8 cable)
446                                                                 
447     {
448         uint8 retError = USBFS_FALSE;
449         uint8 msgIndex;
450
451         /* Protect PrepareInBuffer() function from concurrent calls */
452         #if (USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF)
453             MIDI1_UART_DisableRxInt();
454             #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF)
455                 MIDI2_UART_DisableRxInt();
456             #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF */
457         #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF */
458
459         if (USBFS_midiInPointer >
460                     (USBFS_EP[USBFS_midi_in_ep].bufferSize - USBFS_EVENT_LENGTH))
461         {
462             USBFS_MIDI_IN_EP_Service();
463         }
464         if (USBFS_midiInPointer <=
465                     (USBFS_EP[USBFS_midi_in_ep].bufferSize - USBFS_EVENT_LENGTH))
466         {
467             if((ic < USBFS_EVENT_LENGTH) || (ic >= USBFS_MIDI_STATUS_MASK))
468             {
469                 USBFS_PrepareInBuffer(ic, midiMsg, ic, cable);
470             }
471             else
472             {   /* Only SysEx message is greater than 4 bytes */
473                 msgIndex = 0u;
474                 do
475                 {
476                     USBFS_PrepareInBuffer(USBFS_MIDI_SYSEX, &midiMsg[msgIndex],
477                                                      USBFS_EVENT_BYTE3, cable);
478                     ic -= USBFS_EVENT_BYTE3;
479                     msgIndex += USBFS_EVENT_BYTE3;
480                     if (USBFS_midiInPointer >
481                         (USBFS_EP[USBFS_midi_in_ep].bufferSize - USBFS_EVENT_LENGTH))
482                     {
483                         USBFS_MIDI_IN_EP_Service();
484                         if (USBFS_midiInPointer >
485                             (USBFS_EP[USBFS_midi_in_ep].bufferSize - USBFS_EVENT_LENGTH))
486                         {
487                             /* Error condition. HOST is not ready to receive this packet. */
488                             retError = USBFS_TRUE;
489                             break;
490                         }
491                     }
492                 }while(ic > USBFS_EVENT_BYTE3);
493
494                 if(retError == USBFS_FALSE)
495                 {
496                     USBFS_PrepareInBuffer(USBFS_MIDI_EOSEX, midiMsg, ic, cable);
497                 }
498             }
499         }
500         else
501         {
502             /* Error condition. HOST is not ready to receive this packet. */
503             retError = USBFS_TRUE;
504         }
505
506         #if (USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF)
507             MIDI1_UART_EnableRxInt();
508             #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF)
509                 MIDI2_UART_EnableRxInt();
510             #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF */
511         #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF */
512
513         return (retError);
514     }
515
516
517     /*******************************************************************************
518     * Function Name: USBFS_PrepareInBuffer
519     ********************************************************************************
520     *
521     * Summary:
522     *  Builds a USB MIDI event in the input endpoint buffer at the current pointer.
523     *  Puts one MIDI message into the USB MIDI In endpoint buffer.
524     *
525     * Parameters:
526     *  ic:   0 = No message (should never happen)
527     *        1 - 3 = Complete MIDI message at pMdat[0]
528     *        MIDI_SYSEX = Start or continuation of SysEx message
529     *                     (put eventLen bytes in buffer)
530     *        MIDI_EOSEX = End of SysEx message
531     *                     (put eventLen bytes in buffer,
532     *                      and append MIDI_EOSEX)
533     *        MIDI_TUNEREQ = Tune Request message (single byte system common msg)
534     *        0xf8 - 0xff = Single byte real-time message
535     *
536     *  srcBuff: pointer to MIDI data
537     *  eventLen: number of bytes in MIDI event
538     *  cable: MIDI source port number
539     *
540     * Return:
541     *  None
542     *
543     * Global variables:
544     *  USBFS_midiInBuffer: This buffer is used for saving and combine the
545     *    received from UART(s) and(or) generated internally by
546     *    USBFS_PutUsbMidiIn() function messages.
547     *  USBFS_midiInPointer: Used as an index for midiInBuffer to
548     *     write data.
549     *
550     * Reentrant:
551     *  No
552     *
553     *******************************************************************************/
554     void USBFS_PrepareInBuffer(uint8 ic, const uint8 srcBuff[], uint8 eventLen, uint8 cable)
555                                                                  
556     {
557         uint8 srcBuffZero;
558         uint8 srcBuffOne;
559
560         srcBuffZero = srcBuff[0u];
561         srcBuffOne  = srcBuff[1u];
562
563         if (ic >= (USBFS_MIDI_STATUS_MASK | USBFS_MIDI_SINGLE_BYTE_MASK))
564         {
565             USBFS_midiInBuffer[USBFS_midiInPointer] = USBFS_SINGLE_BYTE | cable;
566             USBFS_midiInPointer++;
567             USBFS_midiInBuffer[USBFS_midiInPointer] = ic;
568             USBFS_midiInPointer++;
569             USBFS_midiInBuffer[USBFS_midiInPointer] = 0u;
570             USBFS_midiInPointer++;
571             USBFS_midiInBuffer[USBFS_midiInPointer] = 0u;
572             USBFS_midiInPointer++;
573         }
574         else if((ic < USBFS_EVENT_LENGTH) || (ic == USBFS_MIDI_SYSEX))
575         {
576             if(ic == USBFS_MIDI_SYSEX)
577             {
578                 USBFS_midiInBuffer[USBFS_midiInPointer] = USBFS_SYSEX | cable;
579                 USBFS_midiInPointer++;
580             }
581             else if (srcBuffZero < USBFS_MIDI_SYSEX)
582             {
583                 USBFS_midiInBuffer[USBFS_midiInPointer] = (srcBuffZero >> 4u) | cable;
584                 USBFS_midiInPointer++;
585             }
586             else if (srcBuffZero == USBFS_MIDI_TUNEREQ)
587             {
588                 USBFS_midiInBuffer[USBFS_midiInPointer] = USBFS_1BYTE_COMMON | cable;
589                 USBFS_midiInPointer++;
590             }
591             else if ((srcBuffZero == USBFS_MIDI_QFM) || (srcBuffZero == USBFS_MIDI_SONGSEL))
592             {
593                 USBFS_midiInBuffer[USBFS_midiInPointer] = USBFS_2BYTE_COMMON | cable;
594                 USBFS_midiInPointer++;
595             }
596             else if (srcBuffZero == USBFS_MIDI_SPP)
597             {
598                 USBFS_midiInBuffer[USBFS_midiInPointer] = USBFS_3BYTE_COMMON | cable;
599                 USBFS_midiInPointer++;
600             }
601             else
602             {
603             }
604
605             USBFS_midiInBuffer[USBFS_midiInPointer] = srcBuffZero;
606             USBFS_midiInPointer++;
607             USBFS_midiInBuffer[USBFS_midiInPointer] = srcBuffOne;
608             USBFS_midiInPointer++;
609             USBFS_midiInBuffer[USBFS_midiInPointer] = srcBuff[2u];
610             USBFS_midiInPointer++;
611         }
612         else if (ic == USBFS_MIDI_EOSEX)
613         {
614             switch (eventLen)
615             {
616                 case 0u:
617                     USBFS_midiInBuffer[USBFS_midiInPointer] =
618                                                                         USBFS_SYSEX_ENDS_WITH1 | cable;
619                     USBFS_midiInPointer++;
620                     USBFS_midiInBuffer[USBFS_midiInPointer] = USBFS_MIDI_EOSEX;
621                     USBFS_midiInPointer++;
622                     USBFS_midiInBuffer[USBFS_midiInPointer] = 0u;
623                     USBFS_midiInPointer++;
624                     USBFS_midiInBuffer[USBFS_midiInPointer] = 0u;
625                     USBFS_midiInPointer++;
626                     break;
627                 case 1u:
628                     USBFS_midiInBuffer[USBFS_midiInPointer] =
629                                                                         USBFS_SYSEX_ENDS_WITH2 | cable;
630                     USBFS_midiInPointer++;
631                     USBFS_midiInBuffer[USBFS_midiInPointer] = srcBuffZero;
632                     USBFS_midiInPointer++;
633                     USBFS_midiInBuffer[USBFS_midiInPointer] = USBFS_MIDI_EOSEX;
634                     USBFS_midiInPointer++;
635                     USBFS_midiInBuffer[USBFS_midiInPointer] = 0u;
636                     USBFS_midiInPointer++;
637                     break;
638                 case 2u:
639                     USBFS_midiInBuffer[USBFS_midiInPointer] =
640                                                                         USBFS_SYSEX_ENDS_WITH3 | cable;
641                     USBFS_midiInPointer++;
642                     USBFS_midiInBuffer[USBFS_midiInPointer] = srcBuffZero;
643                     USBFS_midiInPointer++;
644                     USBFS_midiInBuffer[USBFS_midiInPointer] = srcBuffOne;
645                     USBFS_midiInPointer++;
646                     USBFS_midiInBuffer[USBFS_midiInPointer] = USBFS_MIDI_EOSEX;
647                     USBFS_midiInPointer++;
648                     break;
649                 default:
650                     break;
651             }
652         }
653         else
654         {
655         }
656     }
657
658 #endif /* #if (USBFS_MIDI_IN_BUFF_SIZE > 0) */
659
660
661 /* The implementation for external serial input and output connections
662 *  to route USB MIDI data to and from those connections.
663 */
664 #if (USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF)
665
666
667     /*******************************************************************************
668     * Function Name: USBFS_MIDI_Init
669     ********************************************************************************
670     *
671     * Summary:
672     *  Initializes MIDI variables and starts the UART(s) hardware block(s).
673     *
674     * Parameters:
675     *  None
676     *
677     * Return:
678     *  None
679     *
680     * Side Effects:
681     *  Change the priority of the UART(s) TX interrupts to be higher than the
682     *  default EP ISR priority.
683     *
684     * Global variables:
685     *   USBFS_MIDI_Event: initialized to zero.
686     *   USBFS_MIDI_TxRunStat: initialized to zero.
687     *
688     *******************************************************************************/
689     void USBFS_MIDI_Init(void) 
690     {
691         USBFS_MIDI1_Event.length = 0u;
692         USBFS_MIDI1_Event.count = 0u;
693         USBFS_MIDI1_Event.size = 0u;
694         USBFS_MIDI1_Event.runstat = 0u;
695         USBFS_MIDI1_TxRunStat = 0u;
696         USBFS_MIDI1_InqFlags = 0u;
697         /* Start UART block */
698         MIDI1_UART_Start();
699         /* Change the priority of the UART TX and RX interrupt */
700         CyIntSetPriority(MIDI1_UART_TX_VECT_NUM, USBFS_CUSTOM_UART_TX_PRIOR_NUM);
701         CyIntSetPriority(MIDI1_UART_RX_VECT_NUM, USBFS_CUSTOM_UART_RX_PRIOR_NUM);
702
703         #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF)
704             USBFS_MIDI2_Event.length = 0u;
705             USBFS_MIDI2_Event.count = 0u;
706             USBFS_MIDI2_Event.size = 0u;
707             USBFS_MIDI2_Event.runstat = 0u;
708             USBFS_MIDI2_TxRunStat = 0u;
709             USBFS_MIDI2_InqFlags = 0u;
710             /* Start second UART block */
711             MIDI2_UART_Start();
712             /* Change the priority of the UART TX interrupt */
713             CyIntSetPriority(MIDI2_UART_TX_VECT_NUM, USBFS_CUSTOM_UART_TX_PRIOR_NUM);
714             CyIntSetPriority(MIDI2_UART_RX_VECT_NUM, USBFS_CUSTOM_UART_RX_PRIOR_NUM);
715         #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF*/
716
717         /* `#START MIDI_INIT_CUSTOM` Init other extended UARTs here */
718
719         /* `#END` */
720
721     }
722
723
724     /*******************************************************************************
725     * Function Name: USBFS_ProcessMidiIn
726     ********************************************************************************
727     *
728     * Summary:
729     *  Processes one byte of incoming MIDI data.
730     *
731     * Parameters:
732     *   mData = current MIDI input data byte
733     *   *rxStat = pointer to a MIDI_RX_STATUS structure
734     *
735     * Return:
736     *   0, if no complete message
737     *   1 - 4, if message complete
738     *   MIDI_SYSEX, if start or continuation of system exclusive
739     *   MIDI_EOSEX, if end of system exclusive
740     *   0xf8 - 0xff, if single byte real time message
741     *
742     *******************************************************************************/
743     uint8 USBFS_ProcessMidiIn(uint8 mData, USBFS_MIDI_RX_STATUS *rxStat)
744                                                                 
745     {
746         uint8 midiReturn = 0u;
747
748         /* Check for a MIDI status byte.  All status bytes, except real time messages,
749         *  which are a single byte, force the start of a new buffer cycle.
750         */
751         if ((mData & USBFS_MIDI_STATUS_BYTE_MASK) != 0u)
752         {
753             if ((mData & USBFS_MIDI_STATUS_MASK) == USBFS_MIDI_STATUS_MASK)
754             {
755                 if ((mData & USBFS_MIDI_SINGLE_BYTE_MASK) != 0u) /* System Real-Time Messages(single byte) */
756                 {
757                     midiReturn = mData;
758                 }
759                 else                              /* System Common Messages */
760                 {
761                     switch (mData)
762                     {
763                         case USBFS_MIDI_SYSEX:
764                             rxStat->msgBuff[0u] = USBFS_MIDI_SYSEX;
765                             rxStat->runstat = USBFS_MIDI_SYSEX;
766                             rxStat->count = 1u;
767                             rxStat->length = 3u;
768                             break;
769                         case USBFS_MIDI_EOSEX:
770                             rxStat->runstat = 0u;
771                             rxStat->size = rxStat->count;
772                             rxStat->count = 0u;
773                             midiReturn = USBFS_MIDI_EOSEX;
774                             break;
775                         case USBFS_MIDI_SPP:
776                             rxStat->msgBuff[0u] = USBFS_MIDI_SPP;
777                             rxStat->runstat = 0u;
778                             rxStat->count = 1u;
779                             rxStat->length = 3u;
780                             break;
781                         case USBFS_MIDI_SONGSEL:
782                             rxStat->msgBuff[0u] = USBFS_MIDI_SONGSEL;
783                             rxStat->runstat = 0u;
784                             rxStat->count = 1u;
785                             rxStat->length = 2u;
786                             break;
787                         case USBFS_MIDI_QFM:
788                             rxStat->msgBuff[0u] = USBFS_MIDI_QFM;
789                             rxStat->runstat = 0u;
790                             rxStat->count = 1u;
791                             rxStat->length = 2u;
792                             break;
793                         case USBFS_MIDI_TUNEREQ:
794                             rxStat->msgBuff[0u] = USBFS_MIDI_TUNEREQ;
795                             rxStat->runstat = 0u;
796                             rxStat->size = 1u;
797                             rxStat->count = 0u;
798                             midiReturn = rxStat->size;
799                             break;
800                         default:
801                             break;
802                     }
803                 }
804             }
805             else /* Channel Messages */
806             {
807                 rxStat->msgBuff[0u] = mData;
808                 rxStat->runstat = mData;
809                 rxStat->count = 1u;
810                 switch (mData & USBFS_MIDI_STATUS_MASK)
811                 {
812                     case USBFS_MIDI_NOTE_OFF:
813                     case USBFS_MIDI_NOTE_ON:
814                     case USBFS_MIDI_POLY_KEY_PRESSURE:
815                     case USBFS_MIDI_CONTROL_CHANGE:
816                     case USBFS_MIDI_PITCH_BEND_CHANGE:
817                         rxStat->length = 3u;
818                         break;
819                     case USBFS_MIDI_PROGRAM_CHANGE:
820                     case USBFS_MIDI_CHANNEL_PRESSURE:
821                         rxStat->length = 2u;
822                         break;
823                     default:
824                         rxStat->runstat = 0u;
825                         rxStat->count = 0u;
826                         break;
827                 }
828             }
829         }
830
831         /* Otherwise, it's a data byte */
832         else
833         {
834             if (rxStat->runstat == USBFS_MIDI_SYSEX)
835             {
836                 rxStat->msgBuff[rxStat->count] = mData;
837                 rxStat->count++;
838                 if (rxStat->count >= rxStat->length)
839                 {
840                     rxStat->size = rxStat->count;
841                     rxStat->count = 0u;
842                     midiReturn = USBFS_MIDI_SYSEX;
843                 }
844             }
845             else if (rxStat->count > 0u)
846             {
847                 rxStat->msgBuff[rxStat->count] = mData;
848                 rxStat->count++;
849                 if (rxStat->count >= rxStat->length)
850                 {
851                     rxStat->size = rxStat->count;
852                     rxStat->count = 0u;
853                     midiReturn = rxStat->size;
854                 }
855             }
856             else if (rxStat->runstat != 0u)
857             {
858                 rxStat->msgBuff[0u] = rxStat->runstat;
859                 rxStat->msgBuff[1u] = mData;
860                 rxStat->count = 2u;
861                 switch (rxStat->runstat & USBFS_MIDI_STATUS_MASK)
862                 {
863                     case USBFS_MIDI_NOTE_OFF:
864                     case USBFS_MIDI_NOTE_ON:
865                     case USBFS_MIDI_POLY_KEY_PRESSURE:
866                     case USBFS_MIDI_CONTROL_CHANGE:
867                     case USBFS_MIDI_PITCH_BEND_CHANGE:
868                         rxStat->length = 3u;
869                         break;
870                     case USBFS_MIDI_PROGRAM_CHANGE:
871                     case USBFS_MIDI_CHANNEL_PRESSURE:
872                         rxStat->size =rxStat->count;
873                         rxStat->count = 0u;
874                         midiReturn = rxStat->size;
875                         break;
876                     default:
877                         rxStat->count = 0u;
878                     break;
879                 }
880             }
881             else
882             {
883             }
884         }
885         return (midiReturn);
886     }
887
888
889     /*******************************************************************************
890     * Function Name: USBFS_MIDI1_GetEvent
891     ********************************************************************************
892     *
893     * Summary:
894     *  Checks for incoming MIDI data, calls the MIDI event builder if so.
895     *  Returns either empty or with a complete event.
896     *
897     * Parameters:
898     *  None
899     *
900     * Return:
901     *   0, if no complete message
902     *   1 - 4, if message complete
903     *   MIDI_SYSEX, if start or continuation of system exclusive
904     *   MIDI_EOSEX, if end of system exclusive
905     *   0xf8 - 0xff, if single byte real time message
906     *
907     * Global variables:
908     *  USBFS_MIDI1_Event: RX status structure used to parse received
909     *    data.
910     *
911     *******************************************************************************/
912     uint8 USBFS_MIDI1_GetEvent(void) 
913     {
914         uint8 msgRtn = 0u;
915         uint8 rxData;
916         #if (MIDI1_UART_RXBUFFERSIZE >= 256u)
917             uint16 rxBufferRead;
918             #if CY_PSOC3 /* This local variable is required only for PSOC3 and large buffer */
919                 uint16 rxBufferWrite;
920             #endif /* end CY_PSOC3 */
921         #else
922             uint8 rxBufferRead;
923         #endif /* End MIDI1_UART_RXBUFFERSIZE >= 256 */
924         uint8 rxBufferLoopDetect;
925         /* Read buffer loop condition to the local variable */
926         rxBufferLoopDetect = MIDI1_UART_rxBufferLoopDetect;
927
928         if ( (MIDI1_UART_rxBufferRead != MIDI1_UART_rxBufferWrite) || (rxBufferLoopDetect != 0u) )
929         {
930             /* Protect variables that could change on interrupt by disabling Rx interrupt.*/
931             #if ((MIDI1_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
932                 CyIntDisable(MIDI1_UART_RX_VECT_NUM);
933             #endif /* End MIDI1_UART_RXBUFFERSIZE >= 256 */
934             rxBufferRead = MIDI1_UART_rxBufferRead;
935             #if ((MIDI1_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
936                 rxBufferWrite = MIDI1_UART_rxBufferWrite;
937                 CyIntEnable(MIDI1_UART_RX_VECT_NUM);
938             #endif /* End MIDI1_UART_RXBUFFERSIZE >= 256 */
939
940             /* Stay here until either the buffer is empty or we have a complete message
941             *  in the message buffer. Note that we must use a temporary buffer pointer
942             *  since it takes two instructions to increment with a wrap, and we can't
943             *  risk doing that with the real pointer and getting an interrupt in between
944             *  instructions.
945             */
946
947             #if ((MIDI1_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
948                 while ( ((rxBufferRead != rxBufferWrite) || (rxBufferLoopDetect != 0u)) && (msgRtn == 0u) )
949             #else
950                 while ( ((rxBufferRead != MIDI1_UART_rxBufferWrite) || (rxBufferLoopDetect != 0u)) && (msgRtn == 0u) )
951             #endif /* End MIDI1_UART_RXBUFFERSIZE >= 256 && CY_PSOC3 */
952                 {
953                     rxData = MIDI1_UART_rxBuffer[rxBufferRead];
954                     /* Increment pointer with a wrap */
955                     rxBufferRead++;
956                     if(rxBufferRead >= MIDI1_UART_RXBUFFERSIZE)
957                     {
958                         rxBufferRead = 0u;
959                     }
960                     /* If loop condition was set - update real read buffer pointer
961                     *  to avoid overflow status
962                     */
963                     if(rxBufferLoopDetect != 0u )
964                     {
965                         MIDI1_UART_rxBufferLoopDetect = 0u;
966                         #if ((MIDI1_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
967                             CyIntDisable(MIDI1_UART_RX_VECT_NUM);
968                         #endif /* End MIDI1_UART_RXBUFFERSIZE >= 256 */
969                         MIDI1_UART_rxBufferRead = rxBufferRead;
970                         #if ((MIDI1_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
971                             CyIntEnable(MIDI1_UART_RX_VECT_NUM);
972                         #endif /* End MIDI1_UART_RXBUFFERSIZE >= 256 */
973                     }
974
975                     msgRtn = USBFS_ProcessMidiIn(rxData,
976                                                     (USBFS_MIDI_RX_STATUS *)&USBFS_MIDI1_Event);
977
978                     /* Read buffer loop condition to the local variable */
979                     rxBufferLoopDetect = MIDI1_UART_rxBufferLoopDetect;
980                 }
981
982             /* Finally, update the real output pointer, then return with
983             *  an indication as to whether there's a complete message in the buffer.
984             */
985             #if ((MIDI1_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
986                 CyIntDisable(MIDI1_UART_RX_VECT_NUM);
987             #endif /* End MIDI1_UART_RXBUFFERSIZE >= 256 */
988             MIDI1_UART_rxBufferRead = rxBufferRead;
989             #if ((MIDI1_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
990                 CyIntEnable(MIDI1_UART_RX_VECT_NUM);
991             #endif /* End MIDI1_UART_RXBUFFERSIZE >= 256 */
992         }
993
994         return (msgRtn);
995     }
996
997
998     /*******************************************************************************
999     * Function Name: USBFS_MIDI1_ProcessUsbOut
1000     ********************************************************************************
1001     *
1002     * Summary:
1003     *  Process a USB MIDI output event.
1004     *  Puts data into the MIDI TX output buffer.
1005     *
1006     * Parameters:
1007     *  *epBuf: pointer on MIDI event.
1008     *
1009     * Return:
1010     *   None
1011     *
1012     * Global variables:
1013     *  USBFS_MIDI1_TxRunStat: This variable used to save the MIDI
1014     *    status byte and skip to send the repeated status byte in subsequent event.
1015     *  USBFS_MIDI1_InqFlags: The following flags are set when SysEx
1016     *    message comes.
1017     *    USBFS_INQ_SYSEX_FLAG: Non-Real Time SySEx message received.
1018     *    USBFS_INQ_IDENTITY_REQ_FLAG: Identity Request received.
1019     *      This bit should be cleared by user when Identity Reply message generated.
1020     *
1021     *******************************************************************************/
1022     void USBFS_MIDI1_ProcessUsbOut(const uint8 epBuf[])
1023                                                             
1024     {
1025         uint8 cmd;
1026         uint8 len;
1027         uint8 i;
1028
1029         /* User code is required at the beginning of the procedure */
1030         /* `#START MIDI1_PROCESS_OUT_BEGIN` */
1031
1032         /* `#END` */
1033
1034         cmd = epBuf[USBFS_EVENT_BYTE0] & USBFS_CIN_MASK;
1035         if((cmd != USBFS_RESERVED0) && (cmd != USBFS_RESERVED1))
1036         {
1037             len = USBFS_MIDI_SIZE[cmd];
1038             i = USBFS_EVENT_BYTE1;
1039             /* Universal System Exclusive message parsing */
1040             if(cmd == USBFS_SYSEX)
1041             {
1042                 if((epBuf[USBFS_EVENT_BYTE1] == USBFS_MIDI_SYSEX) &&
1043                    (epBuf[USBFS_EVENT_BYTE2] == USBFS_MIDI_SYSEX_NON_REAL_TIME))
1044                 {   /* Non-Real Time SySEx starts */
1045                     USBFS_MIDI1_InqFlags |= USBFS_INQ_SYSEX_FLAG;
1046                 }
1047                 else
1048                 {
1049                     USBFS_MIDI1_InqFlags &= (uint8)~USBFS_INQ_SYSEX_FLAG;
1050                 }
1051             }
1052             else if(cmd == USBFS_SYSEX_ENDS_WITH1)
1053             {
1054                 USBFS_MIDI1_InqFlags &= (uint8)~USBFS_INQ_SYSEX_FLAG;
1055             }
1056             else if(cmd == USBFS_SYSEX_ENDS_WITH2)
1057             {
1058                 USBFS_MIDI1_InqFlags &= (uint8)~USBFS_INQ_SYSEX_FLAG;
1059             }
1060             else if(cmd == USBFS_SYSEX_ENDS_WITH3)
1061             {
1062                 /* Identify Request support */
1063                 if((USBFS_MIDI1_InqFlags & USBFS_INQ_SYSEX_FLAG) != 0u)
1064                 {
1065                     USBFS_MIDI1_InqFlags &= (uint8)~USBFS_INQ_SYSEX_FLAG;
1066                     if((epBuf[USBFS_EVENT_BYTE1] == USBFS_MIDI_SYSEX_GEN_INFORMATION) &&
1067                     (epBuf[USBFS_EVENT_BYTE2] == USBFS_MIDI_SYSEX_IDENTITY_REQ))
1068                     {   /* Set the flag about received the Identity Request.
1069                         *  The Identity Reply message may be send by user code.
1070                         */
1071                         USBFS_MIDI1_InqFlags |= USBFS_INQ_IDENTITY_REQ_FLAG;
1072                     }
1073                 }
1074             }
1075             else /* Do nothing for other command */
1076             {
1077             }
1078             /* Running Status for Voice and Mode messages only. */
1079             if((cmd >= USBFS_NOTE_OFF) && ( cmd <= USBFS_PITCH_BEND_CHANGE))
1080             {
1081                 if(USBFS_MIDI1_TxRunStat == epBuf[USBFS_EVENT_BYTE1])
1082                 {   /* Skip the repeated Status byte */
1083                     i++;
1084                 }
1085                 else
1086                 {   /* Save Status byte for next event */
1087                     USBFS_MIDI1_TxRunStat = epBuf[USBFS_EVENT_BYTE1];
1088                 }
1089             }
1090             else
1091             {   /* Clear Running Status */
1092                 USBFS_MIDI1_TxRunStat = 0u;
1093             }
1094             /* Puts data into the MIDI TX output buffer.*/
1095             do
1096             {
1097                 MIDI1_UART_PutChar(epBuf[i]);
1098                 i++;
1099             } while (i <= len);
1100         }
1101
1102         /* User code is required at the end of the procedure */
1103         /* `#START MIDI1_PROCESS_OUT_END` */
1104
1105         /* `#END` */
1106     }
1107
1108 #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF)
1109
1110
1111     /*******************************************************************************
1112     * Function Name: USBFS_MIDI2_GetEvent
1113     ********************************************************************************
1114     *
1115     * Summary:
1116     *  Checks for incoming MIDI data, calls the MIDI event builder if so.
1117     *  Returns either empty or with a complete event.
1118     *
1119     * Parameters:
1120     *  None
1121     *
1122     * Return:
1123     *   0, if no complete message
1124     *   1 - 4, if message complete
1125     *   MIDI_SYSEX, if start or continuation of system exclusive
1126     *   MIDI_EOSEX, if end of system exclusive
1127     *   0xf8 - 0xff, if single byte real time message
1128     *
1129     * Global variables:
1130     *  USBFS_MIDI2_Event: RX status structure used to parse received
1131     *    data.
1132     *
1133     *******************************************************************************/
1134     uint8 USBFS_MIDI2_GetEvent(void) 
1135     {
1136         uint8 msgRtn = 0u;
1137         uint8 rxData;
1138         #if (MIDI2_UART_RXBUFFERSIZE >= 256u)
1139             uint16 rxBufferRead;
1140             #if CY_PSOC3 /* This local variable required only for PSOC3 and large buffer */
1141                 uint16 rxBufferWrite;
1142             #endif /* end CY_PSOC3 */
1143         #else
1144             uint8 rxBufferRead;
1145         #endif /* End MIDI2_UART_RXBUFFERSIZE >= 256 */
1146         uint8 rxBufferLoopDetect;
1147         /* Read buffer loop condition to the local variable */
1148         rxBufferLoopDetect = MIDI2_UART_rxBufferLoopDetect;
1149
1150         if ( (MIDI2_UART_rxBufferRead != MIDI2_UART_rxBufferWrite) || (rxBufferLoopDetect != 0u) )
1151         {
1152             /* Protect variables that could change on interrupt by disabling Rx interrupt.*/
1153             #if ((MIDI2_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
1154                 CyIntDisable(MIDI2_UART_RX_VECT_NUM);
1155             #endif /* End MIDI2_UART_RXBUFFERSIZE >= 256 */
1156             rxBufferRead = MIDI2_UART_rxBufferRead;
1157             #if ((MIDI2_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
1158                 rxBufferWrite = MIDI2_UART_rxBufferWrite;
1159                 CyIntEnable(MIDI2_UART_RX_VECT_NUM);
1160             #endif /* End MIDI2_UART_RXBUFFERSIZE >= 256 */
1161
1162             /* Stay here until either the buffer is empty or we have a complete message
1163             *  in the message buffer. Note that we must use a temporary output pointer to
1164             *  since it takes two instructions to increment with a wrap, and we can't
1165             *  risk doing that with the real pointer and getting an interrupt in between
1166             *  instructions.
1167             */
1168
1169             #if ((MIDI2_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
1170                 while ( ((rxBufferRead != rxBufferWrite) || (rxBufferLoopDetect != 0u)) && (msgRtn == 0u) )
1171             #else
1172                 while ( ((rxBufferRead != MIDI2_UART_rxBufferWrite) || (rxBufferLoopDetect != 0u)) && (msgRtn == 0u) )
1173             #endif /* End MIDI2_UART_RXBUFFERSIZE >= 256 && CY_PSOC3 */
1174                 {
1175                     rxData = MIDI2_UART_rxBuffer[rxBufferRead];
1176                     rxBufferRead++;
1177                     if(rxBufferRead >= MIDI2_UART_RXBUFFERSIZE)
1178                     {
1179                         rxBufferRead = 0u;
1180                     }
1181                     /* If loop condition was set - update real read buffer pointer
1182                     *  to avoid overflow status
1183                     */
1184                     if(rxBufferLoopDetect != 0u )
1185                     {
1186                         MIDI2_UART_rxBufferLoopDetect = 0u;
1187                         #if ((MIDI2_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
1188                             CyIntDisable(MIDI2_UART_RX_VECT_NUM);
1189                         #endif /* End MIDI2_UART_RXBUFFERSIZE >= 256 */
1190                         MIDI2_UART_rxBufferRead = rxBufferRead;
1191                         #if ((MIDI2_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
1192                             CyIntEnable(MIDI2_UART_RX_VECT_NUM);
1193                         #endif /* End MIDI2_UART_RXBUFFERSIZE >= 256 */
1194                     }
1195
1196                     msgRtn = USBFS_ProcessMidiIn(rxData,
1197                                                     (USBFS_MIDI_RX_STATUS *)&USBFS_MIDI2_Event);
1198
1199                     /* Read buffer loop condition to the local variable */
1200                     rxBufferLoopDetect = MIDI2_UART_rxBufferLoopDetect;
1201                 }
1202
1203             /* Finally, update the real output pointer, then return with
1204             *  an indication as to whether there's a complete message in the buffer.
1205             */
1206             #if ((MIDI2_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
1207                 CyIntDisable(MIDI2_UART_RX_VECT_NUM);
1208             #endif /* End MIDI2_UART_RXBUFFERSIZE >= 256 */
1209             MIDI2_UART_rxBufferRead = rxBufferRead;
1210             #if ((MIDI2_UART_RXBUFFERSIZE >= 256u) && (CY_PSOC3))
1211                 CyIntEnable(MIDI2_UART_RX_VECT_NUM);
1212             #endif /* End MIDI2_UART_RXBUFFERSIZE >= 256 */
1213         }
1214
1215         return (msgRtn);
1216     }
1217
1218
1219     /*******************************************************************************
1220     * Function Name: USBFS_MIDI2_ProcessUsbOut
1221     ********************************************************************************
1222     *
1223     * Summary:
1224     *  Process a USB MIDI output event.
1225     *  Puts data into the MIDI TX output buffer.
1226     *
1227     * Parameters:
1228     *  *epBuf: pointer on MIDI event.
1229     *
1230     * Return:
1231     *   None
1232     *
1233     * Global variables:
1234     *  USBFS_MIDI2_TxRunStat: This variable used to save the MIDI
1235     *    status byte and skip to send the repeated status byte in subsequent event.
1236     *  USBFS_MIDI2_InqFlags: The following flags are set when SysEx
1237     *    message comes.
1238     *  USBFS_INQ_SYSEX_FLAG: Non-Real Time SySEx message received.
1239     *  USBFS_INQ_IDENTITY_REQ_FLAG: Identity Request received.
1240     *    This bit should be cleared by user when Identity Reply message generated.
1241     *
1242     *******************************************************************************/
1243     void USBFS_MIDI2_ProcessUsbOut(const uint8 epBuf[])
1244                                                             
1245     {
1246         uint8 cmd;
1247         uint8 len;
1248         uint8 i;
1249
1250         /* User code is required at the beginning of the procedure */
1251         /* `#START MIDI2_PROCESS_OUT_START` */
1252
1253         /* `#END` */
1254
1255         cmd = epBuf[USBFS_EVENT_BYTE0] & USBFS_CIN_MASK;
1256         if((cmd != USBFS_RESERVED0) && (cmd != USBFS_RESERVED1))
1257         {
1258             len = USBFS_MIDI_SIZE[cmd];
1259             i = USBFS_EVENT_BYTE1;
1260             /* Universal System Exclusive message parsing */
1261             if(cmd == USBFS_SYSEX)
1262             {
1263                 if((epBuf[USBFS_EVENT_BYTE1] == USBFS_MIDI_SYSEX) &&
1264                    (epBuf[USBFS_EVENT_BYTE2] == USBFS_MIDI_SYSEX_NON_REAL_TIME))
1265                 {   /* SySEx starts */
1266                     USBFS_MIDI2_InqFlags |= USBFS_INQ_SYSEX_FLAG;
1267                 }
1268                 else
1269                 {
1270                     USBFS_MIDI2_InqFlags &= (uint8)~USBFS_INQ_SYSEX_FLAG;
1271                 }
1272             }
1273             else if(cmd == USBFS_SYSEX_ENDS_WITH1)
1274             {
1275                 USBFS_MIDI2_InqFlags &= (uint8)~USBFS_INQ_SYSEX_FLAG;
1276             }
1277             else if(cmd == USBFS_SYSEX_ENDS_WITH2)
1278             {
1279                 USBFS_MIDI2_InqFlags &= (uint8)~USBFS_INQ_SYSEX_FLAG;
1280             }
1281             else if(cmd == USBFS_SYSEX_ENDS_WITH3)
1282             {
1283                 /* Identify Request support */
1284                 if((USBFS_MIDI2_InqFlags & USBFS_INQ_SYSEX_FLAG) != 0u)
1285                 {
1286                     USBFS_MIDI2_InqFlags &= (uint8)~USBFS_INQ_SYSEX_FLAG;
1287                     if((epBuf[USBFS_EVENT_BYTE1] == USBFS_MIDI_SYSEX_GEN_INFORMATION) &&
1288                        (epBuf[USBFS_EVENT_BYTE2] == USBFS_MIDI_SYSEX_IDENTITY_REQ))
1289                     {   /* Set the flag about received the Identity Request.
1290                         *  The Identity Reply message may be send by user code.
1291                         */
1292                         USBFS_MIDI2_InqFlags |= USBFS_INQ_IDENTITY_REQ_FLAG;
1293                     }
1294                 }
1295             }
1296             else /* Do nothing for other command */
1297             {
1298             }
1299             /* Running Status for Voice and Mode messages only. */
1300             if((cmd >= USBFS_NOTE_OFF) && ( cmd <= USBFS_PITCH_BEND_CHANGE))
1301             {
1302                 if(USBFS_MIDI2_TxRunStat == epBuf[USBFS_EVENT_BYTE1])
1303                 {   /* Skip the repeated Status byte */
1304                     i++;
1305                 }
1306                 else
1307                 {   /* Save Status byte for next event */
1308                     USBFS_MIDI2_TxRunStat = epBuf[USBFS_EVENT_BYTE1];
1309                 }
1310             }
1311             else
1312             {   /* Clear Running Status */
1313                 USBFS_MIDI2_TxRunStat = 0u;
1314             }
1315             /* Puts data into the MIDI TX output buffer.*/
1316             do
1317             {
1318                 MIDI2_UART_PutChar(epBuf[i]);
1319                 i++;
1320             } while (i <= len);
1321         }
1322
1323         /* User code is required at the end of the procedure */
1324         /* `#START MIDI2_PROCESS_OUT_END` */
1325
1326         /* `#END` */
1327     }
1328 #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF */
1329 #endif /* End USBFS_MIDI_EXT_MODE >= USBFS_ONE_EXT_INTRF */
1330
1331 #endif  /* End (USBFS_ENABLE_MIDI_API != 0u) */
1332
1333
1334 /* `#START MIDI_FUNCTIONS` Place any additional functions here */
1335
1336 /* `#END` */
1337
1338 #endif  /* End defined(USBFS_ENABLE_MIDI_STREAMING) */
1339
1340
1341 /* [] END OF FILE */