Remove Text Formatting
Loading...

+ Reply to Thread
Results 1 to 8 of 8

Thread: MIDI over USB

  1. #1
    Join Date
    Feb 2012
    Posts
    34

    Default MIDI over USB

    Hello,
    I would like to try to do this, but I don't know if this is possible...

    I would like to behave a PIC based circuit as an (USB) MIDI (receiver) interface.
    In the past I have managed to create circuits with a PIC that behaved like a HID device, that didn't need any drivers.
    The point of this is, that most software applications need to 'see' a MIDI port, in order to send information to that port.
    I suppose I have to change some values in the USB descriptors, but I have no idea where to start.
    Most commercial USB to MIDI interfaces don't need a driver, so I suppose this must be possible.
    Maybe somebody has experimented with this, and is willing to share some code with me?
    Many thanks in advance!

    (Just to be clear: I only need communication FROM the PC to the PIC circuit.)
    Last edited by RuudNL; - 10th November 2017 at 13:07.

  2. #2
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,232

    Default Re: MIDI over USB

    Have you seen this?

    http://www.microchip.com/forums/m409051.aspx

    Edit: or this:


    EDIT again: Or maybe this:
    https://forum.sparkfun.com/viewtopic.php?t=17172

    Robert
    Last edited by Demon; - 10th November 2017 at 20:09. Reason: Google is your friend :D PIC USB MiDI
    Not as dumb as yesterday, but stupider than tomorrow!

  3. #3
    Join Date
    Feb 2012
    Posts
    34

    Default Re: MIDI over USB

    Nice, but not really PicBasic related.
    (Also some of the links don't work.)

  4. #4
    Join Date
    Mar 2008
    Location
    Gerogetown, Texas
    Posts
    94

    Default Re: MIDI over USB

    I did a USB Midi back in 2009, Here is the code. It has been too long ago for me to remember the specifics. Maybe it will help you get started.
    Code:
    ' ************************************************************
    ' * Auto generated EasyHID file. PBP 2.60 and above          *
    ' ************************************************************
    
    ' include the HID descriptor
    INCLUDE "DESCUSB_MIDI.bas"
    DEFINE WRITE_INT 1
    Define	LOADER_USED	1
    DEFINE RESET_ORG 800h ' For Microchip USB Bootloader
    DEFINE INTERRUPT_ORG 808h ' For Microchip USB Bootloader
    
    DEFINE OSC 48                   ' tell program we are using a 20mhz oscillator
    DEFINE HSER_RCSTA 90h           ' enable serial receive 
    DEFINE HSER_TXSTA 24h           ' enable serial transmit
    DEFINE HSER_BAUD 31250          ' set baud rate for MIDI transmission
    DEFINE ADC_BITS 8              ' set the number of bits in the sample
    DEFINE ADC_SAMPLEUS 50          ' set the sample time
    I2C_Data    var PORTD.1
    I2C_CLK     var PORTD.0
    
    
    USBBufferSizeMax   CON 16  ' maximum buffer size
    USBBufferSizeTX    CON 16  ' input
    USBBufferSizeRX    CON 16  ' output
    
    ' the USB buffer...
    USBBuffer        VAR BYTE[USBBufferSizeMax]
    USBBufferCount   VAR BYTE
    
    
    Portb = %11111111
    ADCON1 = %00000101              ' AN0 - AN9 analog
    TRISA = %00101111               ' Set PORTA to inputs
    TRISB = %00001100
    TRISC = %00000000
    TRISD = %11110000
    TRISE = %00000111  ' Porte 1,2 ,3 inputs, 
    CMCON = 7         'PortA Digital
    INTCON2.7 = 0     'weak pullups portB  = 0, disable = 1
    PORTE.7 = 1        '  weak pullups portd enabled
    
    '======================================================================================
    ' Port A Registers (8 Bit Mode)
    IODIRA             con   $00          ' Direction Bit Control Reg
    IOBITSA            con	%11111111	' Direction Bit Settings Reg (0 = output, 1 = input)
    IPOLA              con	$01			' Interrupt Polarity Control Reg
    GPINTENA           con	$02			'Interrupt Enable Reg
    DEFVALA            con	$03
    INTCONA	           con	$04
    IOCONA	           con	$05			' I/O Configuration Reg
    IOCONSETA          con	%10111000	' IOCON register setting
    GPPUA	           con	$06			' Pull-Up Control Reg
    INTFA	           con	$07			' Interrupt Flag Register
    INTCAPA	           con	$08
    GPIOA	           con	$09			' General Purpose I/O
    IOLATA	           con	$0A			' Output Latch Reg
    
    'Port B Registers (8 Bit Mode)
    IODIRB	          con	$10			' Port B Direction Bit Control Address
    IOBITSB	          con	%00000000		' Port B Direction Bit Settings (0 = output, 1 = input)
    IPOLB	          con	$11			' Interrupt Polarity Control
    GPINTENB          con	$12			' Interrupt Enable Reg
    DEFVALB	          con	$13
    INTCONB	          con	$14
    IOCONB	          con	$15			' I/O Configuration Reg
    IOCONSETB         con	%10111000		' IOCON register setting
    GPPUB	          con	$16			' Pull-Up Control Reg
    INTFB	          con	$17			' Interrupt Flag Register
    INTPOLB	          con	$18
    GPIOB	          con	$19			' General Purpose I/O Reg
    IOLATB	          con	$1A			' Output Latch Reg
    
    '========================================================================================
    ' Port A Reguisters (16 Bit Mode)
    IODIRA16            con	    $00
    IODIRB16            con	    $01
    IOCONA16            con	    $0A
    IOCONB16            con	    $0B
    GPIOA16             con		$12
    GPIOB16             con		$13
    OLATA16             con		$14
    OLATB16             con		$15
    
    IO_EXP0WR           con	    $40		' MCP23017  Write
    IO_EXP0RD           con	    $40		' MCP23017  Read
    IO_DAT              var     byte    ' MCP23017  Data read
    IO_DAT_OLD          var     byte
    IO_DATA             var     byte    ' MCP23017  Data read
    IO_DAT_OLDA         var     byte
    IO_DATB             var     byte    ' MCP23017  Data read
    IO_DAT_OLDB         var     byte
    Out_Dat             var     byte
    Enc1                var     byte
    Enc1_Old            var     byte
    Enc1_Mask           con     %00000011
    Enc2                var     byte
    Enc2_Old            var     byte
    Enc2_Mask           con     %00001100
    Enc3                var     byte
    Enc3_Old            var     byte
    Enc3_Mask           con     %00110000
    Enc4                var     byte
    Enc4_Old            var     byte
    Enc4_Mask           con     %11000000
    EncTemp             var     byte
    Enc1_val            var     byte
    Enc2_val            var     byte
    Enc3_val            var     byte
    Enc4_val            var     byte
    
    CPS1                var     byte
    CPS2                var     byte
    CPS3                var     byte
    CPS4                var     byte
    CPS5                var     byte
    CPS6                var     byte
    
    '=============================================================================
    '             The control code assignments for the 6 switches
    '=============================================================================
    CPS1_CC  VAR    BYTE    '           con     30
    CPS2_CC  VAR    BYTE    '           con     31
    CPS3_CC  VAR    BYTE    '           con     66
    CPS4_CC  VAR    BYTE    '           con     41
    CPS5_CC  VAR    BYTE    '           con     42
    CPS6_CC  VAR    BYTE    '           con     43
    '=============================================================================
    '             The control code assignments for the 4 encoders
    '=============================================================================
    CPENC1_CC  VAR    BYTE    '         con     84
    CPENC2_CC  VAR    BYTE    '         con     76
    CPENC3_CC  VAR    BYTE    '         con     68
    CPENC4_CC  VAR    BYTE    '         con     80
    
           '  Flags
    SW1_Flag            var     bit
    CPS1_Flag           var     bit
    CPS2_Flag           var     bit
    CPS3_Flag           var     bit
    CPS4_Flag           var     bit
    CPS5_Flag           var     bit
    CPS6_Flag           var     bit
    
    sl_ADC  var word[9]
    sl_Old  var byte[9]
    Channel var byte
    Control var byte
    Value   var byte
    j   var byte
    C0 Var word	     	            
    C1 Var word                     
    EXP var word
    EXP1    var byte
    EXPOld  var byte
    EXP_CC  var byte
    volout Var byte                 
    Channel = 176
    Control = 0
    Upper  var byte
    Lower  VAR BYTE
    Bass   VAR BYTE
    SwitchBank  var byte
    SwitchBank1  var byte
    SwitchBankOld  var byte
    RSS var byte
    RSSOld  var byte
    CounterA var Byte
    RawData var Byte [16]
    k var byte
    i   var byte
    LED1    var PORTC.2
    
    upper = 12
    lower = 0   '9
    bass = 0    '
    PORTD = $FF
        FOR j = 0 TO 15
           READ j, USBBuffer[j]
        NEXT j
        CPS1_CC =  USBBuffer[0]
        CPS2_CC =  USBBuffer[1]
        CPS3_CC =  USBBuffer[2]
        CPS4_CC =  USBBuffer[3]
        CPS5_CC =  USBBuffer[4]
        CPS6_CC =  USBBuffer[5]
        CPENC1_CC = USBBuffer[6]
        CPENC2_CC = USBBuffer[7]
        CPENC3_CC = USBBuffer[8]
        CPENC4_CC = USBBuffer[9]
    PAUSE 500
    
    
    gosub InitMPC23017
    goto MainLoop        'jump over subs to main loop
    
    
    ' ************************************************************
    '              Start of Subs
    ' ************************************************************
    ' * receive data from the USB bus                            *
    ' ************************************************************
    DoUSBIn:
       USBBufferCount = USBBufferSizeRX              ' RX buffer size
       USBIN 1, USBBuffer, USBBufferCount, DoUSBIn  ' read data, if available
       RETURN
    
    ' ************************************************************
    ' * wait for USB interface to attach                         *
    ' ************************************************************
    DoUSBOut:
       USBBufferCount = USBBufferSizeTX              ' TX buffer size
       USBOUT 1, USBBuffer, USBBufferCount, DoUSBOut ' if bus available, transmit data
       RETURN
    ' ************************************************************
    ' *  USB Attach detach                        *
    ' ************************************************************
    Program:
              led1 = 1
              INCLUDE "USB_ASM_Service.pbp"
              PAUSE 500
              GOSUB DoUSBIn
    
           
            FOR k = 0 TO 15
                READ k , USBBuffer[k]
            NEXT k
            PAUSE 250
            GOSUB DoUSBOut
            PAUSE 250
            GOSUB DoUSBIn
            FOR k = 0 TO 15
                WRITE k, USBBuffer[k]
            NEXT k
                CPS1_CC =  USBBuffer[0]
                CPS2_CC =  USBBuffer[1]
                CPS3_CC =  USBBuffer[2]
                CPS4_CC =  USBBuffer[3]
                CPS5_CC =  USBBuffer[4]
                CPS6_CC =  USBBuffer[5]
                CPENC1_CC = USBBuffer[6]
                CPENC2_CC = USBBuffer[7]
                CPENC3_CC = USBBuffer[8]
                CPENC4_CC = USBBuffer[9]
            
            
            
            
            PAUSE  1000
            GOSUB DoUSBOut
    
    PAUSE 1000
                UCON.3 = 0
    
                 for i = 0 to 20
                    toggle led1
                    pause 200
                 next i
                 led1 = 0
    
    
    
    RETURN
    '*******************************************************************************
    '******************************************************************************
    
       
    InitMPC23017:
    Pause 100
    '=================== PORTA  ====================================================
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOCONA,IOCONSETA]     'IOCON register setting
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IODIRA,$FF]           'PortA inputs
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOLATA,$FF]           'PortA = 0
    'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IPOLA,0]             'Input polarity 1= opposite 0 =  normal
    'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[DEFVALA,0]           'Default value register
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPPUA,$FF]           'pull-ups enabled   1 = enable 0 = disable
    'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[INTCONA,0]           'INTERRUPT-ON-CHANGE CONTROL REGISTER
    'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPINTENA,$FF]        'interupt on change  1= enable 0 = disable
    '==================== PORTB   ====================================================
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOCONB,IOCONSETB]
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IODIRB,$FF]           'PortB inputs
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOLATB,$FF]
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPPUB,$FF]           'pull-ups enabled   1 = enable 0 = disable
    'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IPOLB,0]
    'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[DEFVALB,0]
    'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[INTCONB,0]
    'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPINTENB,0]
    return
    ReInitPortA:
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOCONA,IOCONSETA]
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IODIRA,$FF] 
    i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPPUA,$FF]           'pull-ups enabled
    
    return
    '******************************************************************************
    
    Scale:
       select case sl_ADC[j]
       case 126
       volout = 0
       case  114
        volout = 15
       case 110, 112
       volout = 30
       case 104, 106
        volout = 45   
        case 98
       volout = 60
       case 86
        volout = 75
       case 62
       volout = 90
       case 38
        volout = 105
       case 0
        volout = 125   
        case else
        
       end select
     
       
       Control = j + Upper + lower +  bass ' drawbars are CC 12-20
       HSEROUT [channel,control,volout]       ' send data out serial port as midi information
       sl_old[j] = sl_ADC[j] 
     
    return
    '*******************************************************************************
    SortArray:           'Soer data small to large
    	CounterA=0
    SortLoop:
    	If RawData(CounterA+1) < RawData(CounterA) then
    		RawData(CounterA)     = RawData(CounterA) ^ RawData(CounterA+1)
    		RawData(CounterA+1+0) = RawData(CounterA) ^ RawData(CounterA+1)
    		RawData(CounterA)     = RawData(CounterA) ^ RawData(CounterA+1)
    		If CounterA > 0 then CounterA=CounterA-2
    		endif
    	CounterA=CounterA+1
    	If CounterA < 15 then goto SortLoop
    
        ' Take the middle eight and average
    '    C1 = (RAWDATA[4] + RAWDATA[5] + RAWDATA[6] + RAWDATA[7] + RAWDATA[8] + RAWDATA[9] + RAWDATA[10] + RAWDATA[11]) / 8
        c1 = 0
        for i = 6 to 9
            c1 = c1 + rawdata[i]
        next i
        c1 = c1 / 4
    Return
    '******************************************************************************
    '
    '                             Main Loop
    '
    '******************************************************************************
    
    MainLoop:
    
                'SLIDERS 1-9
    for j = 0 to 8
                                              'Take 16 samoles
        for k = 0 to 15
            ADCIN j,c0                       ' read Volume pot and place value in C0
            rawdata[k] = c0
        next k
        gosub sortarray
        sl_ADC[j] = (C1 >>2)*2                    ' convert reading to a midi value from 1-127
        If sl_ADC[j] <> sl_old[j] Then           ' check to see if the value has changed
        gosub scale
        Endif
    next j
         ' EXPRESSION Pedal
         ADCIN 9,exp 
         exp1 = exp >> 1
          if expold <> exp1 then
          HSEROUT [177,11,exp1]
          expold = exp1
          endif
    switchbank = PORTD & %11110000
    if switchbank <> switchbankold   then
            if switchbank.7 = 0 then         ' 
               if sw1_flag = 0 then
                    sw1_flag = 1: led1 = 1: exp_cc = 127
                elseif sw1_flag = 1 then
                    sw1_flag = 0: led1 = 0: exp_cc = 0
                endif 
        HSEROUT [177,1,EXP_CC]
     endif
                
                 'Slider bank selection
        if switchbank.4 = 0 then                   
        Upper = 12:  lower = 0:  bass = 0         'Select upper bank
            elseif switchbank.5 = 0 then
            Upper = 12:  lower = 9:  bass = 0       'select lower bank
                elseif switchbank.6 = 0 then
                Upper = 12:  lower = 9:  bass = 12    'select bass bank
        endif            
                
      
      
    switchbankold = switchbank
    endif
    '================ MCP23017 Decoder ============================================
    i2cread I2C_Data,I2C_CLK,IO_EXP0rd,gpioa,[IO_data]      'read 23017
    if io_data != io_dat_olda then
    '----------------------------------------------------------------------------- 
       if io_data.0 = 0 and io_data.5 = 0 then
       
       gosub program
       endif
    
    '-----------------------------------------------------------------------------    
        if io_data.0 = 0 then
            if cps1_flag = 0 then
                cps1_flag = 1:  CPS1 = 127
            elseif cps1_flag = 1 then
                cps1_flag = 0: CPS1 = 0
            endif 
        HSEROUT [177,cps1_cc, CPS1]  '"SW1"
       endif
    '-----------------------------------------------------------------------------
       if io_data.1 = 0 then
               if cps2_flag = 0 then
                cps2_flag = 1:  CPS2 = 127
            elseif cps2_flag = 1 then
                cps2_flag = 0: CPS2 = 0
            endif 
    
           HSEROUT [177,cps2_cc, cps2]   '"SW2"
       endif
    '----------------------------------------------------------------------------- 
      if io_data.2 = 0 then
            if cps3_flag = 0 then
                cps3_flag = 1:  CPS3 = 127
            elseif cps3_flag = 1 then
                cps3_flag = 0: CPS3 = 0
            endif 
    
            HSEROUT [177,cps3_cc, cps3]  '"SW3"
      endif
    '-----------------------------------------------------------------------------
      if io_data.3 = 0 then
            if cps4_flag = 0 then
                cps4_flag = 1:  CPS4 = 127
            elseif cps4_flag = 1 then
                cps4_flag = 0: CPS4 = 0
            endif 
             HSEROUT [177,cps4_cc, cps4]  '"SW4"
      endif
    '-----------------------------------------------------------------------------
      if io_data.4 = 0 then
            if cps5_flag = 0 then
                cps5_flag = 1:  CPS5 = 127
            elseif cps5_flag = 1 then
                cps5_flag = 0: CPS5 = 0
            endif 
    
    
            HSEROUT [177,cps5_cc, cps5]  ' "SW5"
      endif
    '-----------------------------------------------------------------------------
      if io_data.5 = 0 then
            if cps6_flag = 0 then
                cps6_flag = 1:  CPS6 = 127
            elseif cps6_flag = 1 then
                cps6_flag = 0: CPS6 = 0
            endif 
    HSEROUT [177,cps6_cc, cps6]  ' "SW6"
      endif
      pause 250
    endif
    
    '-----------------------------------------------------------------------------
    i2cread I2C_Data,I2C_CLK,IO_EXP0rd,gpiob,[IO_datb]      'read 23017
    
    if io_datb != io_dat_oldb then
    
        enc1 = io_datb & enc1_mask
        if enc1_old = enc1   then goto Encoder2
        enctemp = enc1.bit1 ^ enc1_old.bit0
        if enctemp = 1 then goto Inc1
        Enc1_val = Enc1_val - 1
        if enc1_val < 1 then enc1_val = 1
        HSEROUT [177,cpenc1_cc,enc1_val]
        goto Encoder2
    Inc1:    
       Enc1_val = Enc1_val + 1 
       if enc1_val => 127 then enc1_val = 127
       HSEROUT [177,cpenc1_cc,enc1_val]
    '---------------------------------------------------------------------------
    Encoder2:
    
        enc2 = io_datb & enc2_mask
        if enc2_old = enc2   then goto Encoder3
        enctemp = enc2.bit3 ^ enc2_old.bit2
        if enctemp = 1 then goto Inc2
        Enc2_val = Enc2_val - 1
        if enc2_val < 1 then enc2_val = 1
        HSEROUT [177,cpenc2_cc,enc2_val]
        goto encoder3
    Inc2:    
       Enc2_val = Enc2_val + 1 
       if enc2_val => 127 then enc2_val = 127
       HSEROUT [177,cpenc2_cc,enc2_val]
    
    '---------------------------------------------------------------------------
    Encoder3:
    
        enc3 = io_datb & enc3_mask
        if enc3_old = enc3   then goto Encoder4
        enctemp = enc3.bit5 ^ enc3_old.bit4
        if enctemp = 1 then goto Inc3
        Enc3_val = Enc3_val - 1
        if enc3_val < 1 then enc3_val = 1
        HSEROUT [177,cpenc3_cc,enc3_val]
        goto encoder4
    Inc3:    
       Enc3_val = Enc3_val + 1 
       if enc3_val => 127 then enc3_val = 127
        HSEROUT [177,cpenc3_cc,enc3_val]
    
    '---------------------------------------------------------------------------
    Encoder4:
    
        enc4 = io_datb & enc4_mask
        if enc4_old = enc4   then goto Encend
        enctemp = enc4.bit7 ^ enc4_old.bit6
        if enctemp = 1 then goto Inc4
        Enc4_val = Enc4_val - 1
        if enc4_val < 1 then enc4_val = 1
        HSEROUT [177,cpenc4_cc,enc4_val]
        goto encend
    Inc4:    
       Enc4_val = Enc4_val + 1
       if enc4_val => 127 then enc4_val = 127
       HSEROUT [177,cpenc4_cc,enc4_val]
    EncEnd:
    
    '-----------------------------------------------------------------------------
        enc1_old = enc1
        enc2_old = enc2
        enc3_old = enc3
        enc4_old = enc4
    
    io_dat_olda = io_data
    io_dat_oldb = io_datb
    endif
    
    '===============================================================================
    
    
    goto MainLoop
    end
    Code:
    ' USB descriptors for a HID device
    'USBMEMORYADDRESS Con	$400	' USB RAM starts here (set in device header file)
    USBMEMORYSIZE	Con	256	' USB RAM size in bytes
    USBReservedMemory Var Byte[USBMEMORYSIZE] USBMEMORYADDRESS	' Reserve memory used by USB assembler code
    
    goto	hid_desc_end	' Skip over all of the USB assembler code
    asm
    
    #define	USB_EP0_BUFF_SIZE 	64	; 8, 16, 32, or 64
    #define	USB_MAX_NUM_INT		1	; For tracking Alternate Setting
    #define	USB_MAX_EP_NUMBER  	1	; UEP1
    #define	NUM_CONFIGURATIONS	1
    #define	NUM_INTERFACES		1
    
    #define UCFG_VAL	USB_PULLUP_ENABLE|USB_INTERNAL_TRANSCEIVER|USB_FULL_SPEED|USB_PING_PONG__NO_PING_PONG
    ;#define UCFG_VAL	USB_PULLUP_ENABLE|USB_INTERNAL_TRANSCEIVER|USB_LOW_SPEED|USB_PING_PONG__NO_PING_PONG
    
    ;#define USE_SELF_POWER_SENSE_IO
    ;#define USE_USB_BUS_SENSE_IO
    
    #define USB_POLLING
    
    ; HID
    ; Endpoints Allocation
    #define	HID_INTF_ID		  0x00
    #define	HID_EP			  1
    #define	HID_INT_OUT_EP_SIZE	  64
    #define	HID_INT_IN_EP_SIZE	  64
    #define	HID_NUM_OF_DSC		  1
    
       include	"usb_hid.asm"	; Include rest of USB files, starting with HID class code
    
    ; ******************************************************************
    ; This table is polled by the host immediately after USB Reset has been released.
    ; This table defines the maximum packet size EP0 can take.
    ; See section 9.6.1 of the Rev 1.0 USB specification.
    ; These fields are application DEPENDENT. Modify these to meet
    ; your specifications.
    ; ******************************************************************
    DeviceDescriptor
    	retlw	(EndDeviceDescriptor-DeviceDescriptor)/2	; bLength Length of this descriptor
    	retlw	USB_DESCRIPTOR_DEVICE ; bDescType This is a DEVICE descriptor
    	retlw	0x10		; bcdUSBUSB Revision 1.10 (low byte)
    	retlw	0x01		; high byte
    	retlw	0x00		; bDeviceClass zero means each interface operates independently
    	retlw	0x00		; bDeviceSubClass
    	retlw	0x00		; bDeviceProtocol
    	retlw	USB_EP0_BUFF_SIZE ; bMaxPacketSize for EP0
    
            ; idVendor (low byte, high byte)
    	retlw	0xA6
    	retlw	0x01
    
            ; idProduct (low byte, high byte)
    	retlw	0xDB
    	retlw	0x07
    
            retlw	0x00		; bcdDevice (low byte)
    	retlw	0x00		; (high byte)
    	retlw	0x01		; iManufacturer (string index)
    	retlw	0x02		; iProduct      (string index)
    
            ; iSerialNumber (string index)
    	retlw	0x03
    	retlw	NUM_CONFIGURATIONS ; bNumConfigurations
    EndDeviceDescriptor
    
    ; ******************************************************************
    ; This table is retrieved by the host after the address has been set.
    ; This table defines the configurations available for the device.
    ; See section 9.6.2 of the Rev 1.0 USB specification (page 184).
    ; These fields are application DEPENDENT. 
    ; Modify these to meet your specifications.
    ; ******************************************************************
    ; Configuration pointer table
    USB_CD_Ptr
    Configs
    	db	low Config1, high Config1
    	db	upper Config1, 0
    
    ; Configuration Descriptor
    Config1
    	retlw	(Interface1-Config1)/2	; bLength Length of this descriptor
    	retlw	USB_DESCRIPTOR_CONFIGURATION ; bDescType 2=CONFIGURATION
    Config1Len
    	retlw	low ((EndConfig1 - Config1)/2)	; Length of this configuration
    	retlw	high ((EndConfig1 - Config1)/2)
    	retlw	0x01		; bNumInterfaces Number of interfaces
    	retlw	0x01		; bConfigValue Configuration Value
    	retlw	0x00		; iConfig (string index)
    	retlw	_DEFAULT|_SELF	; bmAttributes attributes - bus powered
    
            ; Max power consumption (2X mA)
    	retlw	0x32
    Interface1
    	retlw	(HIDDescriptor1-Interface1)/2	; length of descriptor
    	retlw	USB_DESCRIPTOR_INTERFACE
    	retlw	0x00		; number of interface, 0 based array
    	retlw	0x00		; alternate setting
    	retlw	0x02		; number of endpoints used in this interface
    	retlw	0x03		; interface class - assigned by the USB
    	retlw	0x00		; boot device
    	retlw	0x00		; interface protocol
    	retlw 	0x00		; index to string descriptor that describes this interface
    HIDDescriptor1
    	retlw	(Endpoint1In-HIDDescriptor1)/2	; descriptor size (9 bytes)
            retlw	DSC_HID		; descriptor type (HID)
    	retlw	0x11		; HID class release number (1.11)
    	retlw	0x01
            retlw	0x00		; Localized country code (none)
            retlw	0x01		; # of HID class descriptor to follow (1)
            retlw	0x22		; Report descriptor type (HID)
    ReportDescriptor1Len
    	retlw	low ((EndReportDescriptor1-ReportDescriptor1)/2)
    	retlw	high ((EndReportDescriptor1-ReportDescriptor1)/2)
    Endpoint1In
    	retlw	(EndPoint1Out-Endpoint1In)/2	; length of descriptor
    	retlw	USB_DESCRIPTOR_ENDPOINT
    	retlw	HID_EP|_EP_IN		; EP1, In
    	retlw	_INT		; Interrupt
    	retlw	low (HID_INT_IN_EP_SIZE)		; This should be the size of the endpoint buffer
    	retlw	high (HID_INT_IN_EP_SIZE)
    	retlw	0x0A                        ; Polling interval
    EndPoint1Out
    	retlw	(EndConfig1-EndPoint1Out)/2	; Length of this Endpoint Descriptor
    	retlw	USB_DESCRIPTOR_ENDPOINT		; bDescriptorType = 5 for Endpoint Descriptor
    	retlw	HID_EP|_EP_OUT		; Endpoint number & direction
    	retlw	_INT		; Transfer type supported by this Endpoint
    	retlw	low (HID_INT_OUT_EP_SIZE)		; This should be the size of the endpoint buffer
    	retlw	high (HID_INT_OUT_EP_SIZE)
    	retlw	0x0A                        ; Polling interval
    EndConfig1
    
    ReportDescriptor1
        ; vendor defined usage page
        retlw	0x06		
        retlw	0x00
        retlw	0xFF
    
        ; vendor defined usage
        retlw	0x09
        retlw	0x00
    
        ; collection(application)
        retlw	0xA1
        retlw	0x01
    
        ; *** INPUT REPORT ***
    
        ; vendor defined usage
        retlw	0x09
        retlw	0x01
    
        retlw	0x15 	; logical minimum (-128)
        retlw	0x80    ;
        retlw	0x25 	; logical maximum (127)
        retlw	0x7F    ;
        retlw	0x35 	; Physical Minimum (0)
        retlw	0x00    ;
        retlw	0x45 	; Physical Maximum (255)
        retlw	0xFF    ;
    
        ; report size in bits
        retlw	0x75
        retlw	0x08
    
        ; report count (number of fields)
        retlw	0x95
        retlw	0x10
    
        ; Input (Data, Variable, Absolute)
        retlw	0x81
        retlw	0x02
    
        ; *** OUTPUT REPORT ***
    
        ; vendor defined usage
        retlw	0x09	    ; usage (Vendor Defined)
        retlw	0x02        ;
    
        retlw	0x15	    ; logical minimum (-128)
        retlw	0x80        ;
        retlw	0x25	    ; logical maximum (127)
        retlw	0x7F        ;
        retlw	0x35	    ; Physical Minimum (0)
        retlw	0x00        ;
        retlw	0x45	    ; Physical Maximum (255)
        retlw	0xFF        ;
    
        ; report size in bits
        retlw	0x75
        retlw	0x08
    
        ; report count (number of fields)
        retlw	0x95
        retlw	0x10
    
        ; Output (Data, Variable, Absolute)
        retlw	0x91
        retlw	0x02
    
        retlw   0xC0       	   ; end collection
    
    EndReportDescriptor1
    
    ; String pointer table
    USB_SD_Ptr
    Strings
    	db	low String0, high String0
            db	upper String0, 0
    	db	low String1, high String1
            db	upper String1, 0
    	db	low String2, high String2
           	db	upper String2, 0
    	db	low String3, high String3
    	db	upper String3, 0
    
    String0
    	retlw	(String1-String0)/2	; Length of string
    	retlw	USB_DESCRIPTOR_STRING   ; Descriptor type 3
    	retlw	0x09		        ; Language ID (as defined by MS 0x0409)
    	retlw	0x04
    
    ; company name
    String1
    	retlw	(String2-String1)/2
    	retlw	USB_DESCRIPTOR_STRING
    	
            retlw   'D'
            retlw   0x00
            retlw   'L'
            retlw   0x00
            retlw   'C'
            retlw   0x00
            retlw   'I'
            retlw   0x00
            retlw   'N'
            retlw   0x00
            retlw   'C'
            retlw   0x00
    
    	
    ; product name	
    String2
    	retlw	(String3-String2)/2
    	retlw	USB_DESCRIPTOR_STRING
    	
            retlw   'U'
            retlw   0x00
            retlw   'S'
            retlw   0x00
            retlw   'B'
            retlw   0x00
            retlw   '_'
            retlw   0x00
            retlw   'M'
            retlw   0x00
            retlw   'I'
            retlw   0x00
            retlw   'D'
            retlw   0x00
            retlw   'I'
            retlw   0x00
    
    
    ; serial number
    String3
    	retlw	(String4-String3)/2
    	retlw	USB_DESCRIPTOR_STRING
    	
            retlw   '1'
            retlw   0x00
            retlw   '0'
            retlw   0x00
            retlw   '0'
            retlw   0x00
            retlw   '2'
            retlw   0x00
    
    String4
    
    
    endasm
    hid_desc_end

  5. #5
    Join Date
    Feb 2012
    Posts
    34

    Default Re: MIDI over USB

    Thanks!
    Yes, that looks like a good starting point!
    I will study your example and try to get things working.

  6. #6
    Join Date
    Feb 2012
    Posts
    34

    Default Re: MIDI over USB

    Which PIC did you use? (I will first try if everything compiles before I modify the file(s) )

  7. #7
    Join Date
    Feb 2012
    Posts
    34

    Default Re: MIDI over USB

    DaveC3, your code has been a great help so far.
    Unfortunately, I didn't manage to get it working.
    I suppose there is something wrong with my fuse settings.
    Do you mind to give me your config settings?
    (I stripped most of your code in the body, but the PIC isn't recognised as a MIDI device.)

  8. #8
    Join Date
    Mar 2008
    Location
    Gerogetown, Texas
    Posts
    94

    Default Re: MIDI over USB

    I think I used a 18F4550 for this project. if you haven't already, I would suggest you first make simple HID project to see if you can get your PC to recognize your device. If you send me your e-mail address I will send you the whole project in a zip file.

    Here is the .LST file for the project, you can see the fuse setting I used.

    Code:
    MPASM  5.43                      USB_MIDI.ASM   2-3-2012  20:25:46         PAGE  1
    
    
    LOC  OBJECT CODE     LINE SOURCE TEXT
      VALUE
    
                          00001 
                          00002 ; PICBASIC PRO(TM) Compiler 3.0.4.4, (c) 1998, 2011 microEngineering Labs, Inc. All Rights Reserved. 
      00000001            00003 MPASMWIN_USED                   EQU     1
                          00004 
                          00005 #define PBP_PATH        C:\PBP3\
                          00006 
                          00007 
                          00008 
                          00009 
                          00016         LIST
                          00017         LIST p = 18F4550, r = dec, w = -311, w = -230, f = inhx32
                          00018         INCLUDE "P18F4550.INC"  ; MPASM  Header
                          00001         LIST
                          00002 
                          00003 ;==========================================================================
                          00004 ;  MPASM PIC18F4550 processor include
                          00005 ; 
                          00006 ;  (c) Copyright 1999-2011 Microchip Technology, All rights reserved
                          00007 ;==========================================================================
                          00008 
                          01764         LIST
                          00021         LIST
      00F00000            00022 EEPROM_START    EQU     0F00000h
      00000020            00023 BLOCK_SIZE      EQU     32
                          00024 
                          00025 
                          00026 PBP_HARDWAREDEF  macro
                          00027   endm
                          00028 
                          00029 
                          00030         __CONFIG    _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
    300000 3EE4           00031         __CONFIG    _CONFIG1H, _FOSC_HSPLL_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
                          00032         __CONFIG    _CONFIG2L, _PWRT_OFF_2L & _BOR_ON_2L & _BORV_3_2L & _VREGEN_ON_2L
    300002 F3FF           00033         __CONFIG    _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
    300004 F9FF           00034         __CONFIG    _CONFIG3H, _CCP2MX_ON_3H & _PBADEN_OFF_3H & _LPT1OSC_OFF_3H & _MCLRE_ON_3H
    300006 FF9B           00035         __CONFIG    _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L
                          00036 
                          00037 
                          00038 
                          00039 ; Define statements.
                          00040 ; C:\PBP3\USB18\USB_MIDI\PICBASICPRO\USB_MIDI.PBP       00007   DEFINE WRITE_INT 1
                          00041 #define         WRITE_INT                1
                          00042 ; C:\PBP3\USB18\USB_MIDI\PICBASICPRO\USB_MIDI.PBP       00008   Define  LOADER_USED     1
                          00043 #define         LOADER_USED                     1
                          00044 ; C:\PBP3\USB18\USB_MIDI\PICBASICPRO\USB_MIDI.PBP       00009   DEFINE RESET_ORG 800h ' For Microchip US
                                B Bootloader
                          00045 #define         RESET_ORG                800h 
                          00046 ; C:\PBP3\USB18\USB_MIDI\PICBASICPRO\USB_MIDI.PBP       00010   DEFINE INTERRUPT_ORG 808h ' For Microchi
                                p USB Bootloader
                          00047 #define         INTERRUPT_ORG            808h 
                          00048 ; C:\PBP3\USB18\USB_MIDI\PICBASICPRO\USB_MIDI.PBP       00012   DEFINE OSC 48                   ' tell p
                                rogram we are using a 20mhz oscillator
                          00049 #define         OSC              48                   
    MPASM  5.43                      USB_MIDI.ASM   2-3-2012  20:25:46         PAGE  2

Similar Threads

  1. MIDI over USB peripheral
    By aberco in forum USB
    Replies: 1
    Last Post: - 31st October 2011, 17:06
  2. MIDI to USB
    By DaveC3 in forum USB
    Replies: 0
    Last Post: - 31st March 2011, 21:38
  3. USB to MIDI module
    By Coco Sapone in forum Adverts
    Replies: 0
    Last Post: - 23rd October 2010, 18:13
  4. 12f675 and midi!
    By Alaskanphoenix in forum mel PIC BASIC Pro
    Replies: 18
    Last Post: - 14th April 2006, 16:25
  5. Midi cc controller!
    By Alaskanphoenix in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 8th January 2006, 13:37

Members who have read this thread : 17

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts