Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
card10
firmware
Commits
99298759
Commit
99298759
authored
Aug 24, 2019
by
Rahix
Browse files
Merge 'Epic Serial Bus' - USB Improvements
See merge request
!107
parents
ef12c8bb
9b0fd54f
Pipeline
#3436
passed with stages
in 1 minute and 2 seconds
Changes
18
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
epicardium/FreeRTOSConfig.h
View file @
99298759
...
...
@@ -52,7 +52,7 @@
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTimerPendFunctionCall 1
/* Allow static allocation of data structures */
#define configSUPPORT_STATIC_ALLOCATION 1
...
...
epicardium/cdcacm.c
deleted
100644 → 0
View file @
ef12c8bb
/*******************************************************************************
* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*
* $Id: main.c 32120 2017-11-28 23:51:11Z lorne.smith $
*
*******************************************************************************
*/
/**
* @file main.c
* @brief USB CDC-ACM example
* @details This project creates a virtual COM port, which loops back data sent to it.
* Load the project, connect a cable from the PC to the USB connector
* on the Evaluation Kit, and observe that the PC now recognizes a new COM port.
* A driver for the COM port, if needed, is located in the Driver/ subdirectory.
*
*/
#include
<stdio.h>
#include
<stddef.h>
#include
"mxc_config.h"
#include
"mxc_sys.h"
#include
"mxc_delay.h"
#include
"board.h"
#include
"led.h"
#include
"usb.h"
#include
"usb_event.h"
#include
"enumerate.h"
#include
"cdc_acm.h"
#include
"descriptors.h"
#include
"modules/modules.h"
#include
"modules/log.h"
#include
<errno.h>
/***** Definitions *****/
#define EVENT_ENUM_COMP MAXUSB_NUM_EVENTS
#define BUFFER_SIZE 64
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
/***** Global Data *****/
//SWYM: rename to CDC_xy or put into struct CDC_state
volatile
int
configured
;
//SWYM: actually unused...
volatile
int
suspended
;
volatile
unsigned
int
event_flags
;
int
remote_wake_en
;
/***** Function Prototypes *****/
static
int
setconfig_callback
(
usb_setup_pkt
*
sud
,
void
*
cbdata
);
static
int
setfeature_callback
(
usb_setup_pkt
*
sud
,
void
*
cbdata
);
static
int
clrfeature_callback
(
usb_setup_pkt
*
sud
,
void
*
cbdata
);
static
int
event_callback
(
maxusb_event_t
evt
,
void
*
data
);
static
void
usb_app_sleep
(
void
);
static
void
usb_app_wakeup
(
void
);
static
int
usb_read_callback
(
void
);
//static void echo_usb(void);
/***** File Scope Variables *****/
/* This EP assignment must match the Configuration Descriptor */
static
const
acm_cfg_t
acm_cfg
=
{
1
,
/* EP OUT */
MXC_USBHS_MAX_PACKET
,
/* OUT max packet size */
2
,
/* EP IN */
MXC_USBHS_MAX_PACKET
,
/* IN max packet size */
3
,
/* EP Notify */
MXC_USBHS_MAX_PACKET
,
/* Notify max packet size */
};
static
volatile
int
usb_read_complete
;
int
usb_startup_cb
()
{
const
sys_cfg_usbhs_t
sys_usbhs_cfg
=
NULL
;
return
SYS_USBHS_Init
(
&
sys_usbhs_cfg
);
}
int
usb_shutdown_cb
()
{
return
SYS_USBHS_Shutdown
();
}
/* User-supplied function to delay usec micro-seconds */
void
delay_us
(
unsigned
int
usec
)
{
/* mxc_delay() takes unsigned long, so can't use it directly */
mxc_delay
(
usec
);
}
/******************************************************************************/
int
cdcacm_init
(
void
)
{
maxusb_cfg_options_t
usb_opts
;
/* Initialize state */
configured
=
0
;
suspended
=
0
;
event_flags
=
0
;
remote_wake_en
=
0
;
/* Start out in full speed */
usb_opts
.
enable_hs
=
0
;
usb_opts
.
delay_us
=
delay_us
;
/* Function which will be used for delays */
usb_opts
.
init_callback
=
usb_startup_cb
;
usb_opts
.
shutdown_callback
=
usb_shutdown_cb
;
/* Initialize the usb module */
if
(
usb_init
(
&
usb_opts
)
!=
0
)
{
LOG_ERR
(
"cdcacm"
,
"usb_init() failed"
);
return
-
EIO
;
}
/* Initialize the enumeration module */
if
(
enum_init
()
!=
0
)
{
LOG_ERR
(
"cdcacm"
,
"enum_init() failed"
);
return
-
EIO
;
}
/* Register enumeration data */
enum_register_descriptor
(
ENUM_DESC_DEVICE
,
(
uint8_t
*
)
&
device_descriptor
,
0
);
enum_register_descriptor
(
ENUM_DESC_CONFIG
,
(
uint8_t
*
)
&
config_descriptor
,
0
);
enum_register_descriptor
(
ENUM_DESC_STRING
,
lang_id_desc
,
0
);
enum_register_descriptor
(
ENUM_DESC_STRING
,
mfg_id_desc
,
1
);
enum_register_descriptor
(
ENUM_DESC_STRING
,
prod_id_desc
,
2
);
/* Handle configuration */
enum_register_callback
(
ENUM_SETCONFIG
,
setconfig_callback
,
NULL
);
/* Handle feature set/clear */
enum_register_callback
(
ENUM_SETFEATURE
,
setfeature_callback
,
NULL
);
enum_register_callback
(
ENUM_CLRFEATURE
,
clrfeature_callback
,
NULL
);
/* Initialize the class driver */
if
(
acm_init
(
&
config_descriptor
.
comm_interface_descriptor
)
!=
0
)
{
LOG_ERR
(
"cdcacm"
,
"acm_init() failed"
);
return
-
EIO
;
}
/* Register callbacks */
usb_event_enable
(
MAXUSB_EVENT_NOVBUS
,
event_callback
,
NULL
);
usb_event_enable
(
MAXUSB_EVENT_VBUS
,
event_callback
,
NULL
);
acm_register_callback
(
ACM_CB_READ_READY
,
usb_read_callback
);
usb_read_complete
=
0
;
/* Start with USB in low power mode */
usb_app_sleep
();
/* TODO: Fix priority */
NVIC_SetPriority
(
USB_IRQn
,
6
);
NVIC_EnableIRQ
(
USB_IRQn
);
return
0
;
}
int
cdcacm_num_read_avail
(
void
)
{
return
acm_canread
();
}
uint8_t
cdcacm_read
(
void
)
{
while
(
acm_canread
()
<=
0
)
{
}
uint8_t
buf
;
acm_read
(
&
buf
,
1
);
return
buf
;
}
void
cdcacm_write
(
uint8_t
*
data
,
int
len
)
{
static
int
lockup_disable
=
0
;
if
(
acm_present
()
&&
!
lockup_disable
)
{
int
ret
=
acm_write
(
data
,
len
);
if
(
ret
<
0
)
{
lockup_disable
=
1
;
LOG_ERR
(
"cdcacm"
,
"fifo lockup detected"
);
}
else
if
(
ret
!=
len
)
{
LOG_WARN
(
"cdcacm"
,
"write length mismatch, got %d"
,
ret
);
}
}
}
/******************************************************************************/
#if 0
static void echo_usb(void)
{
int chars;
uint8_t buffer[BUFFER_SIZE];
if ((chars = acm_canread()) > 0) {
if (chars > BUFFER_SIZE) {
chars = BUFFER_SIZE;
}
// Read the data from USB
if (acm_read(buffer, chars) != chars) {
printf("acm_read() failed\n");
return;
}
// Echo it back
if (acm_present()) {
if (acm_write(buffer, chars) != chars) {
printf("acm_write() failed\n");
}
}
}
}
#endif
/******************************************************************************/
static
int
setconfig_callback
(
usb_setup_pkt
*
sud
,
void
*
cbdata
)
{
/* Confirm the configuration value */
if
(
sud
->
wValue
==
config_descriptor
.
config_descriptor
.
bConfigurationValue
)
{
configured
=
1
;
MXC_SETBIT
(
&
event_flags
,
EVENT_ENUM_COMP
);
return
acm_configure
(
&
acm_cfg
);
/* Configure the device class */
}
else
if
(
sud
->
wValue
==
0
)
{
configured
=
0
;
return
acm_deconfigure
();
}
return
-
1
;
}
/******************************************************************************/
static
int
setfeature_callback
(
usb_setup_pkt
*
sud
,
void
*
cbdata
)
{
if
(
sud
->
wValue
==
FEAT_REMOTE_WAKE
)
{
remote_wake_en
=
1
;
}
else
{
// Unknown callback
return
-
1
;
}
return
0
;
}
/******************************************************************************/
static
int
clrfeature_callback
(
usb_setup_pkt
*
sud
,
void
*
cbdata
)
{
if
(
sud
->
wValue
==
FEAT_REMOTE_WAKE
)
{
remote_wake_en
=
0
;
}
else
{
// Unknown callback
return
-
1
;
}
return
0
;
}
/******************************************************************************/
static
void
usb_app_sleep
(
void
)
{
/* TODO: Place low-power code here */
suspended
=
1
;
}
/******************************************************************************/
static
void
usb_app_wakeup
(
void
)
{
/* TODO: Place low-power code here */
suspended
=
0
;
}
/******************************************************************************/
static
int
event_callback
(
maxusb_event_t
evt
,
void
*
data
)
{
/* Set event flag */
MXC_SETBIT
(
&
event_flags
,
evt
);
switch
(
evt
)
{
case
MAXUSB_EVENT_NOVBUS
:
usb_event_disable
(
MAXUSB_EVENT_BRST
);
usb_event_disable
(
MAXUSB_EVENT_SUSP
);
usb_event_disable
(
MAXUSB_EVENT_DPACT
);
usb_disconnect
();
configured
=
0
;
enum_clearconfig
();
acm_deconfigure
();
usb_app_sleep
();
break
;
case
MAXUSB_EVENT_VBUS
:
usb_event_clear
(
MAXUSB_EVENT_BRST
);
usb_event_enable
(
MAXUSB_EVENT_BRST
,
event_callback
,
NULL
);
usb_event_clear
(
MAXUSB_EVENT_SUSP
);
usb_event_enable
(
MAXUSB_EVENT_SUSP
,
event_callback
,
NULL
);
usb_connect
();
usb_app_sleep
();
break
;
case
MAXUSB_EVENT_BRST
:
usb_app_wakeup
();
enum_clearconfig
();
acm_deconfigure
();
configured
=
0
;
suspended
=
0
;
break
;
case
MAXUSB_EVENT_SUSP
:
usb_app_sleep
();
break
;
case
MAXUSB_EVENT_DPACT
:
usb_app_wakeup
();
break
;
default:
break
;
}
return
0
;
}
/******************************************************************************/
static
int
usb_read_callback
(
void
)
{
usb_read_complete
=
1
;
return
0
;
}
/******************************************************************************/
#include
"FreeRTOS.h"
#include
"task.h"
void
USB_IRQHandler
(
void
)
{
usb_event_handler
();
if
(
serial_task_id
!=
NULL
)
{
BaseType_t
xHigherPriorityTaskWoken
=
pdFALSE
;
vTaskNotifyGiveFromISR
(
serial_task_id
,
&
xHigherPriorityTaskWoken
);
portYIELD_FROM_ISR
(
xHigherPriorityTaskWoken
);
}
}
/******************************************************************************/
/* TODO: We probably need to fix something related to this */
#if 0
void SysTick_Handler(void)
{
mxc_delay_handler();
}
#endif /* 0 */
epicardium/descriptors.h
deleted
100644 → 0
View file @
ef12c8bb
/*******************************************************************************
* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*
* Description: Communications Device Class ACM (Serial Port) over USB
* $Id: descriptors.h 36682 2018-08-06 21:14:03Z michael.bayern $
*
*******************************************************************************
*/
#ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_
#include
<stdint.h>
#include
"usb.h"
#include
"hid_kbd.h"
usb_device_descriptor_t
__attribute__
((
aligned
(
4
)))
device_descriptor
=
{
0x12
,
/* bLength = 18 */
0x01
,
/* bDescriptorType = Device */
0x0110
,
/* bcdUSB USB spec rev (BCD) */
0x02
,
/* bDeviceClass = comm class (2) */
0x00
,
/* bDeviceSubClass */
0x00
,
/* bDeviceProtocol */
0x40
,
/* bMaxPacketSize0 is 64 bytes */
0x0B6A
,
/* idVendor (Maxim Integrated) */
0x003C
,
/* idProduct */
0x0100
,
/* bcdDevice */
0x01
,
/* iManufacturer Descriptor ID */
0x02
,
/* iProduct Descriptor ID */
0x00
,
/* iSerialNumber = (0) No string */
0x01
/* bNumConfigurations */
};
__attribute__
((
aligned
(
4
)))
struct
__attribute__
((
packed
))
{
usb_configuration_descriptor_t
config_descriptor
;
usb_interface_descriptor_t
comm_interface_descriptor
;
uint8_t
header_functional_descriptor
[
5
];
uint8_t
call_management_descriptor
[
5
];
uint8_t
acm_functional_descriptor
[
4
];
uint8_t
union_functional_descriptor
[
5
];
usb_endpoint_descriptor_t
endpoint_descriptor_3
;
usb_interface_descriptor_t
data_interface_descriptor
;
usb_endpoint_descriptor_t
endpoint_descriptor_1
;
usb_endpoint_descriptor_t
endpoint_descriptor_2
;
}
config_descriptor
=
{
{
0x09
,
/* bLength = 9 */
0x02
,
/* bDescriptorType = Config (2) */
0x0043
,
/* wTotalLength(L/H) */
0x02
,
/* bNumInterfaces */
0x01
,
/* bConfigValue */
0x00
,
/* iConfiguration */
0xE0
,
/* bmAttributes (self-powered, remote wakeup) */
0x01
,
/* MaxPower is 2ma (units are 2ma/bit) */
},
{
/* First Interface Descriptor For Comm Class Interface */
0x09
,
/* bLength = 9 */
0x04
,
/* bDescriptorType = Interface (4) */
0x00
,
/* bInterfaceNumber */
0x00
,
/* bAlternateSetting */
0x01
,
/* bNumEndpoints (one for OUT) */
0x02
,
/* bInterfaceClass = Communications Interface Class (2) */
0x02
,
/* bInterfaceSubClass = Abstract Control Model (2) */
0x01
,
/* bInterfaceProtocol = Common "AT" commands (1), no class specific protocol (0) */
0x00
,
/* iInterface */
},
{
/* Header Functional Descriptor */
0x05
,
/* bFunctionalLength = 5 */
0x24
,
/* bDescriptorType */
0x00
,
/* bDescriptorSubtype */
0x10
,
0x01
,
/* bcdCDC */
},
{
/* Call Management Descriptor */
0x05
,
/* bFunctionalLength = 5 */
0x24
,
/* bDescriptorType */
0x01
,
/* bDescriptorSubtype */
0x03
,
/* bmCapabilities = Device handles call management itself (0x01), management over data class (0x02) */
0x01
,
/* bmDataInterface */
},
{
/* Abstract Control Management Functional Descriptor */
0x04
,
/* bFunctionalLength = 4 */
0x24
,
/* bDescriptorType */
0x02
,
/* bDescriptorSubtype */
0x02
,
/* bmCapabilities */
},
{
/* Union Functional Descriptor */
0x05
,
/* bFunctionalLength = 5 */
0x24
,
/* bDescriptorType */
0x06
,
/* bDescriptorSubtype */
0x00
,
/* bmMasterInterface */
0x01
,
/* bmSlaveInterface0 */
},
{
/* IN Endpoint 3 (Descriptor #1) */
0x07
,
/* bLength */
0x05
,
/* bDescriptorType (Endpoint) */
0x83
,
/* bEndpointAddress (EP3-IN) */
0x03
,
/* bmAttributes (interrupt) */
0x0040
,
/* wMaxPacketSize */
0xff
,
/* bInterval (milliseconds) */
},
{
/* Second Interface Descriptor For Data Interface */
0x09
,
/* bLength */
0x04
,
/* bDescriptorType (Interface) */
0x01
,
/* bInterfaceNumber */
0x00
,
/* bAlternateSetting */
0x02
,
/* bNumEndpoints */
0x0a
,
/* bInterfaceClass = Data Interface (10) */
0x00
,
/* bInterfaceSubClass = none (0) */
0x00
,
/* bInterfaceProtocol = No class specific protocol (0) */
0x00
,
/* biInterface = No Text String (0) */
},
{
/* OUT Endpoint 1 (Descriptor #2) */
0x07
,
/* bLength */
0x05
,
/* bDescriptorType (Endpoint) */
0x01
,
/* bEndpointAddress (EP1-OUT) */
0x02
,
/* bmAttributes (bulk) */
0x0040
,
/* wMaxPacketSize */
0x00
,
/* bInterval (N/A) */
},
{
/* IN Endpoint 2 (Descriptor #3) */
0x07
,
/* bLength */
0x05
,
/* bDescriptorType (Endpoint) */
0x82
,
/* bEndpointAddress (EP2-IN) */
0x02
,
/* bmAttributes (bulk) */
0x0040
,
/* wMaxPacketSize */
0x00
/* bInterval (N/A) */
}
};
__attribute__
((
aligned
(
4
)))
uint8_t
lang_id_desc
[]
=
{
0x04
,
/* bLength */
0x03
,
/* bDescriptorType */
0x09
,
0x04
/* bString = wLANGID (see usb_20.pdf 9.6.7 String) */
};
__attribute__
((
aligned
(
4
)))
uint8_t
mfg_id_desc
[]
=
{
0x22
,
/* bLength */
0x03
,
/* bDescriptorType */
'M'
,
0
,
'a'
,
0
,
'x'
,
0
,
'i'
,
0
,
'm'
,
0
,
' '
,
0
,
'I'
,
0
,
'n'
,
0
,
't'
,
0
,
'e'
,
0
,
'g'
,
0
,
'r'
,
0
,
'a'
,
0
,
't'
,
0
,
'e'
,
0
,
'd'
,
0
,
};
__attribute__
((
aligned
(
4
)))
uint8_t
prod_id_desc
[]
=
{
0x22
,
/* bLength */
0x03
,
/* bDescriptorType */
'M'
,
0
,
'A'
,
0
,
'X'
,
0
,
'3'
,
0
,
'2'
,
0
,
'6'
,
0
,
'6'
,
0
,
'5'
,
0
,
' '
,
0
,
'C'
,
0
,
'D'
,
0
,
'C'
,
0
,
'-'
,
0
,
'A'
,
0
,
'C'
,
0
,
'M'
,
0
,
};
/* Not currently used (see device descriptor), but could be enabled if desired */
__attribute__
((
aligned
(
4
)))
uint8_t
serial_id_desc
[]
=
{
0x14
,
/* bLength */
0x03
,
/* bDescriptorType */
'0'
,
0
,
'0'
,
0
,
'0'
,
0
,
'0'
,
0
,
'0'
,
0
,
'0'
,
0
,
'0'
,
0
,
'0'
,
0
,
'1'
,
0
};
#endif
/* _DESCRIPTORS_H_ */
epicardium/epicardium.h
View file @
99298759
...
...
@@ -131,6 +131,10 @@ typedef _Bool bool;
#define API_MAX86150_GET_DATA 0x0101
#define API_MAX86150_SET_LED_AMPLITUDE 0x0102
#define API_USB_SHUTDOWN 0x110
#define API_USB_STORAGE 0x111
#define API_USB_CDCACM 0x112
/* clang-format on */
typedef
uint32_t
api_int_id_t
;
...
...
@@ -1700,5 +1704,20 @@ API(API_MAX30001_DISABLE, int epic_max30001_disable_sensor(