diff options
130 files changed, 3630 insertions, 1253 deletions
diff --git a/demos/KINETIS/RT-FREEDOM-K20D50M-EXT/chconf.h b/demos/KINETIS/RT-FREEDOM-K20D50M-EXT/chconf.h index 1eaf053..c95387a 100644 --- a/demos/KINETIS/RT-FREEDOM-K20D50M-EXT/chconf.h +++ b/demos/KINETIS/RT-FREEDOM-K20D50M-EXT/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/KINETIS/RT-FREEDOM-K20D50M/chconf.h b/demos/KINETIS/RT-FREEDOM-K20D50M/chconf.h index 1eaf053..c95387a 100644 --- a/demos/KINETIS/RT-FREEDOM-K20D50M/chconf.h +++ b/demos/KINETIS/RT-FREEDOM-K20D50M/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/KINETIS/RT-FREEDOM-KL25Z-EXT/chconf.h b/demos/KINETIS/RT-FREEDOM-KL25Z-EXT/chconf.h index 1eaf053..c95387a 100644 --- a/demos/KINETIS/RT-FREEDOM-KL25Z-EXT/chconf.h +++ b/demos/KINETIS/RT-FREEDOM-KL25Z-EXT/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/KINETIS/RT-FREEDOM-KL25Z-SHELL/chconf.h b/demos/KINETIS/RT-FREEDOM-KL25Z-SHELL/chconf.h index c78e879..054d6b3 100644 --- a/demos/KINETIS/RT-FREEDOM-KL25Z-SHELL/chconf.h +++ b/demos/KINETIS/RT-FREEDOM-KL25Z-SHELL/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/KINETIS/RT-FREEDOM-KL25Z/chconf.h b/demos/KINETIS/RT-FREEDOM-KL25Z/chconf.h index 1eaf053..c95387a 100644 --- a/demos/KINETIS/RT-FREEDOM-KL25Z/chconf.h +++ b/demos/KINETIS/RT-FREEDOM-KL25Z/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/KINETIS/RT-MCHCK-K20-GPT/chconf.h b/demos/KINETIS/RT-MCHCK-K20-GPT/chconf.h index 1eaf053..c95387a 100644 --- a/demos/KINETIS/RT-MCHCK-K20-GPT/chconf.h +++ b/demos/KINETIS/RT-MCHCK-K20-GPT/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/KINETIS/RT-MCHCK-K20-SPI/chconf.h b/demos/KINETIS/RT-MCHCK-K20-SPI/chconf.h index 1eaf053..c95387a 100644 --- a/demos/KINETIS/RT-MCHCK-K20-SPI/chconf.h +++ b/demos/KINETIS/RT-MCHCK-K20-SPI/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/KINETIS/RT-TEENSY3/chconf.h b/demos/KINETIS/RT-TEENSY3/chconf.h index 1eaf053..c95387a 100644 --- a/demos/KINETIS/RT-TEENSY3/chconf.h +++ b/demos/KINETIS/RT-TEENSY3/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/MSP430X/NIL-EXP430FR5969/chconf.h b/demos/MSP430X/NIL-EXP430FR5969/chconf.h index bf2ad1b..1a017a0 100644 --- a/demos/MSP430X/NIL-EXP430FR5969/chconf.h +++ b/demos/MSP430X/NIL-EXP430FR5969/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_NIL_CONF_
+#define _CHIBIOS_NIL_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/MSP430X/NIL-EXP430FR6989/chconf.h b/demos/MSP430X/NIL-EXP430FR6989/chconf.h index bf2ad1b..1a017a0 100644 --- a/demos/MSP430X/NIL-EXP430FR6989/chconf.h +++ b/demos/MSP430X/NIL-EXP430FR6989/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_NIL_CONF_
+#define _CHIBIOS_NIL_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/NRF51/MICROBIT/chconf.h b/demos/NRF51/MICROBIT/chconf.h index a753ec9..14c1bf3 100644 --- a/demos/NRF51/MICROBIT/chconf.h +++ b/demos/NRF51/MICROBIT/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/NRF51/OSHCHIP_V1.0/chconf.h b/demos/NRF51/OSHCHIP_V1.0/chconf.h index a753ec9..14c1bf3 100644 --- a/demos/NRF51/OSHCHIP_V1.0/chconf.h +++ b/demos/NRF51/OSHCHIP_V1.0/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/NRF51/RT-WVSHARE_BLE400/chconf.h b/demos/NRF51/RT-WVSHARE_BLE400/chconf.h index a753ec9..14c1bf3 100644 --- a/demos/NRF51/RT-WVSHARE_BLE400/chconf.h +++ b/demos/NRF51/RT-WVSHARE_BLE400/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/NRF52/Classic/chconf.h b/demos/NRF52/Classic/chconf.h index 31b74a2..c7ec876 100644 --- a/demos/NRF52/Classic/chconf.h +++ b/demos/NRF52/Classic/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/STM32/RT-STM32F429-DISCOVERY-DMA2D/chconf.h b/demos/STM32/RT-STM32F429-DISCOVERY-DMA2D/chconf.h index a0fc879..17f8197 100644 --- a/demos/STM32/RT-STM32F429-DISCOVERY-DMA2D/chconf.h +++ b/demos/STM32/RT-STM32F429-DISCOVERY-DMA2D/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/STM32/RT-STM32F429-DISCOVERY-TRIBUF/chconf.h b/demos/STM32/RT-STM32F429-DISCOVERY-TRIBUF/chconf.h index 9a33ce5..81ccb47 100644 --- a/demos/STM32/RT-STM32F429-DISCOVERY-TRIBUF/chconf.h +++ b/demos/STM32/RT-STM32F429-DISCOVERY-TRIBUF/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/demos/TIVA/RT-TM4C123G-LAUNCHPAD/chconf.h b/demos/TIVA/RT-TM4C123G-LAUNCHPAD/chconf.h index 25e39f6..0d24275 100644 --- a/demos/TIVA/RT-TM4C123G-LAUNCHPAD/chconf.h +++ b/demos/TIVA/RT-TM4C123G-LAUNCHPAD/chconf.h @@ -18,6 +18,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/demos/TIVA/RT-TM4C1294-LAUNCHPAD-LWIP/chconf.h b/demos/TIVA/RT-TM4C1294-LAUNCHPAD-LWIP/chconf.h index dd5025e..35f9abd 100644 --- a/demos/TIVA/RT-TM4C1294-LAUNCHPAD-LWIP/chconf.h +++ b/demos/TIVA/RT-TM4C1294-LAUNCHPAD-LWIP/chconf.h @@ -18,6 +18,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/demos/TIVA/RT-TM4C1294-LAUNCHPAD/chconf.h b/demos/TIVA/RT-TM4C1294-LAUNCHPAD/chconf.h index 15db44a..cc0b2bd 100644 --- a/demos/TIVA/RT-TM4C1294-LAUNCHPAD/chconf.h +++ b/demos/TIVA/RT-TM4C1294-LAUNCHPAD/chconf.h @@ -18,6 +18,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/demos/various/RT-Win32-TriBuf/chconf.h b/demos/various/RT-Win32-TriBuf/chconf.h index 835d59b..75839d3 100644 --- a/demos/various/RT-Win32-TriBuf/chconf.h +++ b/demos/various/RT-Win32-TriBuf/chconf.h @@ -28,6 +28,9 @@ #ifndef _CHCONF_H_
#define _CHCONF_H_
+#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
+
/*===========================================================================*/
/**
* @name System timers settings
diff --git a/os/common/startup/ARMCMx/devices/TM4C123x/cmparams.h b/os/common/startup/ARMCMx/devices/TM4C123x/cmparams.h index d2693b0..7c40591 100644 --- a/os/common/startup/ARMCMx/devices/TM4C123x/cmparams.h +++ b/os/common/startup/ARMCMx/devices/TM4C123x/cmparams.h @@ -114,6 +114,7 @@ typedef int IRQn_Type; #include "inc/hw_ssi.h" #include "inc/hw_udma.h" #include "inc/hw_pwm.h" +#include "inc/hw_adc.h" #if CORTEX_NUM_VECTORS != ((((NUM_INTERRUPTS - 16) + 7) / 8) * 8) #error "TivaWare NUM_INTERRUPTS mismatch" diff --git a/os/common/startup/ARMCMx/devices/TM4C129x/cmparams.h b/os/common/startup/ARMCMx/devices/TM4C129x/cmparams.h index b73032b..7bf68a0 100644 --- a/os/common/startup/ARMCMx/devices/TM4C129x/cmparams.h +++ b/os/common/startup/ARMCMx/devices/TM4C129x/cmparams.h @@ -99,6 +99,7 @@ typedef int IRQn_Type; #include "inc/hw_ssi.h" #include "inc/hw_udma.h" #include "inc/hw_pwm.h" +#include "inc/hw_adc.h" #if CORTEX_NUM_VECTORS != ((((NUM_INTERRUPTS - 16) + 7) / 8) * 8) #error "TivaWare NUM_INTERRUPTS mismatch" diff --git a/os/hal/include/hal_usb_msd.h b/os/hal/include/hal_usb_msd.h index fcc2cf2..0fe03e4 100644 --- a/os/hal/include/hal_usb_msd.h +++ b/os/hal/include/hal_usb_msd.h @@ -172,7 +172,8 @@ extern "C" { void msdObjectInit(USBMassStorageDriver *msdp); void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp, BaseBlockDevice *blkdev, uint8_t *blkbuf, - const scsi_inquiry_response_t *scsi_inquiry_response); + const scsi_inquiry_response_t *scsi_inquiry_response, + const scsi_unit_serial_number_inquiry_response_t *serialInquiry); void msdStop(USBMassStorageDriver *msdp); bool msd_request_hook(USBDriver *usbp); #ifdef __cplusplus diff --git a/os/hal/include/hal_usbh.h b/os/hal/include/hal_usbh.h index b8c229a..1ed6416 100644 --- a/os/hal/include/hal_usbh.h +++ b/os/hal/include/hal_usbh.h @@ -48,6 +48,10 @@ #define HAL_USBH_USE_HID FALSE #endif +#ifndef HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS +#define HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS FALSE +#endif + #define HAL_USBH_USE_IAD HAL_USBH_USE_UVC #if (HAL_USE_USBH == TRUE) || defined(__DOXYGEN__) @@ -56,13 +60,6 @@ #include "usbh/list.h" #include "usbh/defs.h" -/* TODO: - * - * - Integrate VBUS power switching functionality to the API. - * - */ - - /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -79,6 +76,7 @@ enum usbh_status { USBH_STATUS_SUSPENDED, }; +/* These correspond to the USB spec */ enum usbh_devstatus { USBH_DEVSTATUS_DISCONNECTED = 0, USBH_DEVSTATUS_ATTACHED, @@ -354,10 +352,8 @@ extern "C" { osalDbgCheck(ep != 0); osalDbgCheckClassS(); osalDbgAssert(ep->status != USBH_EPSTATUS_UNINITIALIZED, "invalid state"); - if (ep->status == USBH_EPSTATUS_CLOSED) { - osalOsRescheduleS(); + if (ep->status == USBH_EPSTATUS_CLOSED) return; - } usbh_lld_ep_close(ep); } static inline void usbhEPClose(usbh_ep_t *ep) { @@ -388,6 +384,22 @@ extern "C" { void usbhURBCancelAndWaitS(usbh_urb_t *urb); msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout); + static inline void usbhURBSubmit(usbh_urb_t *urb) { + osalSysLock(); + usbhURBSubmitI(urb); + osalOsRescheduleS(); + osalSysUnlock(); + } + + static inline bool usbhURBCancel(usbh_urb_t *urb) { + bool ret; + osalSysLock(); + ret = usbhURBCancelI(urb); + osalOsRescheduleS(); + osalSysUnlock(); + return ret; + } + /* Main loop */ void usbhMainLoop(USBHDriver *usbh); @@ -402,14 +414,13 @@ extern "C" { typedef struct usbh_classdriver_vmt usbh_classdriver_vmt_t; struct usbh_classdriver_vmt { + void (*init)(void); usbh_baseclassdriver_t *(*load)(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); void (*unload)(usbh_baseclassdriver_t *drv); + /* TODO: add power control, suspend, etc */ }; struct usbh_classdriverinfo { - int16_t class; - int16_t subclass; - int16_t protocol; const char *name; const usbh_classdriver_vmt_t *vmt; }; @@ -423,13 +434,6 @@ struct usbh_baseclassdriver { _usbh_base_classdriver_data }; - -/*===========================================================================*/ -/* Helper functions. */ -/*===========================================================================*/ -#include <usbh/desciter.h> /* descriptor iterators */ -#include <usbh/debug.h> /* debug */ - #endif #endif /* HAL_USBH_H_ */ diff --git a/os/hal/include/usbh/dev/aoa.h b/os/hal/include/usbh/dev/aoa.h index 636768a..a7f1c1b 100644 --- a/os/hal/include/usbh/dev/aoa.h +++ b/os/hal/include/usbh/dev/aoa.h @@ -140,12 +140,8 @@ extern USBHAOADriver USBHAOAD[HAL_USBHAOA_MAX_INSTANCES]; extern "C" { #endif /* AOA device driver */ - void usbhaoaObjectInit(USBHAOADriver *aoap); void usbhaoaChannelStart(USBHAOADriver *aoap); void usbhaoaChannelStop(USBHAOADriver *aoap); - - /* global initializer */ - void usbhaoaInit(void); #ifdef __cplusplus } #endif diff --git a/os/hal/include/usbh/dev/ftdi.h b/os/hal/include/usbh/dev/ftdi.h index bfa3103..eedb056 100644 --- a/os/hal/include/usbh/dev/ftdi.h +++ b/os/hal/include/usbh/dev/ftdi.h @@ -138,16 +138,9 @@ extern USBHFTDIPortDriver FTDIPD[HAL_USBHFTDI_MAX_PORTS]; #ifdef __cplusplus
extern "C" {
#endif
- /* FTDI device driver */
- void usbhftdiObjectInit(USBHFTDIDriver *ftdip);
-
/* FTDI port driver */
- void usbhftdipObjectInit(USBHFTDIPortDriver *ftdipp);
void usbhftdipStart(USBHFTDIPortDriver *ftdipp, const USBHFTDIPortConfig *config);
void usbhftdipStop(USBHFTDIPortDriver *ftdipp);
-
- /* global initializer */
- void usbhftdiInit(void);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/include/usbh/dev/hid.h b/os/hal/include/usbh/dev/hid.h index 0d6b894..c7371ee 100644 --- a/os/hal/include/usbh/dev/hid.h +++ b/os/hal/include/usbh/dev/hid.h @@ -95,6 +95,8 @@ struct USBHHIDDriver { usbh_urb_t in_urb; const USBHHIDConfig *config; + + semaphore_t sem; }; @@ -112,9 +114,6 @@ extern USBHHIDDriver USBHHIDD[HAL_USBHHID_MAX_INSTANCES]; #ifdef __cplusplus extern "C" { #endif - /* HID Driver */ - void usbhHIDObjectInit(USBHHIDDriver *hidp); - /* HID Common API */ usbh_urbstatus_t usbhhidGetReport(USBHHIDDriver *hidp, uint8_t report_id, usbhhid_reporttype_t report_type, @@ -136,9 +135,6 @@ extern "C" { } void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg); - - /* global initializer */ - void usbhhidInit(void); #ifdef __cplusplus } #endif diff --git a/os/hal/include/usbh/dev/hub.h b/os/hal/include/usbh/dev/hub.h index 924ebec..406fbaf 100644 --- a/os/hal/include/usbh/dev/hub.h +++ b/os/hal/include/usbh/dev/hub.h @@ -88,10 +88,6 @@ static inline usbh_urbstatus_t usbhhubSetFeaturePort(usbh_port_t *port, uint8_t 0);
}
-void usbhhubObjectInit(USBHHubDriver *hubdp);
-
-void usbhhubInit(void);
-
#else
static inline usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host,
diff --git a/os/hal/include/usbh/dev/msd.h b/os/hal/include/usbh/dev/msd.h index 84179c5..eedd474 100644 --- a/os/hal/include/usbh/dev/msd.h +++ b/os/hal/include/usbh/dev/msd.h @@ -58,30 +58,15 @@ struct USBHMassStorageLUNDriver { const struct USBHMassStorageDriverVMT *vmt;
_base_block_device_data
+ /* for serializing access to the LUN driver */
+ semaphore_t sem;
+
BlockDeviceInfo info;
USBHMassStorageDriver *msdp;
USBHMassStorageLUNDriver *next;
};
-struct USBHMassStorageDriver {
- /* inherited from abstract class driver */
- _usbh_base_classdriver_data
-
- /* for LUN request serialization, can be removed
- * if the driver is configured to support only one LUN
- * per USBHMassStorageDriver instance */
- mutex_t mtx;
-
- usbh_ep_t epin;
- usbh_ep_t epout;
- uint8_t ifnum;
- uint8_t max_lun;
- uint32_t tag;
-
- USBHMassStorageLUNDriver *luns;
-};
-
/*===========================================================================*/
/* Driver macros. */
@@ -93,18 +78,13 @@ struct USBHMassStorageDriver { /*===========================================================================*/
extern USBHMassStorageLUNDriver MSBLKD[HAL_USBHMSD_MAX_LUNS];
-extern USBHMassStorageDriver USBHMSD[HAL_USBHMSD_MAX_INSTANCES];
#ifdef __cplusplus
extern "C" {
#endif
- /* Mass Storage Driver */
- void usbhmsdObjectInit(USBHMassStorageDriver *msdp);
-
/* Mass Storage LUN Driver (block driver) */
- void usbhmsdLUNObjectInit(USBHMassStorageLUNDriver *lunp);
- void usbhmsdLUNStart(USBHMassStorageLUNDriver *lunp);
- void usbhmsdLUNStop(USBHMassStorageLUNDriver *lunp);
+// void usbhmsdLUNStart(USBHMassStorageLUNDriver *lunp);
+// void usbhmsdLUNStop(USBHMassStorageLUNDriver *lunp);
bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp);
bool usbhmsdLUNDisconnect(USBHMassStorageLUNDriver *lunp);
bool usbhmsdLUNRead(USBHMassStorageLUNDriver *lunp, uint32_t startblk,
@@ -115,9 +95,6 @@ extern "C" { bool usbhmsdLUNGetInfo(USBHMassStorageLUNDriver *lunp, BlockDeviceInfo *bdip);
bool usbhmsdLUNIsInserted(USBHMassStorageLUNDriver *lunp);
bool usbhmsdLUNIsProtected(USBHMassStorageLUNDriver *lunp);
-
- /* global initializer */
- void usbhmsdInit(void);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/include/usbh/dev/uvc.h b/os/hal/include/usbh/dev/uvc.h index c68a082..817d465 100644 --- a/os/hal/include/usbh/dev/uvc.h +++ b/os/hal/include/usbh/dev/uvc.h @@ -22,11 +22,7 @@ #if HAL_USE_USBH && HAL_USBH_USE_UVC -/* TODO: - * - * - */ - +#include "usbh/desciter.h" /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -394,9 +390,6 @@ extern USBHUVCDriver USBHUVCD[HAL_USBHUVC_MAX_INSTANCES]; #ifdef __cplusplus extern "C" { #endif - - void usbhuvcObjectInit(USBHUVCDriver *uvcd); - static inline usbhuvc_state_t usbhuvcGetState(USBHUVCDriver *uvcd) { return uvcd->state; } @@ -457,11 +450,6 @@ extern "C" { static inline void usbhuvcFreeStatusMessage(USBHUVCDriver *uvcdp, usbhuvc_message_status_t *msg) { chPoolFree(&uvcdp->mp_status, msg); } - - - /* global initializer */ - void usbhuvcInit(void); - #ifdef __cplusplus } #endif diff --git a/os/hal/include/usbh/internal.h b/os/hal/include/usbh/internal.h index 70d2f7a..f6f17b7 100644 --- a/os/hal/include/usbh/internal.h +++ b/os/hal/include/usbh/internal.h @@ -54,6 +54,9 @@ void _usbh_urb_completeI(usbh_urb_t *urb, usbh_urbstatus_t status); bool _usbh_urb_abortI(usbh_urb_t *urb, usbh_urbstatus_t status);
void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status);
+bool _usbh_match_vid_pid(usbh_device_t *dev, int32_t vid, int32_t pid);
+bool _usbh_match_descriptor(const uint8_t *descriptor, uint16_t rem,
+ int16_t type, int16_t _class, int16_t subclass, int16_t protocol);
#define USBH_REQTYPE_CLASSIN(type) \
(USBH_REQTYPE_DIR_IN | type | USBH_REQTYPE_TYPE_CLASS)
@@ -137,6 +140,9 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status); #define sizeof_array(x) (sizeof(x)/sizeof(*(x)))
+#include "usbh/desciter.h" /* descriptor iterators */
+#include "usbh/debug.h"
+
#endif
#endif /* USBH_INTERNAL_H_ */
diff --git a/os/hal/include/usbh/list.h b/os/hal/include/usbh/list.h index 317e51b..cdcca04 100644 --- a/os/hal/include/usbh/list.h +++ b/os/hal/include/usbh/list.h @@ -41,21 +41,15 @@ static inline void INIT_LIST_HEAD(struct list_head *list) * This is only for internal list manipulation where we know
* the prev/next entries already!
*/
-#ifndef CONFIG_DEBUG_LIST
-static inline void __list_add(struct list_head *new,
+static inline void __list_add(struct list_head *_new,
struct list_head *prev,
struct list_head *next)
{
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
+ next->prev = _new;
+ _new->next = next;
+ _new->prev = prev;
+ prev->next = _new;
}
-#else
-extern void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next);
-#endif
/**
* list_add - add a new entry
@@ -65,9 +59,9 @@ extern void __list_add(struct list_head *new, * Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
-static inline void list_add(struct list_head *new, struct list_head *head)
+static inline void list_add(struct list_head *_new, struct list_head *head)
{
- __list_add(new, head, head->next);
+ __list_add(_new, head, head->next);
}
@@ -79,9 +73,9 @@ static inline void list_add(struct list_head *new, struct list_head *head) * Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
+static inline void list_add_tail(struct list_head *_new, struct list_head *head)
{
- __list_add(new, head->prev, head);
+ __list_add(_new, head->prev, head);
}
/*
@@ -103,7 +97,7 @@ static inline void __list_del(struct list_head * prev, struct list_head * next) * Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
-#ifndef CONFIG_DEBUG_LIST
+
static inline void __list_del_entry(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
@@ -112,35 +106,6 @@ static inline void __list_del_entry(struct list_head *entry) static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
- // entry->next = LIST_POISON1;
- // entry->prev = LIST_POISON2;
-}
-#else
-extern void __list_del_entry(struct list_head *entry);
-extern void list_del(struct list_head *entry);
-#endif
-
-/**
- * list_replace - replace old entry by new one
- * @old : the element to be replaced
- * @new : the new element to insert
- *
- * If @old was empty, it will be overwritten.
- */
-static inline void list_replace(struct list_head *old,
- struct list_head *new)
-{
- new->next = old->next;
- new->next->prev = new;
- new->prev = old->prev;
- new->prev->next = new;
-}
-
-static inline void list_replace_init(struct list_head *old,
- struct list_head *new)
-{
- list_replace(old, new);
- INIT_LIST_HEAD(old);
}
/**
@@ -154,26 +119,159 @@ static inline void list_del_init(struct list_head *entry) }
/**
- * list_move - delete from one list and add as another's head
+ * list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
- * @head: the head that will precede our entry
+ * @head: the head that will follow our entry
*/
-static inline void list_move(struct list_head *list, struct list_head *head)
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
{
__list_del_entry(list);
- list_add(list, head);
+ list_add_tail(list, head);
}
+
/**
- * list_move_tail - delete from one list and add as another's tail
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * list_next_entry - get the next element in list
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ */
+#define list_next_entry(pos, type, member) \
+ list_entry((pos)->member.next, type, member)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry(pos, type, head, member) \
+ for (pos = list_first_entry(head, type, member); \
+ &pos->member != (head); \
+ pos = list_next_entry(pos, type, member))
+
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry_safe(pos, type, n, head, member) \
+ for (pos = list_first_entry(head, type, member), \
+ n = list_next_entry(pos, type, member); \
+ &pos->member != (head); \
+ pos = n, n = list_next_entry(n, type, member))
+
+#if 0
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_prev_entry - get the prev element in list
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ */
+#define list_prev_entry(pos, type, member) \
+ list_entry((pos)->member.prev, type, member)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; pos != (head); pos = pos->prev)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+ for (pos = (head)->prev, n = pos->prev; \
+ pos != (head); \
+ pos = n, n = pos->prev)
+
+/**
+ * list_last_entry - get the last element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_last_entry(ptr, type, member) \
+ list_entry((ptr)->prev, type, member)
+
+/**
+ * list_first_entry_or_null - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note that if the list is empty, it returns NULL.
+ */
+#define list_first_entry_or_null(ptr, type, member) \
+ (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
+
+
+/**
+ * list_move - delete from one list and add as another's head
* @list: the entry to move
- * @head: the head that will follow our entry
+ * @head: the head that will precede our entry
*/
-static inline void list_move_tail(struct list_head *list,
- struct list_head *head)
+static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del_entry(list);
- list_add_tail(list, head);
+ list_add(list, head);
}
/**
@@ -188,15 +286,6 @@ static inline int list_is_last(const struct list_head *list, }
/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
-{
- return head->next == head;
-}
-
-/**
* list_empty_careful - tests whether a list is empty and not being modified
* @head: the list to test
*
@@ -350,110 +439,28 @@ static inline void list_splice_tail_init(struct list_head *list, }
/**
- * list_entry - get the struct for this entry
- * @ptr: the &struct list_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_head within the struct.
- */
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
-
-/**
- * list_first_entry - get the first element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_head within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_first_entry(ptr, type, member) \
- list_entry((ptr)->next, type, member)
-
-/**
- * list_last_entry - get the last element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_head within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_last_entry(ptr, type, member) \
- list_entry((ptr)->prev, type, member)
-
-/**
- * list_first_entry_or_null - get the first element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_head within the struct.
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
*
- * Note that if the list is empty, it returns NULL.
- */
-#define list_first_entry_or_null(ptr, type, member) \
- (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
-
-/**
- * list_next_entry - get the next element in list
- * @pos: the type * to cursor
- * @member: the name of the list_head within the struct.
- */
-#define list_next_entry(pos, type, member) \
- list_entry((pos)->member.next, type, member)
-
-/**
- * list_prev_entry - get the prev element in list
- * @pos: the type * to cursor
- * @member: the name of the list_head within the struct.
- */
-#define list_prev_entry(pos, type, member) \
- list_entry((pos)->member.prev, type, member)
-
-/**
- * list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop cursor.
- * @head: the head for your list.
- */
-#define list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev - iterate over a list backwards
- * @pos: the &struct list_head to use as a loop cursor.
- * @head: the head for your list.
- */
-#define list_for_each_prev(pos, head) \
- for (pos = (head)->prev; pos != (head); pos = pos->prev)
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos: the &struct list_head to use as a loop cursor.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
+ * If @old was empty, it will be overwritten.
*/
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
+static inline void list_replace(struct list_head *old,
+ struct list_head *_new)
+{
+ _new->next = old->next;
+ _new->next->prev = _new;
+ _new->prev = old->prev;
+ _new->prev->next = _new;
+}
-/**
- * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
- * @pos: the &struct list_head to use as a loop cursor.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
- */
-#define list_for_each_prev_safe(pos, n, head) \
- for (pos = (head)->prev, n = pos->prev; \
- pos != (head); \
- pos = n, n = pos->prev)
+static inline void list_replace_init(struct list_head *old,
+ struct list_head *_new)
+{
+ list_replace(old, _new);
+ INIT_LIST_HEAD(old);
+}
-/**
- * list_for_each_entry - iterate over list of given type
- * @pos: the type * to use as a loop cursor.
- * @head: the head for your list.
- * @member: the name of the list_head within the struct.
- */
-#define list_for_each_entry(pos, type, head, member) \
- for (pos = list_first_entry(head, type, member); \
- &pos->member != (head); \
- pos = list_next_entry(pos, type, member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
@@ -518,19 +525,6 @@ static inline void list_splice_tail_init(struct list_head *list, pos = list_next_entry(pos, type, member))
/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos: the type * to use as a loop cursor.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_head within the struct.
- */
-#define list_for_each_entry_safe(pos, type, n, head, member) \
- for (pos = list_first_entry(head, type, member), \
- n = list_next_entry(pos, type, member); \
- &pos->member != (head); \
- pos = n, n = list_next_entry(n, type, member))
-
-/**
* list_for_each_entry_safe_continue - continue list iteration safe against removal
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
@@ -591,5 +585,6 @@ static inline void list_splice_tail_init(struct list_head *list, */
#define list_safe_reset_next(pos, type, n, member) \
n = list_next_entry(pos, type, member)
+#endif
#endif /* USBH_LIST_H_ */
diff --git a/os/hal/ports/KINETIS/K20x/hal_lld.c b/os/hal/ports/KINETIS/K20x/hal_lld.c index e6eeed8..594f7af 100644 --- a/os/hal/ports/KINETIS/K20x/hal_lld.c +++ b/os/hal/ports/KINETIS/K20x/hal_lld.c @@ -148,11 +148,10 @@ void k20x_clock_init(void) { * frequency, which would required other registers to be modified.
*/
/* Enable OSC, low power mode */
- MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0;
if (KINETIS_XTAL_FREQUENCY > 8000000UL)
- MCG->C2 |= MCG_C2_RANGE0(2);
+ MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0 | MCG_C2_RANGE0(2);
else
- MCG->C2 |= MCG_C2_RANGE0(1);
+ MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0 | MCG_C2_RANGE0(1);
frdiv = 7;
ratio = KINETIS_XTAL_FREQUENCY / 31250UL;
diff --git a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c index 5954cb2..4723508 100644 --- a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c +++ b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c @@ -105,6 +105,13 @@ static void _try_commit_np(USBHDriver *host); static void otg_rxfifo_flush(USBHDriver *usbp); static void otg_txfifo_flush(USBHDriver *usbp, uint32_t fifo); +#if STM32_USBH_USE_OTG1 +USBHDriver USBHD1; +#endif +#if STM32_USBH_USE_OTG2 +USBHDriver USBHD2; +#endif + /*===========================================================================*/ /* Little helper functions. */ /*===========================================================================*/ @@ -120,16 +127,6 @@ static inline void _save_dt_mask(usbh_ep_t *ep, uint32_t hctsiz) { ep->dt_mask = hctsiz & HCTSIZ_DPID_MASK; } -#if 1 -#define _transfer_completed _transfer_completedI -#else -static inline void _transfer_completed(usbh_ep_t *ep, usbh_urb_t *urb, usbh_urbstatus_t status) { - osalSysLockFromISR(); - _transfer_completedI(ep, urb, status); - osalSysUnlockFromISR(); -} -#endif - /*===========================================================================*/ /* Functions called from many places. */ /*===========================================================================*/ @@ -247,7 +244,6 @@ static bool _activate_ep(USBHDriver *host, usbh_ep_t *ep) { ep->xfer.buf = urb->buff; } ep->xfer.error_count = 0; - //urb->status = USBH_URBSTATUS_QUEUED; } else { osalDbgCheck(urb->requestedLength >= urb->actualLength); @@ -459,7 +455,7 @@ static void _purge_queue(USBHDriver *host, struct list_head *list) { _release_channel(host, hcm); _update_urb(ep, hcm->hc->HCTSIZ, urb, FALSE); } - _transfer_completed(ep, urb, USBH_URBSTATUS_DISCONNECTED); + _transfer_completedI(ep, urb, USBH_URBSTATUS_DISCONNECTED); } } @@ -595,7 +591,6 @@ void usbh_lld_ep_object_init(usbh_ep_t *ep) { void usbh_lld_ep_open(usbh_ep_t *ep) { uinfof("\t%s: Open EP", ep->name); ep->status = USBH_EPSTATUS_OPEN; - osalOsRescheduleS(); } void usbh_lld_ep_close(usbh_ep_t *ep) { @@ -607,7 +602,6 @@ void usbh_lld_ep_close(usbh_ep_t *ep) { } uinfof("\t%s: Closed", ep->name); ep->status = USBH_EPSTATUS_CLOSED; - osalOsRescheduleS(); } bool usbh_lld_ep_reset(usbh_ep_t *ep) { @@ -617,6 +611,13 @@ bool usbh_lld_ep_reset(usbh_ep_t *ep) { void usbh_lld_urb_submit(usbh_urb_t *urb) { usbh_ep_t *const ep = urb->ep; + USBHDriver *const host = ep->device->host; + + if (!(host->otg->HPRT & HPRT_PENA)) { + uwarnf("\t%s: Can't submit URB, port disabled", ep->name); + _usbh_urb_completeI(urb, USBH_URBSTATUS_DISCONNECTED); + return; + } /* add the URB to the EP's queue */ list_add_tail(&urb->node, &ep->urb_list); @@ -628,7 +629,7 @@ void usbh_lld_urb_submit(usbh_urb_t *urb) { _move_to_pending_queue(ep); if (usbhEPIsPeriodic(ep)) { - ep->device->host->otg->GINTMSK |= GINTMSK_SOFM; + host->otg->GINTMSK |= GINTMSK_SOFM; } else { /* try to queue non-periodic transfers */ _try_commit_np(ep->device->host); @@ -636,6 +637,7 @@ void usbh_lld_urb_submit(usbh_urb_t *urb) { } } +/* usbh_lld_urb_abort may require a reschedule if called from a S-locked state */ bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status) { osalDbgCheck(usbhURBIsBusy(urb)); @@ -660,8 +662,8 @@ bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status) { return FALSE; } - /* This URB is active, we can cancel it now */ - uinfof("\t%s: usbh_lld_urb_abort: URB is not active", hcm->ep->name); + /* This URB is inactive, we can cancel it now */ + uinfof("\t%s: usbh_lld_urb_abort: URB is not active", ep->name); _transfer_completedI(ep, urb, status); return TRUE; @@ -760,7 +762,7 @@ static void _complete_bulk_int(USBHDriver *host, stm32_hc_management_t *hcm, usb _save_dt_mask(ep, hctsiz); if (_update_urb(ep, hctsiz, urb, TRUE)) { udbgf("\t%s: done", ep->name); - _transfer_completed(ep, urb, USBH_URBSTATUS_OK); + _transfer_completedI(ep, urb, USBH_URBSTATUS_OK); } else { osalDbgCheck(urb->requestedLength > 0x7FFFF); uwarnf("\t%s: incomplete", ep->name); @@ -791,7 +793,7 @@ static void _complete_control(USBHDriver *host, stm32_hc_management_t *hcm, usbh } else { osalDbgCheck(ep->xfer.u.ctrl_phase == USBH_LLD_CTRLPHASE_STATUS); udbgf("\t%s: STATUS done", ep->name); - _transfer_completed(ep, urb, USBH_URBSTATUS_OK); + _transfer_completedI(ep, urb, USBH_URBSTATUS_OK); } _try_commit_np(host); } @@ -817,7 +819,7 @@ static void _complete_iso(USBHDriver *host, stm32_hc_management_t *hcm, usbh_ep_ udbgf("\t%s: done", hcm->ep->name); _release_channel(host, hcm); _update_urb(ep, hctsiz, urb, TRUE); - _transfer_completed(ep, urb, USBH_URBSTATUS_OK); + _transfer_completedI(ep, urb, USBH_URBSTATUS_OK); _try_commit_p(host, FALSE); } @@ -902,7 +904,7 @@ static inline void _chh_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_ switch (reason) { case USBH_LLD_HALTREASON_NAK: if ((ep->type == USBH_EPTYPE_INT) && ep->in) { - _transfer_completed(ep, urb, USBH_URBSTATUS_TIMEOUT); + _transfer_completedI(ep, urb, USBH_URBSTATUS_TIMEOUT); } else { ep->xfer.error_count = 0; _move_to_pending_queue(ep); @@ -917,12 +919,12 @@ static inline void _chh_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_ } else { ep->status = USBH_EPSTATUS_HALTED; } - _transfer_completed(ep, urb, USBH_URBSTATUS_STALL); + _transfer_completedI(ep, urb, USBH_URBSTATUS_STALL); break; case USBH_LLD_HALTREASON_ERROR: if ((ep->type == USBH_EPTYPE_ISO) || done || (ep->xfer.error_count >= 3)) { - _transfer_completed(ep, urb, USBH_URBSTATUS_ERROR); + _transfer_completedI(ep, urb, USBH_URBSTATUS_ERROR); } else { uerrf("\t%s: err=%d, done=%d, retry", ep->name, ep->xfer.error_count, done); _move_to_pending_queue(ep); @@ -931,7 +933,7 @@ static inline void _chh_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_ case USBH_LLD_HALTREASON_ABORT: uwarnf("\t%s: Abort", ep->name); - _transfer_completed(ep, urb, urb->status); + _transfer_completedI(ep, urb, urb->status); break; default: @@ -1018,6 +1020,47 @@ static inline void _hcint_int(USBHDriver *host) { /* Host interrupts. */ /*===========================================================================*/ static inline void _sof_int(USBHDriver *host) { + + /* this is part of the workaround to the LS bug in the OTG core */ +#undef HPRT_PLSTS_MASK +#define HPRT_PLSTS_MASK (3U<<10) + if (host->check_ls_activity) { + stm32_otg_t *const otg = host->otg; + uint16_t remaining = otg->HFNUM >> 16; + if (remaining < 5975) { + uwarnf("LS: ISR called too late (time=%d)", 6000 - remaining); + return; + } + /* 15us loop during which we check if the core generates an actual keep-alive + * (or activity other than idle) on the DP/DM lines. After 15us, we abort + * the loop and wait for the next SOF. If no activity is detected, the upper + * layer will time-out waiting for the reset to happen, and the port will remain + * enabled (though in a dumb state). This will be detected on the next port reset + * request and the OTG core will be reset. */ + for (;;) { + uint32_t line_status = otg->HPRT & HPRT_PLSTS_MASK; + remaining = otg->HFNUM >> 16; + if (!(otg->HPRT & HPRT_PENA)) { + uwarn("LS: Port disabled"); + return; + } + if (line_status != HPRT_PLSTS_DM) { + /* success; report that the port is enabled */ + uinfof("LS: activity detected, line=%d, time=%d", line_status >> 10, 6000 - remaining); + host->check_ls_activity = FALSE; + otg->GINTMSK = (otg->GINTMSK & ~GINTMSK_SOFM) | (GINTMSK_HCM | GINTMSK_RXFLVLM); + host->rootport.lld_status |= USBH_PORTSTATUS_ENABLE; + host->rootport.lld_c_status |= USBH_PORTSTATUS_C_ENABLE; + return; + } + if (remaining < 5910) { + udbg("LS: No activity detected"); + return; + } + } + } + + /* real SOF interrupt */ udbg("SOF"); _try_commit_p(host, TRUE); } @@ -1123,9 +1166,6 @@ static inline void _nptxfe_int(USBHDriver *host) { rem += _write_packet(&host->ep_active_lists[USBH_EPTYPE_BULK], otg->HNPTXSTS & HPTXSTS_PTXFSAVL_MASK); -// if (rem) -// otg->GINTMSK |= GINTMSK_NPTXFEM; - if (!rem) otg->GINTMSK &= ~GINTMSK_NPTXFEM; @@ -1137,17 +1177,19 @@ static inline void _ptxfe_int(USBHDriver *host) { uinfo("PTXFE"); } -static inline void _discint_int(USBHDriver *host) { - uint32_t hprt = host->otg->HPRT; - - uwarn("\tDISCINT"); +static void _disable(USBHDriver *host) { + host->rootport.lld_status &= ~(USBH_PORTSTATUS_CONNECTION | USBH_PORTSTATUS_ENABLE); + host->rootport.lld_c_status |= USBH_PORTSTATUS_C_CONNECTION | USBH_PORTSTATUS_C_ENABLE; - if (!(hprt & HPRT_PCSTS)) { - host->rootport.lld_status &= ~(USBH_PORTSTATUS_CONNECTION | USBH_PORTSTATUS_ENABLE); - host->rootport.lld_c_status |= USBH_PORTSTATUS_C_CONNECTION | USBH_PORTSTATUS_C_ENABLE; - } _purge_active(host); _purge_pending(host); + + host->otg->GINTMSK &= ~(GINTMSK_HCM | GINTMSK_RXFLVLM); +} + +static inline void _discint_int(USBHDriver *host) { + uinfo("DISCINT: Port disconnection detected"); + _disable(host); } static inline void _hprtint_int(USBHDriver *host) { @@ -1163,8 +1205,6 @@ static inline void _hprtint_int(USBHDriver *host) { uinfo("\tHPRT: Port connection detected"); host->rootport.lld_status |= USBH_PORTSTATUS_CONNECTION; host->rootport.lld_c_status |= USBH_PORTSTATUS_C_CONNECTION; - } else { - uinfo("\tHPRT: Port disconnection detected"); } } @@ -1172,9 +1212,32 @@ static inline void _hprtint_int(USBHDriver *host) { hprt_clr |= HPRT_PENCHNG; if (hprt & HPRT_PENA) { uinfo("\tHPRT: Port enabled"); - host->rootport.lld_status |= USBH_PORTSTATUS_ENABLE; host->rootport.lld_status &= ~(USBH_PORTSTATUS_HIGH_SPEED | USBH_PORTSTATUS_LOW_SPEED); + /* configure FIFOs */ +#define HNPTXFSIZ DIEPTXF0 +#if STM32_USBH_USE_OTG1 +#if STM32_USBH_USE_OTG2 + if (&USBHD1 == host) +#endif + { + otg->GRXFSIZ = GRXFSIZ_RXFD(STM32_OTG1_RXFIFO_SIZE / 4); + otg->HNPTXFSIZ = HPTXFSIZ_PTXSA(STM32_OTG1_RXFIFO_SIZE / 4) | HPTXFSIZ_PTXFD(STM32_OTG1_NPTXFIFO_SIZE / 4); + otg->HPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG1_RXFIFO_SIZE / 4) + (STM32_OTG1_NPTXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG1_PTXFIFO_SIZE / 4); + } +#endif +#if STM32_USBH_USE_OTG2 +#if STM32_USBH_USE_OTG1 + if (&USBHD2 == host) +#endif + { + otg->GRXFSIZ = GRXFSIZ_RXFD(STM32_OTG2_RXFIFO_SIZE / 4); + otg->HNPTXFSIZ = HPTXFSIZ_PTXSA(STM32_OTG2_RXFIFO_SIZE / 4) | HPTXFSIZ_PTXFD(STM32_OTG2_NPTXFIFO_SIZE / 4); + otg->HPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG2_RXFIFO_SIZE / 4) + (STM32_OTG2_NPTXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG2_PTXFIFO_SIZE / 4); + } +#endif +#undef HNPTXFSIZ + /* Make sure the FIFOs are flushed. */ otg_txfifo_flush(host, 0x10); otg_rxfifo_flush(host); @@ -1191,9 +1254,23 @@ static inline void _hprtint_int(USBHDriver *host) { host->rootport.lld_status |= USBH_PORTSTATUS_LOW_SPEED; otg->HFIR = 6000; otg->HCFG = (otg->HCFG & ~HCFG_FSLSPCS_MASK) | HCFG_FSLSPCS_6; + + /* Low speed devices connected to the STM32's internal transceiver sometimes + * don't behave correctly. Although HPRT reports a port enable, really + * no traffic is generated, and the core is non-functional. To avoid + * this we won't report the port enable until we are sure that the + * port is working. */ + host->check_ls_activity = TRUE; + otg->GINTMSK |= GINTMSK_SOFM; } else { otg->HFIR = 48000; otg->HCFG = (otg->HCFG & ~HCFG_FSLSPCS_MASK) | HCFG_FSLSPCS_48; + host->check_ls_activity = FALSE; + + /* enable channel and rx interrupts */ + otg->GINTMSK |= GINTMSK_HCM | GINTMSK_RXFLVLM; + host->rootport.lld_status |= USBH_PORTSTATUS_ENABLE; + host->rootport.lld_c_status |= USBH_PORTSTATUS_C_ENABLE; } } else { if (hprt & HPRT_PCSTS) { @@ -1205,13 +1282,8 @@ static inline void _hprtint_int(USBHDriver *host) { } else { uerr("\tHPRT: Port disabled due to disconnect"); } - - _purge_active(host); - _purge_pending(host); - - host->rootport.lld_status &= ~USBH_PORTSTATUS_ENABLE; + _disable(host); } - host->rootport.lld_c_status |= USBH_PORTSTATUS_C_ENABLE; } if (hprt & HPRT_POCCHNG) { @@ -1243,24 +1315,19 @@ static void usb_lld_serve_interrupt(USBHDriver *host) { } /* check mismatch */ - if (gintsts & GINTSTS_MMIS) { - uerr("Mode Mismatch"); - otg->GINTSTS = gintsts; - return; - } + osalDbgAssert((gintsts & GINTSTS_MMIS) == 0, "mode mismatch"); gintsts &= otg->GINTMSK; -#if USBH_DEBUG_ENABLE_WARNINGS if (!gintsts) { +#if USBH_DEBUG_ENABLE_WARNINGS uint32_t a, b; a = otg->GINTSTS; b = otg->GINTMSK; - uwarnf("GINTSTS=%08x, GINTMSK=%08x", a, b); + uwarnf("Masked bits caused an ISR: GINTSTS=%08x, GINTMSK=%08x (unhandled bits=%08x)", a, b, a & ~b); +#endif return; } -#endif - // otg->GINTMSK &= ~(GINTMSK_NPTXFEM | GINTMSK_PTXFEM); otg->GINTSTS = gintsts; if (gintsts & GINTSTS_SOF) @@ -1359,25 +1426,23 @@ static void _init(USBHDriver *host) { #if STM32_USBH_USE_OTG1 #if STM32_USBH_USE_OTG2 - if (&USBHD1 == host) { + if (&USBHD1 == host) #endif + { host->otg = OTG_FS; host->channels_number = STM32_OTG1_CHANNELS_NUMBER; -#if STM32_USBH_USE_OTG2 } #endif -#endif #if STM32_USBH_USE_OTG2 #if STM32_USBH_USE_OTG1 - if (&USBHD2 == host) { + if (&USBHD2 == host) #endif + { host->otg = OTG_HS; host->channels_number = STM32_OTG2_CHANNELS_NUMBER; -#if STM32_USBH_USE_OTG1 } #endif -#endif INIT_LIST_HEAD(&host->ch_free[0]); INIT_LIST_HEAD(&host->ch_free[1]); for (i = 0; i < host->channels_number; i++) { @@ -1411,8 +1476,9 @@ static void _usbh_start(USBHDriver *usbh) { /* Clock activation.*/ #if STM32_USBH_USE_OTG1 #if STM32_USBH_USE_OTG2 - if (&USBHD1 == usbh) { + if (&USBHD1 == usbh) #endif + { /* OTG FS clock enable and reset.*/ rccEnableOTG_FS(FALSE); rccResetOTG_FS(); @@ -1421,15 +1487,14 @@ static void _usbh_start(USBHDriver *usbh) { /* Enables IRQ vector.*/ nvicEnableVector(STM32_OTG1_NUMBER, STM32_USB_OTG1_IRQ_PRIORITY); -#if STM32_USBH_USE_OTG2 } #endif -#endif #if STM32_USBH_USE_OTG2 #if STM32_USBH_USE_OTG1 - if (&USBHD2 == usbh) { + if (&USBHD2 == usbh) #endif + { /* OTG HS clock enable and reset.*/ rccEnableOTG_HS(TRUE); // Enable HS clock when cpu is in sleep mode rccDisableOTG_HSULPI(TRUE); // Disable HS ULPI clock when cpu is in sleep mode @@ -1439,10 +1504,8 @@ static void _usbh_start(USBHDriver *usbh) { /* Enables IRQ vector.*/ nvicEnableVector(STM32_OTG2_NUMBER, STM32_USB_OTG2_IRQ_PRIORITY); -#if STM32_USBH_USE_OTG1 } #endif -#endif otgp->GUSBCFG = GUSBCFG_PHYSEL | GUSBCFG_TRDT(5); @@ -1481,41 +1544,11 @@ static void _usbh_start(USBHDriver *usbh) { otgp->HPRT |= HPRT_PPWR; - /* without this delay, the FIFO sizes are set INcorrectly */ - osalThreadSleepS(MS2ST(200)); - -#define HNPTXFSIZ DIEPTXF0 -#if STM32_USBH_USE_OTG1 -#if STM32_USBH_USE_OTG2 - if (&USBHD1 == usbh) { -#endif - otgp->GRXFSIZ = GRXFSIZ_RXFD(STM32_OTG1_RXFIFO_SIZE / 4); - otgp->HNPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG1_RXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG1_NPTXFIFO_SIZE / 4); - otgp->HPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG1_RXFIFO_SIZE / 4) + (STM32_OTG1_NPTXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG1_PTXFIFO_SIZE / 4); -#if STM32_USBH_USE_OTG2 - } -#endif -#endif -#if STM32_USBH_USE_OTG2 -#if STM32_USBH_USE_OTG1 - if (&USBHD2 == usbh) { -#endif - otgp->GRXFSIZ = GRXFSIZ_RXFD(STM32_OTG2_RXFIFO_SIZE / 4); - otgp->HNPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG2_RXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG2_NPTXFIFO_SIZE / 4); - otgp->HPTXFSIZ = HPTXFSIZ_PTXSA((STM32_OTG2_RXFIFO_SIZE / 4) + (STM32_OTG2_NPTXFIFO_SIZE / 4)) | HPTXFSIZ_PTXFD(STM32_OTG2_PTXFIFO_SIZE / 4); -#if STM32_USBH_USE_OTG1 - } -#endif -#endif -#undef HNPTXFSIZ - otg_txfifo_flush(usbh, 0x10); otg_rxfifo_flush(usbh); otgp->GINTSTS = 0xffffffff; - otgp->GINTMSK = GINTMSK_DISCM /*| GINTMSK_PTXFEM*/ | GINTMSK_HCM | GINTMSK_HPRTM - /*| GINTMSK_IPXFRM | GINTMSK_NPTXFEM*/ | GINTMSK_RXFLVLM - /*| GINTMSK_SOFM */ | GINTMSK_MMISM; + otgp->GINTMSK = GINTMSK_DISCM | GINTMSK_HPRTM | GINTMSK_MMISM; usbh->rootport.lld_status = USBH_PORTSTATUS_POWER; usbh->rootport.lld_c_status = 0; @@ -1580,30 +1613,18 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy break; case USBH_PORT_FEAT_C_OVERCURRENT: - usbh->rootport.lld_c_status &= USBH_PORTSTATUS_C_OVERCURRENT; + usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_OVERCURRENT; break; default: osalDbgAssert(0, "invalid wvalue"); break; } - osalOsRescheduleS(); osalSysUnlock(); break; case GetHubDescriptor: - /*dev_dbg(hsotg->dev, "GetHubDescriptor\n"); - hub_desc = (struct usb_hub_descriptor *)buf; - hub_desc->bDescLength = 9; - hub_desc->bDescriptorType = USB_DT_HUB; - hub_desc->bNbrPorts = 1; - hub_desc->wHubCharacteristics = - cpu_to_le16(HUB_CHAR_COMMON_LPSM | - HUB_CHAR_INDV_PORT_OCPM); - hub_desc->bPwrOn2PwrGood = 1; - hub_desc->bHubContrCurrent = 0; - hub_desc->u.hs.DeviceRemovable[0] = 0; - hub_desc->u.hs.DeviceRemovable[1] = 0xff;*/ + osalDbgAssert(0, "unsupported"); break; case GetHubStatus: @@ -1616,7 +1637,6 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy osalDbgCheck(wlength >= 4); osalSysLock(); *(uint32_t *)buf = usbh->rootport.lld_status | (usbh->rootport.lld_c_status << 16); - osalOsRescheduleS(); osalSysUnlock(); break; @@ -1640,13 +1660,30 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy uint32_t hprt; otg->PCGCCTL = 0; hprt = otg->HPRT; + if (hprt & HPRT_PENA) { + /* This can occur when the OTG core doesn't generate traffic + * despite reporting a successful por enable. */ + uerr("Detected enabled port; resetting OTG core"); + otg->GAHBCFG = 0; + osalThreadSleepS(MS2ST(20)); + _usbh_start(usbh); /* this effectively resets the core */ + osalThreadSleepS(MS2ST(100)); /* during this delay, the core generates connect ISR */ + uinfo("OTG reset ended"); + if (otg->HPRT & HPRT_PCSTS) { + /* if the device is still connected, don't report a C_CONNECTION flag, which would cause + * the upper layer to abort enumeration */ + uinfo("Clear connection change flag"); + usbh->rootport.lld_c_status &= ~USBH_PORTSTATUS_C_CONNECTION; + } + } /* note: writing PENA = 1 actually disables the port */ - hprt &= ~(HPRT_PSUSP | HPRT_PENA | HPRT_PCDET | HPRT_PENCHNG | HPRT_POCCHNG ); + hprt &= ~(HPRT_PSUSP | HPRT_PENA | HPRT_PCDET | HPRT_PENCHNG | HPRT_POCCHNG); + while ((otg->GRSTCTL & GRSTCTL_AHBIDL) == 0); otg->HPRT = hprt | HPRT_PRST; - osalThreadSleepS(MS2ST(60)); + osalThreadSleepS(MS2ST(15)); otg->HPRT = hprt; + osalThreadSleepS(MS2ST(10)); usbh->rootport.lld_c_status |= USBH_PORTSTATUS_C_RESET; - osalOsRescheduleS(); osalSysUnlock(); } break; @@ -1669,16 +1706,7 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy } uint8_t usbh_lld_roothub_get_statuschange_bitmap(USBHDriver *usbh) { - osalSysLock(); - if (usbh->rootport.lld_c_status) { - osalOsRescheduleS(); - osalSysUnlock(); - return 1 << 1; - } - osalOsRescheduleS(); - osalSysUnlock(); - return 0; + return usbh->rootport.lld_c_status ? (1 << 1) : 0; } - #endif diff --git a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h index a2b7628..fd7f4e0 100644 --- a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h +++ b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h @@ -63,6 +63,8 @@ typedef struct stm32_hc_management { #define _usbhdriver_ll_data \ stm32_otg_t *otg; \ + /* low-speed port reset bug */ \ + bool check_ls_activity; \ /* channels */ \ uint8_t channels_number; \ stm32_hc_management_t channels[STM32_OTG2_CHANNELS_NUMBER]; \ diff --git a/os/hal/ports/TIVA/LLD/ADC/driver.mk b/os/hal/ports/TIVA/LLD/ADC/driver.mk new file mode 100644 index 0000000..5a1c80b --- /dev/null +++ b/os/hal/ports/TIVA/LLD/ADC/driver.mk @@ -0,0 +1,9 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),) +PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c +endif +else +PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c +endif + +PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/ADC diff --git a/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c b/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c new file mode 100644 index 0000000..6c1be30 --- /dev/null +++ b/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c @@ -0,0 +1,351 @@ +/* + Copyright (C) 2014..2017 Marco Veeneman + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_adc_lld.c + * @brief PLATFORM ADC subsystem low level driver source. + * + * @addtogroup ADC + * @{ + */ + +#include "hal.h" + +#if (HAL_USE_ADC == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief ADC0 driver identifier.*/ +#if TIVA_ADC_USE_ADC0 || defined(__DOXYGEN__) +ADCDriver ADCD1; +#endif + +/** @brief ADC1 driver identifier.*/ +#if TIVA_ADC_USE_ADC1 || defined(__DOXYGEN__) +ADCDriver ADCD2; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Common IRQ handler. + * + * @param[in] adcp pointer to the @p ADCDriver object + */ +static void serve_interrupt(ADCDriver *adcp) +{ + tiva_udma_table_entry_t *pri = &udmaControlTable.primary[adcp->dmanr]; + tiva_udma_table_entry_t *alt = &udmaControlTable.alternate[adcp->dmanr]; + + if ((pri->chctl & UDMA_CHCTL_XFERMODE_M) == UDMA_CHCTL_XFERMODE_STOP) { + /* Primary is used only for circular transfers */ + if (adcp->grpp->circular) { + if (adcp->depth > 1) { + _adc_isr_half_code(adcp); + } + + /* Reconfigure DMA for new lower half transfer */ + pri->chctl = adcp->prictl; + } + } + + if ((alt->chctl & UDMA_CHCTL_XFERMODE_M) == UDMA_CHCTL_XFERMODE_STOP) { + /* Alternate is used for both linear and circular transfers */ + _adc_isr_full_code(adcp); + + if (adcp->grpp->circular) { + /* Reconfigure DMA for new upper half transfer */ + alt->chctl = adcp->altctl; + } + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if TIVA_ADC_USE_ADC0 +/** + * @brief ADC0 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(TIVA_ADC0_SEQ0_HANDLER) +{ + OSAL_IRQ_PROLOGUE(); + + serve_interrupt(&ADCD1); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if TIVA_ADC_USE_ADC1 +/** + * @brief ADC1 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(TIVA_ADC1_SEQ0_HANDLER) +{ + OSAL_IRQ_PROLOGUE(); + + serve_interrupt(&ADCD2); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level ADC driver initialization. + * + * @notapi + */ +void adc_lld_init(void) +{ +#if TIVA_ADC_USE_ADC0 + /* Driver initialization.*/ + adcObjectInit(&ADCD1); + ADCD1.adc = ADC0_BASE; + ADCD1.dmanr = TIVA_ADC_ADC0_SS0_UDMA_CHANNEL; + ADCD1.chnmap = TIVA_ADC_ADC0_SS0_UDMA_MAPPING; +#endif + +#if TIVA_ADC_USE_ADC1 + /* Driver initialization.*/ + adcObjectInit(&ADCD2); + ADCD2.adc = ADC1_BASE; + ADCD2.dmanr = TIVA_ADC_ADC1_SS0_UDMA_CHANNEL; + ADCD2.chnmap = TIVA_ADC_ADC1_SS0_UDMA_MAPPING; +#endif +} + +/** + * @brief Configures and activates the ADC peripheral. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_start(ADCDriver *adcp) +{ + if (adcp->state == ADC_STOP) { + /* Enables the peripheral.*/ +#if TIVA_ADC_USE_ADC0 + if (&ADCD1 == adcp) { + bool b; + b = udmaChannelAllocate(adcp->dmanr); + osalDbgAssert(!b, "channel already allocated"); + + HWREG(SYSCTL_RCGCADC) |= (1 << 0); + + while (!(HWREG(SYSCTL_PRADC) & (1 << 0))) + ; + + /* Only sequencer 0 is supported */ + nvicEnableVector(TIVA_ADC0_SEQ0_NUMBER, TIVA_ADC0_SEQ0_PRIORITY); + } +#endif + +#if TIVA_ADC_USE_ADC1 + if (&ADCD2 == adcp) { + bool b; + b = udmaChannelAllocate(adcp->dmanr); + osalDbgAssert(!b, "channel already allocated"); + + HWREG(SYSCTL_RCGCADC) |= (1 << 1); + + while (!(HWREG(SYSCTL_PRADC) & (1 << 1))) + ; + + /* Only sequencer 0 is supported */ + nvicEnableVector(TIVA_ADC1_SEQ0_NUMBER, TIVA_ADC1_SEQ0_PRIORITY); + } +#endif + + HWREG(UDMA_CHMAP0 + (adcp->dmanr / 8) * 4) |= (adcp->chnmap << (adcp->dmanr % 8)); + } +} + +/** + * @brief Deactivates the ADC peripheral. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_stop(ADCDriver *adcp) +{ + if (adcp->state == ADC_READY) { + /* Resets the peripheral.*/ + + udmaChannelRelease(adcp->dmanr); + + /* Disables the peripheral.*/ +#if TIVA_ADC_USE_ADC0 + if (&ADCD1 == adcp) { + nvicDisableVector(TIVA_ADC0_SEQ0_NUMBER); + } +#endif + +#if TIVA_ADC_USE_ADC1 + if (&ADCD2 == adcp) { + nvicDisableVector(TIVA_ADC1_SEQ0_NUMBER); + } +#endif + } +} + +/** + * @brief Starts an ADC conversion. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_start_conversion(ADCDriver *adcp) +{ + uint32_t adc = adcp->adc; + tiva_udma_table_entry_t *primary = &udmaControlTable.primary[adcp->dmanr]; + tiva_udma_table_entry_t *alternate = &udmaControlTable.alternate[adcp->dmanr]; + + /* Disable sample sequencer 0 */ + HWREG(adc + ADC_O_ACTSS) &= (1 << 0); + + /* Configure the sample sequencer 0 trigger */ + HWREG(adc + ADC_O_EMUX) = adcp->grpp->emux & 0xff; + + /* If pwm is used as trigger, select in which block the pwm generator is + located */ + if (adcp->grpp->emux >= 6 && adcp->grpp->emux <= 9) { + HWREG(adc + ADC_O_TSSEL) = 0; + } + + /* For each sample in the sample sequencer, select the input source */ + HWREG(adc + ADC_O_SSMUX0) = adcp->grpp->ssmux; + + /* Configure the sample control bits */ + HWREG(adc + ADC_O_SSCTL0) = adcp->grpp->ssctl | 0x44444444; /* Enforce IEn bits */ + + /* Alternate source endpoint is the same for all transfers */ + alternate->srcendp = (void *)(adcp->adc + ADC_O_SSFIFO0); + + /* Configure DMA */ + if ((adcp->grpp->circular) && (adcp->depth > 1)) { + /* Configure DMA in ping-pong mode. + Ping (1st half) is configured in the primary control structure. + Pong (2nd half) is configured in the alternate control structure. */ + + uint32_t ctl; + + /* configure the primary source endpoint */ + primary->srcendp = (void *)(adcp->adc + ADC_O_SSFIFO0); + + /* sample buffer is split in half, the upper half is used here */ + primary->dstendp = (void *)(adcp->samples + + (adcp->grpp->num_channels * adcp->depth / 2) - 1); + /* the lower half is used here */ + alternate->dstendp = (void *)(adcp->samples + + (adcp->grpp->num_channels * adcp->depth) - 1); + + ctl = UDMA_CHCTL_DSTSIZE_32 | UDMA_CHCTL_DSTINC_32 | + UDMA_CHCTL_SRCSIZE_32 | UDMA_CHCTL_SRCINC_NONE | + UDMA_CHCTL_ARBSIZE_1 | + UDMA_CHCTL_XFERSIZE(adcp->grpp->num_channels * adcp->depth / 2) | + UDMA_CHCTL_XFERMODE_PINGPONG; + + adcp->prictl = ctl; + adcp->altctl = ctl; + + dmaChannelPrimary(adcp->dmanr); + } + else { + /* Configure the DMA in basic mode. + This is used for both circular buffers with a depth of 1 and linear + buffers.*/ + alternate->dstendp = (void *)(adcp->samples + + (adcp->grpp->num_channels * adcp->depth) - 1); + adcp->prictl = UDMA_CHCTL_XFERMODE_STOP; + adcp->altctl = UDMA_CHCTL_DSTSIZE_32 | UDMA_CHCTL_DSTINC_32 | + UDMA_CHCTL_SRCSIZE_32 | UDMA_CHCTL_SRCINC_NONE | + UDMA_CHCTL_ARBSIZE_1 | + UDMA_CHCTL_XFERSIZE(adcp->grpp->num_channels * adcp->depth) | + UDMA_CHCTL_XFERMODE_BASIC; + + dmaChannelAlternate(adcp->dmanr); + } + + /* Configure primary and alternate channel control fields */ + primary->chctl = adcp->prictl; + alternate->chctl = adcp->altctl; + + /* Configure DMA channel */ + dmaChannelBurstOnly(adcp->dmanr); + dmaChannelPriorityDefault(adcp->dmanr); + dmaChannelEnableRequest(adcp->dmanr); + + /* Enable DMA channel */ + dmaChannelEnable(adcp->dmanr); + + /* Enable the sample sequencer */ + HWREG(adc + ADC_O_ACTSS) |= (1 << 0); + + /* Enable DMA on the sample sequencer, is this for 129x only?*/ + //HWREG(adc + ADC_O_ACTSS) |= (1 << 8); + + /* Start conversion if configured for CPU trigger */ + if ((adcp->grpp->emux & 0xff) == 0) { + HWREG(adc + ADC_O_PSSI) = ADC_PSSI_SS0; + } +} + +/** + * @brief Stops an ongoing conversion. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_stop_conversion(ADCDriver *adcp) +{ + uint32_t adc = adcp->adc; + + /* Stop ongoing DMA transfer */ + dmaChannelDisable(adcp->dmanr); + + /* Stop ongoing ADC conversion by disabling the active sample sequencer */ + HWREG(adc + ADC_O_ACTSS) &= ~(1 << 0); +} + +#endif /* HAL_USE_ADC == TRUE */ + +/** @} */ diff --git a/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.h b/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.h new file mode 100644 index 0000000..81916b8 --- /dev/null +++ b/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.h @@ -0,0 +1,230 @@ +/* + Copyright (C) 2014..2017 Marco Veeneman + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_adc_lld.h + * @brief PLATFORM ADC subsystem low level driver header. + * + * @addtogroup ADC + * @{ + */ + +#ifndef HAL_ADC_LLD_H +#define HAL_ADC_LLD_H + +#if (HAL_USE_ADC == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name PLATFORM configuration options + * @{ + */ +/** + * @brief ADC1 driver enable switch. + * @details If set to @p TRUE the support for ADC1 is included. + * @note The default is @p FALSE. + */ +#if !defined(PLATFORM_ADC_USE_ADC1) || defined(__DOXYGEN__) +#define PLATFORM_ADC_USE_ADC1 FALSE +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !defined(TIVA_UDMA_REQUIRED) +#define TIVA_UDMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief ADC sample data type. + */ +typedef uint32_t adcsample_t; + +/** + * @brief Channels number in a conversion group. + */ +typedef uint16_t adc_channels_num_t; + +/** + * @brief Possible ADC failure causes. + * @note Error codes are architecture dependent and should not relied + * upon. + */ +typedef enum { + ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */ + ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */ + ADC_ERR_AWD = 2 /**< Analog watchdog triggered. */ +} adcerror_t; + +/** + * @brief Type of a structure representing an ADC driver. + */ +typedef struct ADCDriver ADCDriver; + +/** + * @brief ADC notification callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + * @param[in] buffer pointer to the most recent samples data + * @param[in] n number of buffer rows available starting from @p buffer + */ +typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n); + +/** + * @brief ADC error callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + * @param[in] err ADC error code + */ +typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err); + +/** + * @brief Conversion group configuration structure. + * @details This implementation-dependent structure describes a conversion + * operation. + * @note The use of this configuration structure requires knowledge of + * PLATFORM ADC cell registers interface, please refer to the PLATFORM + * reference manual for details. + */ +typedef struct { + /** + * @brief Enables the circular buffer mode for the group. + */ + bool circular; + /** + * @brief Number of the analog channels belonging to the conversion group. + */ + adc_channels_num_t num_channels; + /** + * @brief Callback function associated to the group or @p NULL. + */ + adccallback_t end_cb; + /** + * @brief Error callback or @p NULL. + */ + adcerrorcallback_t error_cb; + /* End of the mandatory fields.*/ + uint32_t emux; + uint32_t ssmux; + uint32_t ssctl; +} ADCConversionGroup; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + uint32_t dummy; +} ADCConfig; + +/** + * @brief Structure representing an ADC driver. + */ +struct ADCDriver { + /** + * @brief Driver state. + */ + adcstate_t state; + /** + * @brief Current configuration data. + */ + const ADCConfig *config; + /** + * @brief Current samples buffer pointer or @p NULL. + */ + adcsample_t *samples; + /** + * @brief Current samples buffer depth or @p 0. + */ + size_t depth; + /** + * @brief Current conversion group pointer or @p NULL. + */ + const ADCConversionGroup *grpp; +#if (ADC_USE_WAIT == TRUE) || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + thread_reference_t thread; +#endif +#if (ADC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the peripheral. + */ + mutex_t mutex; +#endif +#if defined(ADC_DRIVER_EXT_FIELDS) + ADC_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the ADC registers block. + */ + uint32_t adc; + uint8_t dmanr; + uint8_t chnmap; + uint32_t prictl; + uint32_t altctl; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if TIVA_ADC_USE_ADC0 && !defined(__DOXYGEN__) +extern ADCDriver ADCD1; +#endif + +#if TIVA_ADC_USE_ADC1 && !defined(__DOXYGEN__) +extern ADCDriver ADCD2; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void adc_lld_init(void); + void adc_lld_start(ADCDriver *adcp); + void adc_lld_stop(ADCDriver *adcp); + void adc_lld_start_conversion(ADCDriver *adcp); + void adc_lld_stop_conversion(ADCDriver *adcp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_ADC == TRUE */ + +#endif /* HAL_ADC_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c index 98defed..126959f 100644 --- a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c +++ b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c @@ -359,6 +359,7 @@ void spi_lld_stop(SPIDriver *spip) } } +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) /** * @brief Asserts the slave select signal and prepares for transfers. * @@ -368,7 +369,7 @@ void spi_lld_stop(SPIDriver *spip) */ void spi_lld_select(SPIDriver *spip) { - palClearPad(spip->config->ssport, spip->config->sspad); + /* No implementation on Tiva.*/ } /** @@ -381,8 +382,9 @@ void spi_lld_select(SPIDriver *spip) */ void spi_lld_unselect(SPIDriver *spip) { - palSetPad(spip->config->ssport, spip->config->sspad); + /* No implementation on Tiva.*/ } +#endif /** * @brief Ignores data on the SPI bus. diff --git a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h index 64560eb..4dcf6db 100644 --- a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h +++ b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h @@ -165,6 +165,10 @@ #define TIVA_UDMA_REQUIRED #endif +#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD +#error "SPI_SELECT_MODE_LLD not supported by this driver" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -189,16 +193,34 @@ typedef struct { /** * @brief Operation complete callback or @p NULL. */ - spicallback_t end_cb; - /* End of the mandatory fields.*/ + spicallback_t end_cb; +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LINE) || defined(__DOXYGEN__) + /** + * @brief The chip select line. + */ + ioline_t ssline; +#endif +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PORT) || defined(__DOXYGEN__) + /** + * @brief The chip select port. + */ + ioportid_t ssport; /** - * @brief The chip select line port. + * @brief The chip select port mask. */ - ioportid_t ssport; + uint8fast_t ssmask; +#endif +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PAD) || defined(__DOXYGEN__) /** - * @brief The chip select line pad number. + * @brief The chip select port. */ - uint16_t sspad; + ioportid_t ssport; + /** + * @brief The chip select pad number. + */ + uint_fast8_t sspad; +#endif + /* End of the mandatory fields.*/ /** * @brief SSI CR0 initialization data. */ @@ -289,8 +311,10 @@ extern "C" { void spi_lld_init(void); void spi_lld_start(SPIDriver *spip); void spi_lld_stop(SPIDriver *spip); +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) void spi_lld_select(SPIDriver *spip); void spi_lld_unselect(SPIDriver *spip); +#endif void spi_lld_ignore(SPIDriver *spip, size_t n); void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf); diff --git a/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.h b/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.h index cf90399..a473f6c 100644 --- a/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.h +++ b/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.h @@ -32,7 +32,7 @@ /** * @brief CHCTL XFERSIZE helper. */ -#define UDMA_CHCTL_XFERSIZE(n) ((n-1) << 4) +#define UDMA_CHCTL_XFERSIZE(n) (((n)-1) << 4) /*===========================================================================*/ /* Driver pre-compile time settings. */ diff --git a/os/hal/ports/TIVA/TM4C123x/platform.mk b/os/hal/ports/TIVA/TM4C123x/platform.mk index 2544696..de482d0 100644 --- a/os/hal/ports/TIVA/TM4C123x/platform.mk +++ b/os/hal/ports/TIVA/TM4C123x/platform.mk @@ -11,6 +11,7 @@ HALCONF := $(strip $(shell cat halconf.h | egrep -e "\#define")) endif # Drivers compatible with the platform. +include $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/ADC/driver.mk include $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/GPIO/driver.mk include $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/GPTM/driver.mk include $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/I2C/driver.mk diff --git a/os/hal/ports/TIVA/TM4C129x/platform.mk b/os/hal/ports/TIVA/TM4C129x/platform.mk index fb2dc4a..8e4c9fa 100644 --- a/os/hal/ports/TIVA/TM4C129x/platform.mk +++ b/os/hal/ports/TIVA/TM4C129x/platform.mk @@ -11,6 +11,7 @@ HALCONF := $(strip $(shell cat halconf.h | egrep -e "\#define")) endif # Drivers compatible with the platform. +include $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/ADC/driver.mk include $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/GPIO/driver.mk include $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/GPTM/driver.mk include $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/I2C/driver.mk diff --git a/os/hal/src/hal_usb_msd.c b/os/hal/src/hal_usb_msd.c index 6cc5386..564bad0 100644 --- a/os/hal/src/hal_usb_msd.c +++ b/os/hal/src/hal_usb_msd.c @@ -84,6 +84,19 @@ static const scsi_inquiry_response_t default_scsi_inquiry_response = { {'v',CH_KERNEL_MAJOR+'0','.',CH_KERNEL_MINOR+'0'} }; +/** + * @brief Hardcoded default SCSI unit serial number inquiry response structure. + */ +static const scsi_unit_serial_number_inquiry_response_t default_scsi_unit_serial_number_inquiry_response = +{ + 0x00, + 0x80, + 0x00, + 0x08, + "00000000" +}; + + /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ @@ -373,7 +386,8 @@ void msdStop(USBMassStorageDriver *msdp) { */ void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp, BaseBlockDevice *blkdev, uint8_t *blkbuf, - const scsi_inquiry_response_t *inquiry) { + const scsi_inquiry_response_t *inquiry, + const scsi_unit_serial_number_inquiry_response_t *serialInquiry) { osalDbgCheck((msdp != NULL) && (usbp != NULL) && (blkdev != NULL) && (blkbuf != NULL)); @@ -393,6 +407,12 @@ void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp, else { msdp->scsi_config.inquiry_response = inquiry; } + if (NULL == serialInquiry) { + msdp->scsi_config.unit_serial_number_inquiry_response = &default_scsi_unit_serial_number_inquiry_response; + } + else { + msdp->scsi_config.unit_serial_number_inquiry_response = serialInquiry; + } msdp->scsi_config.blkbuf = blkbuf; msdp->scsi_config.blkdev = blkdev; msdp->scsi_config.transport = &msdp->scsi_transport; diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index d242086..7dff98a 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -20,15 +20,8 @@ #if HAL_USE_USBH #include "usbh/internal.h" -#include <string.h> - -//devices #include "usbh/dev/hub.h" -#include "usbh/dev/aoa.h" -#include "usbh/dev/ftdi.h" -#include "usbh/dev/msd.h" -#include "usbh/dev/hid.h" -#include "usbh/dev/uvc.h" +#include <string.h> #if USBH_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) @@ -62,18 +55,15 @@ #define uerr(f, ...) do {} while(0) #endif -#if STM32_USBH_USE_OTG1 -USBHDriver USBHD1; -#endif -#if STM32_USBH_USE_OTG2 -USBHDriver USBHD2; -#endif - - static void _classdriver_process_device(usbh_device_t *dev); -static bool _classdriver_load(usbh_device_t *dev, uint8_t class, - uint8_t subclass, uint8_t protocol, uint8_t *descbuff, uint16_t rem); +static bool _classdriver_load(usbh_device_t *dev, uint8_t *descbuff, uint16_t rem); +#if HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS +#include "usbh_additional_class_drivers.h" +#ifndef HAL_USBH_ADDITIONAL_CLASS_DRIVERS +#error "Must define HAL_USBH_ADDITIONAL_CLASS_DRIVERS" +#endif +#endif /*===========================================================================*/ /* Checks. */ @@ -113,28 +103,6 @@ void usbhObjectInit(USBHDriver *usbh) { #endif } -void usbhInit(void) { -#if HAL_USBH_USE_FTDI - usbhftdiInit(); -#endif -#if HAL_USBH_USE_AOA - usbhaoaInit(); -#endif -#if HAL_USBH_USE_MSD - usbhmsdInit(); -#endif -#if HAL_USBH_USE_HID - usbhhidInit(); -#endif -#if HAL_USBH_USE_UVC - usbhuvcInit(); -#endif -#if HAL_USBH_USE_HUB - usbhhubInit(); -#endif - usbh_lld_init(); -} - void usbhStart(USBHDriver *usbh) { usbDbgInit(usbh); @@ -143,7 +111,6 @@ void usbhStart(USBHDriver *usbh) { "invalid state"); usbh_lld_start(usbh); usbh->status = USBH_STATUS_STARTED; - osalOsRescheduleS(); osalSysUnlock(); } @@ -256,6 +223,7 @@ void usbhURBObjectResetI(usbh_urb_t *urb) { usbh_lld_urb_object_reset(urb); } +/* usbhURBSubmitI may require a reschedule if called from a S-locked state */ void usbhURBSubmitI(usbh_urb_t *urb) { osalDbgCheckClassI(); _check_urb(urb); @@ -265,11 +233,8 @@ void usbhURBSubmitI(usbh_urb_t *urb) { _usbh_urb_completeI(urb, USBH_URBSTATUS_STALL); return; } - if (ep->status != USBH_EPSTATUS_OPEN) { - _usbh_urb_completeI(urb, USBH_URBSTATUS_DISCONNECTED); - return; - } - if (!(usbhDeviceGetPort(ep->device)->status & USBH_PORTSTATUS_ENABLE)) { + if ((ep->status != USBH_EPSTATUS_OPEN) + || !(usbhDeviceGetPort(ep->device)->status & USBH_PORTSTATUS_ENABLE)) { _usbh_urb_completeI(urb, USBH_URBSTATUS_DISCONNECTED); return; } @@ -277,27 +242,21 @@ void usbhURBSubmitI(usbh_urb_t *urb) { usbh_lld_urb_submit(urb); } +/* _usbh_urb_abortI may require a reschedule if called from a S-locked state */ bool _usbh_urb_abortI(usbh_urb_t *urb, usbh_urbstatus_t status) { osalDbgCheckClassI(); _check_urb(urb); + osalDbgCheck(urb->status != USBH_URBSTATUS_UNINITIALIZED); - switch (urb->status) { -/* case USBH_URBSTATUS_UNINITIALIZED: - * case USBH_URBSTATUS_INITIALIZED: - * case USBH_URBSTATUS_ERROR: - * case USBH_URBSTATUS_TIMEOUT: - * case USBH_URBSTATUS_CANCELLED: - * case USBH_URBSTATUS_STALL: - * case USBH_URBSTATUS_DISCONNECTED: - * case USBH_URBSTATUS_OK: */ - default: - /* already finished */ - _usbh_urb_completeI(urb, status); - return TRUE; - - case USBH_URBSTATUS_PENDING: + if (urb->status == USBH_URBSTATUS_PENDING) { return usbh_lld_urb_abort(urb, status); } + + /* already finished or never submitted: + * USBH_URBSTATUS_INITIALIZED, USBH_URBSTATUS_ERROR, USBH_URBSTATUS_TIMEOUT, + * USBH_URBSTATUS_CANCELLED, USBH_URBSTATUS_STALL, USBH_URBSTATUS_DISCONNECTED + * USBH_URBSTATUS_OK */ + return TRUE; } void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) { @@ -309,18 +268,14 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) { osalThreadSuspendS(&urb->abortingThread); osalDbgAssert(urb->abortingThread == 0, "maybe we should uncomment the line below"); //urb->abortingThread = 0; - } -#if !(USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_WARNINGS) - else { + } else { + /* This call is necessary because _usbh_urb_abortI may require a reschedule */ osalOsRescheduleS(); } -#else uwarn("URB aborted"); - osalOsRescheduleS(); /* debug printing functions call I-class functions inside - which may cause a priority violation without this call */ -#endif } +/* usbhURBCancelI may require a reschedule if called from a S-locked state */ bool usbhURBCancelI(usbh_urb_t *urb) { return _usbh_urb_abortI(urb, USBH_URBSTATUS_CANCELLED); } @@ -330,36 +285,14 @@ void usbhURBCancelAndWaitS(usbh_urb_t *urb) { } msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout) { - msg_t ret; - osalDbgCheckClassS(); _check_urb(urb); - - switch (urb->status) { - case USBH_URBSTATUS_INITIALIZED: - case USBH_URBSTATUS_PENDING: - ret = osalThreadSuspendTimeoutS(&urb->waitingThread, timeout); - osalDbgAssert(urb->waitingThread == 0, "maybe we should uncomment the line below"); - //urb->waitingThread = 0; - break; - - case USBH_URBSTATUS_OK: - ret = MSG_OK; - osalOsRescheduleS(); - break; - -/* case USBH_URBSTATUS_UNINITIALIZED: - * case USBH_URBSTATUS_ERROR: - * case USBH_URBSTATUS_TIMEOUT: - * case USBH_URBSTATUS_CANCELLED: - * case USBH_URBSTATUS_STALL: - * case USBH_URBSTATUS_DISCONNECTED: */ - default: - ret = MSG_RESET; - osalOsRescheduleS(); - break; + if (urb->status == USBH_URBSTATUS_OK) { + return MSG_OK; + } else if (urb->status != USBH_URBSTATUS_PENDING) { + return MSG_RESET; } - return ret; + return osalThreadSuspendTimeoutS(&urb->waitingThread, timeout); } msg_t usbhURBSubmitAndWaitS(usbh_urb_t *urb, systime_t timeout) { @@ -382,6 +315,7 @@ static inline msg_t _wakeup_message(usbh_urbstatus_t status) { return MSG_RESET; } +/* _usbh_urb_completeI may require a reschedule if called from a S-locked state */ void _usbh_urb_completeI(usbh_urb_t *urb, usbh_urbstatus_t status) { osalDbgCheckClassI(); _check_urb(urb); @@ -459,7 +393,7 @@ usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev, wIndex, wLength }; - return usbhControlRequestExtended(dev, &req, buff, NULL, MS2ST(1000)); + return usbhControlRequestExtended(dev, &req, buff, NULL, HAL_USBH_CONTROL_REQUEST_DEFAULT_TIMEOUT); } /*===========================================================================*/ @@ -880,9 +814,6 @@ bool usbhDeviceReadString(usbh_device_t *dev, char *dest, uint8_t size, return HAL_SUCCESS; } - - - /*===========================================================================*/ /* Port processing functions. */ /*===========================================================================*/ @@ -925,46 +856,48 @@ static void _port_process_status_change(usbh_port_t *port) { _port_update_status(port); if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) { - /* port connected status changed */ port->c_status &= ~USBH_PORTSTATUS_C_CONNECTION; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_CONNECTION); - if ((port->status & (USBH_PORTSTATUS_CONNECTION | USBH_PORTSTATUS_ENABLE)) - == USBH_PORTSTATUS_CONNECTION) { - if (port->device.status != USBH_DEVSTATUS_DISCONNECTED) { + + if (port->device.status != USBH_DEVSTATUS_DISCONNECTED) { + if (!(port->status & USBH_PORTSTATUS_CONNECTION)) { _usbh_port_disconnected(port); } + } + } - /* connected, disabled */ + if (port->device.status == USBH_DEVSTATUS_DISCONNECTED) { + if (port->status & USBH_PORTSTATUS_CONNECTION) { _port_connected(port); - } else { - /* disconnected */ - _usbh_port_disconnected(port); } } if (port->c_status & USBH_PORTSTATUS_C_RESET) { port->c_status &= ~USBH_PORTSTATUS_C_RESET; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_RESET); + udbgf("Port %d: reset=%d", port->number, port->status & USBH_PORTSTATUS_RESET ? 1 : 0); } if (port->c_status & USBH_PORTSTATUS_C_ENABLE) { port->c_status &= ~USBH_PORTSTATUS_C_ENABLE; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_ENABLE); + udbgf("Port %d: enable=%d", port->number, port->status & USBH_PORTSTATUS_ENABLE ? 1 : 0); } if (port->c_status & USBH_PORTSTATUS_C_OVERCURRENT) { port->c_status &= ~USBH_PORTSTATUS_C_OVERCURRENT; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_OVERCURRENT); + uwarnf("Port %d: overcurrent=%d", port->number, port->status & USBH_PORTSTATUS_OVERCURRENT ? 1 : 0); } if (port->c_status & USBH_PORTSTATUS_C_SUSPEND) { port->c_status &= ~USBH_PORTSTATUS_C_SUSPEND; usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_SUSPEND); + uinfof("Port %d: suspend=%d", port->number, port->status & USBH_PORTSTATUS_SUSPEND ? 1 : 0); } } - static void _port_connected(usbh_port_t *port) { /* connected */ @@ -974,9 +907,8 @@ static void _port_connected(usbh_port_t *port) { usbh_devspeed_t speed; USBH_DEFINE_BUFFER(usbh_string_descriptor_t strdesc); - uinfof("Port %d connected, wait debounce...", port->number); - port->device.status = USBH_DEVSTATUS_ATTACHED; + uinfof("Port %d: attached, wait debounce...", port->number); /* wait for attach de-bounce */ osalThreadSleepMilliseconds(HAL_USBH_PORT_DEBOUNCE_TIME); @@ -984,16 +916,26 @@ static void _port_connected(usbh_port_t *port) { /* check disconnection */ _port_update_status(port); if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) { - /* connection state changed; abort */ + port->c_status &= ~USBH_PORTSTATUS_C_CONNECTION; + usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_CONNECTION); + uwarnf("Port %d: connection state changed; abort #1", port->number); goto abort; } + /* make sure that the device is still connected */ + if ((port->status & USBH_PORTSTATUS_CONNECTION) == 0) { + uwarnf("Port %d: device is disconnected", port->number); + goto abort; + } + + uinfof("Port %d: connected", port->number); port->device.status = USBH_DEVSTATUS_CONNECTED; retries = 3; reset: for (i = 0; i < 3; i++) { - uinfo("Try reset..."); + uinfof("Port %d: Try reset...", port->number); + /* TODO: check that port is actually disabled */ port->c_status &= ~(USBH_PORTSTATUS_C_RESET | USBH_PORTSTATUS_C_ENABLE); _port_reset(port); osalThreadSleepMilliseconds(20); /* give it some time to reset (min. 10ms) */ @@ -1002,8 +944,12 @@ reset: _port_update_status(port); /* check for disconnection */ - if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) + if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) { + port->c_status &= ~USBH_PORTSTATUS_C_CONNECTION; + usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_CONNECTION); + uwarnf("Port %d: connection state changed; abort #2", port->number); goto abort; + } /* check for reset completion */ if (port->c_status & USBH_PORTSTATUS_C_RESET) { @@ -1017,7 +963,10 @@ reset: } /* check for timeout */ - if (osalOsGetSystemTimeX() - start > HAL_USBH_PORT_RESET_TIMEOUT) break; + if (osalOsGetSystemTimeX() - start > HAL_USBH_PORT_RESET_TIMEOUT) { + uwarnf("Port %d: reset timeout", port->number); + break; + } } } @@ -1025,8 +974,7 @@ reset: goto abort; reset_success: - - uinfo("Reset OK, recovery..."); + uinfof("Port %d: Reset OK, recovery...", port->number); /* reset recovery */ osalThreadSleepMilliseconds(100); @@ -1043,19 +991,22 @@ reset_success: usbhEPOpen(&port->device.ctrl); /* device with default address (0), try enumeration */ - if (_device_enumerate(&port->device)) { + if (_device_enumerate(&port->device) != HAL_SUCCESS) { /* enumeration failed */ usbhEPClose(&port->device.ctrl); - if (!--retries) + if (!--retries) { + uwarnf("Port %d: enumeration failed; abort", port->number); goto abort; + } /* retry reset & enumeration */ + uwarnf("Port %d: enumeration failed; retry reset & enumeration", port->number); goto reset; } /* load the default language ID */ - uinfo("Loading langID0..."); + uinfof("Port %d: Loading langID0...", port->number); if (!usbhStdReqGetStringDescriptor(&port->device, 0, 0, USBH_DT_STRING_SIZE, (uint8_t *)&strdesc) && (strdesc.bLength >= 4) @@ -1063,12 +1014,12 @@ reset_success: 4, (uint8_t *)&strdesc)) { port->device.langID0 = strdesc.wData[0]; - uinfof("langID0=%04x", port->device.langID0); + uinfof("Port %d: langID0=%04x", port->number, port->device.langID0); } /* check if the device has only one configuration */ if (port->device.devDesc.bNumConfigurations == 1) { - uinfo("Device has only one configuration"); + uinfof("Port %d: device has only one configuration", port->number); _device_configure(&port->device, 0); } @@ -1076,7 +1027,7 @@ reset_success: return; abort: - uerr("Abort"); + uerrf("Port %d: abort", port->number); port->device.status = USBH_DEVSTATUS_DISCONNECTED; } @@ -1084,14 +1035,14 @@ void _usbh_port_disconnected(usbh_port_t *port) { if (port->device.status == USBH_DEVSTATUS_DISCONNECTED) return; - uinfo("Port disconnected"); + uinfof("Port %d: disconnected", port->number); /* unload drivers */ while (port->device.drivers) { usbh_baseclassdriver_t *drv = port->device.drivers; /* unload */ - uinfof("Unload driver %s", drv->info->name); + uinfof("Port %d: unload driver %s", port->number, drv->info->name); drv->info->vmt->unload(drv); /* unlink */ @@ -1100,9 +1051,7 @@ void _usbh_port_disconnected(usbh_port_t *port) { } /* close control endpoint */ - osalSysLock(); - usbhEPCloseS(&port->device.ctrl); - osalSysUnlock(); + usbhEPClose(&port->device.ctrl); /* free address */ if (port->device.address) @@ -1114,7 +1063,6 @@ void _usbh_port_disconnected(usbh_port_t *port) { } - /*===========================================================================*/ /* Hub processing functions. */ /*===========================================================================*/ @@ -1142,7 +1090,7 @@ static void _hub_process_status_change(USBHDriver *host, USBHHubDriver *hub) { uinfo("Hub status change. GET_STATUS."); _hub_update_status(host, hub); - if (hub->c_status & USBH_HUBSTATUS_C_HUB_LOCAL_POWER) { + if (hub->c_status & USBH_HUBSTATUS_C_HUB_LOCAL_POWER) { hub->c_status &= ~USBH_HUBSTATUS_C_HUB_LOCAL_POWER; uinfo("Clear USBH_HUB_FEAT_C_HUB_LOCAL_POWER"); usbhhubClearFeatureHub(host, hub, USBH_HUB_FEAT_C_HUB_LOCAL_POWER); @@ -1160,7 +1108,6 @@ static uint32_t _hub_get_status_change_bitmap(USBHDriver *host, USBHHubDriver *h osalSysLock(); uint32_t ret = hub->statuschange; hub->statuschange = 0; - osalOsRescheduleS(); osalSysUnlock(); return ret; } @@ -1226,8 +1173,8 @@ void usbhMainLoop(USBHDriver *usbh) { _hub_process(usbh, NULL); /* process connected hubs */ - USBHHubDriver *hub; - list_for_each_entry(hub, USBHHubDriver, &usbh->hubs, node) { + USBHHubDriver *hub, *temp; + list_for_each_entry_safe(hub, USBHHubDriver, temp, &usbh->hubs, node) { _hub_process(usbh, hub); } #else @@ -1236,75 +1183,78 @@ void usbhMainLoop(USBHDriver *usbh) { #endif } - /*===========================================================================*/ -/* IAD class driver. */ +/* Class driver loader. */ /*===========================================================================*/ -#if HAL_USBH_USE_IAD -static usbh_baseclassdriver_t *iad_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); -static void iad_unload(usbh_baseclassdriver_t *drv); -static const usbh_classdriver_vmt_t usbhiadClassDriverVMT = { - iad_load, - iad_unload -}; -static const usbh_classdriverinfo_t usbhiadClassDriverInfo = { - 0xef, 0x02, 0x01, "IAD", &usbhiadClassDriverVMT -}; -static usbh_baseclassdriver_t *iad_load(usbh_device_t *dev, - const uint8_t *descriptor, uint16_t rem) { - (void)rem; +bool _usbh_match_vid_pid(usbh_device_t *dev, int32_t vid, int32_t pid) { + if (((vid < 0) || (dev->devDesc.idVendor == vid)) + && ((pid < 0) || (dev->devDesc.idProduct == pid))) + return HAL_SUCCESS; - if (descriptor[1] != USBH_DT_DEVICE) - return 0; + return HAL_FAILED; +} - uinfo("Load a driver for each IF collection."); +bool _usbh_match_descriptor(const uint8_t *descriptor, uint16_t rem, + int16_t type, int16_t _class, int16_t subclass, int16_t protocol) { - generic_iterator_t icfg; - if_iterator_t iif; - const usbh_ia_descriptor_t *last_iad = 0; + int16_t dclass, dsubclass, dprotocol; - cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, - dev->basicConfigDesc.wTotalLength); - if (!icfg.valid) { - uerr("Invalid configuration descriptor."); - return 0; - } + if ((rem < descriptor[0]) || (rem < 2)) + return HAL_FAILED; - for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { - if (iif.iad && (iif.iad != last_iad)) { - last_iad = iif.iad; - if (_classdriver_load(dev, iif.iad->bFunctionClass, - iif.iad->bFunctionSubClass, - iif.iad->bFunctionProtocol, - (uint8_t *)iif.iad, - (uint8_t *)iif.curr - (uint8_t *)iif.iad + iif.rem) != HAL_SUCCESS) { - uwarnf("No drivers found for IF collection #%d:%d", - iif.iad->bFirstInterface, - iif.iad->bFirstInterface + iif.iad->bInterfaceCount - 1); - } - } - } + uint8_t dtype = descriptor[1]; - return 0; -} + if ((type >= 0) && (type != dtype)) + return HAL_FAILED; -static void iad_unload(usbh_baseclassdriver_t *drv) { - (void)drv; -} -#endif + switch (dtype) { + case USBH_DT_DEVICE: { + if (rem < USBH_DT_DEVICE_SIZE) + return HAL_FAILED; + const usbh_device_descriptor_t *const desc = (const usbh_device_descriptor_t *)descriptor; + dclass = desc->bDeviceClass; + dsubclass = desc->bDeviceSubClass; + dprotocol = desc->bDeviceProtocol; + } break; + case USBH_DT_INTERFACE: { + if (rem < USBH_DT_INTERFACE_SIZE) + return HAL_FAILED; + const usbh_interface_descriptor_t *const desc = (const usbh_interface_descriptor_t *)descriptor; + dclass = desc->bInterfaceClass; + dsubclass = desc->bInterfaceSubClass; + dprotocol = desc->bInterfaceProtocol; + } break; + case USBH_DT_INTERFACE_ASSOCIATION: { + if (rem < USBH_DT_INTERFACE_ASSOCIATION_SIZE) + return HAL_FAILED; + const usbh_ia_descriptor_t *const desc = (const usbh_ia_descriptor_t *)descriptor; + dclass = desc->bFunctionClass; + dsubclass = desc->bFunctionSubClass; + dprotocol = desc->bFunctionProtocol; + } break; + default: + return HAL_FAILED; + } + if (((_class < 0) || (_class == dclass)) + && ((subclass < 0) || (subclass == dsubclass)) + && ((protocol < 0) || (protocol == dprotocol))) + return HAL_SUCCESS; -/*===========================================================================*/ -/* Class driver loader. */ -/*===========================================================================*/ + return HAL_FAILED; +} static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { +#if HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS + /* user-defined out of tree class drivers */ + HAL_USBH_ADDITIONAL_CLASS_DRIVERS +#endif #if HAL_USBH_USE_FTDI &usbhftdiClassDriverInfo, #endif -#if HAL_USBH_USE_IAD - &usbhiadClassDriverInfo, +#if HAL_USBH_USE_HUB + &usbhhubClassDriverInfo, #endif #if HAL_USBH_USE_UVC &usbhuvcClassDriverInfo, @@ -1318,44 +1268,24 @@ static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { #if HAL_USBH_USE_UVC &usbhuvcClassDriverInfo, #endif -#if HAL_USBH_USE_HUB - &usbhhubClassDriverInfo, -#endif #if HAL_USBH_USE_AOA &usbhaoaClassDriverInfo, /* Leave always last */ #endif }; -static bool _classdriver_load(usbh_device_t *dev, uint8_t class, - uint8_t subclass, uint8_t protocol, uint8_t *descbuff, uint16_t rem) { +static bool _classdriver_load(usbh_device_t *dev, uint8_t *descbuff, uint16_t rem) { uint8_t i; usbh_baseclassdriver_t *drv = NULL; for (i = 0; i < sizeof_array(usbh_classdrivers_lookup); i++) { const usbh_classdriverinfo_t *const info = usbh_classdrivers_lookup[i]; - if (class == 0xff) { - /* vendor specific */ - if (info->class == 0xff) { - uinfof("Try load vendor-specific driver %s", info->name); - drv = info->vmt->load(dev, descbuff, rem); - if (drv != NULL) - goto success; - } - } else if ((info->class < 0) || ((info->class == class) - && ((info->subclass < 0) || ((info->subclass == subclass) - && ((info->protocol < 0) || (info->protocol == protocol)))))) { - uinfof("Try load driver %s", info->name); - drv = info->vmt->load(dev, descbuff, rem); -#if HAL_USBH_USE_IAD - /* special case: */ - if (info == &usbhiadClassDriverInfo) - goto success; //return HAL_SUCCESS; -#endif + uinfof("Try load driver %s", info->name); + drv = info->vmt->load(dev, descbuff, rem); - if (drv != NULL) - goto success; - } + if (drv != NULL) + goto success; } + return HAL_FAILED; success: @@ -1396,13 +1326,16 @@ static void _classdriver_process_device(usbh_device_t *dev) { usbhDevicePrintConfiguration(dev->fullConfigurationDescriptor, dev->basicConfigDesc.wTotalLength); - if (devdesc->bDeviceClass == 0) { - /* each interface defines its own device class/subclass/protocol */ - uinfo("Load a driver for each IF."); +#if HAL_USBH_USE_IAD + if (dev->devDesc.bDeviceClass == 0xef + && dev->devDesc.bDeviceSubClass == 0x02 + && dev->devDesc.bDeviceProtocol == 0x01) { + + uinfo("Load a driver for each IF collection."); generic_iterator_t icfg; if_iterator_t iif; - uint8_t last_if = 0xff; + const usbh_ia_descriptor_t *last_iad = 0; cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, dev->basicConfigDesc.wTotalLength); @@ -1412,24 +1345,49 @@ static void _classdriver_process_device(usbh_device_t *dev) { } for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { - const usbh_interface_descriptor_t *const ifdesc = if_get(&iif); - if (ifdesc->bInterfaceNumber != last_if) { - last_if = ifdesc->bInterfaceNumber; - if (_classdriver_load(dev, ifdesc->bInterfaceClass, - ifdesc->bInterfaceSubClass, - ifdesc->bInterfaceProtocol, - (uint8_t *)ifdesc, iif.rem) != HAL_SUCCESS) { - uwarnf("No drivers found for IF #%d", ifdesc->bInterfaceNumber); + if (iif.iad && (iif.iad != last_iad)) { + last_iad = iif.iad; + if (_classdriver_load(dev, + (uint8_t *)iif.iad, + (uint8_t *)iif.curr - (uint8_t *)iif.iad + iif.rem) != HAL_SUCCESS) { + uwarnf("No drivers found for IF collection #%d:%d", + iif.iad->bFirstInterface, + iif.iad->bFirstInterface + iif.iad->bInterfaceCount - 1); } } } - } else { - if (_classdriver_load(dev, devdesc->bDeviceClass, - devdesc->bDeviceSubClass, - devdesc->bDeviceProtocol, - (uint8_t *)devdesc, USBH_DT_DEVICE_SIZE) != HAL_SUCCESS) { - uwarn("No drivers found."); + } else +#endif + if (_classdriver_load(dev, (uint8_t *)devdesc, USBH_DT_DEVICE_SIZE) != HAL_SUCCESS) { + uinfo("No drivers found for device."); + + if (devdesc->bDeviceClass == 0) { + /* each interface defines its own device class/subclass/protocol */ + uinfo("Try load a driver for each IF."); + + generic_iterator_t icfg; + if_iterator_t iif; + uint8_t last_if = 0xff; + + cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, + dev->basicConfigDesc.wTotalLength); + if (!icfg.valid) { + uerr("Invalid configuration descriptor."); + goto exit; + } + + for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { + const usbh_interface_descriptor_t *const ifdesc = if_get(&iif); + if (ifdesc->bInterfaceNumber != last_if) { + last_if = ifdesc->bInterfaceNumber; + if (_classdriver_load(dev, (uint8_t *)ifdesc, iif.rem) != HAL_SUCCESS) { + uwarnf("No drivers found for IF #%d", ifdesc->bInterfaceNumber); + } + } + } + } else { + uwarn("Unable to load driver."); } } @@ -1439,6 +1397,15 @@ exit: } } +void usbhInit(void) { + uint8_t i; + for (i = 0; i < sizeof_array(usbh_classdrivers_lookup); i++) { + if (usbh_classdrivers_lookup[i]->vmt->init) { + usbh_classdrivers_lookup[i]->vmt->init(); + } + } + usbh_lld_init(); +} #endif diff --git a/os/hal/src/usbh/TODO.txt b/os/hal/src/usbh/TODO.txt new file mode 100644 index 0000000..87269be --- /dev/null +++ b/os/hal/src/usbh/TODO.txt @@ -0,0 +1,21 @@ +In decreasing order of priority: + +Bugs: +- Synchronization on driver unload between usbhMainLoop and driver APIs + - MSD: ok + - AOA: not done + - HUB: ok + - FTDI: not done + - HID: ok + - UVC: not done + + +Enhancements: +- Way to return error from the load() functions in order to stop the enumeration process +- Event sources from the low-level driver, in order to know when to call usbhMainLoop (from the low-level driver and from the HUB driver status callback) +- Possibility of internal main loop +- Linked list for drivers for dynamic registration +- A way to automate matching (similar to linux) +- Hooks to override driver loading and to inform the user of problems +- for STM32 LLD: think of a way to prevent Bulk IN NAK interrupt flood. +- Integrate VBUS power switching functionality to the API. diff --git a/os/hal/src/usbh/hal_usbh_aoa.c b/os/hal/src/usbh/hal_usbh_aoa.c index 1fa49f8..85c3130 100644 --- a/os/hal/src/usbh/hal_usbh_aoa.c +++ b/os/hal/src/usbh/hal_usbh_aoa.c @@ -124,14 +124,16 @@ USBHAOADriver USBHAOAD[HAL_USBHAOA_MAX_INSTANCES]; static usbh_baseclassdriver_t *_aoa_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); static void _aoa_unload(usbh_baseclassdriver_t *drv); +static void _aoa_init(void); static const usbh_classdriver_vmt_t class_driver_vmt = { + _aoa_init, _aoa_load, _aoa_unload }; const usbh_classdriverinfo_t usbhaoaClassDriverInfo = { - 0xff, 0xff, 0xff, "AOA", &class_driver_vmt + "AOA", &class_driver_vmt }; #if defined(HAL_USBHAOA_FILTER_CALLBACK) @@ -144,7 +146,7 @@ static usbh_baseclassdriver_t *_aoa_load(usbh_device_t *dev, const uint8_t *desc if (dev->devDesc.idVendor != AOA_GOOGLE_VID) { uint16_t protocol; - static const USBHAOAConfig config = { + static USBHAOAConfig config = { { HAL_USBHAOA_DEFAULT_MANUFACTURER, HAL_USBHAOA_DEFAULT_MODEL, @@ -221,15 +223,9 @@ static usbh_baseclassdriver_t *_aoa_load(usbh_device_t *dev, const uint8_t *desc return NULL; } - if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_INTERFACE)) - return NULL; - const usbh_interface_descriptor_t * const ifdesc = (const usbh_interface_descriptor_t *)descriptor; - - if ((ifdesc->bInterfaceClass != 0xff) - || (ifdesc->bInterfaceSubClass != 0xff) - || (ifdesc->bInterfaceProtocol != 0x00) - || (ifdesc->bNumEndpoints < 2)) { + if ((_usbh_match_descriptor(descriptor, rem, USBH_DT_INTERFACE, 0xFF, 0xFF, 0x00) != HAL_SUCCESS) + || (ifdesc->bNumEndpoints < 2)) { uerr("AOA: This IF is not the Accessory IF"); return NULL; } @@ -299,7 +295,6 @@ static void _aoa_unload(usbh_baseclassdriver_t *drv) { _stop_channelS(&aoap->channel); aoap->channel.state = USBHAOA_CHANNEL_STATE_STOP; aoap->state = USBHAOA_STATE_STOP; - osalOsRescheduleS(); osalSysUnlock(); } @@ -341,15 +336,15 @@ static size_t _write_timeout(USBHAOAChannel *aoacp, const uint8_t *bp, chDbgCheck(n > 0U); size_t w = 0; - chSysLock(); + osalSysLock(); while (true) { if (aoacp->state != USBHAOA_CHANNEL_STATE_READY) { - chSysUnlock(); + osalSysUnlock(); return w; } while (usbhURBIsBusy(&aoacp->oq_urb)) { if (chThdEnqueueTimeoutS(&aoacp->oq_waiting, timeout) != Q_OK) { - chSysUnlock(); + osalSysUnlock(); return w; } } @@ -357,30 +352,30 @@ static size_t _write_timeout(USBHAOAChannel *aoacp, const uint8_t *bp, *aoacp->oq_ptr++ = *bp++; if (--aoacp->oq_counter == 0) { _submitOutI(aoacp, 64); - chSchRescheduleS(); + osalOsRescheduleS(); } - chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ + osalSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; if (--n == 0U) return w; - chSysLock(); + osalSysLock(); } } static msg_t _put_timeout(USBHAOAChannel *aoacp, uint8_t b, systime_t timeout) { - chSysLock(); + osalSysLock(); if (aoacp->state != USBHAOA_CHANNEL_STATE_READY) { - chSysUnlock(); + osalSysUnlock(); return Q_RESET; } while (usbhURBIsBusy(&aoacp->oq_urb)) { msg_t msg = chThdEnqueueTimeoutS(&aoacp->oq_waiting, timeout); if (msg < Q_OK) { - chSysUnlock(); + osalSysUnlock(); return msg; } } @@ -388,9 +383,9 @@ static msg_t _put_timeout(USBHAOAChannel *aoacp, uint8_t b, systime_t timeout) { *aoacp->oq_ptr++ = b; if (--aoacp->oq_counter == 0) { _submitOutI(aoacp, 64); - chSchRescheduleS(); + osalOsRescheduleS(); } - chSysUnlock(); + osalSysUnlock(); return Q_OK; } @@ -439,41 +434,41 @@ static size_t _read_timeout(USBHAOAChannel *aoacp, uint8_t *bp, chDbgCheck(n > 0U); - chSysLock(); + osalSysLock(); while (true) { if (aoacp->state != USBHAOA_CHANNEL_STATE_READY) { - chSysUnlock(); + osalSysUnlock(); return r; } while (aoacp->iq_counter == 0) { if (!usbhURBIsBusy(&aoacp->iq_urb)) _submitInI(aoacp); if (chThdEnqueueTimeoutS(&aoacp->iq_waiting, timeout) != Q_OK) { - chSysUnlock(); + osalSysUnlock(); return r; } } *bp++ = *aoacp->iq_ptr++; if (--aoacp->iq_counter == 0) { _submitInI(aoacp); - chSchRescheduleS(); + osalOsRescheduleS(); } - chSysUnlock(); + osalSysUnlock(); r++; if (--n == 0U) return r; - chSysLock(); + osalSysLock(); } } static msg_t _get_timeout(USBHAOAChannel *aoacp, systime_t timeout) { uint8_t b; - chSysLock(); + osalSysLock(); if (aoacp->state != USBHAOA_CHANNEL_STATE_READY) { - chSysUnlock(); + osalSysUnlock(); return Q_RESET; } while (aoacp->iq_counter == 0) { @@ -481,16 +476,16 @@ static msg_t _get_timeout(USBHAOAChannel *aoacp, systime_t timeout) { _submitInI(aoacp); msg_t msg = chThdEnqueueTimeoutS(&aoacp->iq_waiting, timeout); if (msg < Q_OK) { - chSysUnlock(); + osalSysUnlock(); return msg; } } b = *aoacp->iq_ptr++; if (--aoacp->iq_counter == 0) { _submitInI(aoacp); - chSchRescheduleS(); + osalOsRescheduleS(); } - chSysUnlock(); + osalSysUnlock(); return (msg_t)b; } @@ -525,11 +520,12 @@ static void _stop_channelS(USBHAOAChannel *aoacp) { chThdDequeueAllI(&aoacp->oq_waiting, Q_RESET); chnAddFlagsI(aoacp, CHN_DISCONNECTED); aoacp->state = USBHAOA_CHANNEL_STATE_ACTIVE; + osalOsRescheduleS(); } static void _vt(void *p) { USBHAOAChannel *const aoacp = (USBHAOAChannel *)p; - chSysLockFromISR(); + osalSysLockFromISR(); uint32_t len = aoacp->oq_ptr - aoacp->oq_buff; if (len && !usbhURBIsBusy(&aoacp->oq_urb)) { _submitOutI(aoacp, len); @@ -538,7 +534,7 @@ static void _vt(void *p) { _submitInI(aoacp); } chVTSetI(&aoacp->vt, MS2ST(16), _vt, aoacp); - chSysUnlockFromISR(); + osalSysUnlockFromISR(); } void usbhaoaChannelStart(USBHAOADriver *aoap) { @@ -566,9 +562,7 @@ void usbhaoaChannelStart(USBHAOADriver *aoap) { aoacp->iq_counter = 0; aoacp->iq_ptr = aoacp->iq_buff; usbhEPOpen(&aoacp->epin); - osalSysLock(); - usbhURBSubmitI(&aoacp->iq_urb); - osalSysUnlock(); + usbhURBSubmit(&aoacp->iq_urb); chVTObjectInit(&aoacp->vt); chVTSet(&aoacp->vt, MS2ST(16), _vt, aoacp); @@ -583,7 +577,6 @@ void usbhaoaChannelStop(USBHAOADriver *aoap) { || (aoap->channel.state == USBHAOA_CHANNEL_STATE_READY)); osalSysLock(); _stop_channelS(&aoap->channel); - osalOsRescheduleS(); osalSysUnlock(); } @@ -658,7 +651,7 @@ static bool _send_string(usbh_device_t *dev, uint8_t index, const char *string) return HAL_SUCCESS; } -void usbhaoaObjectInit(USBHAOADriver *aoap) { +static void _object_init(USBHAOADriver *aoap) { osalDbgCheck(aoap != NULL); memset(aoap, 0, sizeof(*aoap)); aoap->info = &usbhaoaClassDriverInfo; @@ -668,10 +661,10 @@ void usbhaoaObjectInit(USBHAOADriver *aoap) { aoap->channel.state = USBHAOA_CHANNEL_STATE_STOP; } -void usbhaoaInit(void) { +static void _aoa_init(void) { uint8_t i; for (i = 0; i < HAL_USBHAOA_MAX_INSTANCES; i++) { - usbhaoaObjectInit(&USBHAOAD[i]); + _object_init(&USBHAOAD[i]); } } diff --git a/os/hal/src/usbh/hal_usbh_debug.c b/os/hal/src/usbh/hal_usbh_debug.c index 7c4ff7d..d32f1c6 100644 --- a/os/hal/src/usbh/hal_usbh_debug.c +++ b/os/hal/src/usbh/hal_usbh_debug.c @@ -106,17 +106,18 @@ static char *ftoa(char *p, double num, unsigned long precision, bool dot) { } #endif -static inline void _put(char c) { - input_queue_t *iqp = &USBH_DEBUG_USBHD.iq; - - if (iqIsFullI(iqp)) - return; - - iqp->q_counter++; +static inline void _wr(input_queue_t *iqp, char c) { *iqp->q_wrptr++ = c; if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; +} +static inline void _put(char c) { + input_queue_t *iqp = &USBH_DEBUG_USBHD.iq; + if (sizeof(USBH_DEBUG_USBHD.dbg_buff) - iqp->q_counter <= 1) + return; + iqp->q_counter++; + _wr(iqp, c); } int _dbg_printf(const char *fmt, va_list ap) { @@ -341,19 +342,39 @@ unsigned_common: } -static void _print_hdr(void) -{ +static systime_t first, last; +static bool ena; +static uint32_t hdr[2]; + +static void _build_hdr(void) { uint32_t hfnum = USBH_DEBUG_USBHD.otg->HFNUM; uint16_t hfir = USBH_DEBUG_USBHD.otg->HFIR; + last = osalOsGetSystemTimeX(); + if (ena) { + first = last; + } + + if (((hfnum & 0x3fff) == 0x3fff) && (hfir == (hfnum >> 16))) { + hdr[0] = 0xfeff; + hdr[1] = last - first; + ena = FALSE; + } else { + hdr[0] = 0xffff | (hfir << 16); + hdr[1] = hfnum; + ena = TRUE; + } +} - _put(0xff); - _put(0xff); - _put(hfir & 0xff); - _put(hfir >> 8); - _put(hfnum & 0xff); - _put((hfnum >> 8) & 0xff); - _put((hfnum >> 16) & 0xff); - _put((hfnum >> 24) & 0xff); +static void _print_hdr(void) +{ + _put(hdr[0] & 0xff); + _put((hdr[0] >> 8) & 0xff); + _put((hdr[0] >> 16) & 0xff); + _put((hdr[0] >> 24) & 0xff); + _put(hdr[1] & 0xff); + _put((hdr[1] >> 8) & 0xff); + _put((hdr[1] >> 16) & 0xff); + _put((hdr[1] >> 24) & 0xff); } void usbDbgPrintf(const char *fmt, ...) @@ -361,10 +382,16 @@ void usbDbgPrintf(const char *fmt, ...) va_list ap; va_start(ap, fmt); syssts_t sts = chSysGetStatusAndLockX(); - _print_hdr(); - _dbg_printf(fmt, ap); - _put(0); - chThdDequeueNextI(&USBH_DEBUG_USBHD.iq.q_waiting, Q_OK); + input_queue_t *iqp = &USBH_DEBUG_USBHD.iq; + int rem = sizeof(USBH_DEBUG_USBHD.dbg_buff) - iqp->q_counter; + if (rem >= 9) { + _build_hdr(); + _print_hdr(); + _dbg_printf(fmt, ap); + iqp->q_counter++; + _wr(iqp, 0); + chThdDequeueNextI(&USBH_DEBUG_USBHD.iq.q_waiting, Q_OK); + } chSysRestoreStatusX(sts); va_end(ap); } @@ -372,32 +399,28 @@ void usbDbgPrintf(const char *fmt, ...) void usbDbgPuts(const char *s) { - uint32_t buff[2] = { - 0xffff | (USBH_DEBUG_USBHD.otg->HFIR << 16), - USBH_DEBUG_USBHD.otg->HFNUM - }; - uint8_t *p = (uint8_t *)buff; + _build_hdr(); + uint8_t *p = (uint8_t *)hdr; uint8_t *top = p + 8; syssts_t sts = chSysGetStatusAndLockX(); input_queue_t *iqp = &USBH_DEBUG_USBHD.iq; int rem = sizeof(USBH_DEBUG_USBHD.dbg_buff) - iqp->q_counter; - while (rem) { - *iqp->q_wrptr++ = *p; - if (iqp->q_wrptr >= iqp->q_top) - iqp->q_wrptr = iqp->q_buffer; - rem--; - if (++p == top) break; - } - while (rem) { - *iqp->q_wrptr++ = *s; - if (iqp->q_wrptr >= iqp->q_top) - iqp->q_wrptr = iqp->q_buffer; - rem--; - if (!*s++) break; + if (rem >= 9) { + while (rem) { + _wr(iqp, *p); + if (++p == top) break; + } + rem -= 9; + while (rem && *s) { + _wr(iqp, *s); + rem--; + s++; + } + _wr(iqp, 0); + iqp->q_counter = sizeof(USBH_DEBUG_USBHD.dbg_buff) - rem; + chThdDequeueNextI(&USBH_DEBUG_USBHD.iq.q_waiting, Q_OK); } - iqp->q_counter = sizeof(USBH_DEBUG_USBHD.dbg_buff) - rem; - chThdDequeueNextI(&USBH_DEBUG_USBHD.iq.q_waiting, Q_OK); chSysRestoreStatusX(sts); } @@ -429,8 +452,8 @@ void usbDbgSystemHalted(void) { if (!((bool)((USBH_DEBUG_SD.oqueue.q_wrptr == USBH_DEBUG_SD.oqueue.q_rdptr) && (USBH_DEBUG_SD.oqueue.q_counter != 0U)))) break; USBH_DEBUG_SD.oqueue.q_counter++; - while (!(USART1->SR & USART_SR_TXE)); - USART1->DR = *USBH_DEBUG_SD.oqueue.q_rdptr++; + while (!(USBH_DEBUG_SD.usart->SR & USART_SR_TXE)); + USBH_DEBUG_SD.usart->DR = *USBH_DEBUG_SD.oqueue.q_rdptr++; if (USBH_DEBUG_SD.oqueue.q_rdptr >= USBH_DEBUG_SD.oqueue.q_top) { USBH_DEBUG_SD.oqueue.q_rdptr = USBH_DEBUG_SD.oqueue.q_buffer; } @@ -456,15 +479,15 @@ void usbDbgSystemHalted(void) { while (true) { c = _get(); if (c < 0) return; if (!c) { - while (!(USART1->SR & USART_SR_TXE)); - USART1->DR = '\r'; - while (!(USART1->SR & USART_SR_TXE)); - USART1->DR = '\n'; + while (!(USBH_DEBUG_SD.usart->SR & USART_SR_TXE)); + USBH_DEBUG_SD.usart->DR = '\r'; + while (!(USBH_DEBUG_SD.usart->SR & USART_SR_TXE)); + USBH_DEBUG_SD.usart->DR = '\n'; state = 0; break; } - while (!(USART1->SR & USART_SR_TXE)); - USART1->DR = c; + while (!(USBH_DEBUG_SD.usart->SR & USART_SR_TXE)); + USBH_DEBUG_SD.usart->DR = c; } } } @@ -483,8 +506,9 @@ static void usb_debug_thread(void *arg) { if (c == 0xff) state = 1; } else if (state == 1) { if (c == 0xff) state = 2; + else if (c == 0xfe) state = 3; else (state = 0); - } else { + } else if (state == 2) { uint16_t hfir; uint32_t hfnum; @@ -503,10 +527,26 @@ static void usb_debug_thread(void *arg) { uint32_t f = hfnum & 0xffff; uint32_t p = 1000 - ((hfnum >> 16) / (hfir / 1000)); - chprintf((BaseSequentialStream *)&USBH_DEBUG_SD, "%05d.%03d ", f, p); + chprintf((BaseSequentialStream *)&USBH_DEBUG_SD, "%05d.%03d ", f, p); + state = 4; + } else if (state == 3) { + uint32_t t; + c = iqGet(&host->iq); if (c < 0) goto reset; + c = iqGet(&host->iq); if (c < 0) goto reset; + + t = c; + c = iqGet(&host->iq); if (c < 0) goto reset; + t |= c << 8; + c = iqGet(&host->iq); if (c < 0) goto reset; + t |= c << 16; + c = iqGet(&host->iq); if (c < 0) goto reset; + t |= c << 24; + + chprintf((BaseSequentialStream *)&USBH_DEBUG_SD, "+%08d ", t); + state = 4; + } else { while (true) { - c = iqGet(&host->iq); if (c < 0) goto reset; if (!c) { sdPut(&USBH_DEBUG_SD, '\r'); sdPut(&USBH_DEBUG_SD, '\n'); @@ -514,6 +554,7 @@ static void usb_debug_thread(void *arg) { break; } sdPut(&USBH_DEBUG_SD, (uint8_t)c); + c = iqGet(&host->iq); if (c < 0) goto reset; } } diff --git a/os/hal/src/usbh/hal_usbh_ftdi.c b/os/hal/src/usbh/hal_usbh_ftdi.c index ce96958..6fb556d 100644 --- a/os/hal/src/usbh/hal_usbh_ftdi.c +++ b/os/hal/src/usbh/hal_usbh_ftdi.c @@ -27,9 +27,6 @@ #include "usbh/dev/ftdi.h" #include "usbh/internal.h" -//#pragma GCC optimize("Og") - - #if USBHFTDI_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) #define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) @@ -62,22 +59,25 @@ #define uerr(f, ...) do {} while(0) #endif +static void _ftdip_object_init(USBHFTDIPortDriver *ftdipp); /*===========================================================================*/ /* USB Class driver loader for FTDI */ /*===========================================================================*/ USBHFTDIDriver USBHFTDID[HAL_USBHFTDI_MAX_INSTANCES]; +static void _ftdi_init(void); static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); static void _ftdi_unload(usbh_baseclassdriver_t *drv); static const usbh_classdriver_vmt_t class_driver_vmt = { + _ftdi_init, _ftdi_load, _ftdi_unload }; const usbh_classdriverinfo_t usbhftdiClassDriverInfo = { - 0xff, 0xff, 0xff, "FTDI", &class_driver_vmt + "FTDI", &class_driver_vmt }; static USBHFTDIPortDriver *_find_port(void) { @@ -93,10 +93,8 @@ static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *des int i; USBHFTDIDriver *ftdip; - if (dev->devDesc.idVendor != 0x0403) { - uerr("FTDI: Unrecognized VID"); + if (_usbh_match_vid_pid(dev, 0x0403, -1) != HAL_SUCCESS) return NULL; - } switch (dev->devDesc.idProduct) { case 0x6001: @@ -111,7 +109,8 @@ static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *des return NULL; } - if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_INTERFACE)) + if (_usbh_match_descriptor(descriptor, rem, USBH_DT_INTERFACE, + 0xff, 0xff, 0xff) != HAL_SUCCESS) return NULL; if (((const usbh_interface_descriptor_t *)descriptor)->bInterfaceNumber != 0) { @@ -220,7 +219,6 @@ static void _ftdi_unload(usbh_baseclassdriver_t *drv) { while (ftdipp) { osalSysLock(); _stopS(ftdipp); - osalOsRescheduleS(); osalSysUnlock(); ftdipp = ftdipp->next; } @@ -229,7 +227,7 @@ static void _ftdi_unload(usbh_baseclassdriver_t *drv) { osalSysLock(); while (ftdipp) { USBHFTDIPortDriver *next = ftdipp->next; - usbhftdipObjectInit(ftdipp); + _ftdip_object_init(ftdipp); ftdipp = next; } osalSysUnlock(); @@ -417,7 +415,7 @@ static void _out_cb(usbh_urb_t *urb) { return; case USBH_URBSTATUS_DISCONNECTED: uwarn("FTDI: URB OUT disconnected"); - chThdDequeueNextI(&ftdipp->oq_waiting, Q_RESET); + chThdDequeueAllI(&ftdipp->oq_waiting, Q_RESET); return; default: uerrf("FTDI: URB OUT status unexpected = %d", urb->status); @@ -432,15 +430,15 @@ static size_t _write_timeout(USBHFTDIPortDriver *ftdipp, const uint8_t *bp, chDbgCheck(n > 0U); size_t w = 0; - chSysLock(); + osalSysLock(); while (true) { if (ftdipp->state != USBHFTDIP_STATE_READY) { - chSysUnlock(); + osalSysUnlock(); return w; } while (usbhURBIsBusy(&ftdipp->oq_urb)) { if (chThdEnqueueTimeoutS(&ftdipp->oq_waiting, timeout) != Q_OK) { - chSysUnlock(); + osalSysUnlock(); return w; } } @@ -448,30 +446,30 @@ static size_t _write_timeout(USBHFTDIPortDriver *ftdipp, const uint8_t *bp, *ftdipp->oq_ptr++ = *bp++; if (--ftdipp->oq_counter == 0) { _submitOutI(ftdipp, 64); - chSchRescheduleS(); + osalOsRescheduleS(); } - chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ + osalSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; if (--n == 0U) return w; - chSysLock(); + osalSysLock(); } } static msg_t _put_timeout(USBHFTDIPortDriver *ftdipp, uint8_t b, systime_t timeout) { - chSysLock(); + osalSysLock(); if (ftdipp->state != USBHFTDIP_STATE_READY) { - chSysUnlock(); + osalSysUnlock(); return Q_RESET; } while (usbhURBIsBusy(&ftdipp->oq_urb)) { msg_t msg = chThdEnqueueTimeoutS(&ftdipp->oq_waiting, timeout); if (msg < Q_OK) { - chSysUnlock(); + osalSysUnlock(); return msg; } } @@ -479,9 +477,9 @@ static msg_t _put_timeout(USBHFTDIPortDriver *ftdipp, uint8_t b, systime_t timeo *ftdipp->oq_ptr++ = b; if (--ftdipp->oq_counter == 0) { _submitOutI(ftdipp, 64); - chSchRescheduleS(); + osalOsRescheduleS(); } - chSysUnlock(); + osalSysUnlock(); return Q_OK; } @@ -518,12 +516,12 @@ static void _in_cb(usbh_urb_t *urb) { udbgf("FTDI: URB IN no data, status=%02x %02x", ((uint8_t *)urb->buff)[0], ((uint8_t *)urb->buff)[1]); - return; + // return; } break; case USBH_URBSTATUS_DISCONNECTED: uwarn("FTDI: URB IN disconnected"); - chThdDequeueNextI(&ftdipp->iq_waiting, Q_RESET); + chThdDequeueAllI(&ftdipp->iq_waiting, Q_RESET); return; default: uerrf("FTDI: URB IN status unexpected = %d", urb->status); @@ -538,41 +536,41 @@ static size_t _read_timeout(USBHFTDIPortDriver *ftdipp, uint8_t *bp, chDbgCheck(n > 0U); - chSysLock(); + osalSysLock(); while (true) { if (ftdipp->state != USBHFTDIP_STATE_READY) { - chSysUnlock(); + osalSysUnlock(); return r; } while (ftdipp->iq_counter == 0) { if (!usbhURBIsBusy(&ftdipp->iq_urb)) _submitInI(ftdipp); if (chThdEnqueueTimeoutS(&ftdipp->iq_waiting, timeout) != Q_OK) { - chSysUnlock(); + osalSysUnlock(); return r; } } *bp++ = *ftdipp->iq_ptr++; if (--ftdipp->iq_counter == 0) { _submitInI(ftdipp); - chSchRescheduleS(); + osalOsRescheduleS(); } - chSysUnlock(); + osalSysUnlock(); r++; if (--n == 0U) return r; - chSysLock(); + osalSysLock(); } } static msg_t _get_timeout(USBHFTDIPortDriver *ftdipp, systime_t timeout) { uint8_t b; - chSysLock(); + osalSysLock(); if (ftdipp->state != USBHFTDIP_STATE_READY) { - chSysUnlock(); + osalSysUnlock(); return Q_RESET; } while (ftdipp->iq_counter == 0) { @@ -580,16 +578,16 @@ static msg_t _get_timeout(USBHFTDIPortDriver *ftdipp, systime_t timeout) { _submitInI(ftdipp); msg_t msg = chThdEnqueueTimeoutS(&ftdipp->iq_waiting, timeout); if (msg < Q_OK) { - chSysUnlock(); + osalSysUnlock(); return msg; } } b = *ftdipp->iq_ptr++; if (--ftdipp->iq_counter == 0) { _submitInI(ftdipp); - chSchRescheduleS(); + osalOsRescheduleS(); } - chSysUnlock(); + osalSysUnlock(); return (msg_t)b; } @@ -604,7 +602,7 @@ static size_t _read(USBHFTDIPortDriver *ftdipp, uint8_t *bp, size_t n) { static void _vt(void *p) { USBHFTDIPortDriver *const ftdipp = (USBHFTDIPortDriver *)p; - chSysLockFromISR(); + osalSysLockFromISR(); uint32_t len = ftdipp->oq_ptr - ftdipp->oq_buff; if (len && !usbhURBIsBusy(&ftdipp->oq_urb)) { _submitOutI(ftdipp, len); @@ -613,7 +611,7 @@ static void _vt(void *p) { _submitInI(ftdipp); } chVTSetI(&ftdipp->vt, MS2ST(16), _vt, ftdipp); - chSysUnlockFromISR(); + osalSysUnlockFromISR(); } static const struct FTDIPortDriverVMT async_channel_vmt = { @@ -637,6 +635,7 @@ static void _stopS(USBHFTDIPortDriver *ftdipp) { chThdDequeueAllI(&ftdipp->iq_waiting, Q_RESET); chThdDequeueAllI(&ftdipp->oq_waiting, Q_RESET); ftdipp->state = USBHFTDIP_STATE_ACTIVE; + osalOsRescheduleS(); } void usbhftdipStop(USBHFTDIPortDriver *ftdipp) { @@ -647,7 +646,6 @@ void usbhftdipStop(USBHFTDIPortDriver *ftdipp) { chMtxLockS(&ftdipp->ftdip->mtx); _stopS(ftdipp); chMtxUnlockS(&ftdipp->ftdip->mtx); - osalOsRescheduleS(); osalSysUnlock(); } @@ -689,9 +687,7 @@ void usbhftdipStart(USBHFTDIPortDriver *ftdipp, const USBHFTDIPortConfig *config ftdipp->iq_counter = 0; ftdipp->iq_ptr = ftdipp->iq_buff; usbhEPOpen(&ftdipp->epin); - osalSysLock(); - usbhURBSubmitI(&ftdipp->iq_urb); - osalSysUnlock(); + usbhURBSubmit(&ftdipp->iq_urb); chVTObjectInit(&ftdipp->vt); chVTSet(&ftdipp->vt, MS2ST(16), _vt, ftdipp); @@ -700,27 +696,27 @@ void usbhftdipStart(USBHFTDIPortDriver *ftdipp, const USBHFTDIPortConfig *config osalMutexUnlock(&ftdipp->ftdip->mtx); } -void usbhftdiObjectInit(USBHFTDIDriver *ftdip) { +static void _ftdi_object_init(USBHFTDIDriver *ftdip) { osalDbgCheck(ftdip != NULL); memset(ftdip, 0, sizeof(*ftdip)); ftdip->info = &usbhftdiClassDriverInfo; osalMutexObjectInit(&ftdip->mtx); } -void usbhftdipObjectInit(USBHFTDIPortDriver *ftdipp) { +static void _ftdip_object_init(USBHFTDIPortDriver *ftdipp) { osalDbgCheck(ftdipp != NULL); memset(ftdipp, 0, sizeof(*ftdipp)); ftdipp->vmt = &async_channel_vmt; ftdipp->state = USBHFTDIP_STATE_STOP; } -void usbhftdiInit(void) { +static void _ftdi_init(void) { uint8_t i; for (i = 0; i < HAL_USBHFTDI_MAX_INSTANCES; i++) { - usbhftdiObjectInit(&USBHFTDID[i]); + _ftdi_object_init(&USBHFTDID[i]); } for (i = 0; i < HAL_USBHFTDI_MAX_PORTS; i++) { - usbhftdipObjectInit(&FTDIPD[i]); + _ftdip_object_init(&FTDIPD[i]); } } diff --git a/os/hal/src/usbh/hal_usbh_hid.c b/os/hal/src/usbh/hal_usbh_hid.c index e98dff7..2b2c5ce 100644 --- a/os/hal/src/usbh/hal_usbh_hid.c +++ b/os/hal/src/usbh/hal_usbh_hid.c @@ -69,28 +69,32 @@ #define USBH_HID_REQ_SET_PROTOCOL 0x0B /*===========================================================================*/ -/* USB Class driver loader for MSD */ +/* USB Class driver loader for HID */ /*===========================================================================*/ USBHHIDDriver USBHHIDD[HAL_USBHHID_MAX_INSTANCES]; +static void _hid_init(void); static usbh_baseclassdriver_t *_hid_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); static void _hid_unload(usbh_baseclassdriver_t *drv); +static void _stop_locked(USBHHIDDriver *hidp); static const usbh_classdriver_vmt_t class_driver_vmt = { + _hid_init, _hid_load, _hid_unload }; const usbh_classdriverinfo_t usbhhidClassDriverInfo = { - 0x03, -1, -1, "HID", &class_driver_vmt + "HID", &class_driver_vmt }; static usbh_baseclassdriver_t *_hid_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) { int i; USBHHIDDriver *hidp; - if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_INTERFACE)) + if (_usbh_match_descriptor(descriptor, rem, USBH_DT_INTERFACE, + 0x03, -1, -1) != HAL_SUCCESS) return NULL; const usbh_interface_descriptor_t * const ifdesc = (const usbh_interface_descriptor_t *)descriptor; @@ -180,7 +184,11 @@ deinit: } static void _hid_unload(usbh_baseclassdriver_t *drv) { - (void)drv; + USBHHIDDriver *const hidp = (USBHHIDDriver *)drv; + chSemWait(&hidp->sem); + _stop_locked(hidp); + hidp->state = USBHHID_STATE_STOP; + chSemSignal(&hidp->sem); } static void _in_cb(usbh_urb_t *urb) { @@ -209,17 +217,22 @@ static void _in_cb(usbh_urb_t *urb) { void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg) { osalDbgCheck(hidp && cfg); osalDbgCheck(cfg->report_buffer && (cfg->protocol <= USBHHID_PROTOCOL_REPORT)); - osalDbgCheck((hidp->state == USBHHID_STATE_ACTIVE) - || (hidp->state == USBHHID_STATE_READY)); - if (hidp->state == USBHHID_STATE_READY) + chSemWait(&hidp->sem); + if (hidp->state == USBHHID_STATE_READY) { + chSemSignal(&hidp->sem); return; + } + osalDbgCheck(hidp->state == USBHHID_STATE_ACTIVE); hidp->config = cfg; /* init the URBs */ + uint32_t report_len = hidp->epin.wMaxPacketSize; + if (report_len > cfg->report_len) + report_len = cfg->report_len; usbhURBObjectInit(&hidp->in_urb, &hidp->epin, _in_cb, hidp, - cfg->report_buffer, cfg->report_len); + cfg->report_buffer, report_len); /* open the int IN/OUT endpoints */ usbhEPOpen(&hidp->epin); @@ -231,29 +244,31 @@ void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg) { usbhhidSetProtocol(hidp, cfg->protocol); - osalSysLock(); - usbhURBSubmitI(&hidp->in_urb); - osalSysUnlock(); + usbhURBSubmit(&hidp->in_urb); hidp->state = USBHHID_STATE_READY; + chSemSignal(&hidp->sem); } -void usbhhidStop(USBHHIDDriver *hidp) { - osalDbgCheck((hidp->state == USBHHID_STATE_ACTIVE) - || (hidp->state == USBHHID_STATE_READY)); - - if (hidp->state != USBHHID_STATE_READY) +static void _stop_locked(USBHHIDDriver *hidp) { + if (hidp->state == USBHHID_STATE_ACTIVE) return; - osalSysLock(); - usbhEPCloseS(&hidp->epin); + osalDbgCheck(hidp->state == USBHHID_STATE_READY); + + usbhEPClose(&hidp->epin); #if HAL_USBHHID_USE_INTERRUPT_OUT if (hidp->epout.status != USBH_EPSTATUS_UNINITIALIZED) { - usbhEPCloseS(&hidp->epout); + usbhEPClose(&hidp->epout); } #endif hidp->state = USBHHID_STATE_ACTIVE; - osalSysUnlock(); +} + +void usbhhidStop(USBHHIDDriver *hidp) { + chSemWait(&hidp->sem); + _stop_locked(hidp); + chSemSignal(&hidp->sem); } usbh_urbstatus_t usbhhidGetReport(USBHHIDDriver *hidp, @@ -305,17 +320,18 @@ usbh_urbstatus_t usbhhidSetProtocol(USBHHIDDriver *hidp, uint8_t protocol) { protocol, hidp->ifnum, 0, NULL); } -void usbhhidObjectInit(USBHHIDDriver *hidp) { +static void _hid_object_init(USBHHIDDriver *hidp) { osalDbgCheck(hidp != NULL); memset(hidp, 0, sizeof(*hidp)); hidp->info = &usbhhidClassDriverInfo; hidp->state = USBHHID_STATE_STOP; + chSemObjectInit(&hidp->sem, 1); } -void usbhhidInit(void) { +static void _hid_init(void) { uint8_t i; for (i = 0; i < HAL_USBHHID_MAX_INSTANCES; i++) { - usbhhidObjectInit(&USBHHIDD[i]); + _hid_object_init(&USBHHIDD[i]); } } diff --git a/os/hal/src/usbh/hal_usbh_hub.c b/os/hal/src/usbh/hal_usbh_hub.c index 3a84175..6a83c66 100644 --- a/os/hal/src/usbh/hal_usbh_hub.c +++ b/os/hal/src/usbh/hal_usbh_hub.c @@ -63,14 +63,17 @@ USBHHubDriver USBHHUBD[HAL_USBHHUB_MAX_INSTANCES]; static usbh_port_t USBHPorts[HAL_USBHHUB_MAX_PORTS]; -static usbh_baseclassdriver_t *hub_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); -static void hub_unload(usbh_baseclassdriver_t *drv); +static void _hub_init(void); +static usbh_baseclassdriver_t *_hub_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); +static void _hub_unload(usbh_baseclassdriver_t *drv); static const usbh_classdriver_vmt_t usbhhubClassDriverVMT = { - hub_load, - hub_unload + _hub_init, + _hub_load, + _hub_unload }; + const usbh_classdriverinfo_t usbhhubClassDriverInfo = { - 0x09, 0x00, -1, "HUB", &usbhhubClassDriverVMT + "HUB", &usbhhubClassDriverVMT }; @@ -104,7 +107,7 @@ static void _urb_complete(usbh_urb_t *urb) { case USBH_URBSTATUS_TIMEOUT: /* the device NAKed */ udbg("HUB: no info"); - hubdp->statuschange = 0; + //hubdp->statuschange = 0; break; case USBH_URBSTATUS_OK: { uint8_t len = hubdp->hubDesc.bNbrPorts / 8 + 1; @@ -137,16 +140,14 @@ static void _urb_complete(usbh_urb_t *urb) { usbhURBSubmitI(urb); } -static usbh_baseclassdriver_t *hub_load(usbh_device_t *dev, +static usbh_baseclassdriver_t *_hub_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) { int i; USBHHubDriver *hubdp; - if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_DEVICE)) - return NULL; - - if (dev->devDesc.bDeviceProtocol != 0) + if (_usbh_match_descriptor(descriptor, rem, USBH_DT_DEVICE, + 0x09, 0x00, 0x00) != HAL_SUCCESS) return NULL; generic_iterator_t iep, icfg; @@ -158,12 +159,10 @@ static usbh_baseclassdriver_t *hub_load(usbh_device_t *dev, if_iter_init(&iif, &icfg); if (!iif.valid) return NULL; - const usbh_interface_descriptor_t *const ifdesc = if_get(&iif); - if ((ifdesc->bInterfaceClass != 0x09) - || (ifdesc->bInterfaceSubClass != 0x00) - || (ifdesc->bInterfaceProtocol != 0x00)) { + + if (_usbh_match_descriptor(iif.curr, iif.rem, USBH_DT_INTERFACE, + 0x09, 0x00, 0x00) != HAL_SUCCESS) return NULL; - } ep_iter_init(&iep, &iif); if (!iep.valid) @@ -253,22 +252,18 @@ alloc_ok: _urb_complete, hubdp, hubdp->scbuff, (hubdesc->bNbrPorts + 8) / 8); - osalSysLock(); - usbhURBSubmitI(&hubdp->urb); - osalOsRescheduleS(); - osalSysUnlock(); + usbhURBSubmit(&hubdp->urb); + hubdp->dev = NULL; return (usbh_baseclassdriver_t *)hubdp; } -static void hub_unload(usbh_baseclassdriver_t *drv) { +static void _hub_unload(usbh_baseclassdriver_t *drv) { osalDbgCheck(drv != NULL); USBHHubDriver *const hubdp = (USBHHubDriver *)drv; /* close the status change endpoint (this cancels ongoing URBs) */ - osalSysLock(); - usbhEPCloseS(&hubdp->epint); - osalSysUnlock(); + usbhEPClose(&hubdp->epint); /* de-alloc ports and unload drivers */ usbh_port_t *port = hubdp->ports; @@ -283,16 +278,16 @@ static void hub_unload(usbh_baseclassdriver_t *drv) { } -void usbhhubObjectInit(USBHHubDriver *hubdp) { +static void _object_init(USBHHubDriver *hubdp) { osalDbgCheck(hubdp != NULL); memset(hubdp, 0, sizeof(*hubdp)); hubdp->info = &usbhhubClassDriverInfo; } -void usbhhubInit(void) { +static void _hub_init(void) { uint8_t i; for (i = 0; i < HAL_USBHHUB_MAX_INSTANCES; i++) { - usbhhubObjectInit(&USBHHUBD[i]); + _object_init(&USBHHUBD[i]); } } diff --git a/os/hal/src/usbh/hal_usbh_msd.c b/os/hal/src/usbh/hal_usbh_msd.c index b564e8e..069c47b 100644 --- a/os/hal/src/usbh/hal_usbh_msd.c +++ b/os/hal/src/usbh/hal_usbh_msd.c @@ -27,9 +27,6 @@ #include "usbh/dev/msd.h" #include "usbh/internal.h" -//#pragma GCC optimize("Og") - - #if USBHMSD_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) #define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) @@ -62,26 +59,39 @@ #define uerr(f, ...) do {} while(0) #endif - - - +static void _lun_object_deinit(USBHMassStorageLUNDriver *lunp); /*===========================================================================*/ /* USB Class driver loader for MSD */ /*===========================================================================*/ -USBHMassStorageDriver USBHMSD[HAL_USBHMSD_MAX_INSTANCES]; +struct USBHMassStorageDriver { + /* inherited from abstract class driver */ + _usbh_base_classdriver_data + usbh_ep_t epin; + usbh_ep_t epout; + uint8_t ifnum; + uint8_t max_lun; + uint32_t tag; + + USBHMassStorageLUNDriver *luns; +}; + +static USBHMassStorageDriver USBHMSD[HAL_USBHMSD_MAX_INSTANCES]; + +static void _msd_init(void); static usbh_baseclassdriver_t *_msd_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); static void _msd_unload(usbh_baseclassdriver_t *drv); static const usbh_classdriver_vmt_t class_driver_vmt = { + _msd_init, _msd_load, _msd_unload }; const usbh_classdriverinfo_t usbhmsdClassDriverInfo = { - 0x08, 0x06, 0x50, "MSD", &class_driver_vmt + "MSD", &class_driver_vmt }; #define MSD_REQ_RESET 0xFF @@ -93,15 +103,14 @@ static usbh_baseclassdriver_t *_msd_load(usbh_device_t *dev, const uint8_t *desc uint8_t luns; usbh_urbstatus_t stat; - if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_INTERFACE)) + if (_usbh_match_descriptor(descriptor, rem, USBH_DT_INTERFACE, + 0x08, 0x06, 0x50) != HAL_SUCCESS) return NULL; const usbh_interface_descriptor_t * const ifdesc = (const usbh_interface_descriptor_t *)descriptor; if ((ifdesc->bAlternateSetting != 0) - || (ifdesc->bNumEndpoints < 2) - || (ifdesc->bInterfaceSubClass != 0x06) - || (ifdesc->bInterfaceProtocol != 0x50)) { + || (ifdesc->bNumEndpoints < 2)) { return NULL; } @@ -187,15 +196,7 @@ alloc_ok: MSBLKD[i].next = msdp->luns; msdp->luns = &MSBLKD[i]; MSBLKD[i].msdp = msdp; - - osalSysLock(); - MSBLKD[i].state = BLK_ACTIVE; /* transition directly to active, instead of BLK_STOP */ - osalSysUnlock(); - - /* connect the LUN (TODO: review if it's best to leave the LUN disconnected) */ - msdp->dev = dev; - usbhmsdLUNConnect(&MSBLKD[i]); - msdp->dev = NULL; + MSBLKD[i].state = BLK_ACTIVE; luns--; } } @@ -212,25 +213,15 @@ static void _msd_unload(usbh_baseclassdriver_t *drv) { USBHMassStorageDriver *const msdp = (USBHMassStorageDriver *)drv; USBHMassStorageLUNDriver *lunp = msdp->luns; - osalMutexLock(&msdp->mtx); - osalSysLock(); - usbhEPCloseS(&msdp->epin); - usbhEPCloseS(&msdp->epout); + /* disconnect all LUNs */ while (lunp) { - lunp->state = BLK_STOP; + usbhmsdLUNDisconnect(lunp); + _lun_object_deinit(lunp); lunp = lunp->next; } - osalSysUnlock(); - osalMutexUnlock(&msdp->mtx); - /* now that the LUNs are idle, deinit them */ - lunp = msdp->luns; - osalSysLock(); - while (lunp) { - usbhmsdLUNObjectInit(lunp); - lunp = lunp->next; - } - osalSysUnlock(); + usbhEPClose(&msdp->epin); + usbhEPClose(&msdp->epout); } @@ -238,8 +229,6 @@ static void _msd_unload(usbh_baseclassdriver_t *drv) { /* MSD Class driver operations (Bulk-Only transport) */ /*===========================================================================*/ - - /* USB Bulk Only Transport SCSI Command block wrapper */ typedef PACKED_STRUCT { uint32_t dCBWSignature; @@ -704,11 +693,22 @@ static const struct USBHMassStorageDriverVMT blk_vmt = { (bool (*)(void *, BlockDeviceInfo *))usbhmsdLUNGetInfo }; -void usbhmsdLUNObjectInit(USBHMassStorageLUNDriver *lunp) { +static void _lun_object_deinit(USBHMassStorageLUNDriver *lunp) { + osalDbgCheck(lunp != NULL); + chSemWait(&lunp->sem); + lunp->msdp = NULL; + lunp->next = NULL; + memset(&lunp->info, 0, sizeof(lunp->info)); + lunp->state = BLK_STOP; + chSemSignal(&lunp->sem); +} + +static void _lun_object_init(USBHMassStorageLUNDriver *lunp) { osalDbgCheck(lunp != NULL); memset(lunp, 0, sizeof(*lunp)); lunp->vmt = &blk_vmt; lunp->state = BLK_STOP; + chSemObjectInit(&lunp->sem, 1); /* Unnecessary because of the memset: lunp->msdp = NULL; lunp->next = NULL; @@ -716,45 +716,18 @@ void usbhmsdLUNObjectInit(USBHMassStorageLUNDriver *lunp) { */ } -void usbhmsdLUNStart(USBHMassStorageLUNDriver *lunp) { - osalDbgCheck(lunp != NULL); - osalSysLock(); - osalDbgAssert((lunp->state == BLK_STOP) || (lunp->state == BLK_ACTIVE), - "invalid state"); - //TODO: complete - //lunp->state = BLK_ACTIVE; - osalSysUnlock(); -} - -void usbhmsdLUNStop(USBHMassStorageLUNDriver *lunp) { - osalDbgCheck(lunp != NULL); - osalSysLock(); - osalDbgAssert((lunp->state == BLK_STOP) || (lunp->state == BLK_ACTIVE), - "invalid state"); - //TODO: complete - //lunp->state = BLK_STOP; - osalSysUnlock(); -} - bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) { - USBHMassStorageDriver *const msdp = lunp->msdp; + osalDbgCheck(lunp != NULL); + osalDbgCheck(lunp->msdp != NULL); msd_result_t res; - osalDbgCheck(msdp != NULL); - osalSysLock(); - //osalDbgAssert((lunp->state == BLK_ACTIVE) || (lunp->state == BLK_READY), - // "invalid state"); + chSemWait(&lunp->sem); + osalDbgAssert((lunp->state == BLK_READY) || (lunp->state == BLK_ACTIVE), "invalid state"); if (lunp->state == BLK_READY) { - osalSysUnlock(); + chSemSignal(&lunp->sem); return HAL_SUCCESS; - } else if (lunp->state != BLK_ACTIVE) { - osalSysUnlock(); - return HAL_FAILED; } lunp->state = BLK_CONNECTING; - osalSysUnlock(); - - osalMutexLock(&msdp->mtx); { USBH_DEFINE_BUFFER(scsi_inquiry_response_t inq); @@ -820,41 +793,34 @@ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) { (uint32_t)(((uint64_t)lunp->info.blk_size * lunp->info.blk_num) / (1024UL * 1024UL))); uinfo("MSD Connected."); - - osalMutexUnlock(&msdp->mtx); - osalSysLock(); lunp->state = BLK_READY; - osalSysUnlock(); - + chSemSignal(&lunp->sem); return HAL_SUCCESS; /* Connection failed, state reset to BLK_ACTIVE.*/ failed: - osalMutexUnlock(&msdp->mtx); - osalSysLock(); + uinfo("MSD Connect failed."); lunp->state = BLK_ACTIVE; - osalSysUnlock(); + chSemSignal(&lunp->sem); return HAL_FAILED; } - bool usbhmsdLUNDisconnect(USBHMassStorageLUNDriver *lunp) { osalDbgCheck(lunp != NULL); - osalSysLock(); - osalDbgAssert((lunp->state == BLK_ACTIVE) || (lunp->state == BLK_READY), - "invalid state"); + + chSemWait(&lunp->sem); + osalDbgAssert((lunp->state == BLK_READY) || (lunp->state == BLK_ACTIVE), "invalid state"); if (lunp->state == BLK_ACTIVE) { - osalSysUnlock(); + chSemSignal(&lunp->sem); return HAL_SUCCESS; } lunp->state = BLK_DISCONNECTING; - osalSysUnlock(); - //TODO: complete + //TODO: complete: sync, etc. - osalSysLock(); lunp->state = BLK_ACTIVE; - osalSysUnlock(); + chSemSignal(&lunp->sem); + return HAL_SUCCESS; } @@ -867,15 +833,13 @@ bool usbhmsdLUNRead(USBHMassStorageLUNDriver *lunp, uint32_t startblk, msd_result_t res; uint32_t actual_len; - osalSysLock(); + chSemWait(&lunp->sem); if (lunp->state != BLK_READY) { - osalSysUnlock(); + chSemSignal(&lunp->sem); return ret; } lunp->state = BLK_READING; - osalSysUnlock(); - osalMutexLock(&lunp->msdp->mtx); while (n) { if (n > 0xffff) { blocks = 0xffff; @@ -900,15 +864,8 @@ bool usbhmsdLUNRead(USBHMassStorageLUNDriver *lunp, uint32_t startblk, ret = HAL_SUCCESS; exit: - osalMutexUnlock(&lunp->msdp->mtx); - osalSysLock(); - if (lunp->state == BLK_READING) { - lunp->state = BLK_READY; - } else { - osalDbgCheck(lunp->state == BLK_STOP); - uwarn("MSD: State = BLK_STOP"); - } - osalSysUnlock(); + lunp->state = BLK_READY; + chSemSignal(&lunp->sem); return ret; } @@ -921,15 +878,13 @@ bool usbhmsdLUNWrite(USBHMassStorageLUNDriver *lunp, uint32_t startblk, msd_result_t res; uint32_t actual_len; - osalSysLock(); + chSemWait(&lunp->sem); if (lunp->state != BLK_READY) { - osalSysUnlock(); + chSemSignal(&lunp->sem); return ret; } lunp->state = BLK_WRITING; - osalSysUnlock(); - osalMutexLock(&lunp->msdp->mtx); while (n) { if (n > 0xffff) { blocks = 0xffff; @@ -954,15 +909,8 @@ bool usbhmsdLUNWrite(USBHMassStorageLUNDriver *lunp, uint32_t startblk, ret = HAL_SUCCESS; exit: - osalMutexUnlock(&lunp->msdp->mtx); - osalSysLock(); - if (lunp->state == BLK_WRITING) { - lunp->state = BLK_READY; - } else { - osalDbgCheck(lunp->state == BLK_STOP); - uwarn("MSD: State = BLK_STOP"); - } - osalSysUnlock(); + lunp->state = BLK_READY; + chSemSignal(&lunp->sem); return ret; } @@ -976,38 +924,41 @@ bool usbhmsdLUNSync(USBHMassStorageLUNDriver *lunp) { bool usbhmsdLUNGetInfo(USBHMassStorageLUNDriver *lunp, BlockDeviceInfo *bdip) { osalDbgCheck(lunp != NULL); osalDbgCheck(bdip != NULL); - *bdip = lunp->info; - return HAL_SUCCESS; + + osalSysLock(); + if (lunp->state >= BLK_READY) { + *bdip = lunp->info; + osalSysUnlock(); + return HAL_SUCCESS; + } + osalSysUnlock(); + return HAL_FAILED; } bool usbhmsdLUNIsInserted(USBHMassStorageLUNDriver *lunp) { osalDbgCheck(lunp != NULL); - blkstate_t state; - osalSysLock(); - state = lunp->state; - osalSysUnlock(); - return (state >= BLK_ACTIVE); + return (lunp->state >= BLK_ACTIVE); } bool usbhmsdLUNIsProtected(USBHMassStorageLUNDriver *lunp) { osalDbgCheck(lunp != NULL); + //TODO: Implement return FALSE; } -void usbhmsdObjectInit(USBHMassStorageDriver *msdp) { +static void _msd_object_init(USBHMassStorageDriver *msdp) { osalDbgCheck(msdp != NULL); memset(msdp, 0, sizeof(*msdp)); msdp->info = &usbhmsdClassDriverInfo; - osalMutexObjectInit(&msdp->mtx); } -void usbhmsdInit(void) { +static void _msd_init(void) { uint8_t i; for (i = 0; i < HAL_USBHMSD_MAX_INSTANCES; i++) { - usbhmsdObjectInit(&USBHMSD[i]); + _msd_object_init(&USBHMSD[i]); } for (i = 0; i < HAL_USBHMSD_MAX_LUNS; i++) { - usbhmsdLUNObjectInit(&MSBLKD[i]); + _lun_object_init(&MSBLKD[i]); } } #endif diff --git a/os/hal/src/usbh/hal_usbh_uvc.c b/os/hal/src/usbh/hal_usbh_uvc.c index b0507a0..a795cd8 100644 --- a/os/hal/src/usbh/hal_usbh_uvc.c +++ b/os/hal/src/usbh/hal_usbh_uvc.c @@ -27,9 +27,9 @@ #error "USBHUVC needs HAL_USBH_USE_IAD" #endif +#include <string.h> #include "usbh/dev/uvc.h" #include "usbh/internal.h" -#include <string.h> #if USBHUVC_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) @@ -66,17 +66,18 @@ USBHUVCDriver USBHUVCD[HAL_USBHUVC_MAX_INSTANCES]; - -static usbh_baseclassdriver_t *uvc_load(usbh_device_t *dev, +static void _uvc_init(void); +static usbh_baseclassdriver_t *_uvc_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); -static void uvc_unload(usbh_baseclassdriver_t *drv); +static void _uvc_unload(usbh_baseclassdriver_t *drv); static const usbh_classdriver_vmt_t class_driver_vmt = { - uvc_load, - uvc_unload + _uvc_init, + _uvc_load, + _uvc_unload }; const usbh_classdriverinfo_t usbhuvcClassDriverInfo = { - 0x0e, 0x03, 0x00, "UVC", &class_driver_vmt + "UVC", &class_driver_vmt }; static bool _request(USBHUVCDriver *uvcdp, @@ -360,10 +361,8 @@ bool usbhuvcStreamStart(USBHUVCDriver *uvcdp, uint16_t min_ep_sz) { osalDbgCheck(msg); usbhURBObjectInit(&uvcdp->urb_iso, &uvcdp->ep_iso, _cb_iso, uvcdp, msg->data, uvcdp->ep_iso.wMaxPacketSize); } - osalSysLock(); - usbhURBSubmitI(&uvcdp->urb_iso); - osalOsRescheduleS(); - osalSysUnlock(); + + usbhURBSubmit(&uvcdp->urb_iso); ret = HAL_SUCCESS; goto exit; @@ -512,22 +511,13 @@ uint32_t usbhuvcEstimateRequiredEPSize(USBHUVCDriver *uvcdp, const uint8_t *form return (sz * mul) / div + 12; } -void usbhuvcObjectInit(USBHUVCDriver *uvcdp) { - osalDbgCheck(uvcdp != NULL); - memset(uvcdp, 0, sizeof(*uvcdp)); - uvcdp->info = &usbhuvcClassDriverInfo; - chMBObjectInit(&uvcdp->mb, uvcdp->mb_buff, HAL_USBHUVC_MAX_MAILBOX_SZ); - chMtxObjectInit(&uvcdp->mtx); - uvcdp->state = USBHUVC_STATE_STOP; -} - - -static usbh_baseclassdriver_t *uvc_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) { +static usbh_baseclassdriver_t *_uvc_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) { USBHUVCDriver *uvcdp; uint8_t i; - if (descriptor[1] != USBH_DT_INTERFACE_ASSOCIATION) + if (_usbh_match_descriptor(descriptor, rem, USBH_DT_INTERFACE_ASSOCIATION, + 0x0e, 0x03, 0x00) != HAL_SUCCESS) return NULL; /* alloc driver */ @@ -703,14 +693,14 @@ alloc_ok: osalSysLock(); usbhURBSubmitI(&uvcdp->urb_int); uvcdp->state = USBHUVC_STATE_ACTIVE; - osalOsRescheduleS(); + osalOsRescheduleS(); /* because of usbhURBSubmitI */ osalSysUnlock(); dev->keepFullCfgDesc++; return (usbh_baseclassdriver_t *)uvcdp; } -static void uvc_unload(usbh_baseclassdriver_t *drv) { +static void _uvc_unload(usbh_baseclassdriver_t *drv) { USBHUVCDriver *const uvcdp = (USBHUVCDriver *)drv; usbhuvcStreamStop(uvcdp); @@ -727,10 +717,19 @@ static void uvc_unload(usbh_baseclassdriver_t *drv) { osalSysUnlock(); } -void usbhuvcInit(void) { +static void _object_init(USBHUVCDriver *uvcdp) { + osalDbgCheck(uvcdp != NULL); + memset(uvcdp, 0, sizeof(*uvcdp)); + uvcdp->info = &usbhuvcClassDriverInfo; + chMBObjectInit(&uvcdp->mb, uvcdp->mb_buff, HAL_USBHUVC_MAX_MAILBOX_SZ); + chMtxObjectInit(&uvcdp->mtx); + uvcdp->state = USBHUVC_STATE_STOP; +} + +static void _uvc_init(void) { uint8_t i; for (i = 0; i < HAL_USBHUVC_MAX_INSTANCES; i++) { - usbhuvcObjectInit(&USBHUVCD[i]); + _object_init(&USBHUVCD[i]); } } diff --git a/os/various/fatfs_bindings/fatfs_diskio.c b/os/various/fatfs_bindings/fatfs_diskio.c index 6949310..9fa41e2 100644 --- a/os/various/fatfs_bindings/fatfs_diskio.c +++ b/os/various/fatfs_bindings/fatfs_diskio.c @@ -180,7 +180,6 @@ DRESULT disk_read ( /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ -#if _USE_WRITE DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber (0..) */ const BYTE *buff, /* Data to be written */ @@ -226,14 +225,12 @@ DRESULT disk_write ( } return RES_PARERR; } -#endif /* _USE_WRITE */ /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ -#if _USE_IOCTL DRESULT disk_ioctl ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE cmd, /* Control code */ @@ -246,11 +243,13 @@ DRESULT disk_ioctl ( switch (cmd) { case CTRL_SYNC: return RES_OK; +#if _MAX_SS > _MIN_SS case GET_SECTOR_SIZE: *((WORD *)buff) = MMCSD_BLOCK_SIZE; return RES_OK; -#if _USE_ERASE - case CTRL_ERASE_SECTOR: +#endif +#if _USE_TRIM + case CTRL_TRIM: mmcErase(&MMCD1, *((DWORD *)buff), *((DWORD *)buff + 1)); return RES_OK; #endif @@ -265,14 +264,16 @@ DRESULT disk_ioctl ( case GET_SECTOR_COUNT: *((DWORD *)buff) = mmcsdGetCardCapacity(&SDCD1); return RES_OK; +#if _MAX_SS > _MIN_SS case GET_SECTOR_SIZE: *((WORD *)buff) = MMCSD_BLOCK_SIZE; return RES_OK; +#endif case GET_BLOCK_SIZE: *((DWORD *)buff) = 256; /* 512b blocks in one erase block */ return RES_OK; -#if _USE_ERASE - case CTRL_ERASE_SECTOR: +#if _USE_TRIM + case CTRL_TRIM: sdcErase(&SDCD1, *((DWORD *)buff), *((DWORD *)buff + 1)); return RES_OK; #endif @@ -288,12 +289,14 @@ DRESULT disk_ioctl ( case GET_SECTOR_COUNT: *((DWORD *)buff) = MSBLKD[0].info.blk_num; return RES_OK; +#if _MAX_SS > _MIN_SS case GET_SECTOR_SIZE: *((WORD *)buff) = MSBLKD[0].info.blk_size; return RES_OK; -#if _USE_ERASE +#endif +#if _USE_TRIM #error "unimplemented yet!" -// case CTRL_ERASE_SECTOR: +// case CTRL_TRIM: // .... // return RES_OK; #endif @@ -304,7 +307,6 @@ DRESULT disk_ioctl ( } return RES_PARERR; } -#endif /* _USE_IOCTL */ DWORD get_fattime(void) { #if HAL_USE_RTC @@ -316,5 +318,3 @@ DWORD get_fattime(void) { return ((uint32_t)0 | (1 << 16)) | (1 << 21); /* wrong but valid time */ #endif } - - diff --git a/os/various/lib_scsi.c b/os/various/lib_scsi.c index 55aeb7e..ea2adda 100644 --- a/os/various/lib_scsi.c +++ b/os/various/lib_scsi.c @@ -159,7 +159,6 @@ static bool cmd_ignored(SCSITarget *scsip, const uint8_t *cmd) { (void)scsip; (void)cmd; - set_sense_ok(scsip); return SCSI_SUCCESS; } @@ -175,7 +174,12 @@ static bool cmd_ignored(SCSITarget *scsip, const uint8_t *cmd) { */ static bool inquiry(SCSITarget *scsip, const uint8_t *cmd) { - if ((cmd[1] & 0b11) || cmd[2] != 0) { + if ((cmd[1] & 0b1) && cmd[2] == 0x80) { + /* Unit serial number page */ + return transmit_data(scsip, (const uint8_t *)scsip->config->unit_serial_number_inquiry_response, + sizeof(scsi_unit_serial_number_inquiry_response_t)); + } + else if ((cmd[1] & 0b11) || cmd[2] != 0) { set_sense(scsip, SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_ASENSE_INVALID_FIELD_IN_CDB, SCSI_ASENSEQ_NO_QUALIFIER); @@ -199,10 +203,7 @@ static bool inquiry(SCSITarget *scsip, const uint8_t *cmd) { */ static bool request_sense(SCSITarget *scsip, const uint8_t *cmd) { - uint32_t tmp; - memcpy(&tmp, &cmd[1], 3); - - if ((tmp != 0) || (cmd[4] != sizeof(scsi_sense_response_t))) { + if (((cmd[1] & 0x01) != 0) || (cmd[4] != sizeof(scsi_sense_response_t))) { set_sense(scsip, SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_ASENSE_INVALID_FIELD_IN_CDB, SCSI_ASENSEQ_NO_QUALIFIER); @@ -378,6 +379,30 @@ static bool data_read_write10(SCSITarget *scsip, const uint8_t *cmd) { } return SCSI_SUCCESS; } + +/** + * @brief SCSI test unit ready command handler + * @details If block device is inserted, sets sense data in 'all OK' condition + * and returns success status. + * If block device is not inserted, sets sense data to 'Medium not present' considion, + * and returns check condition status. + */ +static bool test_unit_ready(SCSITarget *scsip, const uint8_t *cmd) { + (void)cmd; + + if (blkIsInserted(scsip->config->blkdev)) { + return SCSI_SUCCESS; + } + else { + warnprintf("SCSI Medium is not inserted.\r\n"); + set_sense(scsip, SCSI_SENSE_KEY_NOT_READY, + SCSI_ASENSE_MEDIUM_NOT_PRESENT, + SCSI_ASENSEQ_NO_QUALIFIER); + return SCSI_FAILED; + } + +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -398,54 +423,69 @@ static bool data_read_write10(SCSITarget *scsip, const uint8_t *cmd) { */ bool scsiExecCmd(SCSITarget *scsip, const uint8_t *cmd) { - /* status will be overwritten later in case of error */ - set_sense_ok(scsip); + bool ret = SCSI_SUCCESS; switch (cmd[0]) { case SCSI_CMD_INQUIRY: dbgprintf("SCSI_CMD_INQUIRY\r\n"); - return inquiry(scsip, cmd); + ret = inquiry(scsip, cmd); + break; case SCSI_CMD_REQUEST_SENSE: dbgprintf("SCSI_CMD_REQUEST_SENSE\r\n"); - return request_sense(scsip, cmd); + ret = request_sense(scsip, cmd); + break; case SCSI_CMD_READ_CAPACITY_10: dbgprintf("SCSI_CMD_READ_CAPACITY_10\r\n"); - return read_capacity10(scsip, cmd); + ret = read_capacity10(scsip, cmd); + break; case SCSI_CMD_READ_10: dbgprintf("SCSI_CMD_READ_10\r\n"); - return data_read_write10(scsip, cmd); + ret = data_read_write10(scsip, cmd); + break; case SCSI_CMD_WRITE_10: dbgprintf("SCSI_CMD_WRITE_10\r\n"); - return data_read_write10(scsip, cmd); + ret = data_read_write10(scsip, cmd); + break; case SCSI_CMD_TEST_UNIT_READY: dbgprintf("SCSI_CMD_TEST_UNIT_READY\r\n"); - return cmd_ignored(scsip, cmd); + ret = test_unit_ready(scsip, cmd); + break; case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: dbgprintf("SCSI_CMD_ALLOW_MEDIUM_REMOVAL\r\n"); - return cmd_ignored(scsip, cmd); + ret = cmd_ignored(scsip, cmd); + break; case SCSI_CMD_MODE_SENSE_6: dbgprintf("SCSI_CMD_MODE_SENSE_6\r\n"); - return mode_sense6(scsip, cmd); + ret = mode_sense6(scsip, cmd); + break; case SCSI_CMD_READ_FORMAT_CAPACITIES: dbgprintf("SCSI_CMD_READ_FORMAT_CAPACITIES\r\n"); - return read_format_capacities(scsip, cmd); + ret = read_format_capacities(scsip, cmd); + break; case SCSI_CMD_VERIFY_10: dbgprintf("SCSI_CMD_VERIFY_10\r\n"); - return cmd_ignored(scsip, cmd); + ret = cmd_ignored(scsip, cmd); + break; default: warnprintf("SCSI unhandled command: %X\r\n", cmd[0]); - return cmd_unhandled(scsip, cmd); + ret = cmd_unhandled(scsip, cmd); + break; } + + if (ret == SCSI_SUCCESS) + set_sense_ok(scsip); + + return ret; } /** diff --git a/os/various/lib_scsi.h b/os/various/lib_scsi.h index 97badb0..8384ae3 100644 --- a/os/various/lib_scsi.h +++ b/os/various/lib_scsi.h @@ -133,6 +133,17 @@ typedef struct PACKED_VAR { } scsi_inquiry_response_t; /** + * @brief Represents SCSI unit serial number inquiry response structure. + * @details See SCSI specification. + */ +typedef struct PACKED_VAR { + uint8_t peripheral; + uint8_t page_code; + uint8_t reserved; + uint8_t page_length; + uint8_t serianNumber[8]; +} scsi_unit_serial_number_inquiry_response_t; +/** * @brief Represents SCSI mode sense (6) request structure. * @details See SCSI specification. */ @@ -225,6 +236,10 @@ typedef struct { * @brief Pointer to SCSI inquiry response object. */ const scsi_inquiry_response_t *inquiry_response; + /** + * @brief Pointer to SCSI unit serial number inquiry response object. + */ + const scsi_unit_serial_number_inquiry_response_t *unit_serial_number_inquiry_response; } SCSITargetConfig; /** diff --git a/testhal/KINETIS/FRDM-K20D50M/I2C/chconf.h b/testhal/KINETIS/FRDM-K20D50M/I2C/chconf.h index eecc0a6..5f05547 100644 --- a/testhal/KINETIS/FRDM-K20D50M/I2C/chconf.h +++ b/testhal/KINETIS/FRDM-K20D50M/I2C/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/
/**
diff --git a/testhal/KINETIS/FRDM-K20D50M/USB_SERIAL/chconf.h b/testhal/KINETIS/FRDM-K20D50M/USB_SERIAL/chconf.h index bd97716..222c5ea 100644 --- a/testhal/KINETIS/FRDM-K20D50M/USB_SERIAL/chconf.h +++ b/testhal/KINETIS/FRDM-K20D50M/USB_SERIAL/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/KINETIS/FRDM-KL25Z/ADC/chconf.h b/testhal/KINETIS/FRDM-KL25Z/ADC/chconf.h index eecc0a6..5f05547 100644 --- a/testhal/KINETIS/FRDM-KL25Z/ADC/chconf.h +++ b/testhal/KINETIS/FRDM-KL25Z/ADC/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/
/**
diff --git a/testhal/KINETIS/FRDM-KL25Z/GPT/chconf.h b/testhal/KINETIS/FRDM-KL25Z/GPT/chconf.h index b7ffc80..5d231c8 100644 --- a/testhal/KINETIS/FRDM-KL25Z/GPT/chconf.h +++ b/testhal/KINETIS/FRDM-KL25Z/GPT/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/FRDM-KL25Z/PWM/chconf.h b/testhal/KINETIS/FRDM-KL25Z/PWM/chconf.h index 25dd7b8..2a25a25 100644 --- a/testhal/KINETIS/FRDM-KL25Z/PWM/chconf.h +++ b/testhal/KINETIS/FRDM-KL25Z/PWM/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/FRDM-KL25Z/USB_HID/chconf.h b/testhal/KINETIS/FRDM-KL25Z/USB_HID/chconf.h index 6774a44..424cf02 100644 --- a/testhal/KINETIS/FRDM-KL25Z/USB_HID/chconf.h +++ b/testhal/KINETIS/FRDM-KL25Z/USB_HID/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/FRDM-KL25Z/USB_SERIAL/chconf.h b/testhal/KINETIS/FRDM-KL25Z/USB_SERIAL/chconf.h index 7b54de5..e89ec1f 100644 --- a/testhal/KINETIS/FRDM-KL25Z/USB_SERIAL/chconf.h +++ b/testhal/KINETIS/FRDM-KL25Z/USB_SERIAL/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/FRDM-KL26Z/I2C/chconf.h b/testhal/KINETIS/FRDM-KL26Z/I2C/chconf.h index eecc0a6..5f05547 100644 --- a/testhal/KINETIS/FRDM-KL26Z/I2C/chconf.h +++ b/testhal/KINETIS/FRDM-KL26Z/I2C/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/
/**
diff --git a/testhal/KINETIS/FRDM-KL26Z/PWM/chconf.h b/testhal/KINETIS/FRDM-KL26Z/PWM/chconf.h index 8c37f87..9f9b3e9 100644 --- a/testhal/KINETIS/FRDM-KL26Z/PWM/chconf.h +++ b/testhal/KINETIS/FRDM-KL26Z/PWM/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/FRDM-KL26Z/USB_SERIAL/chconf.h b/testhal/KINETIS/FRDM-KL26Z/USB_SERIAL/chconf.h index c7ed185..9c9a479 100644 --- a/testhal/KINETIS/FRDM-KL26Z/USB_SERIAL/chconf.h +++ b/testhal/KINETIS/FRDM-KL26Z/USB_SERIAL/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/KL27Z/BLINK/chconf.h b/testhal/KINETIS/KL27Z/BLINK/chconf.h index 41259a0..49d21ae 100644 --- a/testhal/KINETIS/KL27Z/BLINK/chconf.h +++ b/testhal/KINETIS/KL27Z/BLINK/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/MCHCK/BOOTLOADER/chconf.h b/testhal/KINETIS/MCHCK/BOOTLOADER/chconf.h index b2448a9..a185459 100644 --- a/testhal/KINETIS/MCHCK/BOOTLOADER/chconf.h +++ b/testhal/KINETIS/MCHCK/BOOTLOADER/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/MCHCK/PWM/chconf.h b/testhal/KINETIS/MCHCK/PWM/chconf.h index 034c6cc..2f2938a 100644 --- a/testhal/KINETIS/MCHCK/PWM/chconf.h +++ b/testhal/KINETIS/MCHCK/PWM/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/MCHCK/USB_SERIAL/chconf.h b/testhal/KINETIS/MCHCK/USB_SERIAL/chconf.h index 7371b49..22272b1 100644 --- a/testhal/KINETIS/MCHCK/USB_SERIAL/chconf.h +++ b/testhal/KINETIS/MCHCK/USB_SERIAL/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY3_x/ADC/chconf.h b/testhal/KINETIS/TEENSY3_x/ADC/chconf.h index caae0c2..029e4ec 100644 --- a/testhal/KINETIS/TEENSY3_x/ADC/chconf.h +++ b/testhal/KINETIS/TEENSY3_x/ADC/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY3_x/EEPROM_EMU/chconf.h b/testhal/KINETIS/TEENSY3_x/EEPROM_EMU/chconf.h index ea87df8..3bb57de 100644 --- a/testhal/KINETIS/TEENSY3_x/EEPROM_EMU/chconf.h +++ b/testhal/KINETIS/TEENSY3_x/EEPROM_EMU/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY3_x/EXT/chconf.h b/testhal/KINETIS/TEENSY3_x/EXT/chconf.h index 0389bed..0be6605 100644 --- a/testhal/KINETIS/TEENSY3_x/EXT/chconf.h +++ b/testhal/KINETIS/TEENSY3_x/EXT/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY3_x/GPT/chconf.h b/testhal/KINETIS/TEENSY3_x/GPT/chconf.h index b2ed194..93ba7b8 100644 --- a/testhal/KINETIS/TEENSY3_x/GPT/chconf.h +++ b/testhal/KINETIS/TEENSY3_x/GPT/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY3_x/PWM/chconf.h b/testhal/KINETIS/TEENSY3_x/PWM/chconf.h index dda26e1..a661f7e 100644 --- a/testhal/KINETIS/TEENSY3_x/PWM/chconf.h +++ b/testhal/KINETIS/TEENSY3_x/PWM/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY3_x/SERIAL/chconf.h b/testhal/KINETIS/TEENSY3_x/SERIAL/chconf.h index 95b505a..27ed81c 100644 --- a/testhal/KINETIS/TEENSY3_x/SERIAL/chconf.h +++ b/testhal/KINETIS/TEENSY3_x/SERIAL/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY3_x/USB_SERIAL/chconf.h b/testhal/KINETIS/TEENSY3_x/USB_SERIAL/chconf.h index 7d9ace3..6dbecb5 100644 --- a/testhal/KINETIS/TEENSY3_x/USB_SERIAL/chconf.h +++ b/testhal/KINETIS/TEENSY3_x/USB_SERIAL/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY_LC/BOOTLOADER/chconf.h b/testhal/KINETIS/TEENSY_LC/BOOTLOADER/chconf.h index d6a7bf8..f0c238c 100644 --- a/testhal/KINETIS/TEENSY_LC/BOOTLOADER/chconf.h +++ b/testhal/KINETIS/TEENSY_LC/BOOTLOADER/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY_LC/EEPROM_EMU/chconf.h b/testhal/KINETIS/TEENSY_LC/EEPROM_EMU/chconf.h index 919e2b0..97c98b7 100644 --- a/testhal/KINETIS/TEENSY_LC/EEPROM_EMU/chconf.h +++ b/testhal/KINETIS/TEENSY_LC/EEPROM_EMU/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/KINETIS/TEENSY_LC/PWM/chconf.h b/testhal/KINETIS/TEENSY_LC/PWM/chconf.h index b18de54..d910706 100644 --- a/testhal/KINETIS/TEENSY_LC/PWM/chconf.h +++ b/testhal/KINETIS/TEENSY_LC/PWM/chconf.h @@ -27,6 +27,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/MSP430X/EXP430FR5969/ADC/chconf.h b/testhal/MSP430X/EXP430FR5969/ADC/chconf.h index 3b7a8e1..0678ca4 100644 --- a/testhal/MSP430X/EXP430FR5969/ADC/chconf.h +++ b/testhal/MSP430X/EXP430FR5969/ADC/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_NIL_CONF_
+#define _CHIBIOS_NIL_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/MSP430X/EXP430FR5969/DMA/chconf.h b/testhal/MSP430X/EXP430FR5969/DMA/chconf.h index cb45526..0a5657c 100644 --- a/testhal/MSP430X/EXP430FR5969/DMA/chconf.h +++ b/testhal/MSP430X/EXP430FR5969/DMA/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_NIL_CONF_
+#define _CHIBIOS_NIL_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/MSP430X/EXP430FR5969/SPI/chconf.h b/testhal/MSP430X/EXP430FR5969/SPI/chconf.h index cb45526..0a5657c 100644 --- a/testhal/MSP430X/EXP430FR5969/SPI/chconf.h +++ b/testhal/MSP430X/EXP430FR5969/SPI/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_NIL_CONF_
+#define _CHIBIOS_NIL_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/NRF51/NRF51822/ADC/chconf.h b/testhal/NRF51/NRF51822/ADC/chconf.h index 71b3bb4..790132e 100644 --- a/testhal/NRF51/NRF51822/ADC/chconf.h +++ b/testhal/NRF51/NRF51822/ADC/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/NRF51/NRF51822/EXT/chconf.h b/testhal/NRF51/NRF51822/EXT/chconf.h index 50218e4..eeb3fa3 100644 --- a/testhal/NRF51/NRF51822/EXT/chconf.h +++ b/testhal/NRF51/NRF51822/EXT/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/NRF51/NRF51822/GPT/chconf.h b/testhal/NRF51/NRF51822/GPT/chconf.h index 71b3bb4..790132e 100644 --- a/testhal/NRF51/NRF51822/GPT/chconf.h +++ b/testhal/NRF51/NRF51822/GPT/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/NRF51/NRF51822/I2C/chconf.h b/testhal/NRF51/NRF51822/I2C/chconf.h index 3d441c6..3f6766a 100644 --- a/testhal/NRF51/NRF51822/I2C/chconf.h +++ b/testhal/NRF51/NRF51822/I2C/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/NRF51/NRF51822/PWM/chconf.h b/testhal/NRF51/NRF51822/PWM/chconf.h index a753ec9..14c1bf3 100644 --- a/testhal/NRF51/NRF51822/PWM/chconf.h +++ b/testhal/NRF51/NRF51822/PWM/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/NRF51/NRF51822/RNG/chconf.h b/testhal/NRF51/NRF51822/RNG/chconf.h index c0af32b..ed43625 100644 --- a/testhal/NRF51/NRF51822/RNG/chconf.h +++ b/testhal/NRF51/NRF51822/RNG/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/NRF51/NRF51822/SPI/chconf.h b/testhal/NRF51/NRF51822/SPI/chconf.h index f777f9d..49a050a 100644 --- a/testhal/NRF51/NRF51822/SPI/chconf.h +++ b/testhal/NRF51/NRF51822/SPI/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/NRF51/NRF51822/WDG/chconf.h b/testhal/NRF51/NRF51822/WDG/chconf.h index 4477bd5..9952575 100644 --- a/testhal/NRF51/NRF51822/WDG/chconf.h +++ b/testhal/NRF51/NRF51822/WDG/chconf.h @@ -29,6 +29,7 @@ #define _CHCONF_H_
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F0xx/crc/chconf.h b/testhal/STM32/STM32F0xx/crc/chconf.h index c2d6f04..6a187da 100644 --- a/testhal/STM32/STM32F0xx/crc/chconf.h +++ b/testhal/STM32/STM32F0xx/crc/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F0xx/onewire/chconf.h b/testhal/STM32/STM32F0xx/onewire/chconf.h index 724dc02..4b2d922 100644 --- a/testhal/STM32/STM32F0xx/onewire/chconf.h +++ b/testhal/STM32/STM32F0xx/onewire/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F0xx/qei/chconf.h b/testhal/STM32/STM32F0xx/qei/chconf.h index 71cbe47..b3260d4 100644 --- a/testhal/STM32/STM32F0xx/qei/chconf.h +++ b/testhal/STM32/STM32F0xx/qei/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F1xx/onewire/chconf.h b/testhal/STM32/STM32F1xx/onewire/chconf.h index ee20e3c..b38dfa3 100644 --- a/testhal/STM32/STM32F1xx/onewire/chconf.h +++ b/testhal/STM32/STM32F1xx/onewire/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F1xx/qei/chconf.h b/testhal/STM32/STM32F1xx/qei/chconf.h index 71cbe47..b3260d4 100644 --- a/testhal/STM32/STM32F1xx/qei/chconf.h +++ b/testhal/STM32/STM32F1xx/qei/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F3xx/COMP/chconf.h b/testhal/STM32/STM32F3xx/COMP/chconf.h index 00eb395..894f737 100644 --- a/testhal/STM32/STM32F3xx/COMP/chconf.h +++ b/testhal/STM32/STM32F3xx/COMP/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F3xx/EEProm/chconf.h b/testhal/STM32/STM32F3xx/EEProm/chconf.h index 00eb395..894f737 100644 --- a/testhal/STM32/STM32F3xx/EEProm/chconf.h +++ b/testhal/STM32/STM32F3xx/EEProm/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F3xx/TIMCAP/chconf.h b/testhal/STM32/STM32F3xx/TIMCAP/chconf.h index 00eb395..894f737 100644 --- a/testhal/STM32/STM32F3xx/TIMCAP/chconf.h +++ b/testhal/STM32/STM32F3xx/TIMCAP/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F4xx/EICU/chconf.h b/testhal/STM32/STM32F4xx/EICU/chconf.h index ad6b53a..736770d 100644 --- a/testhal/STM32/STM32F4xx/EICU/chconf.h +++ b/testhal/STM32/STM32F4xx/EICU/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F4xx/FSMC_NAND/chconf.h b/testhal/STM32/STM32F4xx/FSMC_NAND/chconf.h index 1065821..cf950cd 100644 --- a/testhal/STM32/STM32F4xx/FSMC_NAND/chconf.h +++ b/testhal/STM32/STM32F4xx/FSMC_NAND/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/chconf.h b/testhal/STM32/STM32F4xx/FSMC_SDRAM/chconf.h index 1065821..cf950cd 100644 --- a/testhal/STM32/STM32F4xx/FSMC_SDRAM/chconf.h +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/STM32/STM32F4xx/FSMC_SRAM/chconf.h b/testhal/STM32/STM32F4xx/FSMC_SRAM/chconf.h index 1065821..cf950cd 100644 --- a/testhal/STM32/STM32F4xx/FSMC_SRAM/chconf.h +++ b/testhal/STM32/STM32F4xx/FSMC_SRAM/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/STM32/STM32F4xx/USB_HOST/Makefile b/testhal/STM32/STM32F4xx/USB_HOST/Makefile index 0174baf..dfda9ac 100644 --- a/testhal/STM32/STM32F4xx/USB_HOST/Makefile +++ b/testhal/STM32/STM32F4xx/USB_HOST/Makefile @@ -102,7 +102,7 @@ include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk include $(CHIBIOS)/test/rt/test.mk
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
include $(CHIBIOS)/os/various/shell/shell.mk
-include $(CHIBIOS)/os/various/fatfs_bindings/fatfs.mk
+include $(CHIBIOS_CONTRIB)/os/various/fatfs_bindings/fatfs.mk
# Define linker script file here
LDSCRIPT= $(STARTUPLD)/STM32F407xG.ld
@@ -120,7 +120,7 @@ CSRC = $(STARTUPSRC) \ $(FATFSSRC) \
$(STREAMSSRC) \
$(SHELLSRC) \
- main.c
+ main.c usbh_custom_class_example.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
diff --git a/testhal/STM32/STM32F4xx/USB_HOST/chconf.h b/testhal/STM32/STM32F4xx/USB_HOST/chconf.h index 449cb3d..e112daf 100644 --- a/testhal/STM32/STM32F4xx/USB_HOST/chconf.h +++ b/testhal/STM32/STM32F4xx/USB_HOST/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H
#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_5_0_
/*===========================================================================*/
/**
diff --git a/testhal/STM32/STM32F4xx/USB_HOST/ffconf.h b/testhal/STM32/STM32F4xx/USB_HOST/ffconf.h deleted file mode 100644 index 42388a2..0000000 --- a/testhal/STM32/STM32F4xx/USB_HOST/ffconf.h +++ /dev/null @@ -1,229 +0,0 @@ -/* CHIBIOS FIX */
-#include "ch.h"
-
-/*---------------------------------------------------------------------------/
-/ FatFs - FAT file system module configuration file R0.10b (C)ChaN, 2014
-/---------------------------------------------------------------------------*/
-
-#ifndef _FFCONF
-#define _FFCONF 8051 /* Revision ID */
-
-/*---------------------------------------------------------------------------/
-/ Functions and Buffer Configurations
-/---------------------------------------------------------------------------*/
-
-#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
-/* When _FS_TINY is set to 1, it reduces memory consumption _MAX_SS bytes each
-/ file object. For file data transfer, FatFs uses the common sector buffer in
-/ the file system object (FATFS) instead of private sector buffer eliminated
-/ from the file object (FIL). */
-
-
-#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
-/* Setting _FS_READONLY to 1 defines read only configuration. This removes
-/ writing functions, f_write(), f_sync(), f_unlink(), f_mkdir(), f_chmod(),
-/ f_rename(), f_truncate() and useless f_getfree(). */
-
-
-#define _FS_MINIMIZE 0 /* 0 to 3 */
-/* The _FS_MINIMIZE option defines minimization level to remove API functions.
-/
-/ 0: All basic functions are enabled.
-/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
-/ f_truncate() and f_rename() function are removed.
-/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
-/ 3: f_lseek() function is removed in addition to 2. */
-
-
-#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */
-/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
-
-
-#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
-/* To enable f_mkfs() function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
-
-
-#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
-/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
-
-
-#define _USE_LABEL 0 /* 0:Disable or 1:Enable */
-/* To enable volume label functions, set _USE_LAVEL to 1 */
-
-
-#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
-/* To enable f_forward() function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
-
-
-/*---------------------------------------------------------------------------/
-/ Locale and Namespace Configurations
-/---------------------------------------------------------------------------*/
-
-#define _CODE_PAGE 1252
-/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
-/ Incorrect setting of the code page can cause a file open failure.
-/
-/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
-/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
-/ 949 - Korean (DBCS, OEM, Windows)
-/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
-/ 1250 - Central Europe (Windows)
-/ 1251 - Cyrillic (Windows)
-/ 1252 - Latin 1 (Windows)
-/ 1253 - Greek (Windows)
-/ 1254 - Turkish (Windows)
-/ 1255 - Hebrew (Windows)
-/ 1256 - Arabic (Windows)
-/ 1257 - Baltic (Windows)
-/ 1258 - Vietnam (OEM, Windows)
-/ 437 - U.S. (OEM)
-/ 720 - Arabic (OEM)
-/ 737 - Greek (OEM)
-/ 775 - Baltic (OEM)
-/ 850 - Multilingual Latin 1 (OEM)
-/ 858 - Multilingual Latin 1 + Euro (OEM)
-/ 852 - Latin 2 (OEM)
-/ 855 - Cyrillic (OEM)
-/ 866 - Russian (OEM)
-/ 857 - Turkish (OEM)
-/ 862 - Hebrew (OEM)
-/ 874 - Thai (OEM, Windows)
-/ 1 - ASCII (Valid for only non-LFN configuration) */
-
-
-#define _USE_LFN 0 /* 0 to 3 */
-#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
-/* The _USE_LFN option switches the LFN feature.
-/
-/ 0: Disable LFN feature. _MAX_LFN has no effect.
-/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
-/ 2: Enable LFN with dynamic working buffer on the STACK.
-/ 3: Enable LFN with dynamic working buffer on the HEAP.
-/
-/ When enable LFN feature, Unicode handling functions ff_convert() and ff_wtoupper()
-/ function must be added to the project.
-/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When use stack for the
-/ working buffer, take care on stack overflow. When use heap memory for the working
-/ buffer, memory management functions, ff_memalloc() and ff_memfree(), must be added
-/ to the project. */
-
-
-#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
-/* To switch the character encoding on the FatFs API (TCHAR) to Unicode, enable LFN
-/ feature and set _LFN_UNICODE to 1. This option affects behavior of string I/O
-/ functions. This option must be 0 when LFN feature is not enabled. */
-
-
-#define _STRF_ENCODE 3 /* 0:ANSI/OEM, 1:UTF-16LE, 2:UTF-16BE, 3:UTF-8 */
-/* When Unicode API is enabled by _LFN_UNICODE option, this option selects the character
-/ encoding on the file to be read/written via string I/O functions, f_gets(), f_putc(),
-/ f_puts and f_printf(). This option has no effect when Unicode API is not enabled. */
-
-
-#define _FS_RPATH 0 /* 0 to 2 */
-/* The _FS_RPATH option configures relative path feature.
-/
-/ 0: Disable relative path feature and remove related functions.
-/ 1: Enable relative path. f_chdrive() and f_chdir() function are available.
-/ 2: f_getcwd() function is available in addition to 1.
-/
-/ Note that output of the f_readdir() fnction is affected by this option. */
-
-
-/*---------------------------------------------------------------------------/
-/ Drive/Volume Configurations
-/---------------------------------------------------------------------------*/
-
-#define _VOLUMES 1
-/* Number of volumes (logical drives) to be used. */
-
-
-#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */
-#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
-/* When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
-/ number in the path name. _VOLUME_STRS defines the drive ID strings for each logical
-/ drives. Number of items must be equal to _VOLUMES. Valid characters for the drive ID
-/ strings are: 0-9 and A-Z. */
-
-
-#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Enable multiple partition */
-/* By default(0), each logical drive number is bound to the same physical drive number
-/ and only a FAT volume found on the physical drive is mounted. When it is set to 1,
-/ each logical drive number is bound to arbitrary drive/partition listed in VolToPart[].
-*/
-
-
-#define _MIN_SS 512
-#define _MAX_SS 512
-/* These options configure the range of sector size to be supported. (512, 1024, 2048 or
-/ 4096) Always set both 512 for most systems, all memory card and harddisk. But a larger
-/ value may be required for on-board flash memory and some type of optical media.
-/ When _MAX_SS is larger than _MIN_SS, FatFs is configured to variable sector size and
-/ GET_SECTOR_SIZE command must be implemented to the disk_ioctl() function. */
-
-
-#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
-/* To enable sector erase feature, set _USE_ERASE to 1. Also CTRL_ERASE_SECTOR command
-/ should be added to the disk_ioctl() function. */
-
-
-#define _FS_NOFSINFO 0 /* 0 to 3 */
-/* If you need to know correct free space on the FAT32 volume, set bit 0 of this option
-/ and f_getfree() function at first time after volume mount will force a full FAT scan.
-/ Bit 1 controls the last allocated cluster number as bit 0.
-/
-/ bit0=0: Use free cluster count in the FSINFO if available.
-/ bit0=1: Do not trust free cluster count in the FSINFO.
-/ bit1=0: Use last allocated cluster number in the FSINFO if available.
-/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
-*/
-
-
-
-/*---------------------------------------------------------------------------/
-/ System Configurations
-/---------------------------------------------------------------------------*/
-
-#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */
-/* To enable file lock control feature, set _FS_LOCK to non-zero value.
-/ The value defines how many files/sub-directories can be opened simultaneously
-/ with file lock control. This feature uses bss _FS_LOCK * 12 bytes. */
-
-
-#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
-#define _FS_TIMEOUT MS2ST(1000) /* Timeout period in unit of time tick */
-#define _SYNC_t semaphore_t* /* O/S dependent sync object type. e.g. HANDLE, OS_EVENT*, ID, SemaphoreHandle_t and etc.. */
-/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs module.
-/
-/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
-/ 1: Enable re-entrancy. Also user provided synchronization handlers,
-/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
-/ function must be added to the project.
-*/
-
-
-#define _WORD_ACCESS 0 /* 0 or 1 */
-/* The _WORD_ACCESS option is an only platform dependent option. It defines
-/ which access method is used to the word data on the FAT volume.
-/
-/ 0: Byte-by-byte access. Always compatible with all platforms.
-/ 1: Word access. Do not choose this unless under both the following conditions.
-/
-/ * Address misaligned memory access is always allowed for ALL instructions.
-/ * Byte order on the memory is little-endian.
-/
-/ If it is the case, _WORD_ACCESS can also be set to 1 to improve performance and
-/ reduce code size. Following table shows an example of some processor types.
-/
-/ ARM7TDMI 0 ColdFire 0 V850E2 0
-/ Cortex-M3 0 Z80 0/1 V850ES 0/1
-/ Cortex-M0 0 RX600(LE) 0/1 TLCS-870 0/1
-/ AVR 0/1 RX600(BE) 0 TLCS-900 0/1
-/ AVR32 0 RL78 0 R32C 0
-/ PIC18 0/1 SH-2 0 M16C 0/1
-/ PIC24 0 H8S 0 MSP430 0
-/ PIC32 0 H8/300H 0 x86 0/1
-*/
-
-
-#endif /* _FFCONF */
diff --git a/testhal/STM32/STM32F4xx/USB_HOST/halconf_community.h b/testhal/STM32/STM32F4xx/USB_HOST/halconf_community.h index 51e9a8d..9b22a79 100644 --- a/testhal/STM32/STM32F4xx/USB_HOST/halconf_community.h +++ b/testhal/STM32/STM32F4xx/USB_HOST/halconf_community.h @@ -89,6 +89,7 @@ #define HAL_USBH_PORT_DEBOUNCE_TIME 200
#define HAL_USBH_PORT_RESET_TIMEOUT 500
#define HAL_USBH_DEVICE_ADDRESS_STABILIZATION 20
+#define HAL_USBH_CONTROL_REQUEST_DEFAULT_TIMEOUT MS2ST(1000)
/* MSD */
#define HAL_USBH_USE_MSD TRUE
@@ -141,6 +142,8 @@ #define HAL_USBHHUB_MAX_INSTANCES 1
#define HAL_USBHHUB_MAX_PORTS 6
+#define HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS TRUE
+
/* debug */
#define USBH_DEBUG_ENABLE TRUE
#define USBH_DEBUG_USBHD USBHD1
diff --git a/testhal/STM32/STM32F4xx/USB_HOST/main.c b/testhal/STM32/STM32F4xx/USB_HOST/main.c index 9652da3..c540233 100644 --- a/testhal/STM32/STM32F4xx/USB_HOST/main.c +++ b/testhal/STM32/STM32F4xx/USB_HOST/main.c @@ -18,8 +18,10 @@ #include "hal.h"
#include "ff.h"
#include <string.h>
+#include "usbh/debug.h" /* for usbDbgPuts/usbDbgPrintf */
-#define UVC_TO_MSD_PHOTOS_CAPTURE TRUE
+
+#define UVC_TO_MSD_PHOTOS_CAPTURE FALSE
#if HAL_USBH_USE_FTDI || HAL_USBH_USE_AOA
@@ -84,6 +86,8 @@ static void ThreadTestFTDI(void *p) { (void)p;
USBHFTDIPortDriver *const ftdipp = &FTDIPD[0];
+ chRegSetThreadName("FTDI");
+
shellInit();
start:
@@ -127,7 +131,6 @@ start: shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE,
"shell", NORMALPRIO,
shellThread, (void *)&shell_cfg1);
-
} else if (chThdTerminatedX(shelltp)) {
chThdRelease(shelltp);
if (usbhftdipGetState(ftdipp) != USBHFTDIP_STATE_READY)
@@ -216,6 +219,8 @@ static void ThreadTestAOA(void *p) { USBHAOADriver *const aoap = &USBHAOAD[0];
USBHAOAChannel *const aoacp = &aoap->channel;
+ chRegSetThreadName("AOA");
+
start:
while (usbhaoaGetState(aoap) != USBHAOA_STATE_READY) {
chThdSleepMilliseconds(100);
@@ -301,34 +306,26 @@ static FIL file; static FRESULT scan_files(BaseSequentialStream *chp, char *path) {
FRESULT res;
- FILINFO fno;
DIR dir;
- int i;
- char *fn;
+ UINT i;
+ static FILINFO fno;
-#if _USE_LFN
- fno.lfname = 0;
- fno.lfsize = 0;
-#endif
res = f_opendir(&dir, path);
if (res == FR_OK) {
- i = strlen(path);
for (;;) {
res = f_readdir(&dir, &fno);
if (res != FR_OK || fno.fname[0] == 0)
break;
- if (fno.fname[0] == '.')
- continue;
- fn = fno.fname;
if (fno.fattrib & AM_DIR) {
+ i = strlen(path);
path[i++] = '/';
- strcpy(&path[i], fn);
+ strcpy(&path[i], fno.fname);
res = scan_files(chp, path);
if (res != FR_OK)
break;
path[--i] = 0;
} else {
- usbDbgPrintf("FS: %s/%s", path, fn);
+ usbDbgPrintf("FS: %s/%s", path, fno.fname);
}
}
}
@@ -336,14 +333,16 @@ static FRESULT scan_files(BaseSequentialStream *chp, char *path) { }
#endif
-static THD_WORKING_AREA(waTestMSD, 1024);
+static THD_WORKING_AREA(waTestMSD, 1300);
static void ThreadTestMSD(void *p) {
(void)p;
FATFS *fsp;
DWORD clusters;
FRESULT res;
- blkstate_t state;
+
+ chRegSetThreadName("MSD");
+
#if !UVC_TO_MSD_PHOTOS_CAPTURE
BaseSequentialStream * const chp = (BaseSequentialStream *)&USBH_DEBUG_SD;
systime_t st, et;
@@ -354,11 +353,15 @@ start: for(;;) {
chThdSleepMilliseconds(100);
- chSysLock();
- state = blkGetDriverState(&MSBLKD[0]);
- chSysUnlock();
- if (state != BLK_READY)
+ if (blkGetDriverState(&MSBLKD[0]) == BLK_ACTIVE) {
+ usbDbgPuts("BLK: Active, connect....");
+ usbhmsdLUNConnect(&MSBLKD[0]);
+ }
+ if (blkGetDriverState(&MSBLKD[0]) != BLK_READY) {
continue;
+ }
+
+ usbDbgPuts("BLK: Ready.");
#if !UVC_TO_MSD_PHOTOS_CAPTURE
//raw read test
@@ -371,7 +374,8 @@ start: usbDbgPrintf("BLK: Raw read test (%dMB, %dB blocks)", RAW_READ_SZ_MB, sizeof(fbuff));
st = chVTGetSystemTime();
for (j = 0; j < NITERATIONS; j++) {
- blkRead(&MSBLKD[0], start, fbuff, NBLOCKS);
+ if (blkRead(&MSBLKD[0], start, fbuff, NBLOCKS) != HAL_SUCCESS)
+ goto start;
start += NBLOCKS;
}
et = chVTGetSystemTime();
@@ -509,6 +513,8 @@ static void ThreadTestHID(void *p) { uint8_t i;
static uint8_t kbd_led_states[HAL_USBHHID_MAX_INSTANCES];
+ chRegSetThreadName("HID");
+
for (i = 0; i < HAL_USBHHID_MAX_INSTANCES; i++) {
hidcfg[i].cb_report = _hid_report_callback;
hidcfg[i].protocol = USBHHID_PROTOCOL_BOOT;
@@ -619,6 +625,8 @@ static void ThreadTestUVC(void *p) { (void)p;
USBHUVCDriver *const uvcdp = &USBHUVCD[0];
+ chRegSetThreadName("UVC");
+
for(;;) {
chThdSleepMilliseconds(100);
@@ -914,6 +922,7 @@ int main(void) { //turn on USB power
palClearPad(GPIOC, GPIOC_OTG_FS_POWER_ON);
+ chThdSleepMilliseconds(100);
//start
#if STM32_USBH_USE_OTG1
diff --git a/testhal/STM32/STM32F4xx/USB_HOST/usbh_additional_class_drivers.h b/testhal/STM32/STM32F4xx/USB_HOST/usbh_additional_class_drivers.h new file mode 100644 index 0000000..ac9fc18 --- /dev/null +++ b/testhal/STM32/STM32F4xx/USB_HOST/usbh_additional_class_drivers.h @@ -0,0 +1,38 @@ +/* + ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio + Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef USBH_ADDITIONAL_H_ +#define USBH_ADDITIONAL_H_ + +#include "hal_usbh.h" + +#if HAL_USE_USBH && HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS + +/* Declarations */ +extern const usbh_classdriverinfo_t usbhCustomClassDriverInfo; + + + +/* Comma separated list of additional class drivers */ +#define HAL_USBH_ADDITIONAL_CLASS_DRIVERS \ + &usbhCustomClassDriverInfo, + + + +#endif + +#endif /* USBH_ADDITIONAL_H_ */ diff --git a/testhal/STM32/STM32F4xx/USB_HOST/usbh_custom_class_example.c b/testhal/STM32/STM32F4xx/USB_HOST/usbh_custom_class_example.c new file mode 100644 index 0000000..4585a5c --- /dev/null +++ b/testhal/STM32/STM32F4xx/USB_HOST/usbh_custom_class_example.c @@ -0,0 +1,144 @@ +/* + ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio + Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "hal.h" + +#if HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS + +#include <string.h> +#include "usbh_custom_class_example.h" +#include "usbh/internal.h" + +#if USBH_DEBUG_ENABLE_TRACE +#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) +#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) +#else +#define udbgf(f, ...) do {} while(0) +#define udbg(f, ...) do {} while(0) +#endif + +#if USBH_DEBUG_ENABLE_INFO +#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) +#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__) +#else +#define uinfof(f, ...) do {} while(0) +#define uinfo(f, ...) do {} while(0) +#endif + +#if USBH_DEBUG_ENABLE_WARNINGS +#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) +#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__) +#else +#define uwarnf(f, ...) do {} while(0) +#define uwarn(f, ...) do {} while(0) +#endif + +#if USBH_DEBUG_ENABLE_ERRORS +#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) +#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__) +#else +#define uerrf(f, ...) do {} while(0) +#define uerr(f, ...) do {} while(0) +#endif + +/*===========================================================================*/ +/* USB Class driver loader for Custom Class Example */ +/*===========================================================================*/ + +USBHCustomDriver USBHCUSTOMD[USBH_CUSTOM_CLASS_MAX_INSTANCES]; + +static void _init(void); +static usbh_baseclassdriver_t *_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); +static void _unload(usbh_baseclassdriver_t *drv); + +static const usbh_classdriver_vmt_t class_driver_vmt = { + _init, + _load, + _unload +}; + +const usbh_classdriverinfo_t usbhCustomClassDriverInfo = { + "CUSTOM", &class_driver_vmt +}; + +static usbh_baseclassdriver_t *_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) { + int i; + USBHCustomDriver *custp; + (void)dev; + + if (_usbh_match_vid_pid(dev, 0xABCD, 0x0123) != HAL_SUCCESS) + return NULL; + + const usbh_interface_descriptor_t * const ifdesc = (const usbh_interface_descriptor_t *)descriptor; + + /* alloc driver */ + for (i = 0; i < USBH_CUSTOM_CLASS_MAX_INSTANCES; i++) { + if (USBHCUSTOMD[i].dev == NULL) { + custp = &USBHCUSTOMD[i]; + goto alloc_ok; + } + } + + uwarn("Can't alloc CUSTOM driver"); + + /* can't alloc */ + return NULL; + +alloc_ok: + /* initialize the driver's variables */ + custp->ifnum = ifdesc->bInterfaceNumber; + + /* parse the configuration descriptor */ + if_iterator_t iif; + generic_iterator_t iep; + iif.iad = 0; + iif.curr = descriptor; + iif.rem = rem; + for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) { + const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep); + if ((epdesc->bEndpointAddress & 0x80) && (epdesc->bmAttributes == USBH_EPTYPE_INT)) { + /* ... */ + } else { + uinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x", + epdesc->bEndpointAddress, epdesc->bmAttributes); + } + } + + custp->state = USBHCUSTOM_STATE_ACTIVE; + + return (usbh_baseclassdriver_t *)custp; + +} + +static void _unload(usbh_baseclassdriver_t *drv) { + (void)drv; +} + +static void _object_init(USBHCustomDriver *custp) { + osalDbgCheck(custp != NULL); + memset(custp, 0, sizeof(*custp)); + custp->state = USBHCUSTOM_STATE_STOP; +} + +static void _init(void) { + uint8_t i; + for (i = 0; i < USBH_CUSTOM_CLASS_MAX_INSTANCES; i++) { + _object_init(&USBHCUSTOMD[i]); + } +} + +#endif diff --git a/testhal/STM32/STM32F4xx/USB_HOST/usbh_custom_class_example.h b/testhal/STM32/STM32F4xx/USB_HOST/usbh_custom_class_example.h new file mode 100644 index 0000000..3f00fe7 --- /dev/null +++ b/testhal/STM32/STM32F4xx/USB_HOST/usbh_custom_class_example.h @@ -0,0 +1,80 @@ +/* + ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio + Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef USBH_CUSTOM_H_ +#define USBH_CUSTOM_H_ + +#include "hal_usbh.h" + +#if HAL_USE_USBH && HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ +#define USBH_CUSTOM_CLASS_MAX_INSTANCES 1 + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +typedef enum { + USBHCUSTOM_STATE_UNINIT = 0, + USBHCUSTOM_STATE_STOP = 1, + USBHCUSTOM_STATE_ACTIVE = 2, + USBHCUSTOM_STATE_READY = 3 +} usbhcustom_state_t; + +typedef struct USBHCustomDriver USBHCustomDriver; + +struct USBHCustomDriver { + /* inherited from abstract class driver */ + _usbh_base_classdriver_data + + uint8_t ifnum; + + usbhcustom_state_t state; +}; + + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern USBHCustomDriver USBHCUSTOMD[USBH_CUSTOM_CLASS_MAX_INSTANCES]; + +#ifdef __cplusplus +extern "C" { +#endif + /* API goes here */ + +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* USBH_CUSTOM_H_ */ diff --git a/testhal/STM32/STM32F4xx/onewire/chconf.h b/testhal/STM32/STM32F4xx/onewire/chconf.h index 1065821..cf950cd 100644 --- a/testhal/STM32/STM32F4xx/onewire/chconf.h +++ b/testhal/STM32/STM32F4xx/onewire/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/STM32/STM32F7xx/USB_MSD/chconf.h b/testhal/STM32/STM32F7xx/USB_MSD/chconf.h index 8bdd9f2..346c876 100644 --- a/testhal/STM32/STM32F7xx/USB_MSD/chconf.h +++ b/testhal/STM32/STM32F7xx/USB_MSD/chconf.h @@ -29,6 +29,7 @@ #define CHCONF_H #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/STM32/STM32F7xx/USB_MSD/main.c b/testhal/STM32/STM32F7xx/USB_MSD/main.c index cae2b74..87ca8d2 100644 --- a/testhal/STM32/STM32F7xx/USB_MSD/main.c +++ b/testhal/STM32/STM32F7xx/USB_MSD/main.c @@ -102,7 +102,7 @@ int main(void) { * start mass storage */ msdObjectInit(&USBMSD1); - msdStart(&USBMSD1, &USBD1, (BaseBlockDevice *)&ramdisk, blkbuf, NULL); + msdStart(&USBMSD1, &USBD1, (BaseBlockDevice *)&ramdisk, blkbuf, NULL, NULL); /* * diff --git a/testhal/TIVA/TM4C123x/ADC/.cproject b/testhal/TIVA/TM4C123x/ADC/.cproject new file mode 100644 index 0000000..c62a6c8 --- /dev/null +++ b/testhal/TIVA/TM4C123x/ADC/.cproject @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> + <storageModule moduleId="org.eclipse.cdt.core.settings"> + <cconfiguration id="0.114656749"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.114656749" moduleId="org.eclipse.cdt.core.settings" name="Default"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildProperties="" description="" id="0.114656749" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg"> + <folderInfo id="0.114656749." name="/" resourcePath=""> + <toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1182750861" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain"> + <targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1182750861.169007201" name=""/> + <builder autoBuildTarget="all" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.579570726" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.settings.default.builder"/> + <tool id="org.eclipse.cdt.build.core.settings.holder.libs.2143276802" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/> + <tool id="org.eclipse.cdt.build.core.settings.holder.1873650595" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder"> + <option id="org.eclipse.cdt.build.core.settings.holder.undef.incpaths.972953796" superClass="org.eclipse.cdt.build.core.settings.holder.undef.incpaths" valueType="undefIncludePath"> + <listOptionValue builtIn="false" value="C:/ChibiStudio/ChibiOS-Contrib/os/common/ports/ARMCMx/devices/TM4C123x"/> + <listOptionValue builtIn="false" value="C:/ChibiStudio/chibios161/os/ext/CMSIS/include"/> + <listOptionValue builtIn="false" value="C:/ChibiStudio/chibios161/os/rt/ports/ARMCMx/compilers/GCC"/> + <listOptionValue builtIn="false" value="C:/ChibiStudio/chibios161/os/rt/ports/ARMCMx"/> + </option> + <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1337802279" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> + </tool> + <tool id="org.eclipse.cdt.build.core.settings.holder.1707090075" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder"> + <option id="org.eclipse.cdt.build.core.settings.holder.undef.incpaths.959676881" superClass="org.eclipse.cdt.build.core.settings.holder.undef.incpaths" valueType="undefIncludePath"> + <listOptionValue builtIn="false" value="C:/ChibiStudio/ChibiOS-Contrib/os/common/ports/ARMCMx/devices/TM4C123x"/> + <listOptionValue builtIn="false" value="C:/ChibiStudio/chibios161/os/ext/CMSIS/include"/> + <listOptionValue builtIn="false" value="C:/ChibiStudio/chibios161/os/rt/ports/ARMCMx/compilers/GCC"/> + <listOptionValue builtIn="false" value="C:/ChibiStudio/chibios161/os/rt/ports/ARMCMx"/> + </option> + <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.338985256" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> + </tool> + <tool id="org.eclipse.cdt.build.core.settings.holder.1165165914" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder"> + <option id="org.eclipse.cdt.build.core.settings.holder.undef.incpaths.1617159785" superClass="org.eclipse.cdt.build.core.settings.holder.undef.incpaths" valueType="undefIncludePath"> + <listOptionValue builtIn="false" value="C:/ChibiStudio/ChibiOS-Contrib/os/common/ports/ARMCMx/devices/TM4C123x"/> + <listOptionValue builtIn="false" value="C:/ChibiStudio/chibios161/os/ext/CMSIS/include"/> + <listOptionValue builtIn="false" value="C:/ChibiStudio/chibios161/os/rt/ports/ARMCMx/compilers/GCC"/> + <listOptionValue builtIn="false" value="C:/ChibiStudio/chibios161/os/rt/ports/ARMCMx"/> + </option> + <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.714476670" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> + </tool> + </toolChain> + </folderInfo> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <project id="TM4C123x-ADC.null.1703860681" name="TM4C123x-ADC"/> + </storageModule> + <storageModule moduleId="scannerConfiguration"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <scannerConfigBuildInfo instanceId="0.114656749"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/> + </scannerConfigBuildInfo> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> + <storageModule moduleId="refreshScope"/> +</cproject> diff --git a/testhal/TIVA/TM4C123x/ADC/.project b/testhal/TIVA/TM4C123x/ADC/.project new file mode 100644 index 0000000..031d7e5 --- /dev/null +++ b/testhal/TIVA/TM4C123x/ADC/.project @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>TM4C123x-ADC</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> + <triggers>clean,full,incremental,</triggers> + <arguments> + <dictionary> + <key>?name?</key> + <value></value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.append_environment</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.autoBuildTarget</key> + <value>all</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.buildArguments</key> + <value>-j1</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.buildCommand</key> + <value>make</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.cleanBuildTarget</key> + <value>clean</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.contents</key> + <value>org.eclipse.cdt.make.core.activeConfigSettings</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableAutoBuild</key> + <value>false</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableCleanBuild</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableFullBuild</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.fullBuildTarget</key> + <value>all</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.stopOnError</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key> + <value>true</value> + </dictionary> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> + <triggers>full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.cdt.core.cnature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> + </natures> + <linkedResources> + <link> + <name>board</name> + <type>2</type> + <locationURI>PARENT-1-CHIBIOS/ChibiOS-Contrib/os/hal/boards/TI_TM4C123G_LAUNCHPAD</locationURI> + </link> + <link> + <name>community_os</name> + <type>2</type> + <locationURI>PARENT-1-CHIBIOS/ChibiOS-Contrib/os</locationURI> + </link> + <link> + <name>os</name> + <type>2</type> + <locationURI>CHIBIOS/os</locationURI> + </link> + </linkedResources> + <variableList> + <variable> + <name>CHIBIOS3</name> + <value>file:/C:/ChibiStudio/chibios3</value> + </variable> + </variableList> +</projectDescription> diff --git a/testhal/TIVA/TM4C123x/ADC/Makefile b/testhal/TIVA/TM4C123x/ADC/Makefile new file mode 100644 index 0000000..15ea309 --- /dev/null +++ b/testhal/TIVA/TM4C123x/ADC/Makefile @@ -0,0 +1,220 @@ +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +# Compiler options here. +ifeq ($(USE_OPT),) + USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 +endif + +# C specific options here (added to USE_OPT). +ifeq ($(USE_COPT),) + USE_COPT = +endif + +# C++ specific options here (added to USE_OPT). +ifeq ($(USE_CPPOPT),) + USE_CPPOPT = -fno-rtti +endif + +# Enable this if you want the linker to remove unused code and data +ifeq ($(USE_LINK_GC),) + USE_LINK_GC = yes +endif + +# Linker extra options here. +ifeq ($(USE_LDOPT),) + USE_LDOPT = +endif + +# Enable this if you want link time optimizations (LTO) +ifeq ($(USE_LTO),) + USE_LTO = yes +endif + +# If enabled, this option allows to compile the application in THUMB mode. +ifeq ($(USE_THUMB),) + USE_THUMB = yes +endif + +# Enable this if you want to see the full log while compiling. +ifeq ($(USE_VERBOSE_COMPILE),) + USE_VERBOSE_COMPILE = no +endif + +# If enabled, this option makes the build process faster by not compiling +# modules not used in the current configuration. +ifeq ($(USE_SMART_BUILD),) + USE_SMART_BUILD = no +endif + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Stack size to be allocated to the Cortex-M process stack. This stack is +# the stack used by the main() thread. +ifeq ($(USE_PROCESS_STACKSIZE),) + USE_PROCESS_STACKSIZE = 0x400 +endif + +# Stack size to the allocated to the Cortex-M main/exceptions stack. This +# stack is used for processing interrupts and exceptions. +ifeq ($(USE_EXCEPTIONS_STACKSIZE),) + USE_EXCEPTIONS_STACKSIZE = 0x400 +endif + +# Enables the use of FPU on Cortex-M4 (no, softfp, hard). +ifeq ($(USE_FPU),) + USE_FPU = hard +endif + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, sources and paths +# + +# Define project name here +PROJECT = ch + +# Imported source files and paths +CHIBIOS = ../../../../../ChibiOS-RT +CHIBIOS_CONTRIB = $(CHIBIOS)/../ChibiOS-Contrib +# Startup files. +include $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_tm4c123x.mk +# HAL-OSAL files (optional). +include $(CHIBIOS)/os/hal/hal.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/TM4C123x/platform.mk +include $(CHIBIOS_CONTRIB)/os/hal/boards/TI_TM4C123G_LAUNCHPAD/board.mk +include $(CHIBIOS)/os/hal/osal/rt/osal.mk +# RTOS files (optional). +include $(CHIBIOS)/os/rt/rt.mk +include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk +# Other files (optional). +include $(CHIBIOS)/os/hal/lib/streams/streams.mk + +# Define linker script file here +LDSCRIPT= $(STARTUPLD)/TM4C123xH6.ld + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CSRC = $(STARTUPSRC) \ + $(KERNSRC) \ + $(PORTSRC) \ + $(OSALSRC) \ + $(HALSRC) \ + $(PLATFORMSRC) \ + $(BOARDSRC) \ + $(TESTSRC) \ + $(STREAMSSRC) \ + main.c + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CPPSRC = + +# C sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACSRC = + +# C++ sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACPPSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCPPSRC = + +# List ASM source files here +ASMSRC = +ASMXSRC = $(STARTUPASM) $(PORTASM) $(OSALASM) + +INCDIR = $(CHIBIOS)/os/license \ + $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \ + $(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \ + $(STREAMSINC) $(CHIBIOS)/os/various + +# +# Project, sources and paths +############################################################################## + +############################################################################## +# Compiler settings +# + +MCU = cortex-m4 + +#TRGT = arm-elf- +TRGT = arm-none-eabi- +CC = $(TRGT)gcc +CPPC = $(TRGT)g++ +# Enable loading with g++ only if you need C++ runtime support. +# NOTE: You can use C++ even without C++ support if you are careful. C++ +# runtime support makes code size explode. +LD = $(TRGT)gcc +#LD = $(TRGT)g++ +CP = $(TRGT)objcopy +AS = $(TRGT)gcc -x assembler-with-cpp +AR = $(TRGT)ar +OD = $(TRGT)objdump +SZ = $(TRGT)size +HEX = $(CP) -O ihex +BIN = $(CP) -O binary + +# ARM-specific options here +AOPT = + +# THUMB-specific options here +TOPT = -mthumb -DTHUMB + +# Define C warning options here +CWARN = -Wall -Wextra -Wstrict-prototypes + +# Define C++ warning options here +CPPWARN = -Wall -Wextra + +# +# Compiler settings +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +UDEFS = + +# Define ASM defines here +UADEFS = + +# List all user directories here +UINCDIR = + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = + +# +# End of user defines +############################################################################## + +RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC +include $(RULESPATH)/rules.mk diff --git a/testhal/TIVA/TM4C123x/ADC/chconf.h b/testhal/TIVA/TM4C123x/ADC/chconf.h new file mode 100644 index 0000000..0d24275 --- /dev/null +++ b/testhal/TIVA/TM4C123x/ADC/chconf.h @@ -0,0 +1,510 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _CHCONF_H_ +#define _CHCONF_H_ + +#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16 or 32 bits. + */ +#define CH_CFG_ST_RESOLUTION 32 + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#define CH_CFG_ST_FREQUENCY 10000 + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#define CH_CFG_ST_TIMEDELTA 0 + +/** + * @brief Realtime Counter frequency. + * @details Frequency of the system counter used for realtime delays and + * measurements. + */ +#define CH_CFG_RTC_FREQUENCY 80000000 + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#define CH_CFG_TIME_QUANTUM 0 + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#define CH_CFG_MEMCORE_SIZE 0 + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. */ +#define CH_CFG_NO_IDLE_THREAD FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#define CH_CFG_OPTIMIZE_SPEED TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_TM TRUE + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_REGISTRY TRUE + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_WAITEXIT TRUE + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_SEMAPHORES TRUE + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MUTEXES TRUE + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_CONDVARS TRUE + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_EVENTS TRUE + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MESSAGES TRUE + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_MAILBOXES TRUE + +/** + * @brief I/O Queues APIs. + * @details If enabled then the I/O queues APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_QUEUES TRUE + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMCORE TRUE + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#define CH_CFG_USE_HEAP TRUE + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMPOOLS TRUE + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#define CH_CFG_USE_DYNAMIC TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_STATISTICS FALSE + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_SYSTEM_STATE_CHECK FALSE + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_CHECKS FALSE + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_ASSERTS FALSE + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the context switch circular trace buffer is + * activated. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_TRACE FALSE + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#define CH_DBG_ENABLE_STACK_CHECK FALSE + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_FILL_THREADS FALSE + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#define CH_DBG_THREADS_PROFILING FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p chThdInit() API. + * + * @note It is invoked from within @p chThdInit() and implicitly from all + * the threads creation APIs. + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + * + * @note It is inserted into lock zone. + * @note It is also invoked when the threads simply return in order to + * terminate. + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* System halt code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* _CHCONF_H_ */ + +/** @} */ diff --git a/testhal/TIVA/TM4C123x/ADC/debug/OpenOCD on ICDI (prompts for .cfg target configuration).launch b/testhal/TIVA/TM4C123x/ADC/debug/OpenOCD on ICDI (prompts for .cfg target configuration).launch new file mode 100644 index 0000000..0af6b44 --- /dev/null +++ b/testhal/TIVA/TM4C123x/ADC/debug/OpenOCD on ICDI (prompts for .cfg target configuration).launch @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType"> +<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> +<listEntry value="org.eclipse.ui.externaltools.launchGroup"/> +</listAttribute> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${none}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${eclipse_home}\..\tools\openocd\bin\openocd.exe"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-c "telnet_port 4444" -f "interface/ti-icdi.cfg" -f "${file_prompt}""/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${eclipse_home}\..\tools\openocd\scripts\"/> +</launchConfiguration> diff --git a/testhal/TIVA/TM4C123x/ADC/debug/TM4C123x-ADC (OpenOCD, Flash and Run).launch b/testhal/TIVA/TM4C123x/ADC/debug/TM4C123x-ADC (OpenOCD, Flash and Run).launch new file mode 100644 index 0000000..c3a5d9f --- /dev/null +++ b/testhal/TIVA/TM4C123x/ADC/debug/TM4C123x-ADC (OpenOCD, Flash and Run).launch @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType"> +<stringAttribute key="bad_container_name" value="\TM4C123x-ADC\debug"/> +<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="monitor reset halt monitor reset init"/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/> +<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/> +<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/> +<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/> +<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/> +<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/> +<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/> +<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/> +<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/> +<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/> +<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/> +<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/> +<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="dmachis-spi_serve_interrupt-(format)" val="0"/></contentList>"/> +<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/> +<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/> +<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/> +<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="TM4C123x-ADC"/> +<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/> +<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.114656749"/> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> +<listEntry value="/TM4C123x-ADC"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> +<listEntry value="4"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> +<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> +</listAttribute> +</launchConfiguration> diff --git a/testhal/TIVA/TM4C123x/ADC/halconf.h b/testhal/TIVA/TM4C123x/ADC/halconf.h new file mode 100644 index 0000000..20f0e46 --- /dev/null +++ b/testhal/TIVA/TM4C123x/ADC/halconf.h @@ -0,0 +1,294 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _HALCONF_H_ +#define _HALCONF_H_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC TRUE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the EXT subsystem. + */ +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) +#define HAL_USE_EXT FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL TRUE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 64 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +#endif /* _HALCONF_H_ */ + +/** @} */ diff --git a/testhal/TIVA/TM4C123x/ADC/main.c b/testhal/TIVA/TM4C123x/ADC/main.c new file mode 100644 index 0000000..cbb7362 --- /dev/null +++ b/testhal/TIVA/TM4C123x/ADC/main.c @@ -0,0 +1,165 @@ +/* + Copyright (C) 2014..2016 Marco Veeneman + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "ch.h" +#include "hal.h" +#include "chprintf.h" + +#define ADC_GRP1_NUM_CHANNELS 2 +#define ADC_GRP1_BUF_DEPTH 8 + +#define ADC_GRP2_NUM_CHANNELS 8 +#define ADC_GRP2_BUF_DEPTH 16 + +static adcsample_t samples1[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH]; +static adcsample_t samples2[ADC_GRP2_NUM_CHANNELS * ADC_GRP2_BUF_DEPTH]; + +/* + * ADC streaming callback. + */ +size_t nx = 0, ny = 0; +uint32_t temp = 0; +static void adccallback(ADCDriver *adcp, adcsample_t *buffer, size_t n) { + + (void)adcp; + if (samples2 == buffer) { + nx += n; + + uint8_t i, j; + adcsample_t avg = 0; + + for (j = 0; j < n; j++) { + for (i = 0; i < ADC_GRP2_NUM_CHANNELS; i++) { + avg += *buffer++; + } + } + + avg /= (n * ADC_GRP2_NUM_CHANNELS); + + temp = (uint32_t)(147.5f - ((75.0f * 3.3f * (float)avg)) / 4096.0f); + } + else { + ny += n; + + uint8_t i, j; + adcsample_t avg = 0; + + for (j = 0; j < n; j++) { + for (i = 0; i < ADC_GRP2_NUM_CHANNELS; i++) { + avg += *buffer++; + } + } + + avg /= (n * ADC_GRP2_NUM_CHANNELS); + + temp = (uint32_t)(147.5f - ((75.0f * 3.3f * (float)avg)) / 4096.0f); + } +} + +static void adcerrorcallback(ADCDriver *adcp, adcerror_t err) { + + (void)adcp; + (void)err; +} + +/* + * ADC conversion group. + * Mode: Linear buffer, 8 samples of 2 channels, Always triggered. + * Channels: TS, TS. + */ +static const ADCConversionGroup adcgrpcfg1 = { + FALSE, + ADC_GRP1_NUM_CHANNELS, + NULL, + adcerrorcallback, + 0xF, /* EMUX */ /* Always trigger */ + 0, /* SSMUX */ + (1 << 7) | (1 << 5) | + (1 << 3) /* SSCTL */ /* 2 times TS, 2nd has end bit set */ +}; + +/* + * ADC conversion group. + * Mode: Continuous, 16 samples of 8 channels, Always triggered. + * Channels: TS, TS, TS, TS, TS, TS, TS, TS. + */ +static const ADCConversionGroup adcgrpcfg2 = { + TRUE, + ADC_GRP2_NUM_CHANNELS, + adccallback, + adcerrorcallback, + 0xF, /* EMUX */ /* Always trigger */ + 0, /* SSMUX */ + (1 << 31) | (1 << 29) | + (1 << 27) | + (1 << 23) | + (1 << 19) | + (1 << 15) | + (1 << 11) | + (1 << 7) | + (1 << 3) /* SSCTL */ /* 8 times TS, 8th has end bit set */ +}; + +/* + * Application entry point. + */ +int main(void) +{ + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + chSysInit(); + + /* Configure RX and TX pins for UART0.*/ + palSetLineMode(LINE_UART0_RX, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(1)); + palSetLineMode(LINE_UART0_TX, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(1)); + + sdStart(&SD1, NULL); + + chprintf((BaseSequentialStream *)&SD1, "Starting ADC0..."); + chThdSleepMilliseconds(500); + + /* + * Activates the ADC0 driver. + */ + adcStart(&ADCD1, NULL); + + /* + * Linear conversion. + */ + adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH); + + /* + * Starts an ADC continuous conversion. + */ + adcStartConversion(&ADCD1, &adcgrpcfg2, samples2, ADC_GRP2_BUF_DEPTH); + + /* + * Normal main() thread activity + */ + while (TRUE) { + chThdSleepMilliseconds(500); + + chprintf((BaseSequentialStream *)&SD1, "A:%d\tB:%d\ttmp:%d\r\n", nx, ny, temp); + } + + return 0; +} diff --git a/testhal/TIVA/TM4C123x/ADC/mcuconf.h b/testhal/TIVA/TM4C123x/ADC/mcuconf.h new file mode 100644 index 0000000..02d79d6 --- /dev/null +++ b/testhal/TIVA/TM4C123x/ADC/mcuconf.h @@ -0,0 +1,179 @@ +/* + Copyright (C) 2014..2016 Marco Veeneman + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * TM4C123x drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 7...0 Lowest...Highest. + */ + +#define TM4C123x_MCUCONF + +/* + * HAL driver system settings. + */ +#define TIVA_OSCSRC SYSCTL_RCC2_OSCSRC2_MO +#define TIVA_MOSC_ENABLE TRUE +#define TIVA_DIV400_VALUE 1 +#define TIVA_SYSDIV_VALUE 2 +#define TIVA_USESYSDIV_ENABLE FALSE +#define TIVA_SYSDIV2LSB_ENABLE FALSE +#define TIVA_BYPASS_VALUE 0 +#define TIVA_PWM_FIELDS (SYSCTL_RCC_USEPWMDIV | \ + SYSCTL_RCC_PWMDIV_8) + +/* + * ADC driver system settings. + */ +#define TIVA_ADC_USE_ADC0 TRUE +#define TIVA_ADC_USE_ADC1 TRUE +#define TIVA_ADC_ADC0_SS0_UDMA_CHANNEL 14 +#define TIVA_ADC_ADC1_SS0_UDMA_CHANNEL 24 +#define TIVA_ADC_ADC0_SS0_UDMA_MAPPING 0 +#define TIVA_ADC_ADC1_SS0_UDMA_MAPPING 1 +#define TIVA_ADC0_SEQ0_PRIORITY 4 +#define TIVA_ADC1_SEQ0_PRIORITY 4 +/* + * GPIO driver system settings. + */ +#define TIVA_GPIO_GPIOA_USE_AHB TRUE +#define TIVA_GPIO_GPIOB_USE_AHB TRUE +#define TIVA_GPIO_GPIOC_USE_AHB TRUE +#define TIVA_GPIO_GPIOD_USE_AHB TRUE +#define TIVA_GPIO_GPIOE_USE_AHB TRUE +#define TIVA_GPIO_GPIOF_USE_AHB TRUE + +/* + * GPT driver system settings. + */ +#define TIVA_GPT_USE_GPT0 FALSE +#define TIVA_GPT_USE_GPT1 FALSE +#define TIVA_GPT_USE_GPT2 FALSE +#define TIVA_GPT_USE_GPT3 FALSE +#define TIVA_GPT_USE_GPT4 FALSE +#define TIVA_GPT_USE_GPT5 FALSE +#define TIVA_GPT_USE_WGPT0 FALSE +#define TIVA_GPT_USE_WGPT1 FALSE +#define TIVA_GPT_USE_WGPT2 FALSE +#define TIVA_GPT_USE_WGPT3 FALSE +#define TIVA_GPT_USE_WGPT4 FALSE +#define TIVA_GPT_USE_WGPT5 FALSE + +#define TIVA_GPT_GPT0A_IRQ_PRIORITY 7 +#define TIVA_GPT_GPT1A_IRQ_PRIORITY 7 +#define TIVA_GPT_GPT2A_IRQ_PRIORITY 7 +#define TIVA_GPT_GPT3A_IRQ_PRIORITY 7 +#define TIVA_GPT_GPT4A_IRQ_PRIORITY 7 +#define TIVA_GPT_GPT5A_IRQ_PRIORITY 7 +#define TIVA_GPT_WGPT0A_IRQ_PRIORITY 7 +#define TIVA_GPT_WGPT1A_IRQ_PRIORITY 7 +#define TIVA_GPT_WGPT2A_IRQ_PRIORITY 7 +#define TIVA_GPT_WGPT3A_IRQ_PRIORITY 7 +#define TIVA_GPT_WGPT4A_IRQ_PRIORITY 7 +#define TIVA_GPT_WGPT5A_IRQ_PRIORITY 7 + +/* + * I2C driver system settings. + */ +#define TIVA_I2C_USE_I2C0 FALSE +#define TIVA_I2C_USE_I2C1 FALSE +#define TIVA_I2C_USE_I2C2 FALSE +#define TIVA_I2C_USE_I2C3 FALSE +#define TIVA_I2C_USE_I2C4 FALSE +#define TIVA_I2C_USE_I2C5 FALSE +#define TIVA_I2C_USE_I2C6 FALSE +#define TIVA_I2C_USE_I2C7 FALSE +#define TIVA_I2C_I2C0_IRQ_PRIORITY 4 +#define TIVA_I2C_I2C1_IRQ_PRIORITY 4 +#define TIVA_I2C_I2C2_IRQ_PRIORITY 4 +#define TIVA_I2C_I2C3_IRQ_PRIORITY 4 +#define TIVA_I2C_I2C4_IRQ_PRIORITY 4 +#define TIVA_I2C_I2C5_IRQ_PRIORITY 4 +#define TIVA_I2C_I2C6_IRQ_PRIORITY 4 +#define TIVA_I2C_I2C7_IRQ_PRIORITY 4 + +/* + * PWM driver system settings. + */ +#define TIVA_PWM_USE_PWM0 FALSE +#define TIVA_PWM_USE_PWM1 FALSE +#define TIVA_PWM_PWM0_FAULT_IRQ_PRIORITY 4 +#define TIVA_PWM_PWM0_0_IRQ_PRIORITY 4 +#define TIVA_PWM_PWM0_1_IRQ_PRIORITY 4 +#define TIVA_PWM_PWM0_2_IRQ_PRIORITY 4 +#define TIVA_PWM_PWM0_3_IRQ_PRIORITY 4 +#define TIVA_PWM_PWM1_FAULT_IRQ_PRIORITY 4 +#define TIVA_PWM_PWM1_0_IRQ_PRIORITY 4 +#define TIVA_PWM_PWM1_1_IRQ_PRIORITY 4 +#define TIVA_PWM_PWM1_2_IRQ_PRIORITY 4 +#define TIVA_PWM_PWM1_3_IRQ_PRIORITY 4 + +/* + * SERIAL driver system settings. + */ +#define TIVA_SERIAL_USE_UART0 TRUE +#define TIVA_SERIAL_USE_UART1 FALSE +#define TIVA_SERIAL_USE_UART2 FALSE +#define TIVA_SERIAL_USE_UART3 FALSE +#define TIVA_SERIAL_USE_UART4 FALSE +#define TIVA_SERIAL_USE_UART5 FALSE +#define TIVA_SERIAL_USE_UART6 FALSE +#define TIVA_SERIAL_USE_UART7 FALSE +#define TIVA_SERIAL_UART0_PRIORITY 5 +#define TIVA_SERIAL_UART1_PRIORITY 5 +#define TIVA_SERIAL_UART2_PRIORITY 5 +#define TIVA_SERIAL_UART3_PRIORITY 5 +#define TIVA_SERIAL_UART4_PRIORITY 5 +#define TIVA_SERIAL_UART5_PRIORITY 5 +#define TIVA_SERIAL_UART6_PRIORITY 5 +#define TIVA_SERIAL_UART7_PRIORITY 5 + +/* + * SPI driver system settings. + */ +#define TIVA_SPI_USE_SSI0 TRUE +#define TIVA_SPI_USE_SSI1 FALSE +#define TIVA_SPI_USE_SSI2 FALSE +#define TIVA_SPI_USE_SSI3 FALSE +#define TIVA_SPI_SSI0_RX_UDMA_CHANNEL 10 +#define TIVA_SPI_SSI1_RX_UDMA_CHANNEL 24 +#define TIVA_SPI_SSI2_RX_UDMA_CHANNEL 12 +#define TIVA_SPI_SSI3_RX_UDMA_CHANNEL 14 +#define TIVA_SPI_SSI0_TX_UDMA_CHANNEL 11 +#define TIVA_SPI_SSI1_TX_UDMA_CHANNEL 25 +#define TIVA_SPI_SSI2_TX_UDMA_CHANNEL 13 +#define TIVA_SPI_SSI3_TX_UDMA_CHANNEL 15 +#define TIVA_SPI_SSI0_RX_UDMA_MAPPING 0 +#define TIVA_SPI_SSI1_RX_UDMA_MAPPING 0 +#define TIVA_SPI_SSI2_RX_UDMA_MAPPING 2 +#define TIVA_SPI_SSI3_RX_UDMA_MAPPING 2 +#define TIVA_SPI_SSI0_TX_UDMA_MAPPING 0 +#define TIVA_SPI_SSI1_TX_UDMA_MAPPING 0 +#define TIVA_SPI_SSI2_TX_UDMA_MAPPING 2 +#define TIVA_SPI_SSI3_TX_UDMA_MAPPING 2 + +/* + * ST driver system settings. + */ +#define TIVA_ST_IRQ_PRIORITY 2 +#define TIVA_ST_USE_WIDE_TIMER TRUE +#define TIVA_ST_TIMER_NUMBER 5 +#define TIVA_ST_TIMER_LETTER A diff --git a/testhal/TIVA/TM4C123x/EXT/chconf.h b/testhal/TIVA/TM4C123x/EXT/chconf.h index dd6722a..c56df3c 100644 --- a/testhal/TIVA/TM4C123x/EXT/chconf.h +++ b/testhal/TIVA/TM4C123x/EXT/chconf.h @@ -18,6 +18,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/TIVA/TM4C123x/GPT/chconf.h b/testhal/TIVA/TM4C123x/GPT/chconf.h index 25e39f6..0d24275 100644 --- a/testhal/TIVA/TM4C123x/GPT/chconf.h +++ b/testhal/TIVA/TM4C123x/GPT/chconf.h @@ -18,6 +18,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/TIVA/TM4C123x/I2C/chconf.h b/testhal/TIVA/TM4C123x/I2C/chconf.h index 25e39f6..0d24275 100644 --- a/testhal/TIVA/TM4C123x/I2C/chconf.h +++ b/testhal/TIVA/TM4C123x/I2C/chconf.h @@ -18,6 +18,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/TIVA/TM4C123x/PWM/chconf.h b/testhal/TIVA/TM4C123x/PWM/chconf.h index 25e39f6..0d24275 100644 --- a/testhal/TIVA/TM4C123x/PWM/chconf.h +++ b/testhal/TIVA/TM4C123x/PWM/chconf.h @@ -18,6 +18,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/TIVA/TM4C123x/SPI/chconf.h b/testhal/TIVA/TM4C123x/SPI/chconf.h index 25e39f6..0d24275 100644 --- a/testhal/TIVA/TM4C123x/SPI/chconf.h +++ b/testhal/TIVA/TM4C123x/SPI/chconf.h @@ -18,6 +18,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/testhal/TIVA/TM4C123x/WDG/chconf.h b/testhal/TIVA/TM4C123x/WDG/chconf.h index 25e39f6..0d24275 100644 --- a/testhal/TIVA/TM4C123x/WDG/chconf.h +++ b/testhal/TIVA/TM4C123x/WDG/chconf.h @@ -18,6 +18,7 @@ #define _CHCONF_H_ #define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_5_0_ /*===========================================================================*/ /** diff --git a/tools/mx2board.py b/tools/mx2board.py index 85e643b..ea0b010 100644 --- a/tools/mx2board.py +++ b/tools/mx2board.py @@ -268,7 +268,7 @@ def gen_defines(project): defines['PORT_'+label] = 'GPIO' + port_key defines['PAD_'+label] = pad_key - if re.search(r"TIM\d_CH\d", signal, re.M): + if re.search(r"TIM\d+_CH\d$", signal, re.M): timer = signal.replace('S_TIM', '').replace('_CH', '')[:-1] ch_num = int(signal[-1:]) |