'------------------------------------------------------------------------------
' (c) 1995-2009 MCS Electronics
' virtcom-M32U2.bas
' CDC class, based on Atmels sample
' you do not need to loop back using the real UART. This is just for demonstration
'------------------------------------------------------------------------------
$prog &HC0 , &H7F , &HD9 , &HFB ' generated. Take care that the chip supports all fuse bytes.
$regfile = "m32U4def.dat"
$crystal = 8000000
$baud = 19200
$hwstack = 64
$swstack = 64
$framesize = 64
Const Mdbg = 0 ' turn debug info on
Const Chiddevice = 0 ' this is NOT a HID device '
Config Clockdiv = 1 ' clock division so we get 8 MHz
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Const Usb_config_attributes_reserved = &H80
Const Usb_config_buspowered = Usb_config_attributes_reserved
Const Usb_config_selfpowered = Usb_config_attributes_reserved Or &H40
Const Usb_config_remotewakeup = Usb_config_attributes_reserved Or &H20
Const Usb_remote_wakeup = 0
Const Vendor_id = &H16D0 ' MCS Vendor ID
Const Product_id = &H202D ' MCS product ID, you can buy a VID&PID in the MCS shop
Const User_conf_size = 67
Const Device_class = 2 ' CDC class
Const Device_sub_class = 0
Const Device_protocol = 0
Const Ep_control_length = 32
Const Release_number = &H1000
Const Nb_endpoints = 4 ' number of endpoints in the application including control endpoint
Const Tx_ep = 1
Const Rx_ep = 2
Const Int_ep = 3
'CDC
Const Nb_interface = 2
Const Conf_nb = 1
Const Conf_index = 0
Const Conf_attributes = Usb_config_buspowered + Usb_config_remotewakeup
Const Max_power = 50 ' 100 mA
'Interface 0 descriptor
Const Interface0_nb = 0
Const Alternate0 = 0
Const Nb_endpoint0 = 1
Const Interface0_class = 2 ' CDC
Const Interface0_sub_class = 2
Const Interface0_protocol = 1
Const Interface0_index = 0
' Interface 1 descriptor
Const Interface1_nb = 1
Const Alternate1 = 0
Const Nb_endpoint1 = 2
Const Interface1_class = &H0A ' CDC ACM Data
Const Interface1_sub_class = 0
Const Interface1_protocol = 0
Const Interface1_index = 0
' USB Endpoint 3 descriptor , Interrupt IN
Const Tx_ep_size = &H20
Const Endpoint_nb_3 = &H80 Or Int_ep
Const Ep_attributes_3 = 3 'BULK = 0x02, INTERUPT = 0x03
Const Ep_size_3 = Tx_ep_size
Const Ep_interval_3 = &HFF 'ms interrupt pooling from host
' USB Endpoint 1 descriptor , Bulk IN
Const Endpoint_nb_1 = &H80 Or Tx_ep
Const Ep_attributes_1 = 2 ' BULK = 0x02, INTERUPT = 0x03
Const Ep_size_1 = &H20
Const Ep_interval_1 = 0
' USB Endpoint 2 descriptor ,Bulk OUT RX endpoint
Const Endpoint_nb_2 = Rx_ep
Const Ep_attributes_2 = 2 ' BULK = 0x02, INTERUPT = 0x03
Const Ep_size_2 = &H20
Const Ep_interval_2 = 0
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Print "USB Virtual COM test"
Declare Sub Usb_user_endpoint_init
Declare Sub Hid_test_hit()
Declare Sub Cdc_task()
Declare Sub Cdc_task_init()
Declare Sub Uart_usb_flush()
Declare Sub Uart_usb_putchar(b1 As Byte)
Declare Function Uart_usb_test_hit() As Byte
Declare Function Uart_usb_getchar() As Byte
Declare Sub Cdc_set_control_line_state()
Declare Sub Cdc_get_line_coding()
Declare Sub Cdc_set_line_coding()
'CDC specific
Const Nb_ms_before_flush = 100
Const Get_line_coding = &H1
Const Set_line_coding = &H20
Const Set_control_line_state = &H22
Const Send_break = &H23
Const Send_encapsulated_command = 0
Const Get_encapsulated_command = 1
Config Usb = Device , Language = &H0409 , Manufact = "MCP" , Product = "MCSCDC1623" , Serial = "MC0001"
'Dim some user vars
Dim Dummy As Byte , Dummy1 As Byte , Dummy2 As Byte
Dim Tx_counter As Byte , Rx_counter As Byte , B As Byte
Dim Dwrate As Long , Bcharformat As Byte , Bparitytype As Byte , Bdatabits As Byte , Brate(4) As Byte At Dwrate Overlay
Print "task init"
Usb_task_init
Cdc_task_init
Do
Usb_task
Cdc_task
If Inkey() = "*" Then
Goto &H1800 'try to boot
End If
'you can call your sub program here
' How to send over USB Serial?
Loop
'nothing needed to init
Sub Cdc_task_init()
'init uart
Tx_counter = 0
Rx_counter = 0
Usb_enable_sof_interrupt
End Sub
Sub Cdc_get_line_coding()
Usb_ack_receive_setup
Uedatx = Brate(1)
Uedatx = Brate(2)
Uedatx = Brate(3)
Uedatx = Brate(4)
Uedatx = Bcharformat
Uedatx = Bparitytype
Uedatx = Bdatabits
Usb_send_control_in
Bitwait Ueintx.txini , Set ' while(!Is_usb_read_control_enabled());
Bitwait Ueintx.rxouti , Set ' while(!Is_usb_receive_out());
Usb_ack_receive_out
End Sub
Sub Cdc_set_line_coding()
Usb_ack_receive_setup
Bitwait Ueintx.rxouti , Set ' while(!Is_usb_receive_out());
Brate(1) = Uedatx
Brate(2) = Uedatx
Brate(3) = Uedatx
Brate(4) = Uedatx
Bcharformat = Uedatx
Bparitytype = Uedatx
Bdatabits = Uedatx
Usb_ack_receive_out
Usb_send_control_in ' // send a ZLP for STATUS phase
Bitwait Ueintx.txini , Set
'SET BAUD HERE
End Sub
Sub Cdc_set_control_line_state()
Usb_ack_receive_setup
Usb_send_control_in
Bitwait Ueintx.txini , Set
End Sub
Function Usb_user_read_request(type As Byte , Request As Byte) As Byte
#if Mdbg
Print "USB_USER_READ_REQ"
#endif
Usb_string_type = Uedatx ' Usb read byte
Usb_descriptor_type = Uedatx ' Usb read byte
Select Case Request
Case Get_line_coding : Call Cdc_get_line_coding
Usb_user_read_request = 1
Case Set_line_coding : Call Cdc_set_line_coding
Usb_user_read_request = 1
Case Set_control_line_state : Call Cdc_set_control_line_state
Usb_user_read_request = 1
Case Else
Usb_user_read_request = 0
End Select
End Function
Sub Cdc_task()
If Usb_configuration_nb > 0 Then 'Enumeration Processs Ok
If Cpt_sof >= Nb_ms_before_flush And Tx_counter <> 0 Then ' Flush Buffer In Timeout
Cpt_sof = 0
Uart_usb_flush ' flush UART
End If
If Ucsra.7 = 1 Then ' Something on USART ? uart_test_hit() uart_rx_ready
B = Waitkey() ' get char from UART
Uart_usb_putchar B ' Loop back, USART to USB
End If
If Ucsra.udre1 = 1 Then ' Usart Free Print
If Uart_usb_test_hit() <> 0 Then ' Something Received From The Usb Print
While Rx_counter > 0
B = Uart_usb_getchar()
Print Chr(b ); ' Loop Back Usb To Usart
Wend
End If
End If
End If
End Sub
Function Uart_usb_test_hit() As Byte
If Rx_counter = 0 Then
Usb_select_endpoint Rx_ep ' select end point
If Ueintx.rxouti = 1 Then ' Is_usb_receive_out , test if IN ready
Rx_counter = Uebclx ' Usb_byte_counter() get number of bytes in current endpoint
If Rx_counter = 0 Then
Usb_ack_receive_out
End If
End If
End If
Uart_usb_test_hit = Rx_counter ' return number of bytes
End Function
'get a character from the USB UART
Function Uart_usb_getchar() As Byte
Usb_select_endpoint Rx_ep ' select end point
If Rx_counter = 0 Then ' if we do not have a char yet
Do
B = Uart_usb_test_hit() ' wait till we receive one
Loop Until B > 0
End If
Dummy1 = Uedatx
Decr Rx_counter ' adjust counter
If Rx_counter = 0 Then Usb_ack_receive_out
Uart_usb_getchar = Dummy1 'Usb_read_byte()
End Function
'put a character in the USB UART
Sub Uart_usb_putchar(b1 As Byte)
Usb_select_endpoint Tx_ep ' select end point
Bitwait Ueintx.rwal , Set ' wait till endpoint write allowed
Uedatx = B1 ' write data
Incr Tx_counter
If Ueintx.rwal = 0 Then ' If Endpoint Full - > Flush
Uart_usb_flush '
End If
End Sub
'flush uart data
Sub Uart_usb_flush()
Usb_select_endpoint Tx_ep
Usb_send_in
Tx_counter = 0
End Sub
'usb_init_device.
'This function initializes the USB device controller and
'configures the Default Control Endpoint.
Sub Usb_init_device()
#if Usbhost
Usb_select_device
#endif
#if _chip = 70 Or _chip = 71 'if usb1287 or usb646
If Usbsta.id = 1 Then ' is it an USB device?
#endif
Uenum = Ep_control ' select USB endpoint
If Ueconx.epen = 0 Then ' usb endpoint not enabled yet
Uenum = Ep_control ' select USB end point
Usb_enable_endpoint
Usb_configure_endpoint Ep_control , Type_control , Direction_out , Size_32 , One_bank , Nyet_disabled
End If
#if _chip = 70 Or _chip = 71 'if usb1287 or usb646
End If
#endif
End Sub
'user endpoint init
Sub Usb_user_endpoint_init()
Call Usb_configure_endpoint(int_ep , Type_interrupt , Direction_in , Size_32 , One_bank , Nyet_enabled)
Call Usb_configure_endpoint(tx_ep , Type_bulk , Direction_in , Size_32 , One_bank , Nyet_enabled)
Call Usb_configure_endpoint(rx_ep , Type_bulk , Direction_out , Size_32 , One_bank , Nyet_enabled)
Usb_reset_endpoint Int_ep
Usb_reset_endpoint Tx_ep
Usb_reset_endpoint Rx_ep
End Sub
Usb_dev_desc:
Data 18 , Device_descriptor ' size and device_descriptor
Data 0 , 2 ' Usb_write_word_enum_struc(USB_SPECIFICATION)
Data Device_class , Device_sub_class ' DEVICE_CLASS and DEVICE_SUB_CLASS
Data Device_protocol , Ep_control_length ' device protol and ep_control_length
Data Vendor_id% ' Usb_write_word_enum_struc(VENDOR_ID)
Data Product_id% ' Usb_write_word_enum_struc(PRODUCT_ID)
Data Release_number% ' Usb_write_word_enum_struc(RELEASE_NUMBER)
Data Man_index , Prod_index ' MAN_INDEX and PROD_INDEX
Data Sn_index , Nb_configuration ' SN_INDEX and NB_CONFIGURATION
Usb_conf_desc:
Data 9 , Configuration_descriptor ' length , CONFIGURATION descriptor
Data User_conf_size% ' total length of data returned
Data Nb_interface , Conf_nb ' number of interfaces for this conf. , value for SetConfiguration resquest
Data Conf_index , Conf_attributes ' index of string descriptor , Configuration characteristics
Data Max_power ' maximum power consumption
Data 9 , Interface_descriptor ' length , INTERFACE descriptor type
Data Interface0_nb , Alternate0 ' Number of interface , value to select alternate setting
Data Nb_endpoint0 , Interface0_class ' Number of EP except EP 0 ,Class code assigned by the USB
Data Interface0_sub_class , Interface0_protocol ' Sub-class code assigned by the USB , Protocol code assigned by the USB
Data Interface0_index ' Index Of String Descriptor
Data 5 , &H24 , 0 , &H10 , 1 , 5 , &H24 , 1 , 3 , 1 , 4 , &H24 , 2 , 6 , 5 , &H24 , 6 , 0 , 1 '19
Data 7 , Endpoint_descriptor ' Size Of This Descriptor In Bytes , ENDPOINT descriptor type
Data Endpoint_nb_3 , Ep_attributes_3 ' Address of the endpoint ,Endpoint's attributes
Data Ep_size_3% ' Maximum packet size for this EP , Interval for polling EP in ms
Data Ep_interval_3
Data 9 , Interface_descriptor ' length , INTERFACE descriptor type
Data Interface1_nb , Alternate1 ' Number of interface , value to select alternate setting
Data Nb_endpoint1 , Interface1_class ' Number of EP except EP 0 ,Class code assigned by the USB
Data Interface1_sub_class , Interface1_protocol ' Sub-class code assigned by the USB , Protocol code assigned by the USB
Data Interface1_index ' Index Of String Descriptor
Data 7 , Endpoint_descriptor ' Size Of This Descriptor In Bytes , ENDPOINT descriptor type
Data Endpoint_nb_1 , Ep_attributes_1 ' Address of the endpoint , Endpoint's attributes
Data Ep_size_1% ' Maximum packet size for this EP
Data Ep_interval_1 ' Interval for polling EP in ms
Data 7 , Endpoint_descriptor ' Size Of This Descriptor In Bytes , ENDPOINT descriptor type
Data Endpoint_nb_2 , Ep_attributes_2 ' Address of the endpoint , Endpoint's attributes
Data Ep_size_2% ' Maximum packet size for this EP
Data Ep_interval_2 ' Interval for polling EP in ms
|