mirror of https://github.com/ARMmbed/mbed-os.git
commit
57463eaef0
|
@ -0,0 +1,999 @@
|
|||
/***************************************************************************//**
|
||||
* @file em_usb.h
|
||||
* @brief USB protocol stack library API for EFM32.
|
||||
* @version 3.20.14
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* 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 __EM_USB_H
|
||||
#define __EM_USB_H
|
||||
|
||||
#include "em_device.h"
|
||||
#include "em_assert.h"
|
||||
#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
|
||||
#include "usbconfig.h"
|
||||
#if defined( USB_DEVICE ) || defined( USB_HOST )
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "em_common.h"
|
||||
#include "em_int.h"
|
||||
|
||||
#if defined( USB_USE_PRINTF )
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __CC_ARM
|
||||
#pragma anon_unions
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup USB
|
||||
* @brief USB HOST and DEVICE protocol stacks.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup USB_COMMON
|
||||
* @brief Common parts for both HOST and DEVICE USB stacks, see @ref usb_device
|
||||
* and @ref usb_host pages for device and host library documentation.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#define SILABS_USB_VID 0x10C4 /**< Silicon Labs Vendor ID, supplied by USB-IF. */
|
||||
|
||||
/* SETUP request, direction of data stage */
|
||||
#define USB_SETUP_DIR_OUT 0 /**< Setup request data stage OUT direction value. */
|
||||
#define USB_SETUP_DIR_IN 1 /**< Setup request data stage IN direction value. */
|
||||
#define USB_SETUP_DIR_MASK 0x80 /**< Setup request data stage direction mask. */
|
||||
#define USB_SETUP_DIR_D2H 0x80 /**< Setup request data stage IN direction mask. */
|
||||
#define USB_SETUP_DIR_H2D 0x00 /**< Setup request data stage OUT direction mask. */
|
||||
|
||||
/* SETUP request type */
|
||||
#define USB_SETUP_TYPE_STANDARD 0 /**< Standard setup request value. */
|
||||
#define USB_SETUP_TYPE_CLASS 1 /**< Class setup request value. */
|
||||
#define USB_SETUP_TYPE_VENDOR 2 /**< Vendor setup request value. */
|
||||
#define USB_SETUP_TYPE_STANDARD_MASK 0x00 /**< Standard setup request mask. */
|
||||
#define USB_SETUP_TYPE_CLASS_MASK 0x20 /**< Class setup request mask. */
|
||||
#define USB_SETUP_TYPE_VENDOR_MASK 0x40 /**< Vendor setup request mask. */
|
||||
|
||||
/* SETUP request recipient */
|
||||
#define USB_SETUP_RECIPIENT_DEVICE 0 /**< Setup request device recipient value. */
|
||||
#define USB_SETUP_RECIPIENT_INTERFACE 1 /**< Setup request interface recipient value. */
|
||||
#define USB_SETUP_RECIPIENT_ENDPOINT 2 /**< Setup request endpoint recipient value. */
|
||||
#define USB_SETUP_RECIPIENT_OTHER 3 /**< Setup request other recipient value. */
|
||||
|
||||
/* SETUP standard request codes for Full Speed devices */
|
||||
#define GET_STATUS 0 /**< Standard setup request GET_STATUS. */
|
||||
#define CLEAR_FEATURE 1 /**< Standard setup request CLEAR_FEATURE. */
|
||||
#define SET_FEATURE 3 /**< Standard setup request SET_FEATURE. */
|
||||
#define SET_ADDRESS 5 /**< Standard setup request SET_ADDRESS. */
|
||||
#define GET_DESCRIPTOR 6 /**< Standard setup request GET_DESCRIPTOR. */
|
||||
#define SET_DESCRIPTOR 7 /**< Standard setup request SET_DESCRIPTOR. */
|
||||
#define GET_CONFIGURATION 8 /**< Standard setup request GET_CONFIGURATION. */
|
||||
#define SET_CONFIGURATION 9 /**< Standard setup request SET_CONFIGURATION. */
|
||||
#define GET_INTERFACE 10 /**< Standard setup request GET_INTERFACE. */
|
||||
#define SET_INTERFACE 11 /**< Standard setup request SET_INTERFACE. */
|
||||
#define SYNCH_FRAME 12 /**< Standard setup request SYNCH_FRAME. */
|
||||
|
||||
/* SETUP class request codes */
|
||||
#define USB_HID_GET_REPORT 0x01 /**< HID class setup request GET_REPORT. */
|
||||
#define USB_HID_GET_IDLE 0x02 /**< HID class setup request GET_IDLE. */
|
||||
#define USB_HID_SET_REPORT 0x09 /**< HID class setup request SET_REPORT. */
|
||||
#define USB_HID_SET_IDLE 0x0A /**< HID class setup request SET_IDLE. */
|
||||
#define USB_HID_SET_PROTOCOL 0x0B /**< HID class setup request SET_PROTOCOL. */
|
||||
#define USB_CDC_SETLINECODING 0x20 /**< CDC class setup request SET_LINE_CODING. */
|
||||
#define USB_CDC_GETLINECODING 0x21 /**< CDC class setup request GET_LINE_CODING. */
|
||||
#define USB_CDC_SETCTRLLINESTATE 0x22 /**< CDC class setup request SET_CONTROL_LINE_STATE. */
|
||||
#define USB_MSD_BOTRESET 0xFF /**< MSD class setup request Bulk only transfer reset. */
|
||||
#define USB_MSD_GETMAXLUN 0xFE /**< MSD class setup request Get Max LUN. */
|
||||
#define USB_AUDIO_GET_CUR 0x81 /**< Audio class setup request GET_CUR. */
|
||||
#define USB_AUDIO_SET_CUR 0x01 /**< Audio class setup request SET_CUR. */
|
||||
#define USB_AUDIO_GET_CUR 0x81 /**< Audio class setup request GET_CUR. */
|
||||
#define USB_AUDIO_SET_MIN 0x02 /**< Audio class setup request SET_MIN. */
|
||||
#define USB_AUDIO_GET_MIN 0x82 /**< Audio class setup request GET_MIN. */
|
||||
#define USB_AUDIO_SET_MAX 0x03 /**< Audio class setup request SET_MAX. */
|
||||
#define USB_AUDIO_GET_MAX 0x83 /**< Audio class setup request GET_MAX. */
|
||||
#define USB_AUDIO_SET_RES 0x04 /**< Audio class setup request SET_RES. */
|
||||
#define USB_AUDIO_GET_RES 0x84 /**< Audio class setup request GET_RES. */
|
||||
#define USB_AUDIO_SET_MEM 0x05 /**< Audio class setup request SET_MEM. */
|
||||
#define USB_AUDIO_GET_MEM 0x85 /**< Audio class setup request GET_MEM. */
|
||||
#define USB_AUDIO_GET_STAT 0xFF /**< Audio class setup request GET_STAT. */
|
||||
|
||||
/* SETUP command GET/SET_DESCRIPTOR decriptor types */
|
||||
#define USB_DEVICE_DESCRIPTOR 1 /**< DEVICE descriptor value. */
|
||||
#define USB_CONFIG_DESCRIPTOR 2 /**< CONFIGURATION descriptor value. */
|
||||
#define USB_STRING_DESCRIPTOR 3 /**< STRING descriptor value. */
|
||||
#define USB_MAX_STRING_DESCRIPTOR_CHARS 126 /**< Maximum STRING descriptor bString length. */
|
||||
#define USB_INTERFACE_DESCRIPTOR 4 /**< INTERFACE descriptor value. */
|
||||
#define USB_ENDPOINT_DESCRIPTOR 5 /**< ENDPOINT descriptor value. */
|
||||
#define USB_DEVICE_QUALIFIER_DESCRIPTOR 6 /**< DEVICE_QUALIFIER descriptor value. */
|
||||
#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR 7 /**< OTHER_SPEED_CONFIGURATION descriptor value. */
|
||||
#define USB_INTERFACE_POWER_DESCRIPTOR 8 /**< INTERFACE_POWER descriptor value. */
|
||||
#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR 11 /**< INTERFACE_ASSOCIATION descriptor value. */
|
||||
#define USB_HID_DESCRIPTOR 0x21 /**< HID descriptor value. */
|
||||
#define USB_SMARTCARD_DESCRIPTOR 0x21 /**< Smartcard usb-ccid-specific Descriptor Type. */
|
||||
#define USB_HID_REPORT_DESCRIPTOR 0x22 /**< HID REPORT descriptor value. */
|
||||
#define USB_CS_INTERFACE_DESCRIPTOR 0x24 /**< Audio Class-specific interface Descriptor Type. */
|
||||
#define USB_CS_ENDPOINT_DESCRIPTOR 0x25 /**< Audio Class-specific endpoint Descriptor Type. */
|
||||
#define USB_HUB_DESCRIPTOR 0x29 /**< HUB descriptor value. */
|
||||
#define USB_CA_HEADER_DESCRIPTOR 1 /**< Audio Class-Specific AC Interface Header descriptor.*/
|
||||
#define USB_CA_INPUT_TERMINAL_DESCRIPTOR 2 /**< Audio Class-Specific AC Interface Input Terminal desc. */
|
||||
#define USB_CA_OUTPUT_TERMINAL_DESCRIPTOR 3 /**< Audio Class-Specific AC Interface Output Terminal desc.*/
|
||||
#define USB_CA_MIXER_UNIT_DESCRIPTOR 4 /**< Audio Class-Specific AC Interface Mixer descriptor.*/
|
||||
#define USB_CA_SELECTOR_UNIT_DESCRIPTOR 5 /**< Audio Class-Specific AC Interface Selector desc. */
|
||||
#define USB_CA_FEATURE_UNIT_DESCRIPTOR 6 /**< Audio Class-Specific AC Interface Feature desc. */
|
||||
#define USB_CA_PROCESSING_UNIT_DESCRIPTOR 7 /**< Audio Class-Specific AC Interface Processing desc.*/
|
||||
#define USB_CA_EXTENSION_UNIT_DESCRIPTOR 8 /**< Audio Class-Specific AC Interface Extension desc. */
|
||||
#define USB_CA_EP_GENERAL_DESCRIPTOR 1 /**< Audio Class-Specific general descriptor subtype code.*/
|
||||
#define USB_CA_AS_GENERAL_DESCRIPTOR 1 /**< Audio Class-Specific AS Interface General descriptor.*/
|
||||
#define USB_CA_FORMAT_TYPE_DESCRIPTOR 2 /**< Audio Class-Specific AS Interface Format Type desc. */
|
||||
|
||||
#define USB_DEVICE_DESCSIZE 18 /**< Device descriptor size. */
|
||||
#define USB_CONFIG_DESCSIZE 9 /**< Configuration descriptor size. */
|
||||
#define USB_INTERFACE_DESCSIZE 9 /**< Interface descriptor size. */
|
||||
#define USB_ENDPOINT_DESCSIZE 7 /**< Endpoint descriptor size. */
|
||||
#define USB_DEVICE_QUALIFIER_DESCSIZE 10 /**< Device qualifier descriptor size. */
|
||||
#define USB_OTHER_SPEED_CONFIG_DESCSIZE 9 /**< Device other speed configuration descriptor size. */
|
||||
#define USB_INTERFACE_ASSOCIATION_DESCSIZE 8 /**< INTERFACE_ASSOCIATION descriptor size. */
|
||||
#define USB_HID_DESCSIZE 9 /**< HID descriptor size. */
|
||||
#define USB_SMARTCARD_DESCSIZE 54 /**< CCID descriptor size. */
|
||||
#define USB_CDC_HEADER_FND_DESCSIZE 5 /**< CDC Header functional descriptor size. */
|
||||
#define USB_CDC_CALLMNG_FND_DESCSIZE 5 /**< CDC Call Management functional descriptor size. */
|
||||
#define USB_CDC_ACM_FND_DESCSIZE 4 /**< CDC Abstract Control Management functional descriptor size.*/
|
||||
#define USB_CA_INPUT_TERMINAL_DESCSIZE 12 /**< Audio Input Terminal descriptor size. */
|
||||
#define USB_CA_OUTPUT_TERMINAL_DESCSIZE 9 /**< Audio Output Terminal descriptor size. */
|
||||
#define USB_CA_EP_GENERAL_DESCSIZE 7 /**< Audio Class-Specific general descriptor subtype size.*/
|
||||
#define USB_CA_AS_GENERAL_DESCSIZE 7 /**< Audio Class-Specific AS Interface General desc size.*/
|
||||
#define USB_CA_STD_AS_ENDPOINT_DESCSZIE 9 /**< Audio-class standard audio stream descriptor size.*/
|
||||
|
||||
/* Misc. USB definitions */
|
||||
#define USB_LS_CTRL_EP_MAXSIZE 8 /**< The max size of low speed control endpoints. */
|
||||
#define USB_LS_INTR_EP_MAXSIZE 8 /**< The max size of low speed interrupt endpoints. */
|
||||
#define USB_FS_CTRL_EP_MAXSIZE 64 /**< The max size of full speed control endpoints. */
|
||||
#define USB_FS_INTR_EP_MAXSIZE 64 /**< The max size of full speed interrupt endpoints. */
|
||||
#define USB_FS_BULK_EP_MAXSIZE 64 /**< The max size of full speed bulk endpoints. */
|
||||
#define USB_FS_ISOC_EP_MAXSIZE 1023 /**< The max size of full speed isochronous endpoints. */
|
||||
#define USB_EPTYPE_CTRL 0 /**< Endpoint type control. */
|
||||
#define USB_EPTYPE_ISOC 1 /**< Endpoint type isochron. */
|
||||
#define USB_EPTYPE_BULK 2 /**< Endpoint type bulk. */
|
||||
#define USB_EPTYPE_INTR 3 /**< Endpoint type interrupt. */
|
||||
#define USB_EPSYNC_NO (0 << 2) /**< Endpoint synchronization type, none. */
|
||||
#define USB_EPSYNC_ASYNC (1 << 2) /**< Endpoint synchronization type, asynchronous. */
|
||||
#define USB_EPSYNC_ADAPTIVE (2 << 2) /**< Endpoint synchronization type, adaptive. */
|
||||
#define USB_EPSYNC_SYNC (3 << 2) /**< Endpoint synchronization type, synchronous. */
|
||||
#define USB_EP_DIR_IN 0x80 /**< Endpoint direction mask. */
|
||||
#define USB_SETUP_PKT_SIZE 8 /**< Setup request packet size. */
|
||||
#define USB_EPNUM_MASK 0x0F /**< Endpoint number mask. */
|
||||
#define USB_LANGID_ENUS 0x0409 /**< English-United States language id. */
|
||||
#define USB_MAX_DEVICE_ADDRESS 127 /**< Maximum allowable device address. */
|
||||
|
||||
#define CONFIG_DESC_BM_REMOTEWAKEUP 0x20 /**< Configuration descriptor attribute macro. */
|
||||
#define CONFIG_DESC_BM_SELFPOWERED 0x40 /**< Configuration descriptor attribute macro. */
|
||||
#define CONFIG_DESC_BM_RESERVED_D7 0x80 /**< Configuration descriptor attribute macro. */
|
||||
#define CONFIG_DESC_BM_TRANSFERTYPE 0x03 /**< Configuration descriptor transfer type bitmask. */
|
||||
#define CONFIG_DESC_MAXPOWER_mA(x) (((x)+1)/2) /**< Configuration descriptor power macro. */
|
||||
|
||||
#define DEVICE_IS_SELFPOWERED 0x0001 /**< Standard request GET_STATUS bitmask. */
|
||||
#define REMOTE_WAKEUP_ENABLED 0x0002 /**< Standard request GET_STATUS bitmask. */
|
||||
#define USB_FEATURE_ENDPOINT_HALT 0 /**< Standard request CLEAR/SET_FEATURE bitmask. */
|
||||
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 /**< Standard request CLEAR/SET_FEATURE bitmask. */
|
||||
|
||||
#define HUB_FEATURE_PORT_RESET 4 /**< HUB class request CLEAR/SET_PORT_FEATURE feature selector. */
|
||||
#define HUB_FEATURE_PORT_POWER 8 /**< HUB class request CLEAR/SET_PORT_FEATURE feature selector. */
|
||||
#define HUB_FEATURE_C_PORT_CONNECTION 16 /**< HUB class request CLEAR/SET_PORT_FEATURE feature selector. */
|
||||
#define HUB_FEATURE_C_PORT_RESET 20 /**< HUB class request CLEAR/SET_PORT_FEATURE feature selector. */
|
||||
#define HUB_FEATURE_PORT_INDICATOR 22 /**< HUB class request CLEAR/SET_PORT_FEATURE feature selector. */
|
||||
|
||||
#define USB_CLASS_CDC 2 /**< CDC device/interface class code. */
|
||||
#define USB_CLASS_CDC_DATA 0x0A /**< CDC Data interface class code. */
|
||||
#define USB_CLASS_CDC_ACM 2 /**< CDC Abstract Control Model interface subclass code. */
|
||||
#define USB_CLASS_CDC_HFN 0 /**< CDC class Header Functional Descriptor subtype. */
|
||||
#define USB_CLASS_CDC_CMNGFN 1 /**< CDC class Call Management Functional Descriptor subtype.*/
|
||||
#define USB_CLASS_CDC_ACMFN 2 /**< CDC class Abstract Control Management Functional Descriptor subtype.*/
|
||||
#define USB_CLASS_CDC_UNIONFN 6 /**< CDC class Union Functional Descriptor subtype. */
|
||||
|
||||
#define USB_CLASS_HID 3 /**< HID device/interface class code. */
|
||||
#define USB_CLASS_HID_KEYBOARD 1 /**< HID keyboard interface protocol code. */
|
||||
#define USB_CLASS_HID_MOUSE 2 /**< HID mouse interface protocol code. */
|
||||
|
||||
#define USB_CLASS_HUB 9 /**< HUB device/interface class code. */
|
||||
|
||||
#define USB_CLASS_MSD 8 /**< MSD device/interface class code. */
|
||||
#define USB_CLASS_MSD_BOT_TRANSPORT 0x50 /**< MSD Bulk Only Transport protocol. */
|
||||
#define USB_CLASS_MSD_SCSI_CMDSET 6 /**< MSD Subclass SCSI transparent command set. */
|
||||
#define USB_CLASS_MSD_CSW_CMDPASSED 0 /**< MSD BOT Command status wrapper command passed code. */
|
||||
#define USB_CLASS_MSD_CSW_CMDFAILED 1 /**< MSD BOT Command status wrapper command failed code. */
|
||||
#define USB_CLASS_MSD_CSW_PHASEERROR 2 /**< MSD BOT Command status wrapper cmd phase error code.*/
|
||||
|
||||
#define USB_CLASS_AUDIO 1 /**< Audio interface class code. */
|
||||
#define USB_CLASS_AUDIO_CONTROL 1 /**< Audio subclass code for control interface. */
|
||||
#define USB_CLASS_AUDIO_STREAMING 2 /**< Audio subclass code for streaming interface. */
|
||||
#define USB_CLASS_AUDIO_MIDISTREAMING 3 /**< Audio subclass code for midi streaming interface. */
|
||||
|
||||
/*** Triplet for the device descriptor of a composite device using IAD descriptors. ***/
|
||||
#define USB_CLASS_MISCELLANEOUS 0xEF /**< MISCELLANEOUS device class code. */
|
||||
#define USB_CLASS_MISC_COMMON_SUBCLASS 2 /**< MISCELLANEOUS Common sub class code. */
|
||||
#define USB_CLASS_MISC_IAD_PROTOCOL 1 /**< MISCELLANEOUS Interface Association Descriptor protocol code. */
|
||||
|
||||
#define PORT_FULL_SPEED 1 /**< Full speed return value for USBH_GetPortSpeed(). */
|
||||
#define PORT_LOW_SPEED 2 /**< Low speed return value for USBH_GetPortSpeed(). */
|
||||
|
||||
#if defined( __GNUC__ ) /* GCC compilers */
|
||||
#if defined( __CHAR16_TYPE__ )
|
||||
typedef __CHAR16_TYPE__ char16_t;
|
||||
#else
|
||||
typedef unsigned short char16_t;
|
||||
#endif
|
||||
|
||||
#elif defined( __ICCARM__ ) /* IAR compiler */
|
||||
#include <uchar.h>
|
||||
|
||||
#elif defined( __CC_ARM ) /* MDK-ARM compiler */
|
||||
typedef unsigned short char16_t;
|
||||
#endif
|
||||
|
||||
/** Macro for creating USB compliant UTF-16LE UNICODE string descriptors.
|
||||
* @n Example: STATIC_CONST_STRING_DESC( iManufacturer, 'E','n','e','r','g','y',' ','M','i','c','r','o',' ','A','S' );
|
||||
* @note The size of the resulting struct will be two byte larger than a USB string
|
||||
* descriptor. This is to accommodate a terminating null char for the string.
|
||||
* The value assigned to the 'len' member does not take this into account
|
||||
* and is therefore correct usb wise.
|
||||
*/
|
||||
#define STATIC_CONST_STRING_DESC( _name, ... ) \
|
||||
EFM32_PACK_START( 1 ) \
|
||||
typedef struct \
|
||||
{ \
|
||||
uint8_t len; \
|
||||
uint8_t type; \
|
||||
char16_t name[ 1 + sizeof( (char16_t[]){__VA_ARGS__} ) / 2]; \
|
||||
} __attribute__ ((packed)) _##_name; \
|
||||
EFM32_PACK_END() \
|
||||
EFM32_ALIGN( 4 ) \
|
||||
EFM32_PACK_START( 1 ) \
|
||||
static const _##_name _name __attribute__ ((aligned(4)))= \
|
||||
{ \
|
||||
.len = sizeof( _##_name ) - 2, \
|
||||
.type = USB_STRING_DESCRIPTOR, \
|
||||
.name = {__VA_ARGS__}, \
|
||||
.name[ ( ( sizeof( _##_name ) - 2 ) / 2 ) - 1 ] = '\0' \
|
||||
} \
|
||||
EFM32_PACK_END()
|
||||
|
||||
/** Macro for creating USB compliant language string descriptors.
|
||||
* @n Example: STATIC_CONST_STRING_DESC_LANGID( langID, 0x04, 0x09 );
|
||||
*/
|
||||
#define STATIC_CONST_STRING_DESC_LANGID( _name, x, y ) \
|
||||
EFM32_PACK_START( 1 ) \
|
||||
typedef struct \
|
||||
{ \
|
||||
uint8_t len; \
|
||||
uint8_t type; \
|
||||
uint8_t name[ 2 ]; \
|
||||
} __attribute__ ((packed)) _##_name; \
|
||||
EFM32_PACK_END() \
|
||||
EFM32_ALIGN( 4 ) \
|
||||
EFM32_PACK_START( 1 ) \
|
||||
static const _##_name _name __attribute__ ((aligned(4)))= \
|
||||
{ \
|
||||
.len = 4, \
|
||||
.type = USB_STRING_DESCRIPTOR, \
|
||||
.name = { y, x } \
|
||||
} \
|
||||
EFM32_PACK_END()
|
||||
|
||||
/** Macro for creating WORD (4 byte) aligned uint8_t array with size which
|
||||
* is a multiple of WORD size.
|
||||
* @n Example: @n UBUF( rxBuffer, 37 ); => uint8_t rxBuffer[ 40 ];
|
||||
*/
|
||||
#if !defined(__GNUC__)
|
||||
#define UBUF( x, y ) EFM32_ALIGN( 4 ) uint8_t x[((y)+3)&~3]
|
||||
#define STATIC_UBUF( x, y ) EFM32_ALIGN( 4 ) static uint8_t x[((y)+3)&~3]
|
||||
#else
|
||||
#define UBUF( x, y ) uint8_t x[((y)+3)&~3] __attribute__ ((aligned(4)))
|
||||
|
||||
/** Macro for creating WORD (4 byte) aligned static uint8_t arrays with size which
|
||||
* is a multiple of WORD size.
|
||||
* @n Example: @n STATIC_UBUF( rxBuffer, 37 ); => static uint8_t rxBuffer[ 40 ];
|
||||
*/
|
||||
#define STATIC_UBUF( x, y ) static uint8_t x[((y)+3)&~3] __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief USB transfer status enumerator. */
|
||||
typedef enum
|
||||
{
|
||||
/* NOTE: Please keep in sync with table errMsg[] in em_usbhal.c */
|
||||
USB_STATUS_OK = 0, /**< No errors detected. */
|
||||
USB_STATUS_REQ_ERR = -1, /**< Setup request error. */
|
||||
USB_STATUS_EP_BUSY = -2, /**< Endpoint is busy. */
|
||||
USB_STATUS_REQ_UNHANDLED = -3, /**< Setup request not handled. */
|
||||
USB_STATUS_ILLEGAL = -4, /**< Illegal operation attempted. */
|
||||
USB_STATUS_EP_STALLED = -5, /**< Endpoint is stalled. */
|
||||
USB_STATUS_EP_ABORTED = -6, /**< Endpoint transfer was aborted. */
|
||||
USB_STATUS_EP_ERROR = -7, /**< Endpoint transfer error. */
|
||||
USB_STATUS_EP_NAK = -8, /**< Endpoint NAK'ed transfer request. */
|
||||
USB_STATUS_DEVICE_UNCONFIGURED = -9, /**< Device is unconfigured. */
|
||||
USB_STATUS_DEVICE_SUSPENDED = -10, /**< Device is suspended. */
|
||||
USB_STATUS_DEVICE_RESET = -11, /**< Device is/was reset. */
|
||||
USB_STATUS_TIMEOUT = -12, /**< Transfer timeout. */
|
||||
USB_STATUS_DEVICE_REMOVED = -13, /**< Device was removed. */
|
||||
USB_STATUS_HC_BUSY = -14, /**< Host channel is busy. */
|
||||
USB_STATUS_DEVICE_MALFUNCTION = -15, /**< Malfunctioning device attached. */
|
||||
USB_STATUS_PORT_OVERCURRENT = -16, /**< VBUS shortcircuit/overcurrent failure. */
|
||||
} USB_Status_TypeDef;
|
||||
/** @} (end addtogroup USB_COMMON) */
|
||||
|
||||
|
||||
#if defined( USB_DEVICE )
|
||||
/***************************************************************************//**
|
||||
* @addtogroup USB_DEVICE
|
||||
* @brief USB DEVICE protocol stack, see @ref usb_device page for detailed documentation.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#define USB_PWRSAVE_MODE_OFF 0 /**< No energy saving mode selected. */
|
||||
#define USB_PWRSAVE_MODE_ONSUSPEND 1 /**< Enter USB power-save mode on suspend. */
|
||||
#define USB_PWRSAVE_MODE_ONVBUSOFF 2 /**< Enter USB power-save mode when not attached to host. */
|
||||
#define USB_PWRSAVE_MODE_ENTEREM2 4 /**< Enter EM2 while in power-save mode. */
|
||||
|
||||
#define USB_USBC_32kHz_CLK_LFXO 0 /**< Use 32kHz LFXO clock while in powersave mode. */
|
||||
#define USB_USBC_32kHz_CLK_LFRCO 1 /**< Use 32kHz LFRCO clock while in powersave mode. */
|
||||
|
||||
/** @brief USB device state enumerator. */
|
||||
typedef enum
|
||||
{
|
||||
USBD_STATE_NONE = 0, /**< Device state is undefined/unknown. */
|
||||
USBD_STATE_ATTACHED = 1, /**< Device state is ATTACHED. */
|
||||
USBD_STATE_POWERED = 2, /**< Device state is POWERED. */
|
||||
USBD_STATE_DEFAULT = 3, /**< Device state is DEFAULT. */
|
||||
USBD_STATE_ADDRESSED = 4, /**< Device state is ADDRESSED. */
|
||||
USBD_STATE_CONFIGURED = 5, /**< Device state is CONFIGURED. */
|
||||
USBD_STATE_SUSPENDED = 6, /**< Device state is SUSPENDED. */
|
||||
USBD_STATE_LASTMARKER = 7, /**< Device state enum end marker. */
|
||||
} USBD_State_TypeDef;
|
||||
/** @} (end addtogroup USB_DEVICE) */
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
|
||||
/** @addtogroup USB_COMMON
|
||||
* @{*/
|
||||
|
||||
/** @brief USB Setup request package. */
|
||||
EFM32_PACK_START( 1 )
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t Recipient : 5; /**< Request recipient (device, interface, endpoint or other).*/
|
||||
uint8_t Type : 2; /**< Request type (standard, class or vendor). */
|
||||
uint8_t Direction : 1; /**< Transfer direction of SETUP data phase. */
|
||||
};
|
||||
uint8_t bmRequestType; /**< Request characteristics. */
|
||||
};
|
||||
uint8_t bRequest; /**< Request code. */
|
||||
uint16_t wValue; /**< Varies according to request. */
|
||||
uint16_t wIndex; /**< Index or offset, varies according to request. */
|
||||
uint16_t wLength; /**< Number of bytes to transfer if there is a data stage.*/
|
||||
};
|
||||
uint32_t dw[2];
|
||||
};
|
||||
} __attribute__ ((packed)) USB_Setup_TypeDef;
|
||||
EFM32_PACK_END()
|
||||
|
||||
|
||||
/** @brief USB Device Descriptor. */
|
||||
EFM32_PACK_START( 1 )
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of this descriptor in bytes */
|
||||
uint8_t bDescriptorType; /**< Constant DEVICE Descriptor Type */
|
||||
uint16_t bcdUSB; /**< USB Specification Release Number in Binary-Coded
|
||||
Decimal */
|
||||
uint8_t bDeviceClass; /**< Class code (assigned by the USB-IF) */
|
||||
uint8_t bDeviceSubClass; /**< Subclass code (assigned by the USB-IF) */
|
||||
uint8_t bDeviceProtocol; /**< Protocol code (assigned by the USB-IF) */
|
||||
uint8_t bMaxPacketSize0; /**< Maximum packet size for endpoint zero */
|
||||
uint16_t idVendor; /**< Vendor ID (assigned by the USB-IF) */
|
||||
uint16_t idProduct; /**< Product ID (assigned by the manufacturer) */
|
||||
uint16_t bcdDevice; /**< Device release number in binary-coded decimal */
|
||||
uint8_t iManufacturer; /**< Index of string descriptor describing manufacturer*/
|
||||
uint8_t iProduct; /**< Index of string descriptor describing product */
|
||||
uint8_t iSerialNumber; /**< Index of string descriptor describing the device
|
||||
serialnumber */
|
||||
uint8_t bNumConfigurations; /**< Number of possible configurations */
|
||||
} __attribute__ ((packed)) USB_DeviceDescriptor_TypeDef;
|
||||
EFM32_PACK_END()
|
||||
|
||||
|
||||
/** @brief USB Configuration Descriptor. */
|
||||
EFM32_PACK_START( 1 )
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of this descriptor in bytes */
|
||||
uint8_t bDescriptorType; /**< Constant CONFIGURATION Descriptor Type */
|
||||
uint16_t wTotalLength; /**< Total length of data returned for this
|
||||
configuration. Includes the combined length of all
|
||||
descriptors (configuration, interface, endpoint,
|
||||
and class- or vendor-specific) returned for this
|
||||
configuration. */
|
||||
uint8_t bNumInterfaces; /**< Number of interfaces supported by this
|
||||
configuration */
|
||||
uint8_t bConfigurationValue; /**< Value to use as an argument to the
|
||||
SetConfiguration request to select this
|
||||
configuration. */
|
||||
uint8_t iConfiguration; /**< Index of string descriptor describing this
|
||||
configuration. */
|
||||
uint8_t bmAttributes; /**< Configuration characteristics.
|
||||
@n D7: Reserved (set to one)
|
||||
@n D6: Self-powered
|
||||
@n D5: Remote Wakeup
|
||||
@n D4...0: Reserved (reset to zero) */
|
||||
uint8_t bMaxPower; /**< Maximum power consumption of the USB device, unit
|
||||
is 2mA per LSB */
|
||||
} __attribute__ ((packed)) USB_ConfigurationDescriptor_TypeDef;
|
||||
EFM32_PACK_END()
|
||||
|
||||
|
||||
/** @brief USB Interface Descriptor. */
|
||||
EFM32_PACK_START( 1 )
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of this descriptor in bytes. */
|
||||
uint8_t bDescriptorType; /**< Constant INTERFACE Descriptor Type. */
|
||||
uint8_t bInterfaceNumber; /**< Number of this interface. Zero-based value
|
||||
identifying the index in the array of concurrent
|
||||
interfaces supported by this configuration. */
|
||||
uint8_t bAlternateSetting; /**< Value used to select this alternate setting for
|
||||
the interface identified in the prior field. */
|
||||
uint8_t bNumEndpoints; /**< Number of endpoints used by this interface
|
||||
(excluding endpoint zero). If this value is zero,
|
||||
this interface only uses the Default Control Pipe.*/
|
||||
uint8_t bInterfaceClass; /**< Class code (assigned by the USB-IF). A value
|
||||
of zero is reserved for future standardization. If
|
||||
this field is set to FFH, the interface class is
|
||||
vendor-specific. All other values are reserved for
|
||||
assignment by the USB-IF. */
|
||||
uint8_t bInterfaceSubClass; /**< Subclass code (assigned by the USB-IF). These codes
|
||||
are qualified by the value of the bInterfaceClass
|
||||
field. If the bInterfaceClass field is reset to
|
||||
zero, this field must also be reset to zero. If
|
||||
the bInterfaceClass field is not set to FFH, all
|
||||
values are reserved forassignment by the USB-IF. */
|
||||
uint8_t bInterfaceProtocol; /**< Protocol code (assigned by the USB). These codes
|
||||
are qualified by the value of the bInterfaceClass
|
||||
and the bInterfaceSubClass fields. If an interface
|
||||
supports class-specific requests, this code
|
||||
identifies the protocols that the device uses as
|
||||
defined by the specification of the device class.
|
||||
If this field is reset to zero, the device does
|
||||
not use a class-specific protocol on this
|
||||
interface. If this field is set to FFH, the device
|
||||
uses a vendor-specific protocol for this interface*/
|
||||
uint8_t iInterface; /**< Index of string descriptor describing this
|
||||
interface. */
|
||||
} __attribute__ ((packed)) USB_InterfaceDescriptor_TypeDef;
|
||||
EFM32_PACK_END()
|
||||
|
||||
|
||||
/** @brief USB Endpoint Descriptor. */
|
||||
EFM32_PACK_START( 1 )
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of this descriptor in bytes */
|
||||
uint8_t bDescriptorType; /**< Constant ENDPOINT Descriptor Type */
|
||||
uint8_t bEndpointAddress; /**< The address of the endpoint */
|
||||
uint8_t bmAttributes; /**< This field describes the endpoint attributes */
|
||||
uint16_t wMaxPacketSize; /**< Maximum packet size for the endpoint */
|
||||
uint8_t bInterval; /**< Interval for polling EP for data transfers */
|
||||
} __attribute__ ((packed)) USB_EndpointDescriptor_TypeDef;
|
||||
EFM32_PACK_END()
|
||||
|
||||
|
||||
/** @brief USB String Descriptor. */
|
||||
EFM32_PACK_START( 1 )
|
||||
typedef struct
|
||||
{
|
||||
uint8_t len; /**< Size of this descriptor in bytes. */
|
||||
uint8_t type; /**< Constant STRING Descriptor Type. */
|
||||
char16_t name[]; /**< The string encoded with UTF-16LE UNICODE charset. */
|
||||
} __attribute__ ((packed)) USB_StringDescriptor_TypeDef;
|
||||
EFM32_PACK_END()
|
||||
|
||||
/** @} (end addtogroup USB_COMMON) */
|
||||
|
||||
/*** -------------------- Serial port debug configuration ---------------- ***/
|
||||
|
||||
#if defined( DOXY_DOC_ONLY )
|
||||
/** @addtogroup USB_COMMON
|
||||
* @{*/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Transmit a single char on the debug serial port.
|
||||
*
|
||||
* @note
|
||||
* This function is enabled with \#define DEBUG_USB_API when configuring the
|
||||
* protocol stack in "usbconfig.h".
|
||||
* This is convenient when debugging code, no need to remove use of this
|
||||
* function when debugging has completed.
|
||||
*
|
||||
* @param[in] c
|
||||
* Char to transmit.
|
||||
*
|
||||
* @return
|
||||
* The char transmitted.
|
||||
******************************************************************************/
|
||||
int USB_PUTCHAR( char c );
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Transmit a zero terminated string on the debug serial port.
|
||||
*
|
||||
* @note
|
||||
* This function is enabled with \#define DEBUG_USB_API when configuring the
|
||||
* protocol stack in "usbconfig.h".
|
||||
* This is convenient when debugging code, no need to remove use of this
|
||||
* function when debugging has completed.
|
||||
*
|
||||
* @param[in] p
|
||||
* Pointer to string to transmit.
|
||||
******************************************************************************/
|
||||
void USB_PUTS( const char *p );
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Transmit "printf" formated data on the debug serial port.
|
||||
*
|
||||
* @note
|
||||
* This function is enabled with \#define USB_USE_PRINTF when configuring the
|
||||
* protocol stack in "usbconfig.h".
|
||||
* This is convenient when debugging code, no need to remove use of this
|
||||
* function when debugging has completed.
|
||||
*
|
||||
* @param[in] format
|
||||
* Format string (as in printf). No floating point format support.
|
||||
******************************************************************************/
|
||||
int USB_PRINTF( const char *format, ... );
|
||||
|
||||
/** @} (end addtogroup USB_COMMON) */
|
||||
#endif /* defined( DOXY_DOC_ONLY ) */
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/* Hardware constraint, do not change. */
|
||||
#define MAX_NUM_HOSTCHANNELS 14
|
||||
|
||||
/* The DMA engine use one FIFO ram word for each host channel. */
|
||||
#define MAX_HOST_FIFO_SIZE_INWORDS (512-MAX_NUM_HOSTCHANNELS)/*Unit is 4 bytes*/
|
||||
|
||||
#if defined ( USER_PUTCHAR )
|
||||
void USB_Puts( const char *p );
|
||||
#define USB_PUTS( s ) USB_Puts( s )
|
||||
#define USB_PUTCHAR( c ) USER_PUTCHAR( c )
|
||||
#else
|
||||
#define USB_PUTS( s )
|
||||
#define USB_PUTCHAR( c )
|
||||
#endif
|
||||
|
||||
#if defined( USB_USE_PRINTF )
|
||||
/* Use a printf which don't support floating point formatting */
|
||||
#if defined(__ICCARM__) || defined (__CC_ARM) || defined (__CROSSWORKS_ARM)
|
||||
#define USB_PRINTF printf
|
||||
#else
|
||||
#define USB_PRINTF iprintf
|
||||
#endif
|
||||
#else
|
||||
#define USB_PRINTF(...)
|
||||
#endif /* defined( USB_USE_PRINTF ) */
|
||||
|
||||
#if defined( DEBUG_USB_API )
|
||||
#define DEBUG_USB_API_PUTS( s ) USB_PUTS( s )
|
||||
#define DEBUG_USB_API_PUTCHAR( c ) USB_PUTCHAR( c )
|
||||
#else
|
||||
#define DEBUG_USB_API_PUTS( s )
|
||||
#define DEBUG_USB_API_PUTCHAR( c )
|
||||
#endif /* defined( DEBUG_USB_API ) */
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*** -------------------- Common API definitions ------------------------- ***/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#if defined( USB_HOST )
|
||||
#if defined( NUM_APP_TIMERS )
|
||||
#define NUM_QTIMERS ( NUM_HC_USED + 2 + NUM_APP_TIMERS + 1 )
|
||||
#else
|
||||
#define NUM_QTIMERS ( NUM_HC_USED + 2 + 1 )
|
||||
#endif
|
||||
/* + 2 for default ctrl. host ch. 0 & 1, + 1 for host port timer */
|
||||
#else
|
||||
#if defined( NUM_APP_TIMERS )
|
||||
#define NUM_QTIMERS ( NUM_APP_TIMERS )
|
||||
#else
|
||||
#define NUM_QTIMERS 0
|
||||
#endif
|
||||
#endif /* defined( USB_HOST ) */
|
||||
/** @endcond */
|
||||
|
||||
/** @addtogroup USB_COMMON
|
||||
* @{*/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* USB transfer callback function.
|
||||
*
|
||||
* @details
|
||||
* The callback function is called when a transfer has completed. An application
|
||||
* should check the status, xferred and optionally the remaining parameters
|
||||
* before deciding if the transfer is usable. In the case where the transfer
|
||||
* is part of a control request data stage, the callback function should
|
||||
* return an appropriate @ref USB_Status_TypeDef status.
|
||||
*
|
||||
* @param[in] status
|
||||
* The transfer status. See @ref USB_Status_TypeDef.
|
||||
*
|
||||
* @param[in] xferred
|
||||
* Number of bytes actually transferred.
|
||||
*
|
||||
* @param[in] remaining
|
||||
* Number of bytes not transferred.
|
||||
*
|
||||
* @return
|
||||
* @ref USB_STATUS_OK on success, else an appropriate error code.
|
||||
******************************************************************************/
|
||||
typedef int (*USB_XferCompleteCb_TypeDef)( USB_Status_TypeDef status, uint32_t xferred, uint32_t remaining );
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* USBTIMER callback function.
|
||||
*
|
||||
* @details
|
||||
* The callback function is called when an USBTIMER has expired. The callback
|
||||
* is done with interrupts disabled.
|
||||
******************************************************************************/
|
||||
typedef void (*USBTIMER_Callback_TypeDef)( void );
|
||||
|
||||
char *USB_GetErrorMsgString( int error );
|
||||
|
||||
#if defined( USB_USE_PRINTF )
|
||||
void USB_PrintErrorMsgString( char *pre, int error );
|
||||
#else
|
||||
#define USB_PrintErrorMsgString( pre, error )
|
||||
#endif
|
||||
|
||||
void USBTIMER_DelayMs( uint32_t msec );
|
||||
void USBTIMER_DelayUs( uint32_t usec );
|
||||
void USBTIMER_Init( void );
|
||||
|
||||
#if ( NUM_QTIMERS > 0 )
|
||||
void USBTIMER_Start( uint32_t id, uint32_t timeout, USBTIMER_Callback_TypeDef callback );
|
||||
void USBTIMER_Stop( uint32_t id );
|
||||
#endif /* ( NUM_QTIMERS > 0 ) */
|
||||
/** @} (end addtogroup USB_COMMON) */
|
||||
|
||||
#if defined( USB_DEVICE )
|
||||
/** @addtogroup USB_DEVICE
|
||||
* @{*/
|
||||
/*** -------------------- DEVICE mode API definitions -------------------- ***/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* USB Reset callback function.
|
||||
* @details
|
||||
* Called whenever USB reset signalling is detected on the USB port.
|
||||
******************************************************************************/
|
||||
typedef void (*USBD_UsbResetCb_TypeDef)( void );
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* USB Start Of Frame (SOF) interrupt callback function.
|
||||
*
|
||||
* @details
|
||||
* Called at each SOF interrupt (if enabled),
|
||||
*
|
||||
* @param[in] sofNr
|
||||
* Current frame number. The value rolls over to 0 after 16383 (0x3FFF).
|
||||
******************************************************************************/
|
||||
typedef void (*USBD_SofIntCb_TypeDef)( uint16_t sofNr );
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* USB State change callback function.
|
||||
*
|
||||
* @details
|
||||
* Called whenever the device change state.
|
||||
*
|
||||
* @param[in] oldState
|
||||
* The device USB state just leaved. See @ref USBD_State_TypeDef.
|
||||
*
|
||||
* @param[in] newState
|
||||
* New (the current) USB device state. See @ref USBD_State_TypeDef.
|
||||
******************************************************************************/
|
||||
typedef void (*USBD_DeviceStateChangeCb_TypeDef)( USBD_State_TypeDef oldState, USBD_State_TypeDef newState );
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* USB power mode callback function.
|
||||
*
|
||||
* @details
|
||||
* Called whenever the device stack needs to query if the device is currently
|
||||
* self- or bus-powered. Typically when host has issued an @ref GET_STATUS
|
||||
* setup command.
|
||||
*
|
||||
* @return
|
||||
* True if self-powered, false otherwise.
|
||||
******************************************************************************/
|
||||
typedef bool (*USBD_IsSelfPoweredCb_TypeDef)( void );
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* USB setup request callback function.
|
||||
*
|
||||
* @details
|
||||
* Called on each setup request received from host. This gives the application a
|
||||
* possibility to extend or override standard requests, and to implement class
|
||||
* or vendor specific requests. Return @ref USB_STATUS_OK if the request is
|
||||
* handled, return @ref USB_STATUS_REQ_ERR if it is an illegal request or
|
||||
* return @ref USB_STATUS_REQ_UNHANDLED to pass the request on to the default
|
||||
* request handler.
|
||||
*
|
||||
* @param[in] setup
|
||||
* Pointer to an USB setup packet. See @ref USB_Setup_TypeDef.
|
||||
*
|
||||
* @return
|
||||
* An appropriate status/error code. See @ref USB_Status_TypeDef.
|
||||
******************************************************************************/
|
||||
typedef int (*USBD_SetupCmdCb_TypeDef)( const USB_Setup_TypeDef *setup );
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
struct USBD_Callbacks_TypeDef;
|
||||
typedef struct USBD_Callbacks_TypeDef const *USBD_Callbacks_TypeDef_Pointer;
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/** @brief USB Device stack initialization structure.
|
||||
* @details This structure is passed to @ref USBD_Init() when starting up
|
||||
* the device. */
|
||||
typedef struct
|
||||
{
|
||||
const USB_DeviceDescriptor_TypeDef *deviceDescriptor; /**< Pointer to a device descriptor. */
|
||||
const uint8_t *configDescriptor; /**< Pointer to a configuration descriptor. */
|
||||
const void * const *stringDescriptors; /**< Pointer to an array of string descriptor pointers.*/
|
||||
const uint8_t numberOfStrings; /**< Number of strings in string descriptor array. */
|
||||
const uint8_t *bufferingMultiplier; /**< Pointer to an array defining the size of the
|
||||
endpoint buffers. The size is given in
|
||||
multiples of endpoint size. Generally a value
|
||||
of 1 (single) or 2 (double) buffering should be
|
||||
used. */
|
||||
USBD_Callbacks_TypeDef_Pointer callbacks; /**< Pointer to struct with callbacks
|
||||
(@ref USBD_Callbacks_TypeDef). These callbacks
|
||||
are used by the device stack to signal events
|
||||
to or query the application. */
|
||||
const uint32_t reserved; /**< Reserved for future use. */
|
||||
} USBD_Init_TypeDef;
|
||||
|
||||
|
||||
/** @brief USB Device stack callback structure.
|
||||
* @details Callback functions used by the device stack to signal events or
|
||||
* query status to/from the application. See @ref USBD_Init_TypeDef. Assign
|
||||
* members to NULL if your application don't need a specific callback. */
|
||||
typedef struct USBD_Callbacks_TypeDef
|
||||
{
|
||||
const USBD_UsbResetCb_TypeDef usbReset; /**< Called whenever USB reset signalling is detected
|
||||
on the USB port. */
|
||||
const USBD_DeviceStateChangeCb_TypeDef usbStateChange; /**< Called whenever the device change state. */
|
||||
const USBD_SetupCmdCb_TypeDef setupCmd; /**< Called on each setup request received from host.*/
|
||||
const USBD_IsSelfPoweredCb_TypeDef isSelfPowered; /**< Called whenever the device stack needs to query
|
||||
if the device is currently self- or bus-powered.
|
||||
Applies to devices which can operate in both modes.*/
|
||||
const USBD_SofIntCb_TypeDef sofInt; /**< Called at each SOF interrupt. If NULL, the device
|
||||
stack will not enable the SOF interrupt. */
|
||||
} USBD_Callbacks_TypeDef;
|
||||
|
||||
|
||||
/*** -------------------- DEVICE mode API -------------------------------- ***/
|
||||
|
||||
void USBD_AbortAllTransfers( void );
|
||||
int USBD_AbortTransfer( int epAddr );
|
||||
void USBD_Connect( void );
|
||||
void USBD_Disconnect( void );
|
||||
bool USBD_EpIsBusy( int epAddr );
|
||||
USBD_State_TypeDef USBD_GetUsbState( void );
|
||||
const char * USBD_GetUsbStateName( USBD_State_TypeDef state );
|
||||
int USBD_Init( const USBD_Init_TypeDef *p );
|
||||
int USBD_Read( int epAddr, void *data, int byteCount, USB_XferCompleteCb_TypeDef callback );
|
||||
int USBD_RemoteWakeup( void );
|
||||
bool USBD_SafeToEnterEM2( void );
|
||||
int USBD_StallEp( int epAddr );
|
||||
void USBD_Stop( void );
|
||||
int USBD_UnStallEp( int epAddr );
|
||||
int USBD_Write( int epAddr, void *data, int byteCount, USB_XferCompleteCb_TypeDef callback );
|
||||
|
||||
#ifdef __MBED__
|
||||
int USBD_SetAddress( uint8_t addr );
|
||||
int USBD_AddEndpoint( int epAddr, int transferType, int maxPacketSize, int bufferMult );
|
||||
int USBD_EpIsStalled( int epAddr );
|
||||
void USBD_StallEp0( void );
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup USB_DEVICE) */
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
|
||||
|
||||
#if defined( USB_HOST )
|
||||
/***************************************************************************//**
|
||||
* @addtogroup USB_HOST
|
||||
* @brief USB HOST protocol stack, see @ref usb_host page for detailed documentation.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
/*** -------------------- HOST mode API definitions ---------------------- ***/
|
||||
|
||||
#define USB_VBUSOVRCUR_PORT_NONE -1 /**< No overcurrent flag functionality. */
|
||||
#define USB_VBUSOVRCUR_POLARITY_LOW 0 /**< Overcurrent flag pin polarity is low. */
|
||||
#define USB_VBUSOVRCUR_POLARITY_HIGH 1 /**< Overcurrent flag pin polarity is high. */
|
||||
|
||||
/** USB HOST endpoint status enumerator. */
|
||||
typedef enum
|
||||
{
|
||||
H_EP_IDLE = 0, /**< The endpoint is idle. */
|
||||
H_EP_SETUP = 1, /**< The endpoint is in SETUP stage. */
|
||||
H_EP_DATA_IN = 2, /**< The endpoint is in DATA IN stage. */
|
||||
H_EP_DATA_OUT = 3, /**< The endpoint is in DATA OUT stage. */
|
||||
H_EP_STATUS_IN = 4, /**< The endpoint is in STATUS IN stage. */
|
||||
H_EP_STATUS_OUT = 5, /**< The endpoint is in STATUS OUT stage. */
|
||||
} USBH_EpState_TypeDef;
|
||||
|
||||
|
||||
/** @brief USB HOST endpoint status data.
|
||||
* @details A host application should not manipulate the contents of
|
||||
* this struct. */
|
||||
typedef struct
|
||||
{
|
||||
USB_Setup_TypeDef setup; /**< A SETUP package. */
|
||||
uint8_t setupErrCnt; /**< Error counter for SETUP transfers. */
|
||||
USB_EndpointDescriptor_TypeDef epDesc; /**< Endpoint descriptor. */
|
||||
struct USBH_Device_TypeDef *parentDevice; /**< The device the endpoint belongs to. */
|
||||
uint8_t type; /**< Endpoint type. */
|
||||
uint16_t packetSize; /**< Packet size, current transfer. */
|
||||
uint8_t hcOut; /**< Host channel number assigned for OUT transfers. */
|
||||
uint8_t hcIn; /**< Host channel number assigned for IN transfers. */
|
||||
bool in; /**< Endpoint direction. */
|
||||
uint8_t toggle; /**< Endpoint data toggle. */
|
||||
USBH_EpState_TypeDef state; /**< Endpoint state. */
|
||||
uint8_t addr; /**< Endpoint address. */
|
||||
uint8_t *buf; /**< Transfer buffer. */
|
||||
volatile bool xferCompleted; /**< Transfer completion flag. */
|
||||
USB_Status_TypeDef xferStatus; /**< Transfer status. */
|
||||
USB_XferCompleteCb_TypeDef xferCompleteCb; /**< Transfer completion callback function. */
|
||||
uint32_t xferred; /**< Number of bytes transferred. */
|
||||
uint32_t remaining; /**< Number of bytes remaining. */
|
||||
uint32_t timeout; /**< Transfer timeout. */
|
||||
} USBH_Ep_TypeDef;
|
||||
|
||||
|
||||
/** @brief USB HOST device definition.
|
||||
* @details A host application should not manipulate the contents of
|
||||
* this struct. */
|
||||
typedef struct USBH_Device_TypeDef
|
||||
{
|
||||
USB_DeviceDescriptor_TypeDef devDesc; /**< The device device descriptor. */
|
||||
USB_ConfigurationDescriptor_TypeDef confDesc; /**< The device configuration descriptor. */
|
||||
USB_InterfaceDescriptor_TypeDef itfDesc; /**< The device interface descriptor. */
|
||||
USBH_Ep_TypeDef ep0; /**< Endpoint 0 status data. */
|
||||
USBH_Ep_TypeDef *ep; /**< Array of endpoint status data. */
|
||||
int numEp; /**< Number of endpoints. */
|
||||
uint8_t addr; /**< The device address. */
|
||||
uint8_t speed; /**< The device speed (low or full speed). */
|
||||
} USBH_Device_TypeDef;
|
||||
|
||||
|
||||
/** @brief USB Host stack initialization structure.
|
||||
* @details This structure is passed to @ref USBH_Init() when starting up the
|
||||
* device. Max accumulated FIFO size is 2K bytes. */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t rxFifoSize; /**< Number of FIFO bytes set aside for IN endpoints. */
|
||||
uint32_t nptxFifoSize; /**< Number of FIFO bytes set aside for OUT CTRL/BULK endoints. */
|
||||
uint32_t ptxFifoSize; /**< Number of FIFO bytes set aside for OUT INTR/ISO endoints. */
|
||||
uint32_t reserved; /**< Reserved for future use. */
|
||||
} USBH_Init_TypeDef;
|
||||
|
||||
|
||||
/** Default @ref USBH_Init_TypeDef values, provides reasonable Tx/Rx FIFO
|
||||
* partitioning. */
|
||||
/* In DMA mode the total available FIFO space is smaller. */
|
||||
/* The DMA controller use one FIFO word pr. channel for status. */
|
||||
/* The unit in the table is byte. */
|
||||
#define USBH_INIT_DEFAULT \
|
||||
{ \
|
||||
MAX_HOST_FIFO_SIZE_INWORDS * 2,/* 1024 bytes Rx FIFO size. */ \
|
||||
MAX_HOST_FIFO_SIZE_INWORDS, /* 512 bytes non-periodic Tx FIFO size. */ \
|
||||
MAX_HOST_FIFO_SIZE_INWORDS, /* 512 bytes periodic Tx FIFO size. */ \
|
||||
0 /* Reserved. */ \
|
||||
}
|
||||
|
||||
/*** -------------------- HOST mode API ---------------------------------- ***/
|
||||
|
||||
int USBH_AssignHostChannel( USBH_Ep_TypeDef *ep, uint8_t hcnum );
|
||||
int USBH_ControlMsg( USBH_Ep_TypeDef *ep, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, void *data, int timeout, USB_XferCompleteCb_TypeDef callback );
|
||||
int USBH_ControlMsgB( USBH_Ep_TypeDef *ep, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, void *data, int timeout );
|
||||
bool USBH_DeviceConnected( void );
|
||||
int USBH_GetConfigurationDescriptorB( USBH_Device_TypeDef *device, void *buf, int len, uint8_t configIndex );
|
||||
int USBH_GetDeviceDescriptorB( USBH_Device_TypeDef *device, void *buf, int len );
|
||||
uint8_t USBH_GetPortSpeed( void );
|
||||
int USBH_GetStringB( USBH_Device_TypeDef *device, uint8_t *buf, int bufLen, uint8_t stringIndex, uint16_t langID );
|
||||
int USBH_Init( const USBH_Init_TypeDef *p );
|
||||
int USBH_InitDeviceData( USBH_Device_TypeDef *device, const uint8_t *buf, USBH_Ep_TypeDef *ep, int numEp, uint8_t deviceSpeed );
|
||||
int USBH_PortReset( void );
|
||||
int USBH_PortResume( void );
|
||||
void USBH_PortSuspend( void );
|
||||
void USBH_PrintString( const char *pre, const USB_StringDescriptor_TypeDef *s, const char *post );
|
||||
|
||||
#if defined( USB_USE_PRINTF )
|
||||
int USBH_PrintConfigurationDescriptor( const USB_ConfigurationDescriptor_TypeDef *config, int maxLen );
|
||||
int USBH_PrintDeviceDescriptor( const USB_DeviceDescriptor_TypeDef *device );
|
||||
int USBH_PrintEndpointDescriptor( const USB_EndpointDescriptor_TypeDef *endpoint );
|
||||
int USBH_PrintInterfaceDescriptor( const USB_InterfaceDescriptor_TypeDef *interface );
|
||||
#else
|
||||
#define USBH_PrintConfigurationDescriptor( config, maxLen )
|
||||
#define USBH_PrintDeviceDescriptor( device )
|
||||
#define USBH_PrintEndpointDescriptor( endpoint )
|
||||
#define USBH_PrintInterfaceDescriptor( interface )
|
||||
#endif /* defined( USB_USE_PRINTF ) */
|
||||
|
||||
int USBH_QueryDeviceB( uint8_t *buf, size_t bufsize, uint8_t deviceSpeed );
|
||||
USB_ConfigurationDescriptor_TypeDef* USBH_QGetConfigurationDescriptor( const uint8_t *buf, int configIndex );
|
||||
USB_DeviceDescriptor_TypeDef* USBH_QGetDeviceDescriptor( const uint8_t *buf );
|
||||
USB_EndpointDescriptor_TypeDef* USBH_QGetEndpointDescriptor( const uint8_t *buf, int configIndex, int interfaceIndex, int endpointIndex );
|
||||
USB_InterfaceDescriptor_TypeDef* USBH_QGetInterfaceDescriptor( const uint8_t *buf, int configIndex, int interfaceIndex );
|
||||
|
||||
int USBH_Read( USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout, USB_XferCompleteCb_TypeDef callback );
|
||||
int USBH_ReadB( USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout );
|
||||
int USBH_SetAddressB( USBH_Device_TypeDef *device, uint8_t deviceAddress );
|
||||
int USBH_SetAltInterfaceB( USBH_Device_TypeDef *device, uint8_t interfaceIndex, uint8_t alternateSetting );
|
||||
int USBH_SetConfigurationB( USBH_Device_TypeDef *device, uint8_t configValue );
|
||||
int USBH_StallEpB( USBH_Ep_TypeDef *ep );
|
||||
void USBH_Stop( void );
|
||||
int USBH_UnStallEpB( USBH_Ep_TypeDef *ep );
|
||||
int USBH_WaitForDeviceConnectionB( uint8_t *buf, int timeoutInSeconds );
|
||||
int USBH_Write( USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout, USB_XferCompleteCb_TypeDef callback );
|
||||
int USBH_WriteB( USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout );
|
||||
|
||||
/** @} (end addtogroup USB_HOST) */
|
||||
#endif /* defined( USB_HOST ) */
|
||||
/** @} (end addtogroup USB) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined( USB_DEVICE ) || defined( USB_HOST ) */
|
||||
#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
|
||||
#endif /* __EM_USB_H */
|
|
@ -0,0 +1,206 @@
|
|||
/***************************************************************************//**
|
||||
* @file em_usbd.h
|
||||
* @brief USB protocol stack library API for EFM32.
|
||||
* @version 3.20.14
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* 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 __EM_USBD_H
|
||||
#define __EM_USBD_H
|
||||
|
||||
#include "em_device.h"
|
||||
#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
|
||||
#include "em_usb.h"
|
||||
#if defined( USB_DEVICE )
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#if defined( DEBUG_USB_API )
|
||||
#define DEBUG_TRACE_ABORT( x ) \
|
||||
{ \
|
||||
if ( x == USB_STATUS_EP_STALLED ) \
|
||||
{ DEBUG_USB_API_PUTS( "\nEP cb(), EP stalled" ); } \
|
||||
else if ( x == USB_STATUS_EP_ABORTED ) \
|
||||
{ DEBUG_USB_API_PUTS( "\nEP cb(), EP aborted" ); } \
|
||||
else if ( x == USB_STATUS_DEVICE_UNCONFIGURED ) \
|
||||
{ DEBUG_USB_API_PUTS( "\nEP cb(), device unconfigured" ); } \
|
||||
else if ( x == USB_STATUS_DEVICE_SUSPENDED ) \
|
||||
{ DEBUG_USB_API_PUTS( "\nEP cb(), device suspended" ); } \
|
||||
else /* ( x == USB_STATUS_DEVICE_RESET ) */ \
|
||||
{ DEBUG_USB_API_PUTS( "\nEP cb(), device reset" ); } \
|
||||
}
|
||||
#else
|
||||
#define DEBUG_TRACE_ABORT( x )
|
||||
#endif
|
||||
|
||||
extern USBD_Device_TypeDef *dev;
|
||||
extern volatile bool USBD_poweredDown;
|
||||
|
||||
__STATIC_INLINE void USBD_ArmEp0( USBD_Ep_TypeDef *ep );
|
||||
__STATIC_INLINE void USBD_ArmEpN( USBD_Ep_TypeDef *ep );
|
||||
__STATIC_INLINE void USBD_AbortEp( USBD_Ep_TypeDef *ep );
|
||||
|
||||
void USBD_SetUsbState( USBD_State_TypeDef newState );
|
||||
|
||||
int USBDCH9_SetupCmd( USBD_Device_TypeDef *device );
|
||||
|
||||
void USBDEP_Ep0Handler( USBD_Device_TypeDef *device );
|
||||
void USBDEP_EpHandler( uint8_t epAddr );
|
||||
|
||||
__STATIC_INLINE void USBD_ActivateAllEps( bool forceIdle )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 1; i <= NUM_EP_USED; i++ )
|
||||
{
|
||||
USBDHAL_ActivateEp( &dev->ep[ i ], forceIdle );
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBD_ArmEp( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
if ( ep->num == 0 )
|
||||
{
|
||||
USBD_ArmEp0( ep );
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_ArmEpN( ep );
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBD_ArmEp0( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
if ( ep->in )
|
||||
{
|
||||
if ( ep->remaining == 0 ) /* Zero Length Packet? */
|
||||
{
|
||||
ep->zlp = 1;
|
||||
}
|
||||
|
||||
USBDHAL_SetEp0InDmaPtr( ep->buf );
|
||||
USBDHAL_StartEp0In( EFM32_MIN( ep->remaining, ep->packetSize ),
|
||||
dev->ep0MpsCode );
|
||||
}
|
||||
else
|
||||
{
|
||||
USBDHAL_SetEp0OutDmaPtr( ep->buf );
|
||||
USBDHAL_StartEp0Out( ep->packetSize, dev->ep0MpsCode );
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBD_ArmEpN( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
if ( ep->in )
|
||||
{
|
||||
USBDHAL_StartEpIn( ep );
|
||||
}
|
||||
else
|
||||
{
|
||||
USBDHAL_StartEpOut( ep );
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBD_DeactivateAllEps( USB_Status_TypeDef reason )
|
||||
{
|
||||
int i;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
|
||||
for ( i = 1; i <= NUM_EP_USED; i++ )
|
||||
{
|
||||
ep = &dev->ep[ i ];
|
||||
|
||||
if ( ep->state == D_EP_IDLE )
|
||||
{
|
||||
USBDHAL_DeactivateEp( ep );
|
||||
}
|
||||
}
|
||||
|
||||
USBDHAL_AbortAllTransfers( reason );
|
||||
}
|
||||
|
||||
__STATIC_INLINE USBD_Ep_TypeDef *USBD_GetEpFromAddr( uint8_t epAddr )
|
||||
{
|
||||
int epIndex;
|
||||
USBD_Ep_TypeDef *ep = NULL;
|
||||
|
||||
if ( epAddr & USB_SETUP_DIR_MASK )
|
||||
{
|
||||
epIndex = dev->inEpAddr2EpIndex[ epAddr & USB_EPNUM_MASK ];
|
||||
}
|
||||
else
|
||||
{
|
||||
epIndex = dev->outEpAddr2EpIndex[ epAddr & USB_EPNUM_MASK ];
|
||||
}
|
||||
|
||||
if ( epIndex )
|
||||
{
|
||||
ep = &dev->ep[ epIndex ];
|
||||
}
|
||||
else if ( ( epAddr & USB_EPNUM_MASK ) == 0 )
|
||||
{
|
||||
ep = &dev->ep[ 0 ];
|
||||
}
|
||||
|
||||
return ep;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBD_ReArmEp0( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
if ( ep->in )
|
||||
{
|
||||
USBDHAL_StartEp0In( EFM32_MIN( ep->remaining, ep->packetSize ),
|
||||
dev->ep0MpsCode );
|
||||
}
|
||||
else
|
||||
{
|
||||
USBDHAL_StartEp0Out( ep->packetSize, dev->ep0MpsCode );
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBD_AbortEp( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
if ( ep->state == D_EP_IDLE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ep->in )
|
||||
{
|
||||
USBDHAL_AbortEpIn( ep );
|
||||
}
|
||||
else
|
||||
{
|
||||
USBDHAL_AbortEpOut( ep );
|
||||
}
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
|
||||
#endif /* __EM_USBD_H */
|
|
@ -0,0 +1,75 @@
|
|||
/***************************************************************************//**
|
||||
* @file em_usbh.h
|
||||
* @brief USB protocol stack library API for EFM32.
|
||||
* @version 3.20.14
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* 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 __EM_USBH_H
|
||||
#define __EM_USBH_H
|
||||
|
||||
#include "em_device.h"
|
||||
#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
|
||||
#include "em_usb.h"
|
||||
#if defined( USB_HOST )
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
extern USBH_Hc_TypeDef hcs[];
|
||||
extern int USBH_attachRetryCount;
|
||||
extern const USBH_AttachTiming_TypeDef USBH_attachTiming[];
|
||||
extern USBH_Init_TypeDef USBH_initData;
|
||||
extern volatile USBH_PortState_TypeDef USBH_portStatus;
|
||||
|
||||
USB_Status_TypeDef USBH_CtlSendSetup( USBH_Ep_TypeDef *ep );
|
||||
USB_Status_TypeDef USBH_CtlSendData( USBH_Ep_TypeDef *ep, uint16_t length );
|
||||
USB_Status_TypeDef USBH_CtlReceiveData( USBH_Ep_TypeDef *ep, uint16_t length );
|
||||
|
||||
#if defined( USB_RAW_API )
|
||||
int USBH_CtlRxRaw( uint8_t pid, USBH_Ep_TypeDef *ep, void *data, int byteCount );
|
||||
int USBH_CtlTxRaw( uint8_t pid, USBH_Ep_TypeDef *ep, void *data, int byteCount );
|
||||
#endif
|
||||
|
||||
void USBHEP_EpHandler( USBH_Ep_TypeDef *ep, USB_Status_TypeDef result );
|
||||
void USBHEP_CtrlEpHandler( USBH_Ep_TypeDef *ep, USB_Status_TypeDef result );
|
||||
void USBHEP_TransferDone( USBH_Ep_TypeDef *ep, USB_Status_TypeDef result );
|
||||
|
||||
__STATIC_INLINE uint16_t USBH_GetFrameNum( void )
|
||||
{
|
||||
return USBHHAL_GetFrameNum();
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool USBH_FrameNumIsEven( void )
|
||||
{
|
||||
return ( USBHHAL_GetFrameNum() & 1 ) == 0;
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined( USB_HOST ) */
|
||||
#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
|
||||
#endif /* __EM_USBH_H */
|
|
@ -0,0 +1,757 @@
|
|||
/***************************************************************************//**
|
||||
* @file em_usbhal.h
|
||||
* @brief USB protocol stack library, low level USB peripheral access.
|
||||
* @version 3.20.14
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* 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 __EM_USBHAL_H
|
||||
#define __EM_USBHAL_H
|
||||
|
||||
#include "em_device.h"
|
||||
#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
|
||||
#include "em_usb.h"
|
||||
#if defined( USB_DEVICE ) || defined( USB_HOST )
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#define USB_PID_DATA0 0
|
||||
#define USB_PID_DATA2 1
|
||||
#define USB_PID_DATA1 2
|
||||
#define USB_PID_SETUP 3
|
||||
|
||||
#define HPRT_F_SPEED ( 1 << _USB_HPRT_PRTSPD_SHIFT )
|
||||
#define HPRT_L_SPEED ( 2 << _USB_HPRT_PRTSPD_SHIFT )
|
||||
#define HCFG_PHYCLK_48MHZ 1
|
||||
#define HCFG_PHYCLK_6MHZ 2
|
||||
|
||||
#define DOEP0_XFERSIZE_PKTCNT_MASK ( _USB_DOEP0TSIZ_XFERSIZE_MASK | \
|
||||
_USB_DOEP0TSIZ_PKTCNT_MASK )
|
||||
#define DOEP_XFERSIZE_PKTCNT_MASK ( _USB_DOEP_TSIZ_XFERSIZE_MASK | \
|
||||
_USB_DOEP_TSIZ_PKTCNT_MASK )
|
||||
|
||||
#define DIEP0_XFERSIZE_PKTCNT_MASK ( _USB_DIEP0TSIZ_XFERSIZE_MASK | \
|
||||
_USB_DIEP0TSIZ_PKTCNT_MASK )
|
||||
#define DIEP_XFERSIZE_PKTCNT_MASK ( _USB_DIEP_TSIZ_XFERSIZE_MASK | \
|
||||
_USB_DIEP_TSIZ_PKTCNT_MASK | \
|
||||
_USB_DIEP_TSIZ_MC_MASK )
|
||||
|
||||
#define DIEPCTL_EPTYPE_CONTROL (0 << _USB_DIEP_CTL_EPTYPE_SHIFT )
|
||||
#define DIEPCTL_EPTYPE_ISOC (1 << _USB_DIEP_CTL_EPTYPE_SHIFT )
|
||||
#define DIEPCTL_EPTYPE_BULK (2 << _USB_DIEP_CTL_EPTYPE_SHIFT )
|
||||
#define DIEPCTL_EPTYPE_INTR (3 << _USB_DIEP_CTL_EPTYPE_SHIFT )
|
||||
|
||||
#define DOEPCTL_EPTYPE_CONTROL (0 << _USB_DOEP_CTL_EPTYPE_SHIFT )
|
||||
#define DOEPCTL_EPTYPE_ISOC (1 << _USB_DOEP_CTL_EPTYPE_SHIFT )
|
||||
#define DOEPCTL_EPTYPE_BULK (2 << _USB_DOEP_CTL_EPTYPE_SHIFT )
|
||||
#define DOEPCTL_EPTYPE_INTR (3 << _USB_DOEP_CTL_EPTYPE_SHIFT )
|
||||
|
||||
#define HCCHAR_EPTYPE_CTRL (0 << _USB_HC_CHAR_EPTYPE_SHIFT )
|
||||
#define HCCHAR_EPTYPE_ISOC (1 << _USB_HC_CHAR_EPTYPE_SHIFT )
|
||||
#define HCCHAR_EPTYPE_BULK (2 << _USB_HC_CHAR_EPTYPE_SHIFT )
|
||||
#define HCCHAR_EPTYPE_INTR (3 << _USB_HC_CHAR_EPTYPE_SHIFT )
|
||||
|
||||
#define GRXSTSP_PKTSTS_DEVICE_GOTNAK ( 1 << _USB_GRXSTSP_PKTSTS_SHIFT )
|
||||
#define GRXSTSP_PKTSTS_DEVICE_DATAOUTRECEIVED ( 2 << _USB_GRXSTSP_PKTSTS_SHIFT )
|
||||
#define GRXSTSP_PKTSTS_DEVICE_DATAOUTCOMPLETE ( 3 << _USB_GRXSTSP_PKTSTS_SHIFT )
|
||||
#define GRXSTSP_PKTSTS_DEVICE_SETUPCOMPLETE ( 4 << _USB_GRXSTSP_PKTSTS_SHIFT )
|
||||
#define GRXSTSP_PKTSTS_DEVICE_SETUPRECEIVED ( 6 << _USB_GRXSTSP_PKTSTS_SHIFT )
|
||||
|
||||
#define GRXSTSP_PKTSTS_HOST_DATAINRECEIVED ( 2 << _USB_GRXSTSP_PKTSTS_SHIFT )
|
||||
#define GRXSTSP_PKTSTS_HOST_DATAINCOMPLETE ( 3 << _USB_GRXSTSP_PKTSTS_SHIFT )
|
||||
#define GRXSTSP_PKTSTS_HOST_DATATOGGLEERROR ( 5 << _USB_GRXSTSP_PKTSTS_SHIFT )
|
||||
#define GRXSTSP_PKTSTS_HOST_CHANNELHALTED ( 7 << _USB_GRXSTSP_PKTSTS_SHIFT )
|
||||
|
||||
#define DCTL_WO_BITMASK \
|
||||
( _USB_DCTL_CGOUTNAK_MASK | _USB_DCTL_SGOUTNAK_MASK | \
|
||||
_USB_DCTL_CGNPINNAK_MASK | _USB_DCTL_SGNPINNAK_MASK )
|
||||
#define GUSBCFG_WO_BITMASK ( USB_GUSBCFG_CORRUPTTXPKT )
|
||||
#define DEPCTL_WO_BITMASK \
|
||||
( USB_DIEP_CTL_CNAK | USB_DIEP_CTL_SNAK | \
|
||||
USB_DIEP_CTL_SETD0PIDEF | USB_DIEP_CTL_SETD1PIDOF )
|
||||
|
||||
#define HPRT_WC_MASK ( USB_HPRT_PRTCONNDET | USB_HPRT_PRTENA | \
|
||||
USB_HPRT_PRTENCHNG | USB_HPRT_PRTOVRCURRCHNG )
|
||||
|
||||
typedef __IO uint32_t USB_FIFO_TypeDef[ 0x1000 / sizeof( uint32_t ) ];
|
||||
typedef __IO uint32_t USB_DIEPTXF_TypeDef;
|
||||
|
||||
#define USB_DINEPS ((USB_DIEP_TypeDef *) &USB->DIEP0CTL )
|
||||
#define USB_DOUTEPS ((USB_DOEP_TypeDef *) &USB->DOEP0CTL )
|
||||
#define USB_FIFOS ((USB_FIFO_TypeDef *) &USB->FIFO0D )
|
||||
#define USB_DIEPTXFS ((USB_DIEPTXF_TypeDef *) &USB->DIEPTXF1 )
|
||||
|
||||
void USBHAL_CoreReset( void );
|
||||
|
||||
#if defined( USB_DEVICE )
|
||||
void USBDHAL_AbortAllTransfers( USB_Status_TypeDef reason );
|
||||
USB_Status_TypeDef USBDHAL_CoreInit( const uint32_t totalRxFifoSize,
|
||||
const uint32_t totalTxFifoSize );
|
||||
void USBDHAL_Connect( void );
|
||||
void USBDHAL_Disconnect( void );
|
||||
void USBDHAL_AbortAllEps( void );
|
||||
void USBDHAL_AbortEpIn( USBD_Ep_TypeDef *ep );
|
||||
void USBDHAL_AbortEpOut( USBD_Ep_TypeDef *ep );
|
||||
|
||||
__STATIC_INLINE USB_Status_TypeDef USBDHAL_GetStallStatusEp(
|
||||
USBD_Ep_TypeDef *ep, uint16_t *halt );
|
||||
__STATIC_INLINE uint32_t USBDHAL_GetInEpInts( USBD_Ep_TypeDef *ep );
|
||||
__STATIC_INLINE uint32_t USBDHAL_GetOutEpInts( USBD_Ep_TypeDef *ep );
|
||||
__STATIC_INLINE void USBDHAL_SetEPDISNAK( USBD_Ep_TypeDef *ep );
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
|
||||
#if defined( USB_HOST )
|
||||
USB_Status_TypeDef USBHHAL_CoreInit( const uint32_t rxFifoSize,
|
||||
const uint32_t nptxFifoSize,
|
||||
const uint32_t ptxFifoSize );
|
||||
void USBHHAL_HCHalt( int hcnum, uint32_t hcchar );
|
||||
void USBHHAL_HCInit( int hcnum );
|
||||
void USBHHAL_HCStart( int hcnum );
|
||||
#endif /* defined( USB_HOST ) */
|
||||
|
||||
__STATIC_INLINE void USBHAL_DisableGlobalInt( void )
|
||||
{
|
||||
USB->GAHBCFG &= ~USB_GAHBCFG_GLBLINTRMSK;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHAL_DisablePhyPins( void )
|
||||
{
|
||||
USB->ROUTE = _USB_ROUTE_RESETVALUE;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHAL_DisableUsbInt( void )
|
||||
{
|
||||
USB->IEN = _USB_IEN_RESETVALUE;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHAL_EnableGlobalInt( void )
|
||||
{
|
||||
USB->GAHBCFG |= USB_GAHBCFG_GLBLINTRMSK;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHAL_FlushRxFifo( void )
|
||||
{
|
||||
USB->GRSTCTL = USB_GRSTCTL_RXFFLSH;
|
||||
while ( USB->GRSTCTL & USB_GRSTCTL_RXFFLSH ) {}
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHAL_FlushTxFifo( uint8_t fifoNum )
|
||||
{
|
||||
USB->GRSTCTL = USB_GRSTCTL_TXFFLSH | ( fifoNum << _USB_GRSTCTL_TXFNUM_SHIFT );
|
||||
while ( USB->GRSTCTL & USB_GRSTCTL_TXFFLSH ) {}
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t USBHAL_GetCoreInts( void )
|
||||
{
|
||||
uint32_t retVal;
|
||||
|
||||
retVal = USB->GINTSTS;
|
||||
retVal &= USB->GINTMSK;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool USBHAL_VbusIsOn( void )
|
||||
{
|
||||
return ( USB->STATUS & USB_STATUS_VREGOS ) != 0;
|
||||
}
|
||||
|
||||
#if defined( USB_DEVICE )
|
||||
__STATIC_INLINE void USBDHAL_ActivateEp( USBD_Ep_TypeDef *ep, bool forceIdle )
|
||||
{
|
||||
#define DIEP_MPS_EPTYPE_TXFNUM_MASK ( _USB_DIEP_CTL_MPS_MASK | \
|
||||
_USB_DIEP_CTL_EPTYPE_MASK | \
|
||||
_USB_DIEP_CTL_TXFNUM_MASK )
|
||||
#define DOEP_MPS_EPTYPE_MASK ( _USB_DOEP_CTL_MPS_MASK | \
|
||||
_USB_DOEP_CTL_EPTYPE_MASK )
|
||||
uint32_t daintmask, depctl;
|
||||
|
||||
if ( forceIdle )
|
||||
ep->state = D_EP_IDLE;
|
||||
|
||||
if ( ep->in )
|
||||
{
|
||||
daintmask = ep->mask;
|
||||
depctl = USB_DINEPS[ ep->num ].CTL & ~DEPCTL_WO_BITMASK;
|
||||
|
||||
if ( !( depctl & USB_DIEP_CTL_USBACTEP ) )
|
||||
{
|
||||
depctl = ( depctl &
|
||||
~( DIEP_MPS_EPTYPE_TXFNUM_MASK |
|
||||
USB_DIEP_CTL_STALL ) ) |
|
||||
( ep->packetSize << _USB_DIEP_CTL_MPS_SHIFT ) |
|
||||
( ep->type << _USB_DIEP_CTL_EPTYPE_SHIFT ) |
|
||||
( ep->txFifoNum << _USB_DIEP_CTL_TXFNUM_SHIFT ) |
|
||||
USB_DIEP_CTL_SETD0PIDEF |
|
||||
USB_DIEP_CTL_USBACTEP |
|
||||
USB_DIEP_CTL_SNAK;
|
||||
}
|
||||
else
|
||||
{
|
||||
depctl |= USB_DIEP_CTL_SETD0PIDEF;
|
||||
}
|
||||
USB_DINEPS[ ep->num ].CTL = depctl;
|
||||
}
|
||||
else
|
||||
{
|
||||
daintmask = ep->mask << _USB_DAINTMSK_OUTEPMSK0_SHIFT;
|
||||
depctl = USB_DOUTEPS[ ep->num ].CTL & ~DEPCTL_WO_BITMASK;
|
||||
|
||||
if ( !( depctl & USB_DOEP_CTL_USBACTEP ) )
|
||||
{
|
||||
depctl = ( depctl &
|
||||
~( DOEP_MPS_EPTYPE_MASK |
|
||||
USB_DOEP_CTL_STALL ) ) |
|
||||
( ep->packetSize << _USB_DOEP_CTL_MPS_SHIFT ) |
|
||||
( ep->type << _USB_DOEP_CTL_EPTYPE_SHIFT ) |
|
||||
USB_DOEP_CTL_SETD0PIDEF |
|
||||
USB_DOEP_CTL_USBACTEP |
|
||||
USB_DOEP_CTL_SNAK;
|
||||
}
|
||||
else
|
||||
{
|
||||
depctl |= USB_DOEP_CTL_SETD0PIDEF;
|
||||
}
|
||||
USB_DOUTEPS[ ep->num ].CTL = depctl;
|
||||
}
|
||||
|
||||
/* Enable interrupt for this EP */
|
||||
USB->DAINTMSK |= daintmask;
|
||||
|
||||
#undef DIEP_MPS_EPTYPE_TXFNUM_MASK
|
||||
#undef DOEP_MPS_EPTYPE_MASK
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_ClearRemoteWakeup( void )
|
||||
{
|
||||
USB->DCTL &= ~( DCTL_WO_BITMASK | USB_DCTL_RMTWKUPSIG );
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_DeactivateEp( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
uint32_t daintmask;
|
||||
|
||||
if ( ep->in )
|
||||
{
|
||||
USB_DINEPS[ ep->num ].CTL = 0;
|
||||
daintmask = ep->mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_DOUTEPS[ ep->num ].CTL = 0;
|
||||
daintmask = ep->mask << _USB_DAINTMSK_OUTEPMSK0_SHIFT;
|
||||
}
|
||||
|
||||
/* Disable interrupt for this EP */
|
||||
USB->DAINTMSK &= ~daintmask;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_EnableInts( USBD_Device_TypeDef *dev )
|
||||
{
|
||||
uint32_t mask;
|
||||
|
||||
/* Disable all interrupts. */
|
||||
USB->GINTMSK = 0;
|
||||
|
||||
/* Clear pending interrupts */
|
||||
USB->GINTSTS = 0xFFFFFFFF;
|
||||
|
||||
mask = USB_GINTMSK_USBSUSPMSK |
|
||||
USB_GINTMSK_USBRSTMSK |
|
||||
USB_GINTMSK_ENUMDONEMSK |
|
||||
USB_GINTMSK_IEPINTMSK |
|
||||
USB_GINTMSK_OEPINTMSK |
|
||||
USB_GINTMSK_WKUPINTMSK;
|
||||
|
||||
if ( dev->callbacks->sofInt )
|
||||
{
|
||||
mask |= USB_GINTMSK_SOFMSK;
|
||||
}
|
||||
|
||||
USB->GINTMSK = mask;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_EnableUsbResetAndSuspendInt( void )
|
||||
{
|
||||
/* Disable all interrupts. */
|
||||
USB->GINTMSK = 0;
|
||||
|
||||
USB->GINTMSK = USB_GINTMSK_USBRSTMSK | USB_GINTMSK_USBSUSPMSK;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_Ep0Activate( uint32_t ep0mps )
|
||||
{
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGNPINNAK;
|
||||
|
||||
USB->DOEP0CTL = ( USB->DOEP0CTL & ~DEPCTL_WO_BITMASK )
|
||||
| USB_DOEP0CTL_CNAK | USB_DOEP0CTL_EPENA
|
||||
| ep0mps;
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool USBDHAL_EpIsStalled( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
bool retVal = false;
|
||||
uint16_t stallStatus;
|
||||
|
||||
if ( USBDHAL_GetStallStatusEp( ep, &stallStatus ) == USB_STATUS_OK )
|
||||
{
|
||||
retVal = stallStatus & 1 ? true : false;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t USBDHAL_GetAllInEpInts( void )
|
||||
{
|
||||
uint32_t retVal;
|
||||
|
||||
retVal = USB->DAINT;
|
||||
retVal &= USB->DAINTMSK;
|
||||
return retVal & 0xFFFF;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t USBDHAL_GetAllOutEpInts( void )
|
||||
{
|
||||
uint32_t retVal;
|
||||
|
||||
retVal = USB->DAINT;
|
||||
retVal &= USB->DAINTMSK;
|
||||
return retVal >> 16;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t USBDHAL_GetInEpInts( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
uint32_t retVal, msk;
|
||||
|
||||
msk = USB->DIEPMSK;
|
||||
retVal = USB_DINEPS[ ep->num ].INT;
|
||||
|
||||
return retVal & msk;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t USBDHAL_GetOutEpInts( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
uint32_t retVal;
|
||||
|
||||
retVal = USB_DOUTEPS[ ep->num ].INT;
|
||||
#if defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
retVal &= USB->DOEPMSK | USB_DOEP0INT_STUPPKTRCVD;
|
||||
#else
|
||||
retVal &= USB->DOEPMSK;
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
__STATIC_INLINE USB_Status_TypeDef USBDHAL_GetStallStatusEp(
|
||||
USBD_Ep_TypeDef *ep, uint16_t *halt )
|
||||
{
|
||||
uint32_t depctl, eptype;
|
||||
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
|
||||
|
||||
if ( ep->in == true )
|
||||
{
|
||||
depctl = USB_DINEPS[ ep->num ].CTL;
|
||||
eptype = depctl & _USB_DIEP_CTL_EPTYPE_MASK;
|
||||
|
||||
if (( eptype == DIEPCTL_EPTYPE_INTR ) || ( eptype == DIEPCTL_EPTYPE_BULK ))
|
||||
{
|
||||
*halt = depctl & USB_DIEP_CTL_STALL ? 1 : 0;
|
||||
retVal = USB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
depctl = USB_DOUTEPS[ ep->num ].CTL;
|
||||
eptype = depctl & _USB_DOEP_CTL_EPTYPE_MASK;
|
||||
|
||||
if (( eptype == DOEPCTL_EPTYPE_INTR ) || ( eptype == DOEPCTL_EPTYPE_BULK ))
|
||||
{
|
||||
*halt = depctl & USB_DOEP_CTL_STALL ? 1 : 0;
|
||||
retVal = USB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_ReenableEp0Setup( USBD_Device_TypeDef *dev )
|
||||
|
||||
{
|
||||
USB->DOEP0DMAADDR = (uint32_t)dev->setupPkt;
|
||||
USB->DOEP0CTL = ( USB->DOEP0CTL & ~DEPCTL_WO_BITMASK )
|
||||
| USB_DOEP0CTL_EPENA
|
||||
| dev->ep0MpsCode;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_SetAddr( uint8_t addr )
|
||||
{
|
||||
USB->DCFG = ( USB->DCFG &
|
||||
~_USB_DCFG_DEVADDR_MASK ) |
|
||||
(addr << _USB_DCFG_DEVADDR_SHIFT );
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_SetEp0InDmaPtr( uint8_t* addr )
|
||||
{
|
||||
USB->DIEP0DMAADDR = (uint32_t)addr;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_SetEp0OutDmaPtr( uint8_t* addr )
|
||||
{
|
||||
USB->DOEP0DMAADDR = (uint32_t)addr;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_SetEPDISNAK( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
if ( ep->in )
|
||||
{
|
||||
USB_DINEPS[ ep->num ].CTL = ( USB_DINEPS[ ep->num ].CTL &
|
||||
~DEPCTL_WO_BITMASK ) |
|
||||
USB_DIEP_CTL_SNAK |
|
||||
USB_DIEP_CTL_EPDIS;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_DOUTEPS[ ep->num ].CTL = ( USB_DOUTEPS[ ep->num ].CTL &
|
||||
~DEPCTL_WO_BITMASK ) |
|
||||
USB_DOEP_CTL_EPENA;
|
||||
|
||||
USB_DOUTEPS[ ep->num ].CTL = ( USB_DOUTEPS[ ep->num ].CTL &
|
||||
~DEPCTL_WO_BITMASK ) |
|
||||
USB_DOEP_CTL_SNAK |
|
||||
USB_DOEP_CTL_EPDIS;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_SetRemoteWakeup( void )
|
||||
{
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_RMTWKUPSIG;
|
||||
}
|
||||
|
||||
__STATIC_INLINE USB_Status_TypeDef USBDHAL_StallEp( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
uint32_t depctl, eptype;
|
||||
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
|
||||
|
||||
if ( ep->in == true )
|
||||
{
|
||||
depctl = USB_DINEPS[ ep->num ].CTL & ~DEPCTL_WO_BITMASK;
|
||||
eptype = depctl & _USB_DIEP_CTL_EPTYPE_MASK;
|
||||
|
||||
if ( eptype != DIEPCTL_EPTYPE_ISOC )
|
||||
{
|
||||
if ( depctl & USB_DIEP_CTL_EPENA )
|
||||
{
|
||||
depctl |= USB_DIEP_CTL_EPDIS;
|
||||
}
|
||||
USB_DINEPS[ ep->num ].CTL = depctl | USB_DIEP_CTL_STALL;
|
||||
retVal = USB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
depctl = USB_DOUTEPS[ ep->num ].CTL & ~DEPCTL_WO_BITMASK;
|
||||
eptype = depctl & _USB_DOEP_CTL_EPTYPE_MASK;
|
||||
|
||||
if ( eptype != DIEPCTL_EPTYPE_ISOC )
|
||||
{
|
||||
USB_DOUTEPS[ ep->num ].CTL = depctl | USB_DOEP_CTL_STALL;
|
||||
retVal = USB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_StartEp0In( uint32_t len, uint32_t ep0mps )
|
||||
{
|
||||
USB->DIEP0TSIZ = ( len << _USB_DIEP0TSIZ_XFERSIZE_SHIFT ) |
|
||||
( 1 << _USB_DIEP0TSIZ_PKTCNT_SHIFT );
|
||||
|
||||
USB->DIEP0CTL = ( USB->DIEP0CTL & ~DEPCTL_WO_BITMASK )
|
||||
| USB_DIEP0CTL_CNAK | USB_DIEP0CTL_EPENA
|
||||
| ep0mps;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_StartEp0Out( uint32_t len, uint32_t ep0mps )
|
||||
{
|
||||
USB->DOEP0TSIZ = ( len << _USB_DOEP0TSIZ_XFERSIZE_SHIFT ) |
|
||||
( 1 << _USB_DOEP0TSIZ_PKTCNT_SHIFT );
|
||||
|
||||
USB->DOEP0CTL = ( USB->DOEP0CTL & ~DEPCTL_WO_BITMASK )
|
||||
| USB_DOEP0CTL_CNAK | USB_DOEP0CTL_EPENA
|
||||
| ep0mps;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_StartEp0Setup( USBD_Device_TypeDef *dev )
|
||||
{
|
||||
dev->ep[ 0 ].in = false;
|
||||
|
||||
#if defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
USB->DOEP0TSIZ = ( 8*3 << _USB_DOEP0TSIZ_XFERSIZE_SHIFT ) |
|
||||
( 1 << _USB_DOEP0TSIZ_PKTCNT_SHIFT ) |
|
||||
( 3 << _USB_DOEP0TSIZ_SUPCNT_SHIFT );
|
||||
#else
|
||||
USB->DOEP0TSIZ = 3 << _USB_DOEP0TSIZ_SUPCNT_SHIFT;
|
||||
#endif
|
||||
|
||||
dev->setup = dev->setupPkt;
|
||||
USB->DOEP0DMAADDR = (uint32_t)dev->setup;
|
||||
|
||||
#if defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
USB->DOEP0CTL = ( USB->DOEP0CTL & ~DEPCTL_WO_BITMASK )
|
||||
| USB_DOEP0CTL_EPENA
|
||||
| dev->ep0MpsCode;
|
||||
#else
|
||||
USB->DOEP0CTL = ( USB->DOEP0CTL & ~DEPCTL_WO_BITMASK )
|
||||
| USB_DOEP0CTL_CNAK | USB_DOEP0CTL_EPENA
|
||||
| dev->ep0MpsCode;
|
||||
#endif
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_StartEpIn( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
uint32_t pktcnt, xfersize;
|
||||
|
||||
if ( ep->remaining == 0 ) /* ZLP ? */
|
||||
{
|
||||
pktcnt = 1;
|
||||
xfersize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pktcnt = ( ep->remaining - 1 + ep->packetSize ) / ep->packetSize;
|
||||
xfersize = ep->remaining;
|
||||
}
|
||||
|
||||
USB_DINEPS[ ep->num ].TSIZ =
|
||||
( USB_DINEPS[ ep->num ].TSIZ &
|
||||
~DIEP_XFERSIZE_PKTCNT_MASK ) |
|
||||
( xfersize << _USB_DIEP_TSIZ_XFERSIZE_SHIFT ) |
|
||||
( pktcnt << _USB_DIEP_TSIZ_PKTCNT_SHIFT );
|
||||
|
||||
USB_DINEPS[ ep->num ].DMAADDR = (uint32_t)ep->buf;
|
||||
USB_DINEPS[ ep->num ].CTL =
|
||||
( USB_DINEPS[ ep->num ].CTL & ~DEPCTL_WO_BITMASK ) |
|
||||
USB_DIEP_CTL_CNAK |
|
||||
USB_DIEP_CTL_EPENA;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBDHAL_StartEpOut( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
uint32_t pktcnt, xfersize;
|
||||
|
||||
if ( ep->remaining == 0 ) /* ZLP ? */
|
||||
{
|
||||
pktcnt = 1;
|
||||
xfersize = ep->packetSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
pktcnt = ( ep->remaining - 1 + ep->packetSize ) / ep->packetSize;
|
||||
xfersize = pktcnt * ep->packetSize;
|
||||
}
|
||||
|
||||
USB_DOUTEPS[ ep->num ].TSIZ =
|
||||
( USB_DOUTEPS[ ep->num ].TSIZ &
|
||||
~DOEP_XFERSIZE_PKTCNT_MASK ) |
|
||||
( xfersize << _USB_DOEP_TSIZ_XFERSIZE_SHIFT ) |
|
||||
( pktcnt << _USB_DOEP_TSIZ_PKTCNT_SHIFT );
|
||||
|
||||
ep->hwXferSize = xfersize;
|
||||
USB_DOUTEPS[ ep->num ].DMAADDR = (uint32_t)ep->buf;
|
||||
USB_DOUTEPS[ ep->num ].CTL =
|
||||
( USB_DOUTEPS[ ep->num ].CTL &
|
||||
~DEPCTL_WO_BITMASK ) |
|
||||
USB_DOEP_CTL_CNAK |
|
||||
USB_DOEP_CTL_EPENA;
|
||||
}
|
||||
|
||||
__STATIC_INLINE USB_Status_TypeDef USBDHAL_UnStallEp( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
uint32_t depctl, eptype;
|
||||
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
|
||||
|
||||
if ( ep->in == true )
|
||||
{
|
||||
depctl = USB_DINEPS[ ep->num ].CTL & ~DEPCTL_WO_BITMASK;
|
||||
eptype = depctl & _USB_DIEP_CTL_EPTYPE_MASK;
|
||||
|
||||
if (( eptype == DIEPCTL_EPTYPE_INTR ) || ( eptype == DIEPCTL_EPTYPE_BULK ))
|
||||
{
|
||||
depctl |= USB_DIEP_CTL_SETD0PIDEF;
|
||||
depctl &= ~USB_DIEP_CTL_STALL;
|
||||
USB_DINEPS[ ep->num ].CTL = depctl;
|
||||
retVal = USB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
depctl = USB_DOUTEPS[ ep->num ].CTL & ~DEPCTL_WO_BITMASK;
|
||||
eptype = depctl & _USB_DOEP_CTL_EPTYPE_MASK;
|
||||
|
||||
if (( eptype == DIEPCTL_EPTYPE_INTR ) || ( eptype == DIEPCTL_EPTYPE_BULK ))
|
||||
{
|
||||
depctl |= USB_DOEP_CTL_SETD0PIDEF;
|
||||
depctl &= ~USB_DOEP_CTL_STALL;
|
||||
USB_DOUTEPS[ ep->num ].CTL = depctl;
|
||||
retVal = USB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
|
||||
#if defined( USB_HOST )
|
||||
__STATIC_INLINE void USBHHAL_HCActivate( int hcnum, uint32_t hcchar, bool intep )
|
||||
{
|
||||
uint32_t oddframe;
|
||||
|
||||
if ( intep )
|
||||
{
|
||||
oddframe = USB->HFNUM & 1;
|
||||
|
||||
USB->HC[ hcnum ].CHAR =
|
||||
( hcchar &
|
||||
~( USB_HC_CHAR_CHDIS | _USB_HC_CHAR_ODDFRM_MASK ) ) |
|
||||
|
||||
/* Schedule INT transfers to start in next frame. */
|
||||
( oddframe & 1 ? 0 : USB_HC_CHAR_ODDFRM ) |
|
||||
|
||||
USB_HC_CHAR_CHENA;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB->HC[ hcnum ].CHAR = ( hcchar & ~USB_HC_CHAR_CHDIS ) |
|
||||
USB_HC_CHAR_CHENA;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool USBHHAL_InitializedAndPowered( void )
|
||||
{
|
||||
if ( ( USB->ROUTE & USB_ROUTE_PHYPEN ) &&
|
||||
( USB->HPRT & USB_HPRT_PRTPWR ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHHAL_EnableInts( void )
|
||||
{
|
||||
/* Disable all interrupts. */
|
||||
USB->GINTMSK = 0;
|
||||
|
||||
/* Clear pending OTG interrupts */
|
||||
USB->GOTGINT = 0xFFFFFFFF;
|
||||
|
||||
/* Clear pending interrupts */
|
||||
USB->GINTSTS = 0xFFFFFFFF;
|
||||
|
||||
USB->GINTMSK = USB_GINTMSK_PRTINTMSK |
|
||||
USB_GINTMSK_HCHINTMSK |
|
||||
USB_GINTMSK_DISCONNINTMSK;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint16_t USBHHAL_GetFrameNum( void )
|
||||
{
|
||||
return USB->HFNUM;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t USBHHAL_GetHcChar( uint8_t hcnum )
|
||||
{
|
||||
return USB->HC[ hcnum ].CHAR;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t USBHHAL_GetHcInts( uint8_t hcnum )
|
||||
{
|
||||
uint32_t retVal;
|
||||
|
||||
retVal = USB->HC[ hcnum ].INT;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t USBHHAL_GetHostChannelInts( void )
|
||||
{
|
||||
return USB->HAINT;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint8_t USBHHAL_GetPortSpeed( void )
|
||||
{
|
||||
return ( USB->HPRT & _USB_HPRT_PRTSPD_MASK ) >> _USB_HPRT_PRTSPD_SHIFT;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHHAL_PortReset( bool on )
|
||||
{
|
||||
if ( on )
|
||||
{
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '+' );
|
||||
USB->HPRT = ( USB->HPRT & ~HPRT_WC_MASK ) | USB_HPRT_PRTRST;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '-' );
|
||||
USB->HPRT &= ~( HPRT_WC_MASK | USB_HPRT_PRTRST );
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHHAL_PortResume( bool on )
|
||||
{
|
||||
if ( on )
|
||||
{
|
||||
USB->HPRT = ( USB->HPRT & ~( HPRT_WC_MASK | USB_HPRT_PRTSUSP ) ) |
|
||||
USB_HPRT_PRTRES;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB->HPRT &= ~( HPRT_WC_MASK | USB_HPRT_PRTSUSP | USB_HPRT_PRTRES );
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHHAL_PortSuspend( void )
|
||||
{
|
||||
USB->HPRT = ( USB->HPRT & ~HPRT_WC_MASK ) | USB_HPRT_PRTSUSP;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void USBHHAL_VbusOn( bool on )
|
||||
{
|
||||
if ( on )
|
||||
{
|
||||
USB->HPRT = ( USB->HPRT & ~HPRT_WC_MASK ) | USB_HPRT_PRTPWR;
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '/' );
|
||||
}
|
||||
else
|
||||
{
|
||||
USB->HPRT &= ~( HPRT_WC_MASK | USB_HPRT_PRTPWR );
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '\\' );
|
||||
}
|
||||
}
|
||||
#endif /* defined( USB_HOST ) */
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined( USB_DEVICE ) || defined( USB_HOST ) */
|
||||
#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
|
||||
#endif /* __EM_USBHAL_H */
|
|
@ -0,0 +1,230 @@
|
|||
/***************************************************************************//**
|
||||
* @file em_usbtypes.h
|
||||
* @brief USB protocol stack library, internal type definitions.
|
||||
* @version 3.20.14
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* 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 __EM_USBTYPES_H
|
||||
#define __EM_USBTYPES_H
|
||||
|
||||
#include "em_device.h"
|
||||
#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
|
||||
#include "em_usb.h"
|
||||
#if defined( USB_DEVICE ) || defined( USB_HOST )
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/* Limits imposed by the USB peripheral */
|
||||
#define NP_RX_QUE_DEPTH 8
|
||||
#define HP_RX_QUE_DEPTH 8
|
||||
#define MAX_XFER_LEN 524287L /* 2^19 - 1 bytes */
|
||||
#define MAX_PACKETS_PR_XFER 1023 /* 2^10 - 1 packets */
|
||||
#if defined( _USB_DIEPTXF6_MASK )
|
||||
#define MAX_NUM_TX_FIFOS 6 /* In addition to EP0 Tx FIFO */
|
||||
#define MAX_NUM_IN_EPS 6 /* In addition to EP0 */
|
||||
#define MAX_NUM_OUT_EPS 6 /* In addition to EP0 */
|
||||
#define MAX_DEVICE_FIFO_SIZE_INWORDS 512U
|
||||
#else
|
||||
#define MAX_NUM_TX_FIFOS 3 /* In addition to EP0 Tx FIFO */
|
||||
#define MAX_NUM_IN_EPS 3 /* In addition to EP0 */
|
||||
#define MAX_NUM_OUT_EPS 3 /* In addition to EP0 */
|
||||
#define MAX_DEVICE_FIFO_SIZE_INWORDS 384U
|
||||
#endif
|
||||
#define MIN_EP_FIFO_SIZE_INWORDS 16U /* Unit is words (32bit) */
|
||||
#define MIN_EP_FIFO_SIZE_INBYTES 64U /* Unit is bytes (8bit) */
|
||||
|
||||
/* For MCU's without USB host capability. */
|
||||
#if !defined( USB_ROUTE_VBUSENPEN )
|
||||
#define USB_VBUS_SWITCH_NOT_PRESENT
|
||||
#endif
|
||||
|
||||
/* Limit imposed by the USB standard */
|
||||
#define MAX_USB_EP_NUM 15
|
||||
|
||||
#if defined( USB_DEVICE )
|
||||
/* Check power saving modes. */
|
||||
#ifndef USB_PWRSAVE_MODE
|
||||
/* Default powersave-mode is OFF. */
|
||||
#define USB_PWRSAVE_MODE USB_PWRSAVE_MODE_OFF
|
||||
#else
|
||||
#if ( USB_PWRSAVE_MODE & \
|
||||
~( USB_PWRSAVE_MODE_ONSUSPEND | USB_PWRSAVE_MODE_ONVBUSOFF | \
|
||||
USB_PWRSAVE_MODE_ENTEREM2 ) )
|
||||
#error "Illegal USB powersave mode."
|
||||
#endif
|
||||
#endif /* ifndef USB_PWRSAVE_MODE */
|
||||
|
||||
/* Check power saving low frequency clock selection. */
|
||||
#ifndef USB_USBC_32kHz_CLK
|
||||
/* Default clock source is LFXO. */
|
||||
#define USB_USBC_32kHz_CLK USB_USBC_32kHz_CLK_LFXO
|
||||
#else
|
||||
#if ( ( USB_USBC_32kHz_CLK != USB_USBC_32kHz_CLK_LFXO ) && \
|
||||
( USB_USBC_32kHz_CLK != USB_USBC_32kHz_CLK_LFRCO ) )
|
||||
#error "Illegal USB 32kHz powersave clock selection."
|
||||
#endif
|
||||
#endif /* ifndef USB_USBC_32kHz_CLK */
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
|
||||
#if defined( USB_HOST )
|
||||
/* Check VBUS overcurrent definitions. */
|
||||
#ifndef USB_VBUSOVRCUR_PORT
|
||||
#define USB_VBUSOVRCUR_PORT gpioPortE
|
||||
#define USB_VBUSOVRCUR_PIN 2
|
||||
#define USB_VBUSOVRCUR_POLARITY USB_VBUSOVRCUR_POLARITY_LOW
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Developer mode debugging macro's */
|
||||
#if defined( DEBUG_USB_INT_LO )
|
||||
#define DEBUG_USB_INT_LO_PUTS( s ) USB_PUTS( s )
|
||||
#define DEBUG_USB_INT_LO_PUTCHAR( c ) USB_PUTCHAR( c )
|
||||
#else
|
||||
#define DEBUG_USB_INT_LO_PUTS( s )
|
||||
#define DEBUG_USB_INT_LO_PUTCHAR( c )
|
||||
#endif /* defined( DEBUG_USB_INT_LO ) */
|
||||
|
||||
#if defined( DEBUG_USB_INT_HI )
|
||||
#define DEBUG_USB_INT_HI_PUTS( s ) USB_PUTS( s )
|
||||
#define DEBUG_USB_INT_HI_PUTCHAR( c ) USB_PUTCHAR( c )
|
||||
#else
|
||||
#define DEBUG_USB_INT_HI_PUTS( s )
|
||||
#define DEBUG_USB_INT_HI_PUTCHAR( c )
|
||||
#endif /* defined( DEBUG_USB_INT_HI ) */
|
||||
|
||||
#if defined( USB_HOST )
|
||||
#if defined( NUM_APP_TIMERS )
|
||||
#define HOSTPORT_TIMER_INDEX (NUM_APP_TIMERS)
|
||||
#else
|
||||
#define HOSTPORT_TIMER_INDEX (0)
|
||||
#endif
|
||||
#define HOSTCH_TIMER_INDEX (HOSTPORT_TIMER_INDEX + 1 )
|
||||
#endif
|
||||
|
||||
/* Macros for selecting a hardware timer. */
|
||||
#define USB_TIMER0 0
|
||||
#define USB_TIMER1 1
|
||||
#define USB_TIMER2 2
|
||||
#define USB_TIMER3 3
|
||||
|
||||
#if defined( USB_HOST )
|
||||
#define HCS_NAK 0x01
|
||||
#define HCS_STALL 0x02
|
||||
#define HCS_XACT 0x04
|
||||
#define HCS_TGLERR 0x08
|
||||
#define HCS_BABBLE 0x10
|
||||
#define HCS_TIMEOUT 0x20
|
||||
#define HCS_COMPLETED 0x40
|
||||
#define HCS_RETRY 0x80
|
||||
#endif
|
||||
|
||||
#if defined( USB_DEVICE )
|
||||
typedef enum
|
||||
{
|
||||
D_EP_IDLE = 0,
|
||||
D_EP_TRANSMITTING = 1,
|
||||
D_EP_RECEIVING = 2,
|
||||
D_EP0_IN_STATUS = 3,
|
||||
D_EP0_OUT_STATUS = 4
|
||||
} USBD_EpState_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool in;
|
||||
uint8_t zlp;
|
||||
uint8_t num;
|
||||
uint8_t addr;
|
||||
uint8_t type;
|
||||
uint8_t txFifoNum;
|
||||
uint8_t *buf;
|
||||
uint16_t packetSize;
|
||||
uint16_t mask;
|
||||
uint32_t remaining;
|
||||
uint32_t xferred;
|
||||
uint32_t hwXferSize;
|
||||
uint32_t fifoSize;
|
||||
USBD_EpState_TypeDef state;
|
||||
USB_XferCompleteCb_TypeDef xferCompleteCb;
|
||||
} USBD_Ep_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
USB_Setup_TypeDef *setup;
|
||||
USB_Setup_TypeDef setupPkt[3];
|
||||
uint8_t configurationValue; /* Must be DWORD aligned */
|
||||
bool remoteWakeupEnabled;
|
||||
uint8_t numberOfStrings;
|
||||
uint8_t numberOfInterfaces;
|
||||
USBD_State_TypeDef state;
|
||||
USBD_State_TypeDef savedState;
|
||||
USBD_State_TypeDef lastState;
|
||||
const USB_DeviceDescriptor_TypeDef *deviceDescriptor;
|
||||
const USB_ConfigurationDescriptor_TypeDef *configDescriptor;
|
||||
const void * const *stringDescriptors;
|
||||
const USBD_Callbacks_TypeDef *callbacks;
|
||||
USBD_Ep_TypeDef ep[ NUM_EP_USED + 1 ];
|
||||
uint8_t inEpAddr2EpIndex[ MAX_USB_EP_NUM + 1 ];
|
||||
uint8_t outEpAddr2EpIndex[ MAX_USB_EP_NUM + 1 ];
|
||||
uint32_t ep0MpsCode;
|
||||
} USBD_Device_TypeDef;
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
|
||||
#if defined( USB_HOST )
|
||||
typedef enum
|
||||
{
|
||||
H_PORT_DISCONNECTED = 0,
|
||||
H_PORT_CONNECTED_DEBOUNCING = 1,
|
||||
H_PORT_CONNECTED_RESETTING = 2,
|
||||
H_PORT_CONNECTED = 3,
|
||||
H_PORT_OVERCURRENT = 4
|
||||
} USBH_PortState_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int debounceTime;
|
||||
int resetTime;
|
||||
} USBH_AttachTiming_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *buf;
|
||||
int errorCnt;
|
||||
uint32_t remaining;
|
||||
uint32_t xferred;
|
||||
uint32_t hwXferSize;
|
||||
uint8_t status;
|
||||
bool idle;
|
||||
USBH_Ep_TypeDef *ep;
|
||||
} USBH_Hc_TypeDef;
|
||||
#endif /* defined( USB_HOST ) */
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined( USB_DEVICE ) || defined( USB_HOST ) */
|
||||
#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
|
||||
#endif /* __EM_USBTYPES_H */
|
|
@ -0,0 +1,88 @@
|
|||
/***************************************************************************//**
|
||||
* @file usbconfig.h
|
||||
* @brief USB protocol stack library, application supplied configuration options.
|
||||
* @version 3.20.12
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* 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 __USBCONFIG_H
|
||||
#define __USBCONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Compile stack for device mode. */
|
||||
#define USB_DEVICE
|
||||
|
||||
/* Maximum number of endpoint used, EP0 excluded. If you change this, you must
|
||||
also change USBEndpoints_EFM32.h to match. */
|
||||
#define NUM_EP_USED 6
|
||||
|
||||
/* Power management modes. The following can be or'd toghether. See comments in
|
||||
em_usbd.c under "Energy-saving modes" for more details.
|
||||
|
||||
USB_PWRSAVE_MODE_ONSUSPEND Set USB peripheral in low power mode on suspend
|
||||
|
||||
USB_PWRSAVE_MODE_ONVBUSOFF Set USB peripheral in low power mode when not
|
||||
attached to a host. While this mode assumes that the internal voltage regulator
|
||||
is used and that the VREGI pin of the chip is connected to VBUS it should
|
||||
be safe to use given that VREGOSEN is always enabled. If you disable VREGOSEN
|
||||
you must turn this off.
|
||||
|
||||
USB_PWRSAVE_MODE_ENTEREM2 Enter EM2 when USB peripheral is in low power mode.
|
||||
On Mbed this allows the sleep() and deepsleep() calls to enter EM2, but
|
||||
does not automatically enter any sleep states. Entering EM1 is always allowed.
|
||||
|
||||
Note for Happy Gecko, errata USB_E111: Entering EM2 when both the system clock
|
||||
(HFCLK) and the USB core clock (USBCCLK) is running on USHFRCO will result in
|
||||
a lock-up.
|
||||
*/
|
||||
#define USB_PWRSAVE_MODE (USB_PWRSAVE_MODE_ONSUSPEND|USB_PWRSAVE_MODE_ONVBUSOFF|USB_PWRSAVE_MODE_ENTEREM2)
|
||||
|
||||
/* Use dynamic memory to allocate rx/tx buffers in the HAL. Saves memory
|
||||
as buffers are only allocated for used endpoints. The system malloc
|
||||
must return memory that is aligned by 4.
|
||||
|
||||
Note: if you disable this, using isochronous endpoints with packet
|
||||
sizes that are larger than the maximum for other EP types (64) will
|
||||
not work. */
|
||||
#define USB_USE_DYNAMIC_MEMORY
|
||||
|
||||
/* When the USB peripheral is set in low power mode, it must be clocked by a 32kHz
|
||||
clock. Both LFXO and LFRCO can be used, but only LFXO guarantee USB specification
|
||||
compliance. */
|
||||
#define USB_USBC_32kHz_CLK USB_USBC_32kHz_CLK_LFXO
|
||||
|
||||
/* Uncomment to get some debugging information. Default value for USER_PUTCHAR
|
||||
should work for SiLabs Gecko boards. Printf requires a working retarget
|
||||
implementation for write(). */
|
||||
//#define DEBUG_USB_API
|
||||
//#define USB_USE_PRINTF
|
||||
//#define USER_PUTCHAR ITM_SendChar
|
||||
//#define DEBUG_USB_INT_HI
|
||||
//#define DEBUG_USB_INT_LO
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBCONFIG_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,446 @@
|
|||
/**************************************************************************//**
|
||||
* @file em_usbdep.c
|
||||
* @brief USB protocol stack library, USB device endpoint handlers.
|
||||
* @version 3.20.14
|
||||
******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* 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 "em_device.h"
|
||||
#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
|
||||
#include "em_usb.h"
|
||||
#if defined( USB_DEVICE )
|
||||
|
||||
#include "em_usbtypes.h"
|
||||
#include "em_usbhal.h"
|
||||
#include "em_usbd.h"
|
||||
|
||||
#ifdef USB_USE_PRINTF
|
||||
static const char *epStatusStr[] = {
|
||||
"IDLE","TRANS","RECV","IN_S","OUT_S"
|
||||
};
|
||||
#endif
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/*
|
||||
* USBDEP_Ep0Handler() is called each time a packet has been transmitted
|
||||
* or recieved on the default endpoint.
|
||||
* A state machine navigate us through the phases of a control transfer
|
||||
* according to "chapter 9" in the USB spec.
|
||||
*/
|
||||
#if !defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
void USBDEP_Ep0Handler( USBD_Device_TypeDef *device )
|
||||
{
|
||||
int status;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
static bool statusIn;
|
||||
static uint32_t xferred;
|
||||
static USB_XferCompleteCb_TypeDef callback;
|
||||
|
||||
ep = &device->ep[ 0 ];
|
||||
|
||||
#ifdef __MBED__
|
||||
|
||||
(void)xferred;
|
||||
(void)statusIn;
|
||||
(void)status;
|
||||
|
||||
USB_PRINTF("USBDEP: ep0 %s, rem %ld, z %d\n", epStatusStr[ep->state], ep->remaining, ep->zlp);
|
||||
|
||||
if ( ( ep->state == D_EP_TRANSMITTING ) || ( ep->state == D_EP_RECEIVING ) )
|
||||
{
|
||||
ep->state = D_EP_IDLE;
|
||||
|
||||
if ( ep->xferCompleteCb )
|
||||
{
|
||||
callback = ep->xferCompleteCb;
|
||||
ep->xferCompleteCb = NULL;
|
||||
callback( USB_STATUS_OK, ep->xferred, ep->remaining );
|
||||
}
|
||||
|
||||
USBDHAL_ReenableEp0Setup(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
device->callbacks->setupCmd(device->setup);
|
||||
}
|
||||
|
||||
#else /* not __MBED__ */
|
||||
|
||||
switch ( ep->state )
|
||||
{
|
||||
case D_EP_IDLE:
|
||||
ep->remaining = 0;
|
||||
ep->zlp = 0;
|
||||
callback = NULL;
|
||||
statusIn = false;
|
||||
|
||||
status = USBDCH9_SetupCmd( device );
|
||||
|
||||
if ( status == USB_STATUS_REQ_ERR )
|
||||
{
|
||||
ep->in = true;
|
||||
USBDHAL_StallEp( ep ); /* Stall Ep0 IN */
|
||||
ep->in = false; /* OUT for next SETUP */
|
||||
USBDHAL_StallEp( ep ); /* Stall Ep0 OUT */
|
||||
USBDHAL_ReenableEp0Setup( device ); /* Prepare for next SETUP packet*/
|
||||
}
|
||||
else /* ( Status == USB_STATUS_OK ) */
|
||||
{
|
||||
if ( (ep->state == D_EP_RECEIVING) || (ep->state == D_EP_TRANSMITTING) )
|
||||
{
|
||||
callback = ep->xferCompleteCb;
|
||||
}
|
||||
|
||||
if ( ep->state != D_EP_RECEIVING )
|
||||
{
|
||||
if ( ep->remaining )
|
||||
{
|
||||
/* Data will be sent to host, check if a ZLP must be appended */
|
||||
if ( ( ep->remaining < device->setup->wLength ) &&
|
||||
( ep->remaining % ep->packetSize == 0 ) )
|
||||
{
|
||||
ep->zlp = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prepare for next SETUP packet*/
|
||||
USBDHAL_ReenableEp0Setup( device );
|
||||
|
||||
/* No data stage, a ZLP may have been sent. If not, send one */
|
||||
|
||||
xferred = 0;
|
||||
if ( ep->zlp == 0 )
|
||||
{
|
||||
USBD_Write( 0, NULL, 0, NULL ); /* ACK to host */
|
||||
ep->state = D_EP0_IN_STATUS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->state = D_EP_IDLE;
|
||||
ep->in = false; /* OUT for next SETUP */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case D_EP_RECEIVING:
|
||||
if ( ep->remaining )
|
||||
{
|
||||
/* There is more data to receive */
|
||||
USBD_ReArmEp0( ep );
|
||||
}
|
||||
else
|
||||
{
|
||||
status = USB_STATUS_OK;
|
||||
if ( callback != NULL )
|
||||
{
|
||||
status = callback( USB_STATUS_OK, ep->xferred, 0 );
|
||||
callback = NULL;
|
||||
}
|
||||
|
||||
if ( status != USB_STATUS_OK )
|
||||
{
|
||||
ep->in = true;
|
||||
USBDHAL_StallEp( ep ); /* Stall Ep0 IN */
|
||||
ep->in = false; /* OUT for next SETUP */
|
||||
USBDHAL_StallEp( ep ); /* Stall Ep0 OUT */
|
||||
USBDHAL_ReenableEp0Setup( device ); /* Prepare for next SETUP pkt. */
|
||||
ep->state = D_EP_IDLE;
|
||||
}
|
||||
else /* Everything OK, send a ZLP (ACK) to host */
|
||||
{
|
||||
USBDHAL_ReenableEp0Setup( device );/* Prepare for next SETUP packet*/
|
||||
|
||||
ep->state = D_EP_IDLE; /* USBD_Write() sets state back*/
|
||||
/* to EP_TRANSMITTING */
|
||||
USBD_Write( 0, NULL, 0, NULL );
|
||||
ep->state = D_EP0_IN_STATUS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case D_EP_TRANSMITTING:
|
||||
if ( ep->remaining )
|
||||
{
|
||||
/* There is more data to transmit */
|
||||
USBD_ReArmEp0( ep );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* All data transferred, is a ZLP packet needed ? */
|
||||
if ( ep->zlp == 1 )
|
||||
{
|
||||
xferred = ep->xferred;
|
||||
ep->state = D_EP_IDLE; /* USBD_Write() sets state back */
|
||||
/* to EP_TRANSMITTING */
|
||||
USBD_Write( 0, NULL, 0, NULL ); /* Send ZLP */
|
||||
ep->zlp = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ep->zlp == 0 )
|
||||
{
|
||||
xferred = ep->xferred;
|
||||
}
|
||||
|
||||
ep->state = D_EP_IDLE;
|
||||
USBD_Read( 0, NULL, 0, NULL ); /* Get ZLP packet (ACK) from host */
|
||||
statusIn = true;
|
||||
ep->state = D_EP0_OUT_STATUS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case D_EP0_IN_STATUS:
|
||||
case D_EP0_OUT_STATUS:
|
||||
if ( statusIn )
|
||||
{
|
||||
USBDHAL_ReenableEp0Setup( device );
|
||||
}
|
||||
|
||||
if ( callback != NULL )
|
||||
{
|
||||
callback( USB_STATUS_OK, xferred, 0 );
|
||||
}
|
||||
|
||||
ep->state = D_EP_IDLE;
|
||||
ep->in = false; /* OUT for next SETUP */
|
||||
break;
|
||||
|
||||
default:
|
||||
EFM_ASSERT( false );
|
||||
break;
|
||||
}
|
||||
#endif /* __MBED__ */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
void USBDEP_Ep0Handler( USBD_Device_TypeDef *device )
|
||||
{
|
||||
int status;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
static uint32_t xferred;
|
||||
static USB_XferCompleteCb_TypeDef callback;
|
||||
|
||||
#ifdef __MBED__
|
||||
|
||||
(void)xferred;
|
||||
(void)status;
|
||||
|
||||
ep = &device->ep[ 0 ];
|
||||
|
||||
if ( ( ep->state == D_EP_TRANSMITTING ) || ( ep->state == D_EP_RECEIVING ) )
|
||||
{
|
||||
ep->state = D_EP_IDLE;
|
||||
|
||||
if ( ep->xferCompleteCb )
|
||||
{
|
||||
callback = ep->xferCompleteCb;
|
||||
ep->xferCompleteCb = NULL;
|
||||
callback( USB_STATUS_OK, ep->xferred, ep->remaining );
|
||||
}
|
||||
|
||||
USBDHAL_StartEp0Setup( dev );
|
||||
}
|
||||
else
|
||||
{
|
||||
device->callbacks->setupCmd(device->setup);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ep = &device->ep[ 0 ];
|
||||
|
||||
switch ( ep->state )
|
||||
{
|
||||
case D_EP_IDLE:
|
||||
ep->zlp = 0;
|
||||
ep->remaining = 0;
|
||||
callback = NULL;
|
||||
|
||||
status = USBDCH9_SetupCmd( device );
|
||||
|
||||
if ( status == USB_STATUS_REQ_ERR )
|
||||
{
|
||||
ep->in = true;
|
||||
USBDHAL_StallEp( ep ); /* Stall Ep0 IN */
|
||||
ep->in = false; /* OUT for next SETUP */
|
||||
USBDHAL_StallEp( ep ); /* Stall Ep0 OUT */
|
||||
USBDHAL_StartEp0Setup( dev ); /* Prepare for next SETUP packet*/
|
||||
}
|
||||
else /* ( Status == USB_STATUS_OK ) */
|
||||
{
|
||||
if ( (ep->state == D_EP_RECEIVING) || (ep->state == D_EP_TRANSMITTING) )
|
||||
{
|
||||
callback = ep->xferCompleteCb;
|
||||
}
|
||||
|
||||
if ( ep->state != D_EP_RECEIVING )
|
||||
{
|
||||
if ( ep->remaining )
|
||||
{
|
||||
/* Data will be sent to host, check if a ZLP must be appended */
|
||||
if ( ( ep->remaining < device->setup->wLength ) &&
|
||||
( ep->remaining % ep->packetSize == 0 ) )
|
||||
{
|
||||
ep->zlp = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No data stage, a ZLP may have been sent. If not, send one */
|
||||
xferred = 0;
|
||||
if ( ep->zlp == 0 )
|
||||
{
|
||||
ep->state = D_EP_IDLE;
|
||||
USBD_Write( 0, NULL, 0, NULL ); /* ACK to host */
|
||||
ep->state = D_EP0_IN_STATUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case D_EP_RECEIVING:
|
||||
if ( ep->remaining )
|
||||
{
|
||||
ep->in = false;
|
||||
USBD_ReArmEp0( ep );
|
||||
}
|
||||
else
|
||||
{
|
||||
status = USB_STATUS_OK;
|
||||
if ( callback != NULL )
|
||||
{
|
||||
status = callback( USB_STATUS_OK, ep->xferred, 0 );
|
||||
callback = NULL;
|
||||
}
|
||||
|
||||
if ( status != USB_STATUS_OK )
|
||||
{
|
||||
ep->in = true;
|
||||
USBDHAL_StallEp( ep ); /* Stall Ep0 IN */
|
||||
ep->in = false; /* OUT for next SETUP */
|
||||
USBDHAL_StallEp( ep ); /* Stall Ep0 OUT */
|
||||
USBDHAL_StartEp0Setup( dev ); /* Prepare for next SETUP pkt. */
|
||||
ep->state = D_EP_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
USBDHAL_StartEp0Setup( dev ); /* Prepare for next SETUP packet*/
|
||||
ep->state = D_EP_IDLE; /* USBD_Write() sets state back */
|
||||
/* to EP_TRANSMITTING */
|
||||
USBD_Write( 0, NULL, 0, NULL );
|
||||
ep->state = D_EP0_IN_STATUS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case D_EP_TRANSMITTING:
|
||||
if ( ep->remaining )
|
||||
{
|
||||
ep->in = true;
|
||||
USBD_ReArmEp0( ep );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ep->zlp == 1 )
|
||||
{
|
||||
xferred = ep->xferred;
|
||||
ep->state = D_EP_IDLE; /* USBD_Write() sets state back */
|
||||
/* to EP_TRANSMITTING */
|
||||
USBD_Write( 0, NULL, 0, NULL ); /* Send ZLP */
|
||||
ep->zlp = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ep->zlp == 0 )
|
||||
{
|
||||
xferred = ep->xferred;
|
||||
}
|
||||
|
||||
ep->state = D_EP_IDLE;
|
||||
USBD_Read( 0, NULL, 0, NULL ); /* Get ZLP packet (ACK) from host */
|
||||
ep->state = D_EP0_OUT_STATUS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case D_EP0_IN_STATUS:
|
||||
if ( ( USB->DOEP0CTL & USB_DOEP0CTL_EPENA ) == 0 )
|
||||
{
|
||||
/* Prepare for more SETUP Packets */
|
||||
USBDHAL_StartEp0Setup( dev );
|
||||
}
|
||||
if ( callback != NULL )
|
||||
{
|
||||
callback( USB_STATUS_OK, xferred, 0 );
|
||||
}
|
||||
ep->state = D_EP_IDLE;
|
||||
ep->in = false; /* OUT for next SETUP */
|
||||
break;
|
||||
|
||||
case D_EP0_OUT_STATUS:
|
||||
USBDHAL_StartEp0Setup( dev ); /* Prepare for more SETUP Packets */
|
||||
if ( callback != NULL )
|
||||
{
|
||||
callback( USB_STATUS_OK, xferred, 0 );
|
||||
}
|
||||
ep->state = D_EP_IDLE;
|
||||
ep->in = false; /* OUT for next SETUP */
|
||||
break;
|
||||
}
|
||||
#endif /* __MBED__ */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* USBDEP_EpHandler() is called each time a packet has been transmitted
|
||||
* or recieved on an endpoint other than the default endpoint.
|
||||
*/
|
||||
void USBDEP_EpHandler( uint8_t epAddr )
|
||||
{
|
||||
USB_XferCompleteCb_TypeDef callback;
|
||||
USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
|
||||
|
||||
if ( ( ep->state == D_EP_TRANSMITTING ) || ( ep->state == D_EP_RECEIVING ) )
|
||||
{
|
||||
ep->state = D_EP_IDLE;
|
||||
if ( ep->xferCompleteCb )
|
||||
{
|
||||
callback = ep->xferCompleteCb;
|
||||
ep->xferCompleteCb = NULL;
|
||||
callback( USB_STATUS_OK, ep->xferred, ep->remaining );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EFM_ASSERT( false );
|
||||
}
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
|
|
@ -0,0 +1,946 @@
|
|||
/**************************************************************************//**
|
||||
* @file em_usbdint.c
|
||||
* @brief USB protocol stack library, USB device peripheral interrupt handlers.
|
||||
* @version 3.20.14
|
||||
******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* 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 "em_device.h"
|
||||
#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
|
||||
#include "em_usb.h"
|
||||
#if defined( USB_DEVICE )
|
||||
|
||||
#include "em_cmu.h"
|
||||
#include "em_usbtypes.h"
|
||||
#include "em_usbhal.h"
|
||||
#include "em_usbd.h"
|
||||
|
||||
#ifdef __MBED__
|
||||
extern void usbhal_allow_em2(bool em2_allow);
|
||||
#endif
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#define HANDLE_INT( x ) if ( status & x ) { Handle_##x(); status &= ~x; }
|
||||
|
||||
static void Handle_USB_GINTSTS_ENUMDONE ( void );
|
||||
static void Handle_USB_GINTSTS_IEPINT ( void );
|
||||
static void Handle_USB_GINTSTS_OEPINT ( void );
|
||||
static void Handle_USB_GINTSTS_RESETDET ( void );
|
||||
static void Handle_USB_GINTSTS_SOF ( void );
|
||||
static void Handle_USB_GINTSTS_USBRST ( void );
|
||||
static void Handle_USB_GINTSTS_USBSUSP ( void );
|
||||
static void Handle_USB_GINTSTS_WKUPINT ( void );
|
||||
#if defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
static void HandleOutEpIntr( uint32_t status, USBD_Ep_TypeDef *ep );
|
||||
#else
|
||||
static void ProcessSetup ( void );
|
||||
static void ProcessOepData ( USBD_Ep_TypeDef *ep );
|
||||
#endif
|
||||
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
/* Variables and prototypes for USB powerdown (suspend) functionality. */
|
||||
static bool UsbPowerDown( void );
|
||||
static bool UsbPowerUp( void );
|
||||
|
||||
volatile bool USBD_poweredDown = false;
|
||||
|
||||
/* Storage for backing up USB core registers. */
|
||||
static uint32_t x_USB_GINTMSK;
|
||||
#if defined(_USB_GOTGCTL_MASK)
|
||||
static uint32_t x_USB_GOTGCTL;
|
||||
#endif
|
||||
static uint32_t x_USB_GAHBCFG;
|
||||
static uint32_t x_USB_GUSBCFG;
|
||||
static uint32_t x_USB_GRXFSIZ;
|
||||
static uint32_t x_USB_GNPTXFSIZ;
|
||||
static uint32_t x_USB_DCFG;
|
||||
static uint32_t x_USB_DCTL;
|
||||
static uint32_t x_USB_DAINTMSK;
|
||||
static uint32_t x_USB_DIEPMSK;
|
||||
static uint32_t x_USB_DOEPMSK;
|
||||
static uint32_t x_USB_PCGCCTL;
|
||||
|
||||
#if ( NUM_EP_USED > 0 )
|
||||
static uint32_t x_USB_EP_CTL[ NUM_EP_USED ];
|
||||
static uint32_t x_USB_EP_TSIZ[ NUM_EP_USED ];
|
||||
static uint32_t x_USB_EP_DMAADDR[ NUM_EP_USED ];
|
||||
#endif
|
||||
|
||||
#if ( NUM_EP_USED > MAX_NUM_TX_FIFOS )
|
||||
#define FIFO_CNT MAX_NUM_TX_FIFOS
|
||||
#else
|
||||
#define FIFO_CNT NUM_EP_USED
|
||||
#endif
|
||||
|
||||
#if ( FIFO_CNT > 0 )
|
||||
static uint32_t x_USB_DIEPTXFS[ FIFO_CNT ];
|
||||
#endif
|
||||
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
static uint32_t cmuStatus = 0;
|
||||
#endif
|
||||
|
||||
#endif /* if ( USB_PWRSAVE_MODE ) */
|
||||
|
||||
/*
|
||||
* USB_IRQHandler() is the first level handler for the USB peripheral interrupt.
|
||||
*/
|
||||
void USB_IRQHandler( void )
|
||||
{
|
||||
uint32_t status;
|
||||
bool servedVbusInterrupt = false;
|
||||
|
||||
INT_Disable();
|
||||
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
if ( USBD_poweredDown )
|
||||
{
|
||||
/* Switch USBC clock from 32kHz to a 48MHz clock to be able to */
|
||||
/* read USB peripheral registers. */
|
||||
/* If we woke up from EM2, HFCLK is now HFRCO. */
|
||||
|
||||
/* Restore clock oscillators.*/
|
||||
#if defined( CMU_OSCENCMD_USHFRCOEN )
|
||||
if ( ( CMU->STATUS & CMU_STATUS_USHFRCOENS ) == 0 )/*Wakeup from EM2 ?*/
|
||||
{
|
||||
CMU->OSCENCMD = ( cmuStatus
|
||||
& ( CMU_STATUS_AUXHFRCOENS | CMU_STATUS_HFXOENS ) )
|
||||
| CMU_OSCENCMD_USHFRCOEN;
|
||||
}
|
||||
#else
|
||||
if ( ( CMU->STATUS & CMU_STATUS_HFXOENS ) == 0 ) /* Wakeup from EM2 ? */
|
||||
{
|
||||
CMU->OSCENCMD = cmuStatus
|
||||
& ( CMU_STATUS_AUXHFRCOENS | CMU_STATUS_HFXOENS );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Select correct USBC clock.*/
|
||||
#if defined( CMU_OSCENCMD_USHFRCOEN )
|
||||
CMU->CMD = CMU_CMD_USBCCLKSEL_USHFRCO;
|
||||
while ( ( CMU->STATUS & CMU_STATUS_USBCUSHFRCOSEL ) == 0 ){}
|
||||
#else
|
||||
CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;
|
||||
while ( ( CMU->STATUS & CMU_STATUS_USBCHFCLKSEL ) == 0 ){}
|
||||
#endif
|
||||
}
|
||||
#endif /* if ( USB_PWRSAVE_MODE ) */
|
||||
|
||||
if ( USB->IF && ( USB->CTRL & USB_CTRL_VREGOSEN ) )
|
||||
{
|
||||
if ( USB->IF & USB_IF_VREGOSH )
|
||||
{
|
||||
USB->IFC = USB_IFC_VREGOSH;
|
||||
|
||||
if ( USB->STATUS & USB_STATUS_VREGOS )
|
||||
{
|
||||
servedVbusInterrupt = true;
|
||||
DEBUG_USB_INT_LO_PUTS( "\nVboN" );
|
||||
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
if ( UsbPowerUp() )
|
||||
{
|
||||
USBDHAL_EnableUsbResetAndSuspendInt();
|
||||
}
|
||||
USBD_SetUsbState( USBD_STATE_POWERED );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ( USB->IF & USB_IF_VREGOSL )
|
||||
{
|
||||
USB->IFC = USB_IFC_VREGOSL;
|
||||
|
||||
if ( ( USB->STATUS & USB_STATUS_VREGOS ) == 0 )
|
||||
{
|
||||
servedVbusInterrupt = true;
|
||||
DEBUG_USB_INT_LO_PUTS( "\nVboF" );
|
||||
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
#if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
|
||||
if ( !USBD_poweredDown )
|
||||
{
|
||||
USB->GINTMSK = 0;
|
||||
USB->GINTSTS = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
UsbPowerDown();
|
||||
#endif
|
||||
USBD_SetUsbState( USBD_STATE_NONE );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status = USBHAL_GetCoreInts();
|
||||
if ( status == 0 )
|
||||
{
|
||||
INT_Enable();
|
||||
if ( !servedVbusInterrupt )
|
||||
{
|
||||
DEBUG_USB_INT_LO_PUTS( "\nSinT" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
HANDLE_INT( USB_GINTSTS_RESETDET )
|
||||
HANDLE_INT( USB_GINTSTS_WKUPINT )
|
||||
HANDLE_INT( USB_GINTSTS_USBSUSP )
|
||||
HANDLE_INT( USB_GINTSTS_SOF )
|
||||
HANDLE_INT( USB_GINTSTS_ENUMDONE )
|
||||
HANDLE_INT( USB_GINTSTS_USBRST )
|
||||
HANDLE_INT( USB_GINTSTS_IEPINT )
|
||||
HANDLE_INT( USB_GINTSTS_OEPINT )
|
||||
|
||||
INT_Enable();
|
||||
|
||||
if ( status != 0 )
|
||||
{
|
||||
DEBUG_USB_INT_LO_PUTS( "\nUinT" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle port enumeration interrupt. This has nothing to do with normal
|
||||
* device enumeration.
|
||||
*/
|
||||
static void Handle_USB_GINTSTS_ENUMDONE( void )
|
||||
{
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
UsbPowerUp();
|
||||
#endif
|
||||
|
||||
USBDHAL_Ep0Activate( dev->ep0MpsCode );
|
||||
dev->ep[ 0 ].state = D_EP_IDLE;
|
||||
USBDHAL_EnableInts( dev );
|
||||
DEBUG_USB_INT_LO_PUTS( "EnumD" );
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle IN endpoint transfer interrupt.
|
||||
*/
|
||||
static void Handle_USB_GINTSTS_IEPINT( void )
|
||||
{
|
||||
int epnum;
|
||||
uint16_t epint;
|
||||
uint16_t epmask;
|
||||
uint32_t status;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
|
||||
DEBUG_USB_INT_HI_PUTCHAR( 'i' );
|
||||
|
||||
epint = USBDHAL_GetAllInEpInts();
|
||||
for ( epnum = 0, epmask = 1;
|
||||
epnum <= MAX_NUM_IN_EPS;
|
||||
epnum++, epmask <<= 1 )
|
||||
{
|
||||
if ( epint & epmask )
|
||||
{
|
||||
ep = USBD_GetEpFromAddr( USB_SETUP_DIR_MASK | epnum );
|
||||
status = USBDHAL_GetInEpInts( ep );
|
||||
|
||||
if ( status & USB_DIEP_INT_XFERCOMPL )
|
||||
{
|
||||
USB_DINEPS[ epnum ].INT = USB_DIEP_INT_XFERCOMPL;
|
||||
|
||||
DEBUG_USB_INT_HI_PUTCHAR( 'c' );
|
||||
|
||||
if ( epnum == 0 )
|
||||
{
|
||||
if ( ep->remaining > ep->packetSize )
|
||||
{
|
||||
ep->remaining -= ep->packetSize;
|
||||
ep->xferred += ep->packetSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->xferred += ep->remaining;
|
||||
ep->remaining = 0;
|
||||
}
|
||||
USBDEP_Ep0Handler( dev );
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->xferred = ep->remaining -
|
||||
( ( USB_DINEPS[ epnum ].TSIZ &
|
||||
_USB_DIEP_TSIZ_XFERSIZE_MASK ) >>
|
||||
_USB_DIEP_TSIZ_XFERSIZE_SHIFT );
|
||||
ep->remaining -= ep->xferred;
|
||||
|
||||
USBDEP_EpHandler( ep->addr );
|
||||
#if defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
if ( USB_DINEPS[ ep->num ].INT & USB_DIEP_INT_NAKINTRPT )
|
||||
{
|
||||
USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_NAKINTRPT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle OUT endpoint transfer interrupt.
|
||||
*/
|
||||
static void Handle_USB_GINTSTS_OEPINT( void )
|
||||
{
|
||||
int epnum;
|
||||
uint16_t epint;
|
||||
uint16_t epmask;
|
||||
uint32_t status;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
|
||||
DEBUG_USB_INT_HI_PUTCHAR( 'o' );
|
||||
|
||||
epint = USBDHAL_GetAllOutEpInts();
|
||||
for ( epnum = 0, epmask = 1;
|
||||
epnum <= MAX_NUM_OUT_EPS;
|
||||
epnum++, epmask <<= 1 )
|
||||
{
|
||||
if ( epint & epmask )
|
||||
{
|
||||
ep = USBD_GetEpFromAddr( epnum );
|
||||
status = USBDHAL_GetOutEpInts( ep );
|
||||
|
||||
#if defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
HandleOutEpIntr( status, ep );
|
||||
#else
|
||||
if ( status & USB_DOEP_INT_XFERCOMPL )
|
||||
{
|
||||
USB_DOUTEPS[ epnum ].INT = USB_DOEP_INT_XFERCOMPL;
|
||||
DEBUG_USB_INT_HI_PUTCHAR( 'c' );
|
||||
ProcessOepData( ep );
|
||||
}
|
||||
|
||||
/* Setup Phase Done */
|
||||
if ( status & USB_DOEP0INT_SETUP )
|
||||
{
|
||||
ProcessSetup();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
static void ProcessOepData( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
if ( ep->num == 0 )
|
||||
{
|
||||
|
||||
#ifdef __MBED__
|
||||
int xfer_size = ep->packetSize - (( USB->DOEP0TSIZ & _USB_DOEP0TSIZ_XFERSIZE_MASK )
|
||||
>> _USB_DOEP0TSIZ_XFERSIZE_SHIFT);
|
||||
int setup_pkt_received = USBDHAL_GetOutEpInts( ep ) & USB_DOEP0INT_SETUP;
|
||||
|
||||
if ( (!setup_pkt_received && xfer_size == 0) ||
|
||||
(setup_pkt_received && xfer_size == 8) )
|
||||
{
|
||||
/* Higher levels need to see the correct transfer amount for ZLPs */
|
||||
ep->remaining = 0;
|
||||
ep->xferred = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME - does not work if actual read size > 56 */
|
||||
if ( setup_pkt_received ) xfer_size -= 8;
|
||||
|
||||
ep->xferred = xfer_size;
|
||||
ep->remaining -= xfer_size;
|
||||
}
|
||||
#else
|
||||
if ( ep->remaining > ep->packetSize )
|
||||
{
|
||||
ep->remaining -= ep->packetSize;
|
||||
ep->xferred += ep->packetSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->xferred += ep->remaining;
|
||||
ep->remaining = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
USBDEP_Ep0Handler( dev );
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->xferred = ep->hwXferSize -
|
||||
( ( USB_DOUTEPS[ ep->num ].TSIZ & _USB_DOEP_TSIZ_XFERSIZE_MASK )>>
|
||||
_USB_DOEP_TSIZ_XFERSIZE_SHIFT );
|
||||
ep->remaining -= ep->xferred;
|
||||
USBDEP_EpHandler( ep->addr );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
static void ProcessSetup( void )
|
||||
{
|
||||
DEBUG_USB_INT_LO_PUTS( "\nS" );
|
||||
|
||||
if ( USB->DOEP0INT & USB_DOEP0INT_BACK2BACKSETUP )
|
||||
{ /* Back to back setup packets received */
|
||||
USB->DOEP0INT = USB_DOEP0INT_BACK2BACKSETUP;
|
||||
DEBUG_USB_INT_LO_PUTS( "B2B" );
|
||||
|
||||
dev->setup = (USB_Setup_TypeDef*)( USB->DOEP0DMAADDR - USB_SETUP_PKT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read SETUP packet counter from hw. */
|
||||
int supCnt = ( USB->DOEP0TSIZ & _USB_DOEP0TSIZ_SUPCNT_MASK )
|
||||
>> _USB_DOEP0TSIZ_SUPCNT_SHIFT;
|
||||
|
||||
if ( supCnt == 3 )
|
||||
supCnt = 2;
|
||||
|
||||
dev->setup = &dev->setupPkt[ 2 - supCnt ];
|
||||
}
|
||||
USB->DOEP0TSIZ |= 3 << _USB_DOEP0TSIZ_SUPCNT_SHIFT;
|
||||
USB->DOEP0DMAADDR = (uint32_t)dev->setupPkt;
|
||||
USB->DOEP0INT = USB_DOEP0INT_SETUP;
|
||||
|
||||
USBDEP_Ep0Handler( dev ); /* Call the SETUP handler for EP0 */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handle USB reset detected interrupt in suspend mode.
|
||||
*/
|
||||
static void Handle_USB_GINTSTS_RESETDET ( void )
|
||||
{
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
if ( ! USBD_poweredDown )
|
||||
{
|
||||
USB->GINTSTS = USB_GINTSTS_RESETDET;
|
||||
}
|
||||
|
||||
if ( UsbPowerUp() )
|
||||
{
|
||||
USB->GINTSTS = USB_GINTSTS_RESETDET;
|
||||
}
|
||||
|
||||
#if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
|
||||
/* Power down immediately if VBUS is off. */
|
||||
if ( ! ( USB->STATUS & USB_STATUS_VREGOS ) )
|
||||
{
|
||||
UsbPowerDown();
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
USB->GINTSTS = USB_GINTSTS_RESETDET;
|
||||
#endif /* if ( USB_PWRSAVE_MODE ) */
|
||||
|
||||
if ( USB->STATUS & USB_STATUS_VREGOS )
|
||||
{
|
||||
USBD_SetUsbState( USBD_STATE_DEFAULT );
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_SetUsbState( USBD_STATE_NONE );
|
||||
}
|
||||
DEBUG_USB_INT_LO_PUTS( "RsuP\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle Start Of Frame (SOF) interrupt.
|
||||
*/
|
||||
static void Handle_USB_GINTSTS_SOF( void )
|
||||
{
|
||||
USB->GINTSTS = USB_GINTSTS_SOF;
|
||||
|
||||
if ( dev->callbacks->sofInt )
|
||||
{
|
||||
dev->callbacks->sofInt(
|
||||
( USB->DSTS & _USB_DSTS_SOFFN_MASK ) >> _USB_DSTS_SOFFN_SHIFT );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle USB port reset interrupt.
|
||||
*/
|
||||
static void Handle_USB_GINTSTS_USBRST( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUG_USB_INT_LO_PUTS( "ReseT" );
|
||||
|
||||
/* Clear Remote Wakeup Signalling */
|
||||
USB->DCTL &= ~( DCTL_WO_BITMASK | USB_DCTL_RMTWKUPSIG );
|
||||
USBHAL_FlushTxFifo( 0 );
|
||||
|
||||
/* Clear pending interrupts */
|
||||
for ( i = 0; i <= MAX_NUM_IN_EPS; i++ )
|
||||
{
|
||||
USB_DINEPS[ i ].INT = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
for ( i = 0; i <= MAX_NUM_OUT_EPS; i++ )
|
||||
{
|
||||
USB_DOUTEPS[ i ].INT = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
USB->DAINTMSK = USB_DAINTMSK_INEPMSK0 | USB_DAINTMSK_OUTEPMSK0;
|
||||
#if defined( USB_DOEPMSK_STSPHSERCVDMSK )
|
||||
USB->DOEPMSK = USB_DOEPMSK_SETUPMSK | USB_DOEPMSK_XFERCOMPLMSK
|
||||
| USB_DOEPMSK_STSPHSERCVDMSK;
|
||||
#else
|
||||
USB->DOEPMSK = USB_DOEPMSK_SETUPMSK | USB_DOEPMSK_XFERCOMPLMSK;
|
||||
#endif
|
||||
USB->DIEPMSK = USB_DIEPMSK_XFERCOMPLMSK;
|
||||
|
||||
/* Reset Device Address */
|
||||
USB->DCFG &= ~_USB_DCFG_DEVADDR_MASK;
|
||||
|
||||
/* Setup EP0 to receive SETUP packets */
|
||||
USBDHAL_StartEp0Setup( dev );
|
||||
USBDHAL_EnableInts( dev );
|
||||
|
||||
if ( dev->callbacks->usbReset )
|
||||
{
|
||||
dev->callbacks->usbReset();
|
||||
}
|
||||
|
||||
USBD_SetUsbState( USBD_STATE_DEFAULT );
|
||||
USBDHAL_AbortAllTransfers( USB_STATUS_DEVICE_RESET );
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle USB port suspend interrupt.
|
||||
*/
|
||||
static void Handle_USB_GINTSTS_USBSUSP( void )
|
||||
{
|
||||
USBD_State_TypeDef state;
|
||||
|
||||
USB->GINTSTS = USB_GINTSTS_USBSUSP;
|
||||
USBDHAL_AbortAllTransfers( USB_STATUS_DEVICE_SUSPENDED );
|
||||
DEBUG_USB_INT_LO_PUTS( "\nSusP" );
|
||||
|
||||
if ( USBD_GetUsbState() == USBD_STATE_NONE )
|
||||
{
|
||||
USBD_SetUsbState( USBD_STATE_POWERED );
|
||||
}
|
||||
|
||||
state = USBD_GetUsbState();
|
||||
if ( ( state == USBD_STATE_POWERED ) ||
|
||||
( state == USBD_STATE_DEFAULT ) ||
|
||||
( state == USBD_STATE_ADDRESSED ) ||
|
||||
( state == USBD_STATE_CONFIGURED ) )
|
||||
{
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
UsbPowerDown();
|
||||
#endif
|
||||
USBD_SetUsbState( USBD_STATE_SUSPENDED );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle USB port wakeup interrupt.
|
||||
*/
|
||||
static void Handle_USB_GINTSTS_WKUPINT( void )
|
||||
{
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
if ( ! USBD_poweredDown )
|
||||
{
|
||||
USB->GINTSTS = USB_GINTSTS_WKUPINT;
|
||||
}
|
||||
|
||||
if ( UsbPowerUp() )
|
||||
{
|
||||
USB->GINTSTS = USB_GINTSTS_WKUPINT;
|
||||
USBDHAL_StartEp0Setup( dev );
|
||||
USBDHAL_Ep0Activate( dev->ep0MpsCode );
|
||||
}
|
||||
#else
|
||||
USB->GINTSTS = USB_GINTSTS_WKUPINT;
|
||||
#endif
|
||||
|
||||
USBD_SetUsbState( dev->savedState );
|
||||
DEBUG_USB_INT_LO_PUTS( "WkuP\n" );
|
||||
}
|
||||
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
/*
|
||||
* Backup essential USB core registers, and set the core in partial powerdown
|
||||
* mode. Optionally prepare entry into EM2.
|
||||
*/
|
||||
static bool UsbPowerDown( void )
|
||||
{
|
||||
#if ( NUM_EP_USED > 0 ) || ( FIFO_CNT > 0 )
|
||||
int i;
|
||||
#endif
|
||||
#if ( NUM_EP_USED > 0 )
|
||||
int epNum;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
#endif
|
||||
|
||||
if ( !USBD_poweredDown )
|
||||
{
|
||||
USBD_poweredDown = true;
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '\\' );
|
||||
|
||||
/* Backup USB core registers. */
|
||||
x_USB_GINTMSK = USB->GINTMSK;
|
||||
#if defined(_USB_GOTGCTL_MASK)
|
||||
x_USB_GOTGCTL = USB->GOTGCTL;
|
||||
#endif
|
||||
x_USB_GAHBCFG = USB->GAHBCFG;
|
||||
x_USB_GUSBCFG = USB->GUSBCFG;
|
||||
x_USB_GRXFSIZ = USB->GRXFSIZ;
|
||||
x_USB_GNPTXFSIZ = USB->GNPTXFSIZ;
|
||||
x_USB_DCFG = USB->DCFG;
|
||||
x_USB_DCTL = USB->DCTL;
|
||||
x_USB_DAINTMSK = USB->DAINTMSK;
|
||||
x_USB_DIEPMSK = USB->DIEPMSK;
|
||||
x_USB_DOEPMSK = USB->DOEPMSK;
|
||||
x_USB_PCGCCTL = USB->PCGCCTL;
|
||||
|
||||
#if ( NUM_EP_USED > 0 )
|
||||
for ( i = 0; i < NUM_EP_USED; i++ )
|
||||
{
|
||||
ep = &dev->ep[ i+1 ];
|
||||
epNum = ep->num;
|
||||
if ( ep->in )
|
||||
{
|
||||
x_USB_EP_CTL[ i ] = USB_DINEPS[ epNum ].CTL;
|
||||
x_USB_EP_TSIZ[ i ] = USB_DINEPS[ epNum ].TSIZ;
|
||||
x_USB_EP_DMAADDR[ i ] = USB_DINEPS[ epNum ].DMAADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
x_USB_EP_CTL[ i ] = USB_DOUTEPS[ epNum ].CTL;
|
||||
x_USB_EP_TSIZ[ i ] = USB_DOUTEPS[ epNum ].TSIZ;
|
||||
x_USB_EP_DMAADDR[ i ] = USB_DOUTEPS[ epNum ].DMAADDR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( FIFO_CNT > 0 )
|
||||
for ( i = 0; i < FIFO_CNT; i++ )
|
||||
{
|
||||
x_USB_DIEPTXFS[ i ] = USB_DIEPTXFS[ i ];
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Prepare for wakeup on resume and reset. */
|
||||
USB->DCFG = (USB->DCFG & ~_USB_DCFG_RESVALID_MASK) |
|
||||
(4 << _USB_DCFG_RESVALID_SHIFT);
|
||||
USB->DCFG |= USB_DCFG_ENA32KHZSUSP;
|
||||
USB->GINTMSK = USB_GINTMSK_RESETDETMSK | USB_GINTMSK_WKUPINTMSK;
|
||||
|
||||
/* Enter partial powerdown mode. */
|
||||
USB->PCGCCTL |= USB_PCGCCTL_PWRCLMP;
|
||||
USB->PCGCCTL |= USB_PCGCCTL_RSTPDWNMODULE;
|
||||
USB->PCGCCTL |= USB_PCGCCTL_STOPPCLK;
|
||||
|
||||
/* Record current clock settings. */
|
||||
cmuStatus = CMU->STATUS;
|
||||
|
||||
#if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ENTEREM2 )
|
||||
#ifndef __MBED__
|
||||
/* Enter EM2 on interrupt exit. */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk;
|
||||
#else
|
||||
usbhal_allow_em2(true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Switch USBC clock to 32 kHz. */
|
||||
#if ( USB_USBC_32kHz_CLK == USB_USBC_32kHz_CLK_LFXO )
|
||||
CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;
|
||||
while ( ( CMU->STATUS & CMU_STATUS_USBCLFXOSEL ) == 0 ){}
|
||||
#else
|
||||
CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;
|
||||
while ( ( CMU->STATUS & CMU_STATUS_USBCLFRCOSEL ) == 0 ){}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif /* if ( USB_PWRSAVE_MODE ) */
|
||||
|
||||
#if ( USB_PWRSAVE_MODE )
|
||||
/*
|
||||
* Exit USB core partial powerdown mode, restore essential USB core registers.
|
||||
* Will prevent re-entry back to EM2.
|
||||
* Returns true if a powerup sequence was performed.
|
||||
*/
|
||||
static bool UsbPowerUp( void )
|
||||
{
|
||||
#if ( NUM_EP_USED > 0 ) || ( FIFO_CNT > 0 )
|
||||
int i;
|
||||
#endif
|
||||
#if ( NUM_EP_USED > 0 )
|
||||
int epNum;
|
||||
uint32_t tmp;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
#endif
|
||||
|
||||
if ( USBD_poweredDown )
|
||||
{
|
||||
USBD_poweredDown = false;
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '/' );
|
||||
|
||||
#if !defined( USB_CORECLK_HFRCO ) || !defined( CMU_OSCENCMD_USHFRCOEN )
|
||||
/* Switch HFCLK from HFRCO to HFXO. */
|
||||
CMU_ClockSelectSet( cmuClock_HF, cmuSelect_HFXO );
|
||||
#endif
|
||||
|
||||
/* Turn off HFRCO when not needed. */
|
||||
if ( ( cmuStatus & CMU_STATUS_HFRCOENS ) == 0 )
|
||||
{
|
||||
CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
|
||||
}
|
||||
|
||||
/* Exit partial powerdown mode. */
|
||||
USB->PCGCCTL &= ~USB_PCGCCTL_STOPPCLK;
|
||||
USB->PCGCCTL &= ~(USB_PCGCCTL_PWRCLMP | USB_PCGCCTL_RSTPDWNMODULE);
|
||||
|
||||
if (( USB->GINTSTS & ( USB_GINTSTS_WKUPINT | USB_GINTSTS_RESETDET ) ) == 0)
|
||||
{
|
||||
USB->DCTL = x_USB_DCTL | USB_DCTL_RMTWKUPSIG;
|
||||
USB->DCTL = x_USB_DCTL;
|
||||
}
|
||||
|
||||
/* Restore USB core registers. */
|
||||
USB->GUSBCFG = x_USB_GUSBCFG;
|
||||
USB->DCFG = x_USB_DCFG;
|
||||
|
||||
#if ( FIFO_CNT > 0 )
|
||||
for ( i = 0; i < FIFO_CNT; i++ )
|
||||
{
|
||||
USB_DIEPTXFS[ i ] = x_USB_DIEPTXFS[ i ];
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( NUM_EP_USED > 0 )
|
||||
for ( i = 0; i < NUM_EP_USED; i++ )
|
||||
{
|
||||
ep = &dev->ep[ i+1 ];
|
||||
epNum = ep->num;
|
||||
|
||||
tmp = x_USB_EP_CTL[ i ] &
|
||||
~( USB_DIEP_CTL_CNAK | USB_DIEP_CTL_SNAK |
|
||||
USB_DIEP_CTL_SETD0PIDEF | USB_DIEP_CTL_SETD1PIDOF );
|
||||
|
||||
if ( x_USB_EP_CTL[ i ] & USB_DIEP_CTL_DPIDEOF )
|
||||
tmp |= USB_DIEP_CTL_SETD1PIDOF;
|
||||
else
|
||||
tmp |= USB_DIEP_CTL_SETD0PIDEF;
|
||||
|
||||
if ( x_USB_EP_CTL[ i ] & USB_DIEP_CTL_NAKSTS )
|
||||
tmp |= USB_DIEP_CTL_SNAK;
|
||||
else
|
||||
tmp |= USB_DIEP_CTL_CNAK;
|
||||
|
||||
if ( ep->in )
|
||||
{
|
||||
USB_DINEPS[ epNum ].CTL = tmp;
|
||||
USB_DINEPS[ epNum ].TSIZ = x_USB_EP_TSIZ[ i ];
|
||||
USB_DINEPS[ epNum ].DMAADDR = x_USB_EP_DMAADDR[ i ];
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_DOUTEPS[ epNum ].CTL = tmp;
|
||||
USB_DOUTEPS[ epNum ].TSIZ = x_USB_EP_TSIZ[ i ];
|
||||
USB_DOUTEPS[ epNum ].DMAADDR = x_USB_EP_DMAADDR[ i ];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
USB->PCGCCTL = x_USB_PCGCCTL;
|
||||
USB->DOEPMSK = x_USB_DOEPMSK;
|
||||
USB->DIEPMSK = x_USB_DIEPMSK;
|
||||
USB->DAINTMSK = x_USB_DAINTMSK;
|
||||
USB->DCTL = x_USB_DCTL;
|
||||
USB->GNPTXFSIZ = x_USB_GNPTXFSIZ;
|
||||
USB->GRXFSIZ = x_USB_GRXFSIZ;
|
||||
USB->GAHBCFG = x_USB_GAHBCFG;
|
||||
#if defined(_USB_GOTGCTL_MASK)
|
||||
USB->GOTGCTL = x_USB_GOTGCTL;
|
||||
#endif
|
||||
USB->GINTMSK = x_USB_GINTMSK;
|
||||
|
||||
USB->DCTL |= USB_DCTL_PWRONPRGDONE;
|
||||
|
||||
#if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ENTEREM2 )
|
||||
#ifndef __MBED__
|
||||
/* Do not reenter EM2 on interrupt exit. */
|
||||
SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
|
||||
#else
|
||||
usbhal_allow_em2(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif /* if ( USB_PWRSAVE_MODE ) */
|
||||
|
||||
#if defined( USB_DOEP0INT_STUPPKTRCVD )
|
||||
static void HandleOutEpIntr( uint32_t status, USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
uint32_t doeptsiz;
|
||||
|
||||
if ( ep->num == 0 )
|
||||
{
|
||||
if ( status & USB_DOEP0INT_XFERCOMPL )
|
||||
{
|
||||
USB->DOEP0INT = USB_DOEP0INT_XFERCOMPL;
|
||||
doeptsiz = USB->DOEP0TSIZ;
|
||||
|
||||
if ( ep->state == D_EP_IDLE )
|
||||
{
|
||||
if ( status & USB_DOEP0INT_STUPPKTRCVD )
|
||||
{
|
||||
USB->DOEP0INT = USB_DOEP0INT_STUPPKTRCVD;
|
||||
}
|
||||
status = USBDHAL_GetOutEpInts( ep );
|
||||
doeptsiz = USB->DOEP0TSIZ;
|
||||
|
||||
if ( status & USB_DOEP0INT_SETUP )
|
||||
{
|
||||
retry:
|
||||
/* Already started data stage, clear setup */
|
||||
USB->DOEP0INT = USB_DOEP0INT_SETUP;
|
||||
status &= ~USB_DOEP0INT_SETUP;
|
||||
{
|
||||
int supCnt = ( doeptsiz & _USB_DOEP0TSIZ_SUPCNT_MASK )
|
||||
>> _USB_DOEP0TSIZ_SUPCNT_SHIFT;
|
||||
|
||||
if ( supCnt == 3 )
|
||||
supCnt = 2;
|
||||
|
||||
dev->setup = &dev->setupPkt[ 2 - supCnt ];
|
||||
}
|
||||
DEBUG_USB_INT_LO_PUTS( "\nS" );
|
||||
USBDEP_Ep0Handler( dev );
|
||||
|
||||
/* Prepare for more setup packets */
|
||||
if ( ep->state == D_EP0_IN_STATUS || ep->state == D_EP_TRANSMITTING )
|
||||
{
|
||||
USBDHAL_StartEp0Setup( dev );
|
||||
}
|
||||
}
|
||||
else /* xfercompl && idle && !setup */
|
||||
{
|
||||
status = USBDHAL_GetOutEpInts( ep );
|
||||
if ( status & USB_DOEP0INT_SETUP )
|
||||
goto retry;
|
||||
USBDHAL_StartEp0Setup( dev );
|
||||
}
|
||||
}
|
||||
else /* ep0state != EP0_IDLE */
|
||||
{
|
||||
#ifdef __MBED__
|
||||
if ( ep->state == D_EP_RECEIVING )
|
||||
{
|
||||
int xfer_size = ep->packetSize - (( USB->DOEP0TSIZ & _USB_DOEP0TSIZ_XFERSIZE_MASK )
|
||||
>> _USB_DOEP0TSIZ_XFERSIZE_SHIFT);
|
||||
int setup_pkt_received = status & USB_DOEP0INT_SETUP;
|
||||
|
||||
if ( (!setup_pkt_received && xfer_size == 0) ||
|
||||
(setup_pkt_received && xfer_size == 8) )
|
||||
{
|
||||
/* Higher levels need to see the correct transfer amount for ZLPs */
|
||||
ep->remaining = 0;
|
||||
ep->xferred = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME - does not work if actual read size > 56 */
|
||||
if ( setup_pkt_received ) xfer_size -= 8;
|
||||
|
||||
ep->xferred = xfer_size;
|
||||
ep->remaining -= xfer_size;
|
||||
}
|
||||
|
||||
USBDEP_Ep0Handler( dev );
|
||||
}
|
||||
#else
|
||||
if ( ep->state == D_EP_RECEIVING )
|
||||
{
|
||||
if ( ep->remaining > ep->packetSize )
|
||||
{
|
||||
ep->remaining -= ep->packetSize;
|
||||
ep->xferred += ep->packetSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->xferred += ep->remaining;
|
||||
ep->remaining = 0;
|
||||
}
|
||||
USBDEP_Ep0Handler( dev );
|
||||
}
|
||||
else if ( ep->state == D_EP0_OUT_STATUS )
|
||||
{
|
||||
USBDEP_Ep0Handler( dev );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} /* if ( status & USB_DOEP0INT_XFERCOMPL ) */
|
||||
|
||||
if ( status & USB_DOEP0INT_STSPHSERCVD )
|
||||
{
|
||||
USB->DOEP0INT = USB_DOEP0INT_STSPHSERCVD;
|
||||
}
|
||||
|
||||
if ( status & USB_DOEP0INT_SETUP )
|
||||
{
|
||||
USB->DOEP0INT = USB_DOEP0INT_SETUP;
|
||||
{
|
||||
int supCnt = ( USB->DOEP0TSIZ & _USB_DOEP0TSIZ_SUPCNT_MASK )
|
||||
>> _USB_DOEP0TSIZ_SUPCNT_SHIFT;
|
||||
|
||||
if ( supCnt == 3 )
|
||||
supCnt = 2;
|
||||
|
||||
dev->setup = &dev->setupPkt[ 2 - supCnt ];
|
||||
}
|
||||
DEBUG_USB_INT_LO_PUTS( "\nS" );
|
||||
USBDEP_Ep0Handler( dev );
|
||||
}
|
||||
}
|
||||
else /* epnum != 0 */
|
||||
{
|
||||
if ( status & USB_DOEP_INT_XFERCOMPL )
|
||||
{
|
||||
USB_DOUTEPS[ ep->num ].INT = USB_DOEP_INT_XFERCOMPL;
|
||||
|
||||
ep->xferred = ep->hwXferSize -
|
||||
( ( USB_DOUTEPS[ ep->num ].TSIZ & _USB_DOEP_TSIZ_XFERSIZE_MASK )>>
|
||||
_USB_DOEP_TSIZ_XFERSIZE_SHIFT );
|
||||
ep->remaining -= ep->xferred;
|
||||
|
||||
USBDEP_EpHandler( ep->addr );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
|
|
@ -0,0 +1,799 @@
|
|||
/**************************************************************************//**
|
||||
* @file em_usbhal.c
|
||||
* @brief USB protocol stack library, low level USB peripheral access.
|
||||
* @version 3.20.14
|
||||
******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* 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 "em_device.h"
|
||||
#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
|
||||
#include "em_usb.h"
|
||||
#if defined( USB_DEVICE ) || defined( USB_HOST )
|
||||
|
||||
#include "em_usbtypes.h"
|
||||
#include "em_usbhal.h"
|
||||
#if defined( USB_DEVICE )
|
||||
#include "em_usbd.h"
|
||||
#endif
|
||||
#if defined( USB_HOST )
|
||||
#include "em_usbh.h"
|
||||
#endif
|
||||
#include "em_cmu.h"
|
||||
#include "em_gpio.h"
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#define EPABORT_BREAK_LOOP_COUNT 15000 /* Approx. 100 ms */
|
||||
|
||||
/* NOTE: The sequence of error message strings must agree with the */
|
||||
/* definition of USB_Status_TypeDef enum. */
|
||||
static const char * const errMsg[] =
|
||||
{
|
||||
[ USB_STATUS_OK ] = "No errors",
|
||||
[ -USB_STATUS_REQ_ERR ] = "Setup request error",
|
||||
[ -USB_STATUS_EP_BUSY ] = "Endpoint is busy",
|
||||
[ -USB_STATUS_REQ_UNHANDLED ] = "Setup request not handled",
|
||||
[ -USB_STATUS_ILLEGAL ] = "Illegal operation attempted",
|
||||
[ -USB_STATUS_EP_STALLED ] = "Endpoint is stalled",
|
||||
[ -USB_STATUS_EP_ABORTED ] = "Transfer aborted",
|
||||
[ -USB_STATUS_EP_ERROR ] = "Transfer error",
|
||||
[ -USB_STATUS_EP_NAK ] = "Endpoint NAK",
|
||||
[ -USB_STATUS_DEVICE_UNCONFIGURED ] = "Device is not configured",
|
||||
[ -USB_STATUS_DEVICE_SUSPENDED ] = "Device is suspended",
|
||||
[ -USB_STATUS_DEVICE_RESET ] = "Device has been reset",
|
||||
[ -USB_STATUS_TIMEOUT ] = "Transfer timeout",
|
||||
[ -USB_STATUS_DEVICE_REMOVED ] = "Device removed",
|
||||
[ -USB_STATUS_HC_BUSY ] = "Host channel is busy",
|
||||
[ -USB_STATUS_DEVICE_MALFUNCTION ] = "Device malfunction",
|
||||
[ -USB_STATUS_PORT_OVERCURRENT ] = "VBUS overcurrent",
|
||||
};
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Return an error message string for a given error code.
|
||||
*
|
||||
* @param[in] error
|
||||
* Error code, see \ref USB_Status_TypeDef.
|
||||
*
|
||||
* @return
|
||||
* Error message string pointer.
|
||||
******************************************************************************/
|
||||
char *USB_GetErrorMsgString( int error )
|
||||
{
|
||||
if ( error >= 0 )
|
||||
return (char*)errMsg[ 0 ];
|
||||
|
||||
return (char*)errMsg[ -error ];
|
||||
}
|
||||
|
||||
|
||||
#if defined( USB_USE_PRINTF )
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Format and print a text string given an error code, prepends an optional user
|
||||
* supplied leader string.
|
||||
*
|
||||
* @param[in] pre
|
||||
* Optional leader string to prepend to error message string.
|
||||
*
|
||||
* @param[in] error
|
||||
* Error code, see \ref USB_Status_TypeDef.
|
||||
******************************************************************************/
|
||||
void USB_PrintErrorMsgString( char *pre, int error )
|
||||
{
|
||||
if ( pre )
|
||||
{
|
||||
USB_PRINTF( "%s", pre );
|
||||
}
|
||||
|
||||
if ( error > USB_STATUS_OK )
|
||||
{
|
||||
USB_PRINTF( "%d", error );
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_PRINTF( "%s", USB_GetErrorMsgString( error ) );
|
||||
}
|
||||
}
|
||||
#endif /* defined( USB_USE_PRINTF ) */
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#if defined( DEBUG_EFM_USER )
|
||||
static void PrintI( int i )
|
||||
{
|
||||
#if !defined ( USER_PUTCHAR )
|
||||
(void)i;
|
||||
#else
|
||||
if ( i >= 10 )
|
||||
{
|
||||
PrintI( i / 10 );
|
||||
}
|
||||
|
||||
DEBUG_USB_API_PUTCHAR( ( i % 10 ) + '0' );
|
||||
#endif
|
||||
}
|
||||
|
||||
void assertEFM( const char *file, int line )
|
||||
{
|
||||
#if !defined ( USER_PUTCHAR )
|
||||
(void)file;
|
||||
#endif
|
||||
|
||||
DEBUG_USB_API_PUTS( "\nASSERT " );
|
||||
DEBUG_USB_API_PUTS( file );
|
||||
DEBUG_USB_API_PUTCHAR( ' ' );
|
||||
PrintI( line );
|
||||
for(;;){}
|
||||
}
|
||||
#endif /* defined( DEBUG_EFM_USER ) */
|
||||
|
||||
#if defined ( USER_PUTCHAR )
|
||||
void USB_Puts( const char *p )
|
||||
{
|
||||
while( *p )
|
||||
USB_PUTCHAR( *p++ );
|
||||
}
|
||||
#endif /* defined ( USER_PUTCHAR ) */
|
||||
|
||||
void USBHAL_CoreReset( void )
|
||||
{
|
||||
USB->PCGCCTL &= ~USB_PCGCCTL_STOPPCLK;
|
||||
USB->PCGCCTL &= ~(USB_PCGCCTL_PWRCLMP | USB_PCGCCTL_RSTPDWNMODULE);
|
||||
|
||||
/* Core Soft Reset */
|
||||
USB->GRSTCTL |= USB_GRSTCTL_CSFTRST;
|
||||
while ( USB->GRSTCTL & USB_GRSTCTL_CSFTRST ) {}
|
||||
|
||||
USBTIMER_DelayUs( 1 );
|
||||
|
||||
/* Wait for AHB master IDLE state. */
|
||||
while ( !( USB->GRSTCTL & USB_GRSTCTL_AHBIDLE ) ) {}
|
||||
}
|
||||
|
||||
#ifdef USB_DEVICE
|
||||
void USBDHAL_Connect( void )
|
||||
{
|
||||
USB->DCTL &= ~( DCTL_WO_BITMASK | USB_DCTL_SFTDISCON );
|
||||
}
|
||||
|
||||
USB_Status_TypeDef USBDHAL_CoreInit( uint32_t totalRxFifoSize,
|
||||
uint32_t totalTxFifoSize )
|
||||
{
|
||||
uint8_t i, j;
|
||||
uint16_t start, depth;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
|
||||
#if !defined( USB_VBUS_SWITCH_NOT_PRESENT )
|
||||
CMU_ClockEnable( cmuClock_GPIO, true );
|
||||
GPIO_PinModeSet( gpioPortF, 5, gpioModePushPull, 0 ); /* Enable VBUSEN pin */
|
||||
USB->ROUTE = USB_ROUTE_PHYPEN | USB_ROUTE_VBUSENPEN; /* Enable PHY pins. */
|
||||
#else
|
||||
USB->ROUTE = USB_ROUTE_PHYPEN; /* Enable PHY pins. */
|
||||
#endif
|
||||
|
||||
USBHAL_CoreReset(); /* Reset USB core */
|
||||
|
||||
#if defined( USB_GUSBCFG_FORCEHSTMODE )
|
||||
/* Force Device Mode */
|
||||
USB->GUSBCFG = ( USB->GUSBCFG &
|
||||
~(GUSBCFG_WO_BITMASK | USB_GUSBCFG_FORCEHSTMODE ) ) |
|
||||
USB_GUSBCFG_FORCEDEVMODE;
|
||||
#endif
|
||||
|
||||
INT_Enable();
|
||||
USBTIMER_DelayMs( 50 );
|
||||
INT_Disable();
|
||||
|
||||
/* Set device speed */
|
||||
USB->DCFG = ( USB->DCFG & ~_USB_DCFG_DEVSPD_MASK ) | 3; /* Full speed PHY */
|
||||
|
||||
/* Stall on non-zero len status OUT packets (ctrl transfers). */
|
||||
USB->DCFG |= USB_DCFG_NZSTSOUTHSHK;
|
||||
|
||||
/* Set periodic frame interval to 80% */
|
||||
USB->DCFG &= ~_USB_DCFG_PERFRINT_MASK;
|
||||
|
||||
USB->GAHBCFG = ( USB->GAHBCFG & ~_USB_GAHBCFG_HBSTLEN_MASK ) |
|
||||
USB_GAHBCFG_DMAEN | USB_GAHBCFG_HBSTLEN_INCR;
|
||||
|
||||
/* Ignore frame numbers on ISO transfers. */
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_IGNRFRMNUM;
|
||||
|
||||
/* Set Rx FIFO size */
|
||||
start = EFM32_MAX( totalRxFifoSize, MIN_EP_FIFO_SIZE_INWORDS );
|
||||
USB->GRXFSIZ = ( start << _USB_GRXFSIZ_RXFDEP_SHIFT ) &
|
||||
_USB_GRXFSIZ_RXFDEP_MASK;
|
||||
|
||||
/* Set Tx EP0 FIFO size */
|
||||
depth = EFM32_MAX( dev->ep[ 0 ].fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
|
||||
USB->GNPTXFSIZ = ( ( depth << _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT ) &
|
||||
_USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK ) |
|
||||
( ( start << _USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT ) &
|
||||
_USB_GNPTXFSIZ_NPTXFSTADDR_MASK );
|
||||
|
||||
|
||||
/* Set Tx EP FIFO sizes for all IN ep's */
|
||||
for ( j = 1; j <= MAX_NUM_TX_FIFOS; j++ )
|
||||
{
|
||||
for ( i = 1; i <= MAX_NUM_IN_EPS; i++ )
|
||||
{
|
||||
ep = USBD_GetEpFromAddr( USB_SETUP_DIR_MASK | i );
|
||||
if ( ep ) /* Is EP in use ? */
|
||||
{
|
||||
if ( ep->txFifoNum == j ) /* Is it correct FIFO number ? */
|
||||
{
|
||||
start += depth;
|
||||
depth = EFM32_MAX( ep->fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
|
||||
USB_DIEPTXFS[ ep->txFifoNum - 1 ] =
|
||||
( depth << _USB_DIEPTXF1_INEPNTXFDEP_SHIFT ) |
|
||||
( start & _USB_DIEPTXF1_INEPNTXFSTADDR_MASK );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( totalRxFifoSize + totalTxFifoSize > MAX_DEVICE_FIFO_SIZE_INWORDS )
|
||||
return USB_STATUS_ILLEGAL;
|
||||
|
||||
if ( start > MAX_DEVICE_FIFO_SIZE_INWORDS )
|
||||
return USB_STATUS_ILLEGAL;
|
||||
|
||||
/* Flush the FIFO's */
|
||||
USBHAL_FlushTxFifo( 0x10 ); /* All Tx FIFO's */
|
||||
USBHAL_FlushRxFifo(); /* The Rx FIFO */
|
||||
|
||||
/* Disable all device interrupts */
|
||||
USB->DIEPMSK = 0;
|
||||
USB->DOEPMSK = 0;
|
||||
USB->DAINTMSK = 0;
|
||||
USB->DIEPEMPMSK = 0;
|
||||
|
||||
/* Disable all EP's, clear all EP ints. */
|
||||
for ( i = 0; i <= MAX_NUM_IN_EPS; i++ )
|
||||
{
|
||||
USB_DINEPS[ i ].CTL = 0;
|
||||
USB_DINEPS[ i ].TSIZ = 0;
|
||||
USB_DINEPS[ i ].INT = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
for ( i = 0; i <= MAX_NUM_OUT_EPS; i++ )
|
||||
{
|
||||
USB_DOUTEPS[ i ].CTL = 0;
|
||||
USB_DOUTEPS[ i ].TSIZ = 0;
|
||||
USB_DOUTEPS[ i ].INT = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
#if ( USB_DCTL_SFTDISCON_DEFAULT != 0 )
|
||||
USBD_Connect();
|
||||
#endif
|
||||
|
||||
/* Enable VREGO sense. */
|
||||
USB->CTRL |= USB_CTRL_VREGOSEN;
|
||||
USB->IFC = USB_IFC_VREGOSH | USB_IFC_VREGOSL;
|
||||
USB->IEN = USB_IFC_VREGOSH | USB_IFC_VREGOSL;
|
||||
/* Force a VREGO interrupt. */
|
||||
if ( USB->STATUS & USB_STATUS_VREGOS)
|
||||
USB->IFS = USB_IFS_VREGOSH;
|
||||
else
|
||||
USB->IFS = USB_IFS_VREGOSL;
|
||||
|
||||
return USB_STATUS_OK;
|
||||
}
|
||||
|
||||
USB_Status_TypeDef USBDHAL_ReconfigureFifos( uint32_t totalRxFifoSize,
|
||||
uint32_t totalTxFifoSize )
|
||||
{
|
||||
uint8_t i, j;
|
||||
uint16_t start, depth;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
|
||||
/* Set Rx FIFO size */
|
||||
start = EFM32_MAX( totalRxFifoSize, MIN_EP_FIFO_SIZE_INWORDS );
|
||||
USB->GRXFSIZ = ( start << _USB_GRXFSIZ_RXFDEP_SHIFT ) &
|
||||
_USB_GRXFSIZ_RXFDEP_MASK;
|
||||
|
||||
/* Set Tx EP0 FIFO size */
|
||||
depth = EFM32_MAX( dev->ep[ 0 ].fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
|
||||
USB->GNPTXFSIZ = ( ( depth << _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT ) &
|
||||
_USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK ) |
|
||||
( ( start << _USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT ) &
|
||||
_USB_GNPTXFSIZ_NPTXFSTADDR_MASK );
|
||||
|
||||
|
||||
/* Set Tx EP FIFO sizes for all IN ep's */
|
||||
for ( j = 1; j <= MAX_NUM_TX_FIFOS; j++ )
|
||||
{
|
||||
for ( i = 1; i <= MAX_NUM_IN_EPS; i++ )
|
||||
{
|
||||
ep = USBD_GetEpFromAddr( USB_SETUP_DIR_MASK | i );
|
||||
if ( ep ) /* Is EP in use ? */
|
||||
{
|
||||
if ( ep->txFifoNum == j ) /* Is it correct FIFO number ? */
|
||||
{
|
||||
start += depth;
|
||||
depth = EFM32_MAX( ep->fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
|
||||
USB_DIEPTXFS[ ep->txFifoNum - 1 ] =
|
||||
( depth << _USB_DIEPTXF1_INEPNTXFDEP_SHIFT ) |
|
||||
( start & _USB_DIEPTXF1_INEPNTXFSTADDR_MASK );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( totalRxFifoSize + totalTxFifoSize > MAX_DEVICE_FIFO_SIZE_INWORDS )
|
||||
return USB_STATUS_ILLEGAL;
|
||||
|
||||
if ( start > MAX_DEVICE_FIFO_SIZE_INWORDS )
|
||||
return USB_STATUS_ILLEGAL;
|
||||
|
||||
/* Flush the FIFO's */
|
||||
USBHAL_FlushTxFifo( 0x10 ); /* All Tx FIFO's */
|
||||
USBHAL_FlushRxFifo(); /* The Rx FIFO */
|
||||
|
||||
return USB_STATUS_OK;
|
||||
}
|
||||
|
||||
void USBDHAL_Disconnect( void )
|
||||
{
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_SFTDISCON;
|
||||
}
|
||||
|
||||
void USBDHAL_AbortEpIn( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
/* Clear epdis & inepnakeff INT's */
|
||||
USB_DINEPS[ ep->num ].INT |= USB_DIEP_INT_EPDISBLD |
|
||||
USB_DIEP_INT_INEPNAKEFF;
|
||||
|
||||
/* Enable epdis & inepnakeff INT's */
|
||||
USB->DIEPMSK |= USB_DIEPMSK_EPDISBLDMSK | USB_DIEPMSK_INEPNAKEFFMSK;
|
||||
USB_DINEPS[ ep->num ].CTL = ( USB_DINEPS[ ep->num ].CTL &
|
||||
~DEPCTL_WO_BITMASK ) |
|
||||
USB_DIEP_CTL_SNAK;
|
||||
|
||||
/* Wait for inepnakeff INT */
|
||||
while ( !( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_INEPNAKEFF ) ) {}
|
||||
USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_INEPNAKEFF;
|
||||
USB->DIEPMSK &= ~USB_DIEPMSK_INEPNAKEFFMSK;
|
||||
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '.' );
|
||||
|
||||
USBDHAL_SetEPDISNAK( ep );
|
||||
/* Wait for epdis INT */
|
||||
while ( !( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_EPDISBLD ) ) {}
|
||||
USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_EPDISBLD;
|
||||
USB->DIEPMSK &= ~USB_DIEPMSK_EPDISBLDMSK;
|
||||
USBHAL_FlushTxFifo( ep->txFifoNum );
|
||||
|
||||
/* Clear any interrupts generated by the abort sequence. */
|
||||
NVIC_ClearPendingIRQ( USB_IRQn );
|
||||
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '.' );
|
||||
}
|
||||
|
||||
void USBDHAL_AbortEpOut( USBD_Ep_TypeDef *ep )
|
||||
{
|
||||
int cnt;
|
||||
|
||||
/* Clear epdis INT's */
|
||||
USB_DOUTEPS[ ep->num ].INT |= USB_DOEP_INT_EPDISBLD;
|
||||
|
||||
/* Clear Global OUT NAK if already set */
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
|
||||
USB->GINTMSK |= USB_GINTMSK_GOUTNAKEFFMSK; /* Enable GOUTNAKEFF int */
|
||||
|
||||
/* Set Global OUT NAK */
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_SGOUTNAK;
|
||||
|
||||
/* Wait for goutnakeff */
|
||||
cnt = EPABORT_BREAK_LOOP_COUNT;
|
||||
while ( !( USB->GINTSTS & USB_GINTSTS_GOUTNAKEFF ) && cnt )
|
||||
{
|
||||
cnt--;
|
||||
}
|
||||
|
||||
USB->GINTMSK &= ~USB_GINTMSK_GOUTNAKEFFMSK; /* Disable GOUTNAKEFF int */
|
||||
USB->DOEPMSK |= USB_DOEPMSK_EPDISBLDMSK; /* Enable EPDIS interrupt */
|
||||
|
||||
DEBUG_USB_INT_LO_PUTCHAR( ',' );
|
||||
|
||||
USBDHAL_SetEPDISNAK( ep ); /* Disable ep */
|
||||
|
||||
/* Wait for epdis INT */
|
||||
cnt = EPABORT_BREAK_LOOP_COUNT;
|
||||
while ( !( USBDHAL_GetOutEpInts( ep ) & USB_DOEP_INT_EPDISBLD ) && cnt )
|
||||
{
|
||||
cnt--;
|
||||
}
|
||||
|
||||
USB_DOUTEPS[ ep->num ].INT = USB_DOEP_INT_EPDISBLD;
|
||||
USB->DOEPMSK &= ~USB_DOEPMSK_EPDISBLDMSK; /* Disable EPDIS interrupt */
|
||||
|
||||
/* Clear Global OUT NAK */
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
|
||||
|
||||
/* Clear any interrupts generated by the abort sequence. */
|
||||
NVIC_ClearPendingIRQ( USB_IRQn );
|
||||
|
||||
DEBUG_USB_INT_LO_PUTCHAR( ',' );
|
||||
}
|
||||
|
||||
void USBDHAL_AbortAllEps( void )
|
||||
{
|
||||
int i, cnt;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
uint16_t im, om, inmask=0, outmask=0;
|
||||
|
||||
/* Clear epdis & inepnakeff INT's */
|
||||
for ( i = 1; i <= NUM_EP_USED; i++ )
|
||||
{
|
||||
ep = &dev->ep[i];
|
||||
if ( ep->state != D_EP_IDLE )
|
||||
{
|
||||
if ( ep->in )
|
||||
{
|
||||
inmask |= ep->mask;
|
||||
USB_DINEPS[ ep->num ].INT |= USB_DIEP_INT_EPDISBLD |
|
||||
USB_DIEP_INT_INEPNAKEFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
outmask |= ep->mask;
|
||||
USB_DOUTEPS[ ep->num ].INT |= USB_DOEP_INT_EPDISBLD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( inmask )
|
||||
{
|
||||
/* Enable epdis & inepnakeff INT's */
|
||||
USB->DIEPMSK |= USB_DIEPMSK_EPDISBLDMSK | USB_DIEPMSK_INEPNAKEFFMSK;
|
||||
|
||||
/* Set NAK on all IN ep's */
|
||||
im = inmask;
|
||||
for ( i = 1; i <= NUM_EP_USED; i++ )
|
||||
{
|
||||
ep = &dev->ep[i];
|
||||
if ( im & ep->mask )
|
||||
{
|
||||
USB_DINEPS[ ep->num ].CTL = ( USB_DINEPS[ ep->num ].CTL &
|
||||
~DEPCTL_WO_BITMASK ) |
|
||||
USB_DIEP_CTL_SNAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( outmask )
|
||||
{
|
||||
/* Clear Global OUT NAK if already set */
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
|
||||
|
||||
USB->GINTMSK |= USB_GINTMSK_GOUTNAKEFFMSK; /* Enable GOUTNAKEFF int */
|
||||
|
||||
/* Set Global OUT NAK */
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_SGOUTNAK;
|
||||
|
||||
/* Wait for goutnakeff */
|
||||
cnt = EPABORT_BREAK_LOOP_COUNT;
|
||||
while ( !( USB->GINTSTS & USB_GINTSTS_GOUTNAKEFF ) && cnt )
|
||||
{
|
||||
cnt--;
|
||||
}
|
||||
USB->GINTMSK &= ~USB_GINTMSK_GOUTNAKEFFMSK; /* Disable GOUTNAKEFF int */
|
||||
USB->DOEPMSK |= USB_DOEPMSK_EPDISBLDMSK; /* Enable EPDIS interrupt */
|
||||
}
|
||||
|
||||
if ( inmask )
|
||||
{
|
||||
/* Wait for inepnakeff INT on all IN ep's */
|
||||
im = inmask;
|
||||
cnt = EPABORT_BREAK_LOOP_COUNT;
|
||||
do
|
||||
{
|
||||
for ( i = 1; i <= NUM_EP_USED; i++ )
|
||||
{
|
||||
ep = &dev->ep[i];
|
||||
if ( im & ep->mask )
|
||||
{
|
||||
if ( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_INEPNAKEFF )
|
||||
{
|
||||
USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_INEPNAKEFF;
|
||||
im &= ~ep->mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
cnt--;
|
||||
} while ( im && cnt );
|
||||
USB->DIEPMSK &= ~USB_DIEPMSK_INEPNAKEFFMSK;
|
||||
}
|
||||
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '\'' );
|
||||
|
||||
/* Disable ep's */
|
||||
for ( i = 1; i <= NUM_EP_USED; i++ )
|
||||
{
|
||||
ep = &dev->ep[i];
|
||||
if ( ep->state != D_EP_IDLE )
|
||||
{
|
||||
USBDHAL_SetEPDISNAK( ep );
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for epdis INT */
|
||||
im = inmask;
|
||||
om = outmask;
|
||||
cnt = EPABORT_BREAK_LOOP_COUNT;
|
||||
do
|
||||
{
|
||||
for ( i = 1; i <= NUM_EP_USED; i++ )
|
||||
{
|
||||
ep = &dev->ep[i];
|
||||
if ( ep->in && ( im & ep->mask ) )
|
||||
{
|
||||
if ( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_EPDISBLD )
|
||||
{
|
||||
USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_EPDISBLD;
|
||||
im &= ~ep->mask;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !ep->in && ( om & ep->mask ) )
|
||||
{
|
||||
if ( USBDHAL_GetOutEpInts( ep ) & USB_DOEP_INT_EPDISBLD )
|
||||
{
|
||||
USB_DOUTEPS[ ep->num ].INT = USB_DOEP_INT_EPDISBLD;
|
||||
om &= ~ep->mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
cnt--;
|
||||
} while ( ( im || om ) && cnt );
|
||||
|
||||
if ( inmask )
|
||||
{
|
||||
USB->DIEPMSK &= ~USB_DIEPMSK_EPDISBLDMSK; /* Disable EPDIS interrupt */
|
||||
USBHAL_FlushTxFifo( 0x10 ); /* Flush all Tx FIFO's */
|
||||
}
|
||||
|
||||
if ( outmask )
|
||||
{
|
||||
USB->DOEPMSK &= ~USB_DOEPMSK_EPDISBLDMSK; /* Disable EPDIS interrupt */
|
||||
/* Clear Global OUT NAK */
|
||||
USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
|
||||
}
|
||||
|
||||
DEBUG_USB_INT_LO_PUTCHAR( '\'' );
|
||||
}
|
||||
|
||||
void USBDHAL_AbortAllTransfers( USB_Status_TypeDef reason )
|
||||
{
|
||||
int i;
|
||||
USBD_Ep_TypeDef *ep;
|
||||
USB_XferCompleteCb_TypeDef callback;
|
||||
|
||||
if ( reason != USB_STATUS_DEVICE_RESET )
|
||||
{
|
||||
USBDHAL_AbortAllEps();
|
||||
}
|
||||
|
||||
for ( i = 1; i <= NUM_EP_USED; i++ )
|
||||
{
|
||||
ep = &(dev->ep[i]);
|
||||
if ( ep->state != D_EP_IDLE )
|
||||
{
|
||||
ep->state = D_EP_IDLE;
|
||||
if ( ep->xferCompleteCb )
|
||||
{
|
||||
callback = ep->xferCompleteCb;
|
||||
ep->xferCompleteCb = NULL;
|
||||
|
||||
if ( ( dev->lastState == USBD_STATE_CONFIGURED ) &&
|
||||
( dev->state == USBD_STATE_ADDRESSED ) )
|
||||
{
|
||||
USBDHAL_DeactivateEp( ep );
|
||||
}
|
||||
|
||||
DEBUG_TRACE_ABORT( reason );
|
||||
callback( reason, ep->xferred, ep->remaining );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear any interrupts generated by the abort sequence. */
|
||||
NVIC_ClearPendingIRQ( USB_IRQn );
|
||||
}
|
||||
#endif /* defined( USB_DEVICE ) */
|
||||
|
||||
#if defined( USB_HOST )
|
||||
USB_Status_TypeDef USBHHAL_CoreInit( uint32_t rxFifoSize,
|
||||
uint32_t nptxFifoSize,
|
||||
uint32_t ptxFifoSize )
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
rxFifoSize /= 4; /* Convert from byte count to word count. */
|
||||
nptxFifoSize /= 4;
|
||||
ptxFifoSize /= 4;
|
||||
|
||||
CMU_ClockEnable( cmuClock_GPIO, true );
|
||||
GPIO_PinModeSet( gpioPortF, 5, gpioModePushPull, 0 ); /* Enable VBUSEN pin */
|
||||
|
||||
#if ( USB_VBUSOVRCUR_PORT != USB_VBUSOVRCUR_PORT_NONE )
|
||||
/* Enable VBUS overcurrent flag pin. */
|
||||
GPIO_PinModeSet( USB_VBUSOVRCUR_PORT, USB_VBUSOVRCUR_PIN, gpioModeInput, 0 );
|
||||
#endif
|
||||
|
||||
USB->ROUTE = USB_ROUTE_PHYPEN | USB_ROUTE_VBUSENPEN; /* Enable PHY pins. */
|
||||
USBHAL_CoreReset(); /* Reset USB core */
|
||||
|
||||
/* Force Host Mode */
|
||||
USB->GUSBCFG = ( USB->GUSBCFG &
|
||||
~(GUSBCFG_WO_BITMASK | USB_GUSBCFG_FORCEDEVMODE ) ) |
|
||||
USB_GUSBCFG_FORCEHSTMODE;
|
||||
|
||||
INT_Enable();
|
||||
USBTIMER_DelayMs( 100 );
|
||||
INT_Disable();
|
||||
|
||||
/* Set 48 MHz PHY clock, FS/LS mode */
|
||||
USB->HCFG = ( USB->HCFG & ~_USB_HCFG_FSLSPCLKSEL_MASK ) |
|
||||
( 1 << _USB_HCFG_FSLSPCLKSEL_SHIFT ) |
|
||||
( USB_HCFG_FSLSSUPP );
|
||||
|
||||
USB->GAHBCFG = ( USB->GAHBCFG & ~_USB_GAHBCFG_HBSTLEN_MASK ) |
|
||||
USB_GAHBCFG_DMAEN | USB_GAHBCFG_HBSTLEN_INCR;
|
||||
|
||||
/* Set Rx FIFO size */
|
||||
USB->GRXFSIZ = ( rxFifoSize << _USB_GRXFSIZ_RXFDEP_SHIFT ) &
|
||||
_USB_GRXFSIZ_RXFDEP_MASK;
|
||||
|
||||
/* Set Tx FIFO sizes */
|
||||
USB->GNPTXFSIZ = ( ( nptxFifoSize <<
|
||||
_USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT ) &
|
||||
_USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK ) |
|
||||
( ( rxFifoSize <<
|
||||
_USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT ) &
|
||||
_USB_GNPTXFSIZ_NPTXFSTADDR_MASK );
|
||||
|
||||
USB->HPTXFSIZ = ( ( ptxFifoSize << _USB_HPTXFSIZ_PTXFSIZE_SHIFT ) &
|
||||
_USB_HPTXFSIZ_PTXFSIZE_MASK ) |
|
||||
( ( ( rxFifoSize + nptxFifoSize )
|
||||
<< _USB_HPTXFSIZ_PTXFSTADDR_SHIFT ) &
|
||||
_USB_HPTXFSIZ_PTXFSTADDR_MASK );
|
||||
|
||||
/* Flush Tx and Rx FIFO's */
|
||||
USBHAL_FlushTxFifo( 0x10 );
|
||||
USBHAL_FlushRxFifo();
|
||||
|
||||
for ( i = 0; i < MAX_NUM_HOSTCHANNELS; i++ )
|
||||
{
|
||||
USB->HC[ i ].CHAR = USB_HC_CHAR_CHDIS; /* Disable channel */
|
||||
USB->HC[ i ].INT = 0xFFFFFFFF; /* Clear pending interrupts */
|
||||
}
|
||||
|
||||
/* Enable and halt all channels */
|
||||
for ( i = 0; i < MAX_NUM_HOSTCHANNELS; i++ )
|
||||
{
|
||||
USB->HC[ i ].CHAR |= USB_HC_CHAR_CHDIS | USB_HC_CHAR_CHENA;
|
||||
do
|
||||
{
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
}
|
||||
while ( USB->HC[ i ].CHAR & USB_HC_CHAR_CHENA );
|
||||
}
|
||||
|
||||
/* Disable all interrupts */
|
||||
for ( i = 0; i < MAX_NUM_HOSTCHANNELS; i++ )
|
||||
{
|
||||
USB->HC[ i ].INTMSK = 0;
|
||||
}
|
||||
|
||||
USB->HAINTMSK = 0;
|
||||
|
||||
return USB_STATUS_OK;
|
||||
}
|
||||
|
||||
void USBHHAL_HCHalt( int hcnum, uint32_t hcchar )
|
||||
{
|
||||
hcchar |= USB_HC_CHAR_CHENA | USB_HC_CHAR_CHDIS;
|
||||
USB->HC[ hcnum ].CHAR = hcchar;
|
||||
}
|
||||
|
||||
void USBHHAL_HCInit( int hcnum )
|
||||
{
|
||||
USBH_Ep_TypeDef *ep;
|
||||
|
||||
ep = hcs[ hcnum ].ep;
|
||||
USB->HC[ hcnum ].INT = 0xFFFFFFFF; /* Clear all interrupt flags */
|
||||
|
||||
switch ( ep->type ) /* Enable host channel int. types */
|
||||
{
|
||||
case USB_EPTYPE_CTRL:
|
||||
case USB_EPTYPE_BULK:
|
||||
case USB_EPTYPE_INTR:
|
||||
USB->HC[ hcnum ].INTMSK = USB_HC_INT_CHHLTD;
|
||||
break;
|
||||
}
|
||||
|
||||
hcs[ hcnum ].errorCnt = 0;
|
||||
|
||||
USB->HAINTMSK |= 1 << hcnum; /* Enable host channel interrupt */
|
||||
|
||||
USB->HC[ hcnum ].CHAR = /* Program HCCHAR register */
|
||||
( ep->parentDevice->addr << _USB_HC_CHAR_DEVADDR_SHIFT ) |
|
||||
( ( ep->addr & USB_EPNUM_MASK ) << _USB_HC_CHAR_EPNUM_SHIFT ) |
|
||||
( ep->type << _USB_HC_CHAR_EPTYPE_SHIFT ) |
|
||||
( ep->packetSize << _USB_HC_CHAR_MPS_SHIFT ) |
|
||||
( ep->in ? USB_HC_CHAR_EPDIR : 0 ) |
|
||||
( ep->parentDevice->speed ==
|
||||
HPRT_L_SPEED >> _USB_HPRT_PRTSPD_SHIFT
|
||||
? USB_HC_CHAR_LSPDDEV : 0 );
|
||||
}
|
||||
|
||||
void USBHHAL_HCStart( int hcnum )
|
||||
{
|
||||
USBH_Hc_TypeDef *hc;
|
||||
uint16_t packets, len;
|
||||
|
||||
hc = &hcs[ hcnum ];
|
||||
hc->status = 0;
|
||||
hc->idle = false;
|
||||
|
||||
if ( hc->remaining > 0 )
|
||||
{
|
||||
packets = ( hc->remaining + hc->ep->packetSize - 1 ) / hc->ep->packetSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
packets = 1;
|
||||
}
|
||||
|
||||
if ( hc->ep->in )
|
||||
{
|
||||
len = packets * hc->ep->packetSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = hc->remaining;
|
||||
}
|
||||
|
||||
/* Initialize the HCTSIZn register */
|
||||
hc->hwXferSize = len;
|
||||
USB->HC[ hcnum ].TSIZ =
|
||||
( ( len << _USB_HC_TSIZ_XFERSIZE_SHIFT ) &
|
||||
_USB_HC_TSIZ_XFERSIZE_MASK ) |
|
||||
( ( packets << _USB_HC_TSIZ_PKTCNT_SHIFT ) &
|
||||
_USB_HC_TSIZ_PKTCNT_MASK ) |
|
||||
( ( hc->ep->toggle << _USB_HC_TSIZ_PID_SHIFT ) &
|
||||
_USB_HC_TSIZ_PID_MASK );
|
||||
|
||||
USB->HC[ hcnum ].DMAADDR = (uint32_t)hc->buf;
|
||||
|
||||
USBHHAL_HCActivate( hcnum,
|
||||
USB->HC[ hcnum ].CHAR,
|
||||
hc->ep->type == USB_EPTYPE_INTR );
|
||||
}
|
||||
#endif /* defined( USB_HOST ) */
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#endif /* defined( USB_DEVICE ) || defined( USB_HOST ) */
|
||||
#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
|
|
@ -0,0 +1,381 @@
|
|||
/***************************************************************************//**
|
||||
* @file em_usbtimer.c
|
||||
* @brief USB protocol stack library, timer API.
|
||||
* @version 3.20.14
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
* 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 "em_device.h"
|
||||
#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
|
||||
#include "em_usb.h"
|
||||
#if defined( USB_DEVICE ) || defined( USB_HOST )
|
||||
#include "em_cmu.h"
|
||||
#include "em_timer.h"
|
||||
#include "em_usbtypes.h"
|
||||
#include "em_usbhal.h"
|
||||
|
||||
#include "device_peripherals.h"
|
||||
|
||||
/*
|
||||
* Use one HW timer to serve n software milisecond timers.
|
||||
* A timer is, when running, in a linked list of timers.
|
||||
* A given timers timeout period is the acculmulated timeout
|
||||
* of all timers preceeding it in the queue.
|
||||
* This makes timer start (linked list insertion) computing intensive,
|
||||
* but the checking of the queue at each tick very effective.
|
||||
* ______ ______ ______
|
||||
* | | --->| | --->| |
|
||||
* head --> | | | | | | | |
|
||||
* |______|--- |______|--- |______|---/ NULL
|
||||
*/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#ifndef USB_TIMER
|
||||
#error HW platform must define the timer to use for USB
|
||||
#endif
|
||||
|
||||
#if ( USB_TIMER == USB_TIMER0 ) && ( TIMER_COUNT >= 1 )
|
||||
#define TIMER TIMER0
|
||||
#define TIMER_CLK cmuClock_TIMER0
|
||||
#define TIMER_IRQ TIMER0_IRQn
|
||||
#define TIMER_IRQHandler TIMER0_IRQHandler
|
||||
|
||||
#elif ( USB_TIMER == USB_TIMER1 ) && ( TIMER_COUNT >= 2 )
|
||||
#define TIMER TIMER1
|
||||
#define TIMER_CLK cmuClock_TIMER1
|
||||
#define TIMER_IRQ TIMER1_IRQn
|
||||
#define TIMER_IRQHandler TIMER1_IRQHandler
|
||||
|
||||
#elif ( USB_TIMER == USB_TIMER2 ) && ( TIMER_COUNT >= 3 )
|
||||
#define TIMER TIMER2
|
||||
#define TIMER_CLK cmuClock_TIMER2
|
||||
#define TIMER_IRQ TIMER2_IRQn
|
||||
#define TIMER_IRQHandler TIMER2_IRQHandler
|
||||
|
||||
#elif ( USB_TIMER == USB_TIMER3 ) && ( TIMER_COUNT == 4 )
|
||||
#define TIMER TIMER3
|
||||
#define TIMER_CLK cmuClock_TIMER3
|
||||
#define TIMER_IRQ TIMER3_IRQn
|
||||
#define TIMER_IRQHandler TIMER3_IRQHandler
|
||||
|
||||
#else
|
||||
#error "Illegal USB TIMER definition"
|
||||
#endif
|
||||
|
||||
typedef struct _timer
|
||||
{
|
||||
uint32_t timeout; /* Delta value relative to prev. timer */
|
||||
struct _timer *next;
|
||||
USBTIMER_Callback_TypeDef callback;
|
||||
bool running;
|
||||
} USBTIMER_Timer_TypeDef;
|
||||
|
||||
#if ( NUM_QTIMERS > 0 )
|
||||
static USBTIMER_Timer_TypeDef timers[ NUM_QTIMERS ];
|
||||
static USBTIMER_Timer_TypeDef *head = NULL;
|
||||
#endif
|
||||
|
||||
static uint32_t ticksPrMs, ticksPr1us, ticksPr10us, ticksPr100us;
|
||||
|
||||
#if ( NUM_QTIMERS > 0 )
|
||||
|
||||
static void TimerTick( void );
|
||||
|
||||
void TIMER_IRQHandler( void )
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
flags = TIMER_IntGet( TIMER );
|
||||
|
||||
if ( flags & TIMER_IF_CC0 )
|
||||
{
|
||||
TIMER_IntClear( TIMER, TIMER_IFC_CC0 );
|
||||
TIMER_CompareSet( TIMER, 0, TIMER_CaptureGet( TIMER, 0 ) + ticksPrMs );
|
||||
TimerTick();
|
||||
}
|
||||
}
|
||||
#endif /* ( NUM_QTIMERS > 0 ) */
|
||||
|
||||
static void DelayTicks( uint16_t ticks )
|
||||
{
|
||||
uint16_t startTime;
|
||||
volatile uint16_t now;
|
||||
|
||||
if ( ticks )
|
||||
{
|
||||
startTime = TIMER_CounterGet( TIMER );
|
||||
do
|
||||
{
|
||||
now = TIMER_CounterGet(TIMER);
|
||||
} while ( (uint16_t)( now - startTime ) < ticks );
|
||||
}
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/** @addtogroup USB_COMMON
|
||||
* @{*/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Active wait millisecond delay function. Can also be used inside
|
||||
* interrupt handlers.
|
||||
*
|
||||
* @param[in] msec
|
||||
* Number of milliseconds to wait.
|
||||
******************************************************************************/
|
||||
void USBTIMER_DelayMs( uint32_t msec )
|
||||
{
|
||||
uint64_t totalTicks;
|
||||
|
||||
totalTicks = (uint64_t)ticksPrMs * msec;
|
||||
while ( totalTicks > 20000 )
|
||||
{
|
||||
DelayTicks( 20000 );
|
||||
totalTicks -= 20000;
|
||||
}
|
||||
DelayTicks( (uint16_t)totalTicks );
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Active wait microsecond delay function. Can also be used inside
|
||||
* interrupt handlers.
|
||||
*
|
||||
* @param[in] usec
|
||||
* Number of microseconds to wait.
|
||||
******************************************************************************/
|
||||
void USBTIMER_DelayUs( uint32_t usec )
|
||||
{
|
||||
uint64_t totalTicks;
|
||||
|
||||
totalTicks = (uint64_t)ticksPr1us * usec;
|
||||
if ( totalTicks == 0 )
|
||||
{
|
||||
usec /= 10;
|
||||
totalTicks = (uint64_t)ticksPr10us * usec;
|
||||
|
||||
if ( totalTicks == 0 )
|
||||
{
|
||||
usec /= 10;
|
||||
totalTicks = (uint64_t)ticksPr100us * usec;
|
||||
}
|
||||
}
|
||||
|
||||
while ( totalTicks > 60000 )
|
||||
{
|
||||
DelayTicks( 60000 );
|
||||
totalTicks -= 60000;
|
||||
}
|
||||
DelayTicks( (uint16_t)totalTicks );
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Activate the hardware timer used to pace the 1 millisecond timer system.
|
||||
*
|
||||
* @details
|
||||
* Call this function whenever the HFPERCLK frequency is changed.
|
||||
* This function is initially called by HOST and DEVICE stack xxxx_Init()
|
||||
* functions.
|
||||
******************************************************************************/
|
||||
void USBTIMER_Init( void )
|
||||
{
|
||||
uint32_t freq;
|
||||
TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
|
||||
TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;
|
||||
|
||||
freq = CMU_ClockFreqGet( cmuClock_HFPER );
|
||||
ticksPrMs = ( freq + 500 ) / 1000;
|
||||
ticksPr1us = ( freq + 500000 ) / 1000000;
|
||||
ticksPr10us = ( freq + 50000 ) / 100000;
|
||||
ticksPr100us = ( freq + 5000 ) / 10000;
|
||||
|
||||
timerCCInit.mode = timerCCModeCompare;
|
||||
CMU_ClockEnable( TIMER_CLK, true );
|
||||
TIMER_TopSet( TIMER, 0xFFFF );
|
||||
TIMER_InitCC( TIMER, 0, &timerCCInit );
|
||||
TIMER_Init( TIMER, &timerInit );
|
||||
|
||||
#if ( NUM_QTIMERS > 0 )
|
||||
TIMER_IntClear( TIMER, 0xFFFFFFFF );
|
||||
TIMER_IntEnable( TIMER, TIMER_IEN_CC0 );
|
||||
TIMER_CompareSet( TIMER, 0, TIMER_CounterGet( TIMER ) + ticksPrMs );
|
||||
NVIC_ClearPendingIRQ( TIMER_IRQ );
|
||||
NVIC_EnableIRQ( TIMER_IRQ );
|
||||
#endif /* ( NUM_QTIMERS > 0 ) */
|
||||
}
|
||||
|
||||
#if ( NUM_QTIMERS > 0 ) || defined( DOXY_DOC_ONLY )
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Start a timer.
|
||||
*
|
||||
* @details
|
||||
* If the timer is already running, it will be restarted with new timeout.
|
||||
*
|
||||
* @param[in] id
|
||||
* Timer id (0..).
|
||||
*
|
||||
* @param[in] timeout
|
||||
* Number of milliseconds before timer will elapse.
|
||||
*
|
||||
* @param[in] callback
|
||||
* Function to be called on timer elapse, ref. @ref USBTIMER_Callback_TypeDef.
|
||||
******************************************************************************/
|
||||
void USBTIMER_Start( uint32_t id, uint32_t timeout,
|
||||
USBTIMER_Callback_TypeDef callback )
|
||||
{
|
||||
uint32_t accumulated;
|
||||
USBTIMER_Timer_TypeDef *this, **last;
|
||||
|
||||
INT_Disable();
|
||||
|
||||
if ( timers[ id ].running )
|
||||
{
|
||||
USBTIMER_Stop( id );
|
||||
}
|
||||
|
||||
if ( timeout == 0 )
|
||||
{
|
||||
callback();
|
||||
INT_Enable();
|
||||
return;
|
||||
}
|
||||
|
||||
timers[ id ].running = true;
|
||||
timers[ id ].callback = callback;
|
||||
timers[ id ].next = NULL;
|
||||
|
||||
if ( !head ) /* Queue empty ? */
|
||||
{
|
||||
timers[ id ].timeout = timeout;
|
||||
head = &timers[ id ];
|
||||
}
|
||||
else
|
||||
{
|
||||
this = head;
|
||||
last = &head;
|
||||
accumulated = 0;
|
||||
|
||||
/* Do a sorted insert */
|
||||
while ( this )
|
||||
{
|
||||
if ( timeout < accumulated + this->timeout ) /* Insert before "this" ? */
|
||||
{
|
||||
timers[ id ].timeout = timeout - accumulated;
|
||||
timers[ id ].next = this;
|
||||
*last = &timers[ id ];
|
||||
this->timeout -= timers[ id ].timeout; /* Adjust timeout */
|
||||
break;
|
||||
}
|
||||
else if ( this->next == NULL ) /* At end of queue ? */
|
||||
{
|
||||
timers[ id ].timeout = timeout - accumulated - this->timeout;
|
||||
this->next = &timers[ id ];
|
||||
break;
|
||||
}
|
||||
accumulated += this->timeout;
|
||||
last = &this->next;
|
||||
this = this->next;
|
||||
}
|
||||
}
|
||||
|
||||
INT_Enable();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Stop a timer.
|
||||
*
|
||||
* @param[in] id
|
||||
* Timer id (0..).
|
||||
******************************************************************************/
|
||||
void USBTIMER_Stop( uint32_t id )
|
||||
{
|
||||
USBTIMER_Timer_TypeDef *this, **last;
|
||||
|
||||
INT_Disable();
|
||||
|
||||
if ( head ) /* Queue empty ? */
|
||||
{
|
||||
this = head;
|
||||
last = &head;
|
||||
timers[ id ].running = false;
|
||||
|
||||
while ( this )
|
||||
{
|
||||
if ( this == &timers[ id ] ) /* Correct timer ? */
|
||||
{
|
||||
if ( this->next )
|
||||
{
|
||||
this->next->timeout += timers[ id ].timeout; /* Adjust timeout */
|
||||
}
|
||||
*last = this->next;
|
||||
break;
|
||||
}
|
||||
last = &this->next;
|
||||
this = this->next;
|
||||
}
|
||||
}
|
||||
|
||||
INT_Enable();
|
||||
}
|
||||
#endif /* ( NUM_QTIMERS > 0 ) */
|
||||
|
||||
/** @} (end addtogroup USB_COMMON) */
|
||||
|
||||
#if ( NUM_QTIMERS > 0 )
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
static void TimerTick( void )
|
||||
{
|
||||
USBTIMER_Callback_TypeDef cb;
|
||||
|
||||
INT_Disable();
|
||||
|
||||
if ( head )
|
||||
{
|
||||
head->timeout--;
|
||||
|
||||
while ( head )
|
||||
{
|
||||
if ( head->timeout == 0 )
|
||||
{
|
||||
cb = head->callback;
|
||||
head->running = false;
|
||||
head = head->next;
|
||||
/* The callback may place new items in the queue !!! */
|
||||
if ( cb )
|
||||
{
|
||||
(cb)();
|
||||
}
|
||||
continue; /* There might be more than one timeout pr. tick */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
INT_Enable();
|
||||
}
|
||||
/** @endcond */
|
||||
#endif /* ( NUM_QTIMERS > 0 ) */
|
||||
|
||||
#endif /* defined( USB_DEVICE ) || defined( USB_HOST ) */
|
||||
#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
|
|
@ -49,6 +49,8 @@ typedef enum {
|
|||
#include "USBEndpoints_RZ_A1H.h"
|
||||
#elif defined(TARGET_Maxim)
|
||||
#include "USBEndpoints_Maxim.h"
|
||||
#elif defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32HG_STK3400)
|
||||
#include "USBEndpoints_EFM32.h"
|
||||
#else
|
||||
#error "Unknown target type"
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
#ifndef TARGET_EFM32HG_STK3400
|
||||
# define NUMBER_OF_LOGICAL_ENDPOINTS (6)
|
||||
#else
|
||||
# define NUMBER_OF_LOGICAL_ENDPOINTS (3)
|
||||
#endif
|
||||
|
||||
#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2)
|
||||
#define NUMBER_OF_ENDPOINTS (NUMBER_OF_PHYSICAL_ENDPOINTS + 2) /* Includes EP0 */
|
||||
|
||||
#define EP0OUT (0)
|
||||
#define EP0IN (1)
|
||||
#define EP1OUT (2)
|
||||
#define EP1IN (3)
|
||||
#define EP2OUT (4)
|
||||
#define EP2IN (5)
|
||||
#define EP3OUT (6)
|
||||
#define EP3IN (7)
|
||||
#ifndef TARGET_EFM32HG_STK3400
|
||||
# define EP4OUT (8)
|
||||
# define EP4IN (9)
|
||||
# define EP5OUT (10)
|
||||
# define EP5IN (11)
|
||||
# define EP6OUT (12)
|
||||
# define EP6IN (13)
|
||||
#endif
|
||||
|
||||
#define USB_EP_TO_INDEX(ep) (ep)
|
||||
#define USB_EP_TO_ADDR(ep) (((ep)>>1) | (((ep) & 1 ) ? 0x80 : 0x00))
|
||||
#define USB_ADDR_TO_EP(ep) (((ep)<<1) | (((ep) & 0x80) ? 0x01 : 0x00))
|
||||
|
||||
/* Maximum Packet sizes */
|
||||
|
||||
#define MAX_PACKET_SIZE_EP0 64
|
||||
#define MAX_PACKET_SIZE_EP1 64
|
||||
#define MAX_PACKET_SIZE_EP2 64
|
||||
#define MAX_PACKET_SIZE_EP3 64
|
||||
#ifndef TARGET_EFM32HG_STK3400
|
||||
# define MAX_PACKET_SIZE_EP4 64
|
||||
# define MAX_PACKET_SIZE_EP5 64
|
||||
# define MAX_PACKET_SIZE_EP6 64
|
||||
#endif
|
||||
|
||||
/* Generic endpoints - intended to be portable accross devices */
|
||||
/* and be suitable for simple USB devices. */
|
||||
|
||||
/* Bulk endpoints */
|
||||
#define EPBULK_OUT EP2OUT
|
||||
#define EPBULK_IN EP2IN
|
||||
#define EPBULK_OUT_callback EP2_OUT_callback
|
||||
#define EPBULK_IN_callback EP2_IN_callback
|
||||
/* Interrupt endpoints */
|
||||
#define EPINT_OUT EP1OUT
|
||||
#define EPINT_IN EP1IN
|
||||
#define EPINT_OUT_callback EP1_OUT_callback
|
||||
#define EPINT_IN_callback EP1_IN_callback
|
||||
/* Isochronous endpoints */
|
||||
#define EPISO_OUT EP3OUT
|
||||
#define EPISO_IN EP3IN
|
||||
#define EPISO_OUT_callback EP3_OUT_callback
|
||||
#define EPISO_IN_callback EP3_IN_callback
|
||||
|
||||
#define MAX_PACKET_SIZE_EPBULK 64
|
||||
#define MAX_PACKET_SIZE_EPINT 64
|
||||
#define MAX_PACKET_SIZE_EPISO 1023
|
|
@ -0,0 +1,775 @@
|
|||
/* Copyright 2015 Silicon Labs, http://www.silabs.com
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined TARGET_EFM32GG_STK3700 || \
|
||||
defined TARGET_EFM32LG_STK3600 || \
|
||||
defined TARGET_EFM32WG_STK3800 || \
|
||||
defined TARGET_EFM32HG_STK3400
|
||||
|
||||
#include "USBHAL.h"
|
||||
#include "em_usb.h"
|
||||
#include "em_usbtypes.h"
|
||||
#include "em_usbhal.h"
|
||||
#include "em_usbd.h"
|
||||
|
||||
#include "sleepmodes.h"
|
||||
|
||||
enum USBISRCommand {
|
||||
CMD_HANDLED = 0,
|
||||
CMD_EP0SETUP,
|
||||
CMD_EP0IN,
|
||||
CMD_EP0OUT,
|
||||
CMD_EP_XFER_COMPLETED,
|
||||
CMD_SOF,
|
||||
CMD_BUSRESET,
|
||||
CMD_SUSPEND_STATE_CHANGED,
|
||||
CMD_ENUM_END_MARKER
|
||||
};
|
||||
|
||||
enum IEPStatus {
|
||||
NOT_CONFIGURED = 0,
|
||||
IDLE = 1,
|
||||
READ_PENDING = 2,
|
||||
WRITE_PENDING = 3,
|
||||
READ_COMPLETE = 4,
|
||||
WRITE_COMPLETE = 5,
|
||||
FAILED_INVALID = 6,
|
||||
FAILED_STALLED = 7
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
IEPStatus status;
|
||||
uint32_t byte_count;
|
||||
uint32_t max_packet;
|
||||
USB_XferCompleteCb_TypeDef intern_cb;
|
||||
uint8_t *data_buf;
|
||||
} ep_state_t;
|
||||
|
||||
USBHAL * USBHAL::instance;
|
||||
static uint8_t ep0setupdata[8];
|
||||
static ep_state_t ep_state[NUMBER_OF_ENDPOINTS];
|
||||
#ifdef USB_USE_DYNAMIC_MEMORY
|
||||
static uint8_t ep0in_data_buf[MAX_PACKET_SIZE_EP0] __attribute__ ((aligned (4)));
|
||||
static uint8_t ep0out_data_buf[MAX_PACKET_SIZE_EP0]; // FIXME: does this need to be this big?
|
||||
#else
|
||||
static uint8_t ep_data_buf[NUMBER_OF_ENDPOINTS][64] __attribute__ ((aligned (4)));
|
||||
#endif
|
||||
|
||||
static void run_cmd(USBISRCommand cmd, uint32_t param);
|
||||
static void (*isrptr)() = NULL;
|
||||
static USBISRCommand usb_isrcmd = CMD_HANDLED;
|
||||
static uint32_t usb_isrcmd_param = 0;
|
||||
|
||||
extern "C" void usbhal_allow_em2(bool allow_em2);
|
||||
|
||||
#ifdef DEBUG_USB_API
|
||||
#define TRACE(fmt,...) printf("USB: %s: " fmt "\n", __func__, __VA_ARGS__);
|
||||
#define TRACE_FUNC_IN printf("USB: > %s\n",__func__);
|
||||
#define TRACE_FUNC_IN_P(fmt, ...) printf("USB: > %s: " fmt "\n", __func__, __VA_ARGS__);
|
||||
#else
|
||||
#define TRACE(fmt,...)
|
||||
#define TRACE_FUNC_IN
|
||||
#define TRACE_FUNC_IN_P(fmt, ...)
|
||||
#endif
|
||||
|
||||
static EP_STATUS internEndpointRead(uint8_t ep, uint32_t maxSize);
|
||||
|
||||
static int usbhal_xfer_complete_cb(uint8_t epaddr, USB_Status_TypeDef status,
|
||||
uint32_t xferred, uint32_t remaining);
|
||||
static void usbhal_free_buffers(void);
|
||||
|
||||
/* Internal EP transfer complete callbacks */
|
||||
#define EPCB(n) static int usbhal_xfer_complete_cb_##n(USB_Status_TypeDef status, \
|
||||
uint32_t xferred, uint32_t remaining) { \
|
||||
return usbhal_xfer_complete_cb(n, status, xferred, remaining); \
|
||||
}
|
||||
/* ------^ */
|
||||
EPCB(EP0OUT)
|
||||
EPCB(EP0IN)
|
||||
EPCB(EP1OUT)
|
||||
EPCB(EP1IN)
|
||||
EPCB(EP2OUT)
|
||||
EPCB(EP2IN)
|
||||
EPCB(EP3OUT)
|
||||
EPCB(EP3IN)
|
||||
#ifndef TARGET_EFM32HG_STK3400
|
||||
EPCB(EP4OUT)
|
||||
EPCB(EP4IN)
|
||||
EPCB(EP5OUT)
|
||||
EPCB(EP5IN)
|
||||
EPCB(EP6OUT)
|
||||
EPCB(EP6IN)
|
||||
#endif
|
||||
|
||||
static inline bool is_aligned(const void *pointer, size_t byte_count)
|
||||
{
|
||||
return ((uintptr_t)pointer % byte_count == 0);
|
||||
}
|
||||
|
||||
USBHAL::USBHAL(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
|
||||
isrptr = &USBHAL::_usbisr;
|
||||
|
||||
if (instance) {
|
||||
TRACE("Assert self failed! instance=%p", instance);
|
||||
abort();
|
||||
}
|
||||
instance = this;
|
||||
|
||||
// When USB is active, we can't go below EM1. This block may
|
||||
// be dynamically removed/reinstated to allow deeper sleep.
|
||||
usbhal_allow_em2(false);
|
||||
|
||||
// When in suspend / Vbus off we can go to EM2, but never below
|
||||
// that as long as USB is being used. Despite the name the call here
|
||||
// blocks entering modes _below_ EM2, but allows EM2.
|
||||
blockSleepMode(EM2);
|
||||
|
||||
epCallback[EP0OUT] = NULL;
|
||||
epCallback[EP0IN ] = NULL;
|
||||
epCallback[EP1OUT] = &USBHAL::EP1_OUT_callback;
|
||||
epCallback[EP1IN ] = &USBHAL::EP1_IN_callback;
|
||||
epCallback[EP2OUT] = &USBHAL::EP2_OUT_callback;
|
||||
epCallback[EP2IN ] = &USBHAL::EP2_IN_callback;
|
||||
epCallback[EP3OUT] = &USBHAL::EP3_OUT_callback;
|
||||
epCallback[EP3IN ] = &USBHAL::EP3_IN_callback;
|
||||
#ifndef TARGET_EFM32HG_STK3400
|
||||
epCallback[EP4OUT] = &USBHAL::EP4_OUT_callback;
|
||||
epCallback[EP4IN ] = &USBHAL::EP4_IN_callback;
|
||||
epCallback[EP5OUT] = &USBHAL::EP5_OUT_callback;
|
||||
epCallback[EP5IN ] = &USBHAL::EP5_IN_callback;
|
||||
epCallback[EP6OUT] = &USBHAL::EP6_OUT_callback;
|
||||
epCallback[EP6IN ] = &USBHAL::EP6_IN_callback;
|
||||
#endif
|
||||
|
||||
memset(ep_state, 0, sizeof(ep_state));
|
||||
|
||||
ep_state[EP0OUT].intern_cb = usbhal_xfer_complete_cb_EP0OUT;
|
||||
ep_state[EP0IN ].intern_cb = usbhal_xfer_complete_cb_EP0IN;
|
||||
ep_state[EP1OUT].intern_cb = usbhal_xfer_complete_cb_EP1OUT;
|
||||
ep_state[EP1IN ].intern_cb = usbhal_xfer_complete_cb_EP1IN;
|
||||
ep_state[EP2OUT].intern_cb = usbhal_xfer_complete_cb_EP2OUT;
|
||||
ep_state[EP2IN ].intern_cb = usbhal_xfer_complete_cb_EP2IN;
|
||||
ep_state[EP3OUT].intern_cb = usbhal_xfer_complete_cb_EP3OUT;
|
||||
ep_state[EP3IN ].intern_cb = usbhal_xfer_complete_cb_EP3IN;
|
||||
#ifndef TARGET_EFM32HG_STK3400
|
||||
ep_state[EP4OUT].intern_cb = usbhal_xfer_complete_cb_EP4OUT;
|
||||
ep_state[EP4IN ].intern_cb = usbhal_xfer_complete_cb_EP4IN;
|
||||
ep_state[EP5OUT].intern_cb = usbhal_xfer_complete_cb_EP5OUT;
|
||||
ep_state[EP5IN ].intern_cb = usbhal_xfer_complete_cb_EP5IN;
|
||||
ep_state[EP6OUT].intern_cb = usbhal_xfer_complete_cb_EP6OUT;
|
||||
ep_state[EP6IN ].intern_cb = usbhal_xfer_complete_cb_EP6IN;
|
||||
#endif
|
||||
|
||||
#ifdef USB_USE_DYNAMIC_MEMORY
|
||||
ep_state[EP0OUT].data_buf = ep0out_data_buf;
|
||||
ep_state[EP0IN].data_buf = ep0in_data_buf;
|
||||
#else
|
||||
for (int i=0 ; i<NUMBER_OF_ENDPOINTS ; i++) {
|
||||
ep_state[i].data_buf = ep_data_buf[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
USBHAL::~USBHAL(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
USBD_AbortAllTransfers();
|
||||
USBD_Disconnect();
|
||||
usbhal_free_buffers();
|
||||
|
||||
usbhal_allow_em2(true);
|
||||
unblockSleepMode(EM2);
|
||||
}
|
||||
|
||||
extern "C" void usbhal_allow_em2(bool allow_em2)
|
||||
{
|
||||
if (allow_em2) {
|
||||
// unblockSleepMode is safe to call even if we would unblock
|
||||
// an already unblocked mode, so no checks here.
|
||||
unblockSleepMode(EM1);
|
||||
} else {
|
||||
blockSleepMode(EM1);
|
||||
}
|
||||
}
|
||||
|
||||
static void usbhal_reset_cb(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
run_cmd(CMD_BUSRESET, 0);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_USB_API
|
||||
static const char *usbstate[] = { "NONE", "ATTACHED", "POWERED", "DEFAULT",
|
||||
"ADDRESSED", "CONFIGURED", "SUSPENDED", "???" };
|
||||
#endif
|
||||
|
||||
static void usbhal_state_change_cb(USBD_State_TypeDef oldState,
|
||||
USBD_State_TypeDef newState)
|
||||
{
|
||||
TRACE("state changed %s -> %s", usbstate[oldState], usbstate[newState]);
|
||||
|
||||
if (oldState == USBD_STATE_SUSPENDED) {
|
||||
run_cmd(CMD_SUSPEND_STATE_CHANGED, 0);
|
||||
}
|
||||
|
||||
if (newState == USBD_STATE_SUSPENDED) {
|
||||
run_cmd(CMD_SUSPEND_STATE_CHANGED, 1);
|
||||
}
|
||||
|
||||
// Should call connectStateChanged from here as well but there is
|
||||
// no documentation on when to actually do so. (And the implementation
|
||||
// in USBDevice.cpp is a stub)
|
||||
|
||||
// HACK! Since connectStateChanged is not used, indicate the loss
|
||||
// off connection by reporting a bus reset. This causes USBDevice
|
||||
// to realise that at least it's not in CONFIGURED anymore, and
|
||||
// stop trying to read/write in a busyloop.
|
||||
if (newState == USBD_STATE_NONE) {
|
||||
run_cmd(CMD_BUSRESET, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int usbhal_setupcmd_cb(const USB_Setup_TypeDef *setup)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
if (!setup) {
|
||||
EFM_ASSERT(false);
|
||||
return USB_STATUS_REQ_ERR;
|
||||
}
|
||||
|
||||
memcpy(ep0setupdata, setup, 8);
|
||||
run_cmd(CMD_EP0SETUP, 0);
|
||||
|
||||
return USB_STATUS_OK;
|
||||
}
|
||||
|
||||
static void usbhal_sof_cb(uint16_t frameNum)
|
||||
{
|
||||
run_cmd(CMD_SOF, frameNum);
|
||||
}
|
||||
|
||||
static void usbhal_free_buffers(void)
|
||||
{
|
||||
#ifdef USB_USE_DYNAMIC_MEMORY
|
||||
TRACE_FUNC_IN;
|
||||
|
||||
for (int i=EP1OUT ; i<NUMBER_OF_ENDPOINTS ; i++ ) {
|
||||
if (ep_state[i].data_buf) {
|
||||
free(ep_state[i].data_buf);
|
||||
ep_state[i].data_buf = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void USBHAL::connect(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
|
||||
// Init datastructures must be static - driver will use these even after the init function exits!
|
||||
|
||||
static const uint8_t buffer_multiplier[] = { 1 }; // Mult 1 for control EP
|
||||
static const USBD_Callbacks_TypeDef usbd_callbacks = {
|
||||
.usbReset = usbhal_reset_cb,
|
||||
.usbStateChange = usbhal_state_change_cb,
|
||||
.setupCmd = usbhal_setupcmd_cb,
|
||||
.isSelfPowered = NULL,
|
||||
.sofInt = usbhal_sof_cb
|
||||
};
|
||||
|
||||
USBD_Init_TypeDef initdata = {
|
||||
.deviceDescriptor = NULL,
|
||||
.configDescriptor = NULL,
|
||||
.stringDescriptors = NULL,
|
||||
.numberOfStrings = 0,
|
||||
.bufferingMultiplier = buffer_multiplier,
|
||||
.callbacks = &usbd_callbacks,
|
||||
.reserved = 0
|
||||
};
|
||||
|
||||
int ret = USBD_Init(&initdata);
|
||||
|
||||
TRACE("init = %d, devicedesc = %lx, configdesc = %lx", ret,
|
||||
(uint32_t) initdata.deviceDescriptor,
|
||||
(uint32_t) initdata.configDescriptor);
|
||||
|
||||
EFM_ASSERT(ret == USB_STATUS_OK);
|
||||
}
|
||||
|
||||
void USBHAL::disconnect(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
USBD_Disconnect();
|
||||
}
|
||||
|
||||
void USBHAL::configureDevice(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
USBD_SetUsbState(USBD_STATE_CONFIGURED);
|
||||
}
|
||||
|
||||
void USBHAL::unconfigureDevice(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
USBD_SetUsbState(USBD_STATE_DEFAULT);
|
||||
usbhal_free_buffers();
|
||||
}
|
||||
|
||||
void USBHAL::setAddress(uint8_t address)
|
||||
{
|
||||
TRACE_FUNC_IN_P("addr 0x%x", (unsigned)address);
|
||||
USBD_SetAddress(address);
|
||||
}
|
||||
|
||||
void USBHAL::remoteWakeup(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
USBD_RemoteWakeup();
|
||||
}
|
||||
|
||||
void USBHAL::EP0setup(uint8_t *buffer)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
EFM_ASSERT(buffer);
|
||||
if (buffer) {
|
||||
memcpy(buffer, ep0setupdata, 8);
|
||||
}
|
||||
}
|
||||
|
||||
void USBHAL::EP0read(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
(void)internEndpointRead(0, MAX_PACKET_SIZE_EP0);
|
||||
}
|
||||
|
||||
void USBHAL::EP0readStage(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
// Not needed
|
||||
}
|
||||
|
||||
uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
EFM_ASSERT(buffer);
|
||||
|
||||
uint32_t read = 0;
|
||||
endpointReadResult(0, buffer, &read);
|
||||
return read;
|
||||
}
|
||||
|
||||
static int usbhal_xfer_complete_cb(uint8_t ep, USB_Status_TypeDef status,
|
||||
uint32_t xferred, uint32_t remaining)
|
||||
{
|
||||
TRACE_FUNC_IN_P("ep 0x%x, status %u, xferred %lu, rem %lu",
|
||||
ep, status, xferred, remaining);
|
||||
|
||||
if (ep >= NUMBER_OF_ENDPOINTS) {
|
||||
EFM_ASSERT(false);
|
||||
return USB_STATUS_REQ_ERR;
|
||||
}
|
||||
|
||||
switch (ep) {
|
||||
case EP0OUT:
|
||||
if (ep_state[EP0OUT].status == READ_PENDING) {
|
||||
ep_state[EP0OUT].status = READ_COMPLETE;
|
||||
ep_state[EP0OUT].byte_count = xferred;
|
||||
// drop zlp
|
||||
if (xferred == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
run_cmd(CMD_EP0OUT, 0);
|
||||
break;
|
||||
|
||||
case EP0IN:
|
||||
run_cmd(CMD_EP0IN, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
bool write = ep & 1;
|
||||
|
||||
if (status == USB_STATUS_OK) {
|
||||
if (!write && ep_state[ep].status == READ_PENDING) {
|
||||
ep_state[ep].status = READ_COMPLETE;
|
||||
ep_state[ep].byte_count = xferred;
|
||||
} else if (write && ep_state[ep].status == WRITE_PENDING) {
|
||||
ep_state[ep].status = WRITE_COMPLETE;
|
||||
} else {
|
||||
ep_state[ep].status = FAILED_INVALID;
|
||||
}
|
||||
} else {
|
||||
ep_state[ep].status = FAILED_INVALID;
|
||||
}
|
||||
|
||||
if (ep_state[ep].status != FAILED_INVALID) {
|
||||
run_cmd(CMD_EP_XFER_COMPLETED, ep);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return USB_STATUS_OK;
|
||||
}
|
||||
|
||||
void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
|
||||
{
|
||||
//TRACE_FUNC_IN_P("buffer %lx, size %lu", (uint32_t) buffer, size);
|
||||
|
||||
int ret;
|
||||
USB_XferCompleteCb_TypeDef cb = ep_state[EP0IN].intern_cb;
|
||||
|
||||
EFM_ASSERT((buffer != NULL) || (size == 0));
|
||||
EFM_ASSERT(size <= MAX_PACKET_SIZE_EP0);
|
||||
|
||||
if (!buffer || size == 0) {
|
||||
// No callback after writing EP0 ZLP
|
||||
cb = NULL;
|
||||
}
|
||||
|
||||
if (buffer && !is_aligned(buffer,4)) {
|
||||
// Copy unaligned data to write-buffer before USBD_Write
|
||||
memcpy(ep_state[EP0IN].data_buf, buffer, size);
|
||||
ret = USBD_Write(0, ep_state[EP0IN].data_buf, size, cb);
|
||||
} else {
|
||||
ret = USBD_Write(0, buffer, size, cb);
|
||||
}
|
||||
|
||||
if (ret != USB_STATUS_OK) {
|
||||
TRACE("FAILED - ret %d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
void USBHAL::EP0stall(void)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
USBD_StallEp0();
|
||||
}
|
||||
|
||||
static EP_STATUS internEndpointRead(uint8_t ep, uint32_t maxSize)
|
||||
{
|
||||
//TRACE_FUNC_IN_P("endpoint 0x%x, size %ld, cb %d", (unsigned)ep, maxSize, useCallback);
|
||||
|
||||
if (ep >= NUMBER_OF_ENDPOINTS) {
|
||||
EFM_ASSERT(false);
|
||||
return EP_INVALID;
|
||||
}
|
||||
|
||||
ep_state[ep].status = READ_PENDING;
|
||||
|
||||
int ret = USBD_Read(USB_EP_TO_ADDR(ep), ep_state[ep].data_buf, maxSize,
|
||||
ep_state[ep].intern_cb);
|
||||
|
||||
if (ret == USB_STATUS_OK) {
|
||||
return EP_PENDING;
|
||||
} else {
|
||||
TRACE("FAILED - ret %d", ret);
|
||||
|
||||
if (ret == USB_STATUS_EP_STALLED) {
|
||||
return EP_STALLED;
|
||||
} else {
|
||||
return EP_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize)
|
||||
{
|
||||
return internEndpointRead(endpoint, maximumSize);
|
||||
}
|
||||
|
||||
EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *data, uint32_t *bytesRead)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
|
||||
if (endpoint >= NUMBER_OF_ENDPOINTS) {
|
||||
EFM_ASSERT(false);
|
||||
return EP_INVALID;
|
||||
}
|
||||
|
||||
EFM_ASSERT(data);
|
||||
EFM_ASSERT(bytesRead);
|
||||
if (!data || !bytesRead) {
|
||||
return EP_INVALID;
|
||||
}
|
||||
|
||||
switch (ep_state[endpoint].status) {
|
||||
case READ_PENDING:
|
||||
return EP_PENDING;
|
||||
|
||||
case READ_COMPLETE:
|
||||
memcpy(data, ep_state[endpoint].data_buf, ep_state[endpoint].byte_count);
|
||||
*bytesRead = ep_state[endpoint].byte_count;
|
||||
ep_state[endpoint].status = IDLE;
|
||||
return EP_COMPLETED;
|
||||
|
||||
case FAILED_STALLED:
|
||||
ep_state[endpoint].status = IDLE;
|
||||
return EP_STALLED;
|
||||
|
||||
default:
|
||||
ep_state[endpoint].status = IDLE;
|
||||
return EP_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
|
||||
{
|
||||
TRACE_FUNC_IN_P("endpoint 0x%x, data 0x%lx, size %lu", (unsigned )endpoint, (uint32_t)data, size);
|
||||
|
||||
EFM_ASSERT(endpoint < NUMBER_OF_ENDPOINTS);
|
||||
EFM_ASSERT(endpoint > EP0IN);
|
||||
EFM_ASSERT(size <= ep_state[endpoint].max_packet);
|
||||
EFM_ASSERT(data);
|
||||
|
||||
uint8_t ep = USB_EP_TO_INDEX(endpoint);
|
||||
|
||||
if (endpoint >= NUMBER_OF_ENDPOINTS || endpoint <= EP0IN) {
|
||||
return EP_INVALID;
|
||||
}
|
||||
|
||||
if (size > ep_state[endpoint].max_packet) {
|
||||
return EP_INVALID;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return EP_INVALID;
|
||||
}
|
||||
|
||||
memcpy(ep_state[ep].data_buf, data, size);
|
||||
|
||||
ep_state[ep].status = WRITE_PENDING;
|
||||
int ret = USBD_Write(USB_EP_TO_ADDR(endpoint), ep_state[ep].data_buf, size, ep_state[ep].intern_cb);
|
||||
|
||||
if (ret == USB_STATUS_EP_STALLED) {
|
||||
ep_state[ep].status = IDLE;
|
||||
return EP_STALLED;
|
||||
} else if (ret != USB_STATUS_OK) {
|
||||
ep_state[ep].status = IDLE;
|
||||
return EP_INVALID;
|
||||
}
|
||||
|
||||
return EP_PENDING;
|
||||
}
|
||||
|
||||
EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
|
||||
{
|
||||
if (endpoint >= NUMBER_OF_ENDPOINTS) {
|
||||
EFM_ASSERT(false);
|
||||
return EP_INVALID;
|
||||
}
|
||||
|
||||
switch (ep_state[endpoint].status) {
|
||||
case WRITE_PENDING:
|
||||
return EP_PENDING;
|
||||
|
||||
case WRITE_COMPLETE:
|
||||
ep_state[endpoint].status = IDLE;
|
||||
return EP_COMPLETED;
|
||||
|
||||
case FAILED_STALLED:
|
||||
ep_state[endpoint].status = IDLE;
|
||||
return EP_STALLED;
|
||||
|
||||
default:
|
||||
ep_state[endpoint].status = IDLE;
|
||||
return EP_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
void USBHAL::stallEndpoint(uint8_t endpoint)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
|
||||
EFM_ASSERT(endpoint < NUMBER_OF_ENDPOINTS);
|
||||
EFM_ASSERT((endpoint != EP0OUT) && (endpoint != EP0IN));
|
||||
|
||||
USBD_StallEp(USB_EP_TO_ADDR(endpoint));
|
||||
}
|
||||
|
||||
void USBHAL::unstallEndpoint(uint8_t endpoint)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
|
||||
EFM_ASSERT(endpoint < NUMBER_OF_ENDPOINTS);
|
||||
EFM_ASSERT((endpoint != EP0OUT) && (endpoint != EP0IN));
|
||||
|
||||
USBD_UnStallEp(USB_EP_TO_ADDR(endpoint));
|
||||
}
|
||||
|
||||
bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options)
|
||||
{
|
||||
TRACE_FUNC_IN_P("endpoint %d, packetsize %ld, options 0x%lx", endpoint,
|
||||
maxPacket, options);
|
||||
|
||||
int mult = 1; // RX/TX buffer size multiplier
|
||||
int type = USB_EPTYPE_INTR;
|
||||
|
||||
if (endpoint >= NUMBER_OF_ENDPOINTS) {
|
||||
EFM_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (endpoint == EP0IN || endpoint == EP0OUT) {
|
||||
EFM_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
ep_state[endpoint].max_packet = 0;
|
||||
|
||||
if (endpoint == EPISO_OUT || endpoint == EPISO_IN) {
|
||||
if (maxPacket > MAX_PACKET_SIZE_EPISO) {
|
||||
EFM_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
} else if ((maxPacket > MAX_PACKET_SIZE_EPBULK) || (maxPacket > MAX_PACKET_SIZE_EPINT)) {
|
||||
EFM_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// USBDevice performs a read right after creating the endpoints,
|
||||
// before calling configureDevice. The read will fail since
|
||||
// at that point the device state is still ADDRESSED. Workaround
|
||||
// is to force configured state here.
|
||||
//
|
||||
// This relies on USBDevice to not call realiseEndpoint unless
|
||||
// it is transitioning to the CONFIGURED state.
|
||||
USBD_SetUsbState(USBD_STATE_CONFIGURED);
|
||||
|
||||
// Why doesn't this function have a type param? This is silly...
|
||||
switch (endpoint) {
|
||||
case EPBULK_OUT:
|
||||
case EPBULK_IN:
|
||||
type = USB_EPTYPE_BULK;
|
||||
mult = 2;
|
||||
break;
|
||||
case EPINT_OUT:
|
||||
case EPINT_IN:
|
||||
type = USB_EPTYPE_INTR;
|
||||
mult = 1;
|
||||
break;
|
||||
case EPISO_OUT:
|
||||
case EPISO_IN:
|
||||
type = USB_EPTYPE_ISOC;
|
||||
mult = 2; // ?
|
||||
break;
|
||||
}
|
||||
|
||||
// Some options force the endpoint to a specific type
|
||||
if( options & ISOCHRONOUS ) {
|
||||
type = USB_EPTYPE_ISOC;
|
||||
mult = 2; // ?
|
||||
} else if ( options & RATE_FEEDBACK_MODE ) {
|
||||
// No support for whatever rate feedback is, but for interrupt only
|
||||
type = USB_EPTYPE_INTR;
|
||||
mult = 1;
|
||||
}
|
||||
|
||||
#ifdef USB_USE_DYNAMIC_MEMORY
|
||||
if (ep_state[endpoint].data_buf) {
|
||||
free(ep_state[endpoint].data_buf);
|
||||
}
|
||||
|
||||
ep_state[endpoint].data_buf = (uint8_t *)malloc(maxPacket);
|
||||
|
||||
if (!ep_state[endpoint].data_buf) {
|
||||
EFM_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ret = USBD_AddEndpoint(USB_EP_TO_ADDR(endpoint), type, maxPacket, mult);
|
||||
|
||||
if (ret == USB_STATUS_OK) {
|
||||
ep_state[endpoint].status = IDLE;
|
||||
ep_state[endpoint].max_packet = maxPacket;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool USBHAL::getEndpointStallState(unsigned char endpoint)
|
||||
{
|
||||
TRACE_FUNC_IN;
|
||||
if (endpoint >= NUMBER_OF_ENDPOINTS) {
|
||||
EFM_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
return USBD_EpIsStalled(USB_EP_TO_ADDR(endpoint));
|
||||
}
|
||||
|
||||
static void run_cmd(USBISRCommand cmd, uint32_t param)
|
||||
{
|
||||
if (usb_isrcmd != CMD_HANDLED || cmd >= CMD_ENUM_END_MARKER) {
|
||||
EFM_ASSERT(false);
|
||||
abort();
|
||||
}
|
||||
|
||||
usb_isrcmd = cmd;
|
||||
usb_isrcmd_param = param;
|
||||
isrptr();
|
||||
}
|
||||
|
||||
void USBHAL::_usbisr(void)
|
||||
{
|
||||
EFM_ASSERT(instance);
|
||||
instance->usbisr();
|
||||
}
|
||||
|
||||
void USBHAL::usbisr(void)
|
||||
{
|
||||
//TRACE_FUNC_IN;
|
||||
|
||||
// This "ISR" is used just to route callbacks from SiL USB driver
|
||||
// callback context (which can not call protected/private USBHAL
|
||||
// methods), to the actual USBHAL.
|
||||
|
||||
EFM_ASSERT(usb_isrcmd != CMD_HANDLED);
|
||||
switch (usb_isrcmd) {
|
||||
case CMD_EP0SETUP:
|
||||
this->EP0setupCallback();
|
||||
break;
|
||||
case CMD_EP0IN:
|
||||
this->EP0in();
|
||||
break;
|
||||
case CMD_EP0OUT:
|
||||
this->EP0out();
|
||||
break;
|
||||
case CMD_BUSRESET:
|
||||
this->busReset();
|
||||
break;
|
||||
case CMD_EP_XFER_COMPLETED:
|
||||
if (epCallback[usb_isrcmd_param] && instance) {
|
||||
(instance->*(epCallback[usb_isrcmd_param]))();
|
||||
}
|
||||
break;
|
||||
case CMD_SOF:
|
||||
this->SOF(usb_isrcmd_param);
|
||||
break;
|
||||
case CMD_SUSPEND_STATE_CHANGED:
|
||||
this->suspendStateChanged(usb_isrcmd_param);
|
||||
break;
|
||||
default:
|
||||
EFM_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
usb_isrcmd = CMD_HANDLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
// End of file
|
|
@ -1,5 +1,5 @@
|
|||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2009 */
|
||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2012 */
|
||||
/* (SBCS code pages) */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 437 U.S. (OEM)
|
||||
|
@ -31,463 +31,463 @@
|
|||
#if _CODE_PAGE == 437
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 720
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
|
||||
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
|
||||
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
|
||||
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
|
||||
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 737
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
|
||||
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
|
||||
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
|
||||
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
|
||||
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
|
||||
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
|
||||
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
|
||||
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
|
||||
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 775
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
|
||||
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
|
||||
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
|
||||
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
|
||||
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
|
||||
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
|
||||
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
|
||||
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
|
||||
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
|
||||
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
|
||||
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 850
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 852
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
|
||||
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
|
||||
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
|
||||
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
|
||||
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
|
||||
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
|
||||
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
|
||||
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
|
||||
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
|
||||
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
|
||||
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 855
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
|
||||
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
|
||||
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
|
||||
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
|
||||
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
|
||||
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
|
||||
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
|
||||
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
|
||||
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
|
||||
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
|
||||
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
|
||||
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
|
||||
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
|
||||
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
|
||||
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 857
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
|
||||
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
|
||||
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 858
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 862
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 866
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 874
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
|
||||
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
|
||||
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
|
||||
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
|
||||
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
|
||||
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
|
||||
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
|
||||
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
|
||||
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
|
||||
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
|
||||
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
|
||||
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
|
||||
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
|
||||
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
|
||||
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
|
||||
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
|
||||
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
|
||||
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
|
||||
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
|
||||
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
|
||||
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
|
||||
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
|
||||
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1250
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
|
||||
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
|
||||
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
|
||||
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
|
||||
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
|
||||
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
|
||||
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
|
||||
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
|
||||
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
|
||||
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
|
||||
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
|
||||
const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
|
||||
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
|
||||
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
|
||||
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
|
||||
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
|
||||
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
|
||||
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
|
||||
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
|
||||
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
|
||||
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
|
||||
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1251
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
|
||||
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
|
||||
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
|
||||
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
|
||||
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
|
||||
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
|
||||
const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
|
||||
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
|
||||
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
|
||||
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
|
||||
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
|
||||
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1252
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
|
||||
const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1253
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
|
||||
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
|
||||
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
|
||||
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
|
||||
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
|
||||
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
|
||||
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
|
||||
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
|
||||
const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
|
||||
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
|
||||
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
|
||||
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
|
||||
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
|
||||
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
|
||||
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
|
||||
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1254
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
|
||||
const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1255
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
|
||||
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
|
||||
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
|
||||
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
|
||||
const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
|
||||
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
|
||||
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
|
||||
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1256
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
|
||||
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
|
||||
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
|
||||
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
|
||||
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
|
||||
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
|
||||
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
|
||||
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
|
||||
}
|
||||
const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
|
||||
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
|
||||
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
|
||||
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
|
||||
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
|
||||
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
|
||||
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
|
||||
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1257
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
|
||||
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
|
||||
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
|
||||
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
|
||||
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
|
||||
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
|
||||
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
|
||||
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
|
||||
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
|
||||
const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
|
||||
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
|
||||
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
|
||||
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
|
||||
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
|
||||
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
|
||||
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
|
||||
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
|
||||
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1258
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
|
||||
const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -498,43 +498,44 @@ const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
|
|||
#endif
|
||||
|
||||
|
||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||
WCHAR src, /* Character code to be converted */
|
||||
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
|
||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||
WCHAR chr, /* Character code to be converted */
|
||||
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
|
||||
)
|
||||
{
|
||||
WCHAR c;
|
||||
WCHAR c;
|
||||
|
||||
|
||||
if (src < 0x80) { /* ASCII */
|
||||
c = src;
|
||||
if (chr < 0x80) { /* ASCII */
|
||||
c = chr;
|
||||
|
||||
} else {
|
||||
if (dir) { /* OEMCP to Unicode */
|
||||
c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
|
||||
} else {
|
||||
if (dir) { /* OEMCP to Unicode */
|
||||
c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
|
||||
|
||||
} else { /* Unicode to OEMCP */
|
||||
for (c = 0; c < 0x80; c++) {
|
||||
if (src == Tbl[c]) break;
|
||||
}
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
} else { /* Unicode to OEMCP */
|
||||
for (c = 0; c < 0x80; c++) {
|
||||
if (chr == Tbl[c]) break;
|
||||
}
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
WCHAR ff_wtoupper ( /* Upper converted character */
|
||||
WCHAR chr /* Input character */
|
||||
WCHAR ff_wtoupper ( /* Upper converted character */
|
||||
WCHAR chr /* Input character */
|
||||
)
|
||||
{
|
||||
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
|
||||
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
|
||||
int i;
|
||||
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
|
||||
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
|
||||
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
|
||||
|
||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,30 +13,30 @@
|
|||
using namespace mbed;
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE drv /* Physical drive nmuber (0..) */
|
||||
BYTE pdrv /* Physical drive number (0..) */
|
||||
)
|
||||
{
|
||||
debug_if(FFS_DBG, "disk_initialize on drv [%d]\n", drv);
|
||||
return (DSTATUS)FATFileSystem::_ffs[drv]->disk_initialize();
|
||||
debug_if(FFS_DBG, "disk_initialize on pdrv [%d]\n", pdrv);
|
||||
return (DSTATUS)FATFileSystem::_ffs[pdrv]->disk_initialize();
|
||||
}
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE drv /* Physical drive nmuber (0..) */
|
||||
BYTE pdrv /* Physical drive number (0..) */
|
||||
)
|
||||
{
|
||||
debug_if(FFS_DBG, "disk_status on drv [%d]\n", drv);
|
||||
return (DSTATUS)FATFileSystem::_ffs[drv]->disk_status();
|
||||
debug_if(FFS_DBG, "disk_status on pdrv [%d]\n", pdrv);
|
||||
return (DSTATUS)FATFileSystem::_ffs[pdrv]->disk_status();
|
||||
}
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE drv, /* Physical drive nmuber (0..) */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
BYTE pdrv, /* Physical drive number (0..) */
|
||||
BYTE* buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector address (LBA) */
|
||||
BYTE count /* Number of sectors to read (1..255) */
|
||||
UINT count /* Number of sectors to read (1..) */
|
||||
)
|
||||
{
|
||||
debug_if(FFS_DBG, "disk_read(sector %d, count %d) on drv [%d]\n", sector, count, drv);
|
||||
if (FATFileSystem::_ffs[drv]->disk_read((uint8_t*)buff, sector, count))
|
||||
debug_if(FFS_DBG, "disk_read(sector %d, count %d) on pdrv [%d]\n", sector, count, pdrv);
|
||||
if (FATFileSystem::_ffs[pdrv]->disk_read((uint8_t*)buff, sector, count))
|
||||
return RES_PARERR;
|
||||
else
|
||||
return RES_OK;
|
||||
|
@ -44,14 +44,14 @@ DRESULT disk_read (
|
|||
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (
|
||||
BYTE drv, /* Physical drive nmuber (0..) */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
BYTE pdrv, /* Physical drive number (0..) */
|
||||
const BYTE* buff, /* Data to be written */
|
||||
DWORD sector, /* Sector address (LBA) */
|
||||
BYTE count /* Number of sectors to write (1..255) */
|
||||
UINT count /* Number of sectors to write (1..) */
|
||||
)
|
||||
{
|
||||
debug_if(FFS_DBG, "disk_write(sector %d, count %d) on drv [%d]\n", sector, count, drv);
|
||||
if (FATFileSystem::_ffs[drv]->disk_write((uint8_t*)buff, sector, count))
|
||||
debug_if(FFS_DBG, "disk_write(sector %d, count %d) on pdrv [%d]\n", sector, count, pdrv);
|
||||
if (FATFileSystem::_ffs[pdrv]->disk_write((uint8_t*)buff, sector, count))
|
||||
return RES_PARERR;
|
||||
else
|
||||
return RES_OK;
|
||||
|
@ -59,25 +59,25 @@ DRESULT disk_write (
|
|||
#endif /* _READONLY */
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE drv, /* Physical drive nmuber (0..) */
|
||||
BYTE ctrl, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
BYTE pdrv, /* Physical drive number (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void* buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
debug_if(FFS_DBG, "disk_ioctl(%d)\n", ctrl);
|
||||
switch(ctrl) {
|
||||
debug_if(FFS_DBG, "disk_ioctl(%d)\n", cmd);
|
||||
switch(cmd) {
|
||||
case CTRL_SYNC:
|
||||
if(FATFileSystem::_ffs[drv] == NULL) {
|
||||
if(FATFileSystem::_ffs[pdrv] == NULL) {
|
||||
return RES_NOTRDY;
|
||||
} else if(FATFileSystem::_ffs[drv]->disk_sync()) {
|
||||
} else if(FATFileSystem::_ffs[pdrv]->disk_sync()) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_OK;
|
||||
case GET_SECTOR_COUNT:
|
||||
if(FATFileSystem::_ffs[drv] == NULL) {
|
||||
if(FATFileSystem::_ffs[pdrv] == NULL) {
|
||||
return RES_NOTRDY;
|
||||
} else {
|
||||
DWORD res = FATFileSystem::_ffs[drv]->disk_sectors();
|
||||
DWORD res = FATFileSystem::_ffs[pdrv]->disk_sectors();
|
||||
if(res > 0) {
|
||||
*((DWORD*)buff) = res; // minimum allowed
|
||||
return RES_OK;
|
||||
|
|
|
@ -1,76 +1,81 @@
|
|||
//-----------------------------------------------------------------------
|
||||
// Low level disk interface modlue include file
|
||||
//-----------------------------------------------------------------------
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#define _READONLY 0 // 1: Remove write functions
|
||||
#define _USE_IOCTL 1 // 1: Use disk_ioctl fucntion
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _USE_WRITE 1 /* 1: Enable disk_write function */
|
||||
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
// Status of Disk Functions
|
||||
typedef BYTE DSTATUS;
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
// Results of Disk Functions
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, // 0: Successful
|
||||
RES_ERROR, // 1: R/W Error
|
||||
RES_WRPRT, // 2: Write Protected
|
||||
RES_NOTRDY, // 3: Not Ready
|
||||
RES_PARERR // 4: Invalid Parameter
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
// Prototypes for disk control functions
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
int assign_drives (int, int);
|
||||
DSTATUS disk_initialize (BYTE);
|
||||
DSTATUS disk_status (BYTE);
|
||||
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
DRESULT disk_ioctl (BYTE, BYTE, void*);
|
||||
|
||||
|
||||
|
||||
// Disk Status Bits (DSTATUS)
|
||||
#define STA_NOINIT 0x01 // Drive not initialized
|
||||
#define STA_NODISK 0x02 // No medium in the drive
|
||||
#define STA_PROTECT 0x04 // Write protected
|
||||
|
||||
|
||||
// Command code for disk_ioctrl fucntion
|
||||
|
||||
// Generic command (defined for FatFs)
|
||||
#define CTRL_SYNC 0 // Flush disk cache (for write functions)
|
||||
#define GET_SECTOR_COUNT 1 // Get media size (for only f_mkfs())
|
||||
#define GET_SECTOR_SIZE 2 // Get sector size (for multiple sector size (_MAX_SS >= 1024))
|
||||
#define GET_BLOCK_SIZE 3 // Get erase block size (for only f_mkfs())
|
||||
#define CTRL_ERASE_SECTOR 4 // Force erased a block of sectors (for only _USE_ERASE)
|
||||
|
||||
// Generic command
|
||||
#define CTRL_POWER 5 // Get/Set power status
|
||||
#define CTRL_LOCK 6 // Lock/Unlock media removal
|
||||
#define CTRL_EJECT 7 // Eject media
|
||||
|
||||
// MMC/SDC specific ioctl command
|
||||
#define MMC_GET_TYPE 10 // Get card type
|
||||
#define MMC_GET_CSD 11 // Get CSD
|
||||
#define MMC_GET_CID 12 // Get CID
|
||||
#define MMC_GET_OCR 13 // Get OCR
|
||||
#define MMC_GET_SDSTAT 14 // Get SD status
|
||||
|
||||
// ATA/CF specific ioctl command
|
||||
#define ATA_GET_REV 20 // Get F/W revision
|
||||
#define ATA_GET_MODEL 21 // Get model name
|
||||
#define ATA_GET_SN 22 // Get serial number
|
||||
|
||||
// NAND specific ioctl command
|
||||
#define NAND_FORMAT 30 // Create physical format
|
||||
|
||||
|
||||
#define _DISKIO
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,29 +1,30 @@
|
|||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.09a (C)ChaN, 2012
|
||||
/ FatFs - FAT file system module include R0.11 (C)ChaN, 2015
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following terms.
|
||||
/ FatFs module is a free software that opened under license policy of
|
||||
/ following conditions.
|
||||
/
|
||||
/ Copyright (C) 2012, ChaN, all right reserved.
|
||||
/ Copyright (C) 2015, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 4004 /* Revision ID */
|
||||
#define _FATFS 32020 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
@ -32,18 +33,18 @@ extern "C" {
|
|||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
|
||||
#define LD2PT(vol) 0 /* Always mounts the 1st partition or in SFD */
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
|
||||
#define LD2PT(vol) 0 /* Find first valid partition or in SFD */
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -51,9 +52,9 @@ extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
|||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#if !_USE_LFN
|
||||
#error _LFN_UNICODE must be 0 in non-LFN cfg.
|
||||
#error _LFN_UNICODE must be 0 at non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
|
@ -61,7 +62,7 @@ typedef WCHAR TCHAR;
|
|||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
|
||||
#else /* ANSI/OEM string */
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
|
@ -75,35 +76,35 @@ typedef char TCHAR;
|
|||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
BYTE n_fats; /* Number of FAT copies (1,2) */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
#if _MAX_SS != 512
|
||||
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
BYTE n_fats; /* Number of FAT copies (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
#if _MAX_SS != _MIN_SS
|
||||
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector (FAT32) */
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
#endif
|
||||
#if _FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
|
||||
DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD volbase; /* Volume start sector */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
@ -111,62 +112,68 @@ typedef struct {
|
|||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the related file system object */
|
||||
WORD id; /* File system mount ID of the related file system object */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE pad1;
|
||||
DWORD fptr; /* File read/write pointer (0ed on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD sclust; /* File data start cluster (0:no data cluster, always 0 when fsize is 0) */
|
||||
DWORD clust; /* Current cluster of fpter */
|
||||
DWORD dsect; /* Current data sector of fpter */
|
||||
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */
|
||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
||||
BYTE flag; /* Status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */
|
||||
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */
|
||||
DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the window */
|
||||
DWORD dir_sect; /* Sector number containing the directory entry */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */
|
||||
#endif
|
||||
#if _FS_LOCK
|
||||
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File data read/write buffer */
|
||||
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
/* Directory object structure (FATFS_DIR) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current read/write index number */
|
||||
DWORD sclust; /* Table start cluster (0:Root dir) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */
|
||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
||||
WORD index; /* Current read/write index number */
|
||||
DWORD sclust; /* Table start cluster (0:Root FATFS_DIR) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* FATFS_DIR; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _FS_LOCK
|
||||
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
#if _USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} FATFS_DIR;
|
||||
|
||||
|
||||
|
||||
/* File status structure (FILINFO) */
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
||||
#if _USE_LFN
|
||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
@ -175,26 +182,26 @@ typedef struct {
|
|||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
@ -202,38 +209,45 @@ typedef enum {
|
|||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (FATFS_DIR*, const TCHAR*); /* Open an existing directory */
|
||||
FRESULT f_readdir (FATFS_DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const TCHAR*); /* Create a new directory */
|
||||
FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attribute of the file/dir */
|
||||
FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change times-tamp of the file/dir */
|
||||
FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */
|
||||
FRESULT f_chdrive (BYTE); /* Change current drive */
|
||||
FRESULT f_chdir (const TCHAR*); /* Change current directory */
|
||||
FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
|
||||
FRESULT f_fdisk (BYTE, const DWORD[], void*); /* Divide a physical drive into some partitions */
|
||||
int f_putc (TCHAR, FIL*); /* Put a character to the file */
|
||||
int f_puts (const TCHAR*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */
|
||||
FRESULT f_opendir (FATFS_DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (FATFS_DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (FATFS_DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (FATFS_DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (FATFS_DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of the file/FATFS_DIR */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/FATFS_DIR */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
|
@ -246,26 +260,26 @@ TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the fil
|
|||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY
|
||||
#if !_FS_READONLY && !_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* Unicode support functions */
|
||||
#if _USE_LFN /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
void* ff_memalloc (UINT); /* Allocate memory block */
|
||||
void ff_memfree (void*); /* Free memory block */
|
||||
#if _USE_LFN /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR chr, UINT FATFS_DIR); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */
|
||||
int ff_req_grant (_SYNC_t); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t); /* Unlock sync object */
|
||||
int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
|
||||
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -277,57 +291,56 @@ int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
|
|||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA__ERROR 0x80
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
|
||||
#if !_FS_READONLY
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* Fast seek feature */
|
||||
#define CREATE_LINKMAP 0xFFFFFFFF
|
||||
#define CREATE_LINKMAP 0xFFFFFFFF
|
||||
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -335,3 +348,4 @@ int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
|
|||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
||||
|
||||
|
|
|
@ -1,192 +1,276 @@
|
|||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.09a (C)ChaN, 2012
|
||||
/----------------------------------------------------------------------------/
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 4004 /* Revision ID */
|
||||
/ FatFs - FAT file system module configuration file R0.11 (C)ChaN, 2015
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFS_DBG 0
|
||||
#define _FFCONF 32020 /* Revision ID */
|
||||
|
||||
#define FFS_DBG 0
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Functions and Buffer Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
#define _FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS
|
||||
/ bytes. Instead of private sector buffer eliminated from the file object,
|
||||
/ common sector buffer in the file system object (FATFS) is used for the file
|
||||
/ data transfer. */
|
||||
|
||||
|
||||
#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_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0 /* 0 to 3 */
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
#define _FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to 1.
|
||||
/ 3: f_lseek is removed in addition to 2. */
|
||||
/ 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_STRFUNC 0
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
|
||||
/ f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_MKFS 1 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
#define _USE_FIND 0
|
||||
/* This option switches filtered directory read feature and related functions,
|
||||
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#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. */
|
||||
#define _USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
|
||||
#define _USE_FASTSEEK 0
|
||||
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_TINY need to be set to 1. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 858
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
#define _CODE_PAGE 858
|
||||
/* This option 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 only (Valid for non LFN cfg.)
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift_JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 1 /* 0 to 3 */
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
#define _USE_LFN 1
|
||||
#define _MAX_LFN 255
|
||||
/* The _USE_LFN option switches the LFN feature.
|
||||
/
|
||||
/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
||||
/ 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.
|
||||
/
|
||||
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
|
||||
/ Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
||||
/ to the project. When enable to use heap, memory control functions
|
||||
/ ff_memalloc() and ff_memfree() must be added to the project. */
|
||||
/ When enable the LFN feature, Unicode handling functions (option/unicode.c) 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 code set on FatFs API to Unicode,
|
||||
/ enable LFN feature and set _LFN_UNICODE to 1. */
|
||||
#define _LFN_UNICODE 0
|
||||
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode)
|
||||
/ To use Unicode string for the path name, enable LFN feature and set _LFN_UNICODE
|
||||
/ to 1. This option also affects behavior of string I/O functions. */
|
||||
|
||||
|
||||
#define _FS_RPATH 0 /* 0 to 2 */
|
||||
/* The _FS_RPATH option configures relative path feature.
|
||||
#define _STRF_ENCODE 3
|
||||
/* When _LFN_UNICODE is 1, 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().
|
||||
/
|
||||
/ 0: ANSI/OEM
|
||||
/ 1: UTF-16LE
|
||||
/ 2: UTF-16BE
|
||||
/ 3: UTF-8
|
||||
/
|
||||
/ When _LFN_UNICODE is 0, this option has no effect. */
|
||||
|
||||
|
||||
#define _FS_RPATH 0
|
||||
/* This option configures relative path feature.
|
||||
/
|
||||
/ 0: Disable relative path feature and remove related functions.
|
||||
/ 1: Enable relative path. f_chdrive() and f_chdir() are available.
|
||||
/ 2: f_getcwd() is available in addition to 1.
|
||||
/ 1: Enable relative path feature. f_chdir() and f_chdrive() 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. */
|
||||
|
||||
/ Note that directory items read via f_readdir() are affected by this option. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Physical Drive Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||
/* Maximum sector size to be handled.
|
||||
/ Always set 512 for memory card and hard disk but a larger value may be
|
||||
/ required for on-board flash memory, floppy disk and optical disk.
|
||||
/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size
|
||||
/ and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
/* _STR_VOLUME_ID option switches string volume ID feature.
|
||||
/ 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: A-Z and 0-9. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0 /* 0:Single partition, 1/2:Enable multiple partition */
|
||||
/* When set to 0, each volume is bound to the same physical drive number and
|
||||
/ it can mount only first primaly partition. When it is set to 1, each volume
|
||||
/ is tied to the partitions listed in VolToPart[]. */
|
||||
#define _MULTI_PARTITION 0
|
||||
/* This option switches multi-partition feature. By default (0), each logical drive
|
||||
/ number is bound to the same physical drive number and only an FAT volume found on
|
||||
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
|
||||
/ each logical drive number is bound to arbitrary physical drive and partition
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
|
||||
|
||||
|
||||
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command
|
||||
/ should be added to the disk_ioctl functio. */
|
||||
#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 type of memory cards 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_TRIM 0
|
||||
/* This option switches ATA-TRIM feature. (0:Disable or 1:Enable)
|
||||
/ To enable Trim feature, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define _FS_NOFSINFO 0
|
||||
/* 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 use of last allocated cluster number.
|
||||
/
|
||||
/ 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 _WORD_ACCESS 0 /* 0 or 1 */
|
||||
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
|
||||
/ option defines which access method is used to the word data on the FAT volume.
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 2
|
||||
#define _NORTC_MDAY 1
|
||||
#define _NORTC_YEAR 2015
|
||||
/* The _FS_NORTC option switches timestamp feature. If the system does not have
|
||||
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
|
||||
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
|
||||
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR.
|
||||
/ When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need
|
||||
/ to be added to the project to read current time form RTC. _NORTC_MON,
|
||||
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (_FS_READONLY == 1). */
|
||||
|
||||
|
||||
#define _FS_LOCK 0
|
||||
/* The _FS_LOCK option switches file lock feature to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Byte-by-byte access.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/ 0: Disable file lock feature. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock feature. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock feature is independent of re-entrancy. */
|
||||
|
||||
|
||||
#define _FS_REENTRANT 0
|
||||
#define _FS_TIMEOUT 1000
|
||||
#define _SYNC_t HANDLE
|
||||
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this feature.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned word
|
||||
/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code size.
|
||||
/ 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. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.c. */
|
||||
|
||||
|
||||
#define _WORD_ACCESS 0
|
||||
/* 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 to ALL instructions.
|
||||
/ * Byte order on the memory is little-endian.
|
||||
/
|
||||
/ If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size.
|
||||
/ Following table shows allowable settings of some processor types.
|
||||
/
|
||||
/ ARM7TDMI 0 *2 ColdFire 0 *1 V850E 0 *2
|
||||
/ Cortex-M3 0 *3 Z80 0/1 V850ES 0/1
|
||||
/ Cortex-M0 0 *2 x86 0/1 TLCS-870 0/1
|
||||
/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1
|
||||
/ AVR32 0 *1 RL78 0 *2 R32C 0 *2
|
||||
/ PIC18 0/1 SH-2 0 *1 M16C 0/1
|
||||
/ PIC24 0 *2 H8S 0 *1 MSP430 0 *2
|
||||
/ PIC32 0 *1 H8/300H 0 *1 8051 0/1
|
||||
/
|
||||
/ *1:Big-endian.
|
||||
/ *2:Unaligned memory access is not supported.
|
||||
/ *3:Some compilers generate LDM/STM for mem_cpy function.
|
||||
*/
|
||||
|
||||
|
||||
/* A header file that defines sync object types on the O/S, such as
|
||||
/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */
|
||||
|
||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
|
||||
/* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module.
|
||||
/
|
||||
/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
|
||||
/ 1: Enable reentrancy. 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 _FS_LOCK 0 /* 0:Disable or >=1:Enable */
|
||||
/* To enable file lock control feature, set _FS_LOCK to 1 or greater.
|
||||
The value defines how many files can be opened simultaneously. */
|
||||
|
||||
#define FLUSH_ON_NEW_CLUSTER 0 /* Sync the file on every new cluster */
|
||||
#define FLUSH_ON_NEW_SECTOR 1 /* Sync the file on every new sector */
|
||||
/* Only one of these two defines needs to be set to 1. If both are set to 0
|
||||
|
@ -194,5 +278,3 @@
|
|||
Clusters are group of sectors (eg: 8 sectors). Flushing on new cluster means
|
||||
it would be less often than flushing on new sector. Sectors are generally
|
||||
512 Bytes long. */
|
||||
|
||||
#endif /* _FFCONFIG */
|
||||
|
|
|
@ -2,36 +2,33 @@
|
|||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _INTEGER
|
||||
#define _INTEGER
|
||||
#ifndef _FF_INTEGER
|
||||
#define _FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#else /* Embedded platform */
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types must be 16-bit, 32-bit or larger integer */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
/* This type MUST be 8 bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types must be 8-bit integer */
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char BYTE;
|
||||
/* These types MUST be 16 bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types must be 16-bit integer */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
/* These types MUST be 16 bit or 32 bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types must be 32-bit integer */
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long DWORD;
|
||||
/* These types MUST be 32 bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -30,8 +30,9 @@ FATDirHandle::FATDirHandle(const FATFS_DIR &the_dir) {
|
|||
}
|
||||
|
||||
int FATDirHandle::closedir() {
|
||||
int retval = f_closedir(&dir);
|
||||
delete this;
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct dirent *FATDirHandle::readdir() {
|
||||
|
|
|
@ -47,9 +47,10 @@ FATFileSystem::FATFileSystem(const char* n) : FileSystemLike(n) {
|
|||
for(int i=0; i<_VOLUMES; i++) {
|
||||
if(_ffs[i] == 0) {
|
||||
_ffs[i] = this;
|
||||
_fsid = i;
|
||||
debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%d]\n", _name, _fsid);
|
||||
f_mount(i, &_fs);
|
||||
_fsid[0] = '0' + i;
|
||||
_fsid[1] = '\0';
|
||||
debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%s]\n", _name, _fsid);
|
||||
f_mount(&_fs, _fsid, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -60,15 +61,15 @@ FATFileSystem::~FATFileSystem() {
|
|||
for (int i=0; i<_VOLUMES; i++) {
|
||||
if (_ffs[i] == this) {
|
||||
_ffs[i] = 0;
|
||||
f_mount(i, NULL);
|
||||
f_mount(NULL, _fsid, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileHandle *FATFileSystem::open(const char* name, int flags) {
|
||||
debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%d]\n", name, _name, _fsid);
|
||||
debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%s]\n", name, _name, _fsid);
|
||||
char n[64];
|
||||
sprintf(n, "%d:/%s", _fsid, name);
|
||||
sprintf(n, "%s:/%s", _fsid, name);
|
||||
|
||||
/* POSIX flags -> FatFS open mode */
|
||||
BYTE openmode;
|
||||
|
@ -141,13 +142,13 @@ int FATFileSystem::mkdir(const char *name, mode_t mode) {
|
|||
}
|
||||
|
||||
int FATFileSystem::mount() {
|
||||
FRESULT res = f_mount(_fsid, &_fs);
|
||||
FRESULT res = f_mount(&_fs, _fsid, 1);
|
||||
return res == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
int FATFileSystem::unmount() {
|
||||
if (disk_sync())
|
||||
return -1;
|
||||
FRESULT res = f_mount(_fsid, NULL);
|
||||
FRESULT res = f_mount(NULL, _fsid, 0);
|
||||
return res == 0 ? 0 : -1;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
|
||||
static FATFileSystem * _ffs[_VOLUMES]; // FATFileSystem objects, as parallel to FatFs drives array
|
||||
FATFS _fs; // Work area (file system object) for logical drive
|
||||
int _fsid;
|
||||
char _fsid[2];
|
||||
|
||||
/**
|
||||
* Opens a file on the filesystem
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#ifndef MBED_H
|
||||
#define MBED_H
|
||||
|
||||
#define MBED_LIBRARY_VERSION 103
|
||||
#define MBED_LIBRARY_VERSION 104
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "mbed_interface.h"
|
||||
|
||||
WEAK void mbed_die(void) {
|
||||
#ifndef NRF51_H
|
||||
#if !defined (NRF51_H) && !defined(TARGET_EFM32)
|
||||
__disable_irq(); // dont allow interrupts to disturb the flash pattern
|
||||
#endif
|
||||
#if (DEVICE_ERROR_RED == 1)
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
#include "cmsis_nvic.h"
|
||||
|
||||
#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFE000) // Vectors positioned at start of RAM
|
||||
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash
|
||||
#define NVIC_FLASH_VECTOR_ADDRESS (__vector_table) // Initial vector position in flash
|
||||
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
|
||||
uint32_t *vectors = (uint32_t*)SCB->VTOR;
|
||||
uint32_t i;
|
||||
|
||||
// Copy and switch to dynamic vectors if the first time called
|
||||
if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) {
|
||||
if (SCB->VTOR < NVIC_RAM_VECTOR_ADDRESS) {
|
||||
uint32_t *old_vectors = vectors;
|
||||
vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
|
||||
for (i=0; i<NVIC_NUM_VECTORS; i++) {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
;WITHOUT SOFTDEVICE:
|
||||
;LR_IROM1 0x00000000 0x00040000 {
|
||||
; ER_IROM1 0x00000000 0x00040000 {
|
||||
; *.o (RESET, +First)
|
||||
; *(InRoot$$Sections)
|
||||
; .ANY (+RO)
|
||||
; }
|
||||
; RW_IRAM1 0x20000000 0x00004000 {
|
||||
; .ANY (+RW +ZI)
|
||||
; }
|
||||
;}
|
||||
;
|
||||
;WITH SOFTDEVICE:
|
||||
|
||||
LR_IROM1 0x18000 0x0028000 {
|
||||
ER_IROM1 0x18000 0x0028000 {
|
||||
*.o (RESET, +First)
|
||||
*(InRoot$$Sections)
|
||||
.ANY (+RO)
|
||||
}
|
||||
RW_IRAM1 0x20002000 0x00002000 {
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/* Linker script to configure memory regions. */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00016000, LENGTH = 0x2A000
|
||||
RAM (rwx) : ORIGIN = 0x20002000, LENGTH = 0x2000
|
||||
}
|
||||
|
||||
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
|
||||
/* Linker script to place sections and symbol values. Should be used together
|
||||
* with other linker script that defines memory regions FLASH and RAM.
|
||||
* It references following symbols, which must be defined in code:
|
||||
* Reset_Handler : Entry of reset handler
|
||||
*
|
||||
* It defines following symbols, which code can use without definition:
|
||||
* __exidx_start
|
||||
* __exidx_end
|
||||
* __etext
|
||||
* __data_start__
|
||||
* __preinit_array_start
|
||||
* __preinit_array_end
|
||||
* __init_array_start
|
||||
* __init_array_end
|
||||
* __fini_array_start
|
||||
* __fini_array_end
|
||||
* __data_end__
|
||||
* __bss_start__
|
||||
* __bss_end__
|
||||
* __end__
|
||||
* end
|
||||
* __HeapLimit
|
||||
* __StackLimit
|
||||
* __StackTop
|
||||
* __stack
|
||||
*/
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.Vectors))
|
||||
*(.text*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(.rodata*)
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
} > FLASH
|
||||
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} > FLASH
|
||||
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} > FLASH
|
||||
__exidx_end = .;
|
||||
|
||||
__etext = .;
|
||||
|
||||
.data : AT (__etext)
|
||||
{
|
||||
__data_start__ = .;
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
*(.jcr)
|
||||
. = ALIGN(4);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
|
||||
} > RAM
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} > RAM
|
||||
|
||||
.heap (COPY):
|
||||
{
|
||||
__end__ = .;
|
||||
end = __end__;
|
||||
*(.heap*)
|
||||
__HeapLimit = .;
|
||||
} > RAM
|
||||
|
||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||
* used for linker to calculate size of stack sections, and assign
|
||||
* values to stack symbols later */
|
||||
.stack_dummy (COPY):
|
||||
{
|
||||
*(.stack*)
|
||||
} > RAM
|
||||
|
||||
/* Set stack top to end of RAM, and stack limit move down by
|
||||
* size of stack_dummy section */
|
||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||
PROVIDE(__stack = __StackTop);
|
||||
|
||||
/* Check if data + heap + stack exceeds RAM limit */
|
||||
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||
}
|
|
@ -34,6 +34,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf_delay.h"
|
||||
#include "system_nrf51.h"
|
||||
|
||||
/*lint ++flb "Enter library region" */
|
||||
|
@ -42,6 +43,7 @@
|
|||
|
||||
static bool is_manual_peripheral_setup_needed(void);
|
||||
static bool is_disabled_in_debug_needed(void);
|
||||
static void init_clock(void);
|
||||
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
|
@ -82,8 +84,19 @@ void SystemInit(void)
|
|||
}
|
||||
|
||||
// Start the external 32khz crystal oscillator.
|
||||
init_clock();
|
||||
}
|
||||
|
||||
#if defined(TARGET_DELTA_DFCM_NNN40) || defined(TARGET_HRM1017)
|
||||
void init_clock(void)
|
||||
{
|
||||
/* For compatibility purpose, the default behaviour is to first attempt to initialise an
|
||||
external clock, and after a timeout, use the internal RC one. To avoid this wait, boards that
|
||||
don't have an external oscillator can set TARGET_NRF_LFCLK_RC directly. */
|
||||
int i = 0;
|
||||
const uint32_t polling_period = 200;
|
||||
const uint32_t timeout = 1000000;
|
||||
|
||||
#if defined(TARGET_NRF_LFCLK_RC)
|
||||
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
|
||||
#else
|
||||
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
|
||||
|
@ -91,7 +104,26 @@ void SystemInit(void)
|
|||
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
|
||||
// Wait for the external oscillator to start up.
|
||||
/* Wait for the external oscillator to start up.
|
||||
nRF51822 product specification (8.1.5) gives a typical value of 300ms for external clock
|
||||
startup duration, and a maximum value of 1s. When using the internal RC source, typical delay
|
||||
will be 390µs, so we use a polling period of 200µs.
|
||||
|
||||
We can't use us_ticker at this point, so we have to rely on a less precise method for
|
||||
measuring our timeout. Because of this, the actual timeout will be slightly longer than 1
|
||||
second, which isn't an issue at all, since this fallback should only be used as a safety net.
|
||||
*/
|
||||
for (i = 0; i < (timeout / polling_period); i++) {
|
||||
if (NRF_CLOCK->EVENTS_LFCLKSTARTED != 0)
|
||||
return;
|
||||
nrf_delay_us(polling_period);
|
||||
}
|
||||
|
||||
/* Fallback to internal clock. Belt and braces, since the internal clock is used by default
|
||||
whilst no external source is running. This is not only a sanity check, but it also allows
|
||||
code down the road (e.g. ble initialisation) to directly know which clock is used. */
|
||||
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
|
|
@ -159,9 +159,9 @@ typedef enum {
|
|||
|
||||
typedef struct { /*!< GPIO_PORT Structure */
|
||||
__IO uint8_t B[76]; /*!< Byte pin registers */
|
||||
__I uint32_t RESERVED0[45];
|
||||
__I uint32_t RESERVED0[1005];
|
||||
__IO uint32_t W[76]; /*!< Word pin registers */
|
||||
__I uint32_t RESERVED1[1908];
|
||||
__I uint32_t RESERVED1[948];
|
||||
__IO uint32_t DIR[3]; /*!< Port Direction registers */
|
||||
__I uint32_t RESERVED2[29];
|
||||
__IO uint32_t MASK[3]; /*!< Port Mask register */
|
||||
|
|
|
@ -89,7 +89,7 @@ void timer_oc_irq_handler(void)
|
|||
// Prepare next interrupt
|
||||
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, val + HAL_TICK_DELAY);
|
||||
PreviousVal = val;
|
||||
#if 1 // For DEBUG only
|
||||
#if 0 // For DEBUG only
|
||||
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6);
|
||||
#endif
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
|
|||
// Enable timer
|
||||
HAL_TIM_Base_Start(&TimMasterHandle);
|
||||
|
||||
#if 1 // For DEBUG only
|
||||
#if 0 // For DEBUG only
|
||||
__GPIOB_CLK_ENABLE();
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6;
|
||||
|
|
|
@ -1010,19 +1010,30 @@ typedef struct
|
|||
/******************************************************************************/
|
||||
|
||||
/*********************** Bit definition for dualtimer ***********************/
|
||||
#define DUALTIMER_TimerControl_TimerDIsable (0x0ul << 7)
|
||||
#define DUALTIMER_TimerControl_TimerEnable (0x1ul << 7)
|
||||
#define DUALTIMER_TimerControl_FreeRunning (0x0ul << 6)
|
||||
#define DUALTIMER_TimerControl_Periodic (0x1ul << 6)
|
||||
#define DUALTIMER_TimerControl_IntDisable (0x0ul << 5)
|
||||
#define DUALTIMER_TimerControl_IntEnable (0x1ul << 5)
|
||||
#define DUALTIMER_TimerControl_Pre_1 (0x0ul << 2)
|
||||
#define DUALTIMER_TimerControl_Pre_16 (0x1ul << 2)
|
||||
#define DUALTIMER_TimerControl_Pre_256 (0x2ul << 2)
|
||||
#define DUALTIMER_TimerControl_Size_16 (0x0ul << 1)
|
||||
#define DUALTIMER_TimerControl_Size_32 (0x1ul << 1)
|
||||
#define DUALTIMER_TimerControl_Wrapping (0x0ul << 0)
|
||||
#define DUALTIMER_TimerControl_OneShot (0x1ul << 0)
|
||||
#define DUALTIMER_TimerControl_TimerDIsable 0x0ul
|
||||
#define DUALTIMER_TimerControl_TimerEnable 0x1ul
|
||||
#define DUALTIMER_TimerControl_TimerEnable_Pos 7
|
||||
|
||||
#define DUALTIMER_TimerControl_FreeRunning 0x0ul
|
||||
#define DUALTIMER_TimerControl_Periodic 0x1ul
|
||||
#define DUALTIMER_TimerControl_TimerMode_Pos 6
|
||||
|
||||
#define DUALTIMER_TimerControl_IntDisable 0x0ul
|
||||
#define DUALTIMER_TimerControl_IntEnable 0x1ul
|
||||
#define DUALTIMER_TimerControl_IntEnable_Pos 5
|
||||
|
||||
#define DUALTIMER_TimerControl_Pre_1 0x0ul
|
||||
#define DUALTIMER_TimerControl_Pre_16 0x1ul
|
||||
#define DUALTIMER_TimerControl_Pre_256 0x2ul
|
||||
#define DUALTIMER_TimerControl_Pre_Pos 2
|
||||
|
||||
#define DUALTIMER_TimerControl_Size_16 0x0ul
|
||||
#define DUALTIMER_TimerControl_Size_32 0x1ul
|
||||
#define DUALTIMER_TimerControl_Size_Pos 1
|
||||
|
||||
#define DUALTIMER_TimerControl_Wrapping 0x0ul
|
||||
#define DUALTIMER_TimerControl_OneShot 0x1ul
|
||||
#define DUALTIMER_TimerControl_OneShot_Pos 0
|
||||
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "W7500x_uart.h"
|
||||
#include "W7500x_i2c.h"
|
||||
#include "W7500x_adc.h"
|
||||
#include "W7500x_dualtimer.h"
|
||||
#include "system_W7500x.h"
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file W7500x_stdPeriph_Driver/src/W7500x_dualtimer.c
|
||||
* @author IOP Team
|
||||
* @version v1.0.0
|
||||
* @date 01-May-2015
|
||||
* @brief This file contains all the functions prototypes for the dualtimer
|
||||
* firmware library.
|
||||
******************************************************************************
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes -------------------------------------------*/
|
||||
#include "W7500x.h"
|
||||
|
||||
void DUALTIMER_ClockEnable(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
if(DUALTIMERn == DUALTIMER0_0)
|
||||
TIMCLKEN0_0 = DUALTIMER_Clock_Enable;
|
||||
else if(DUALTIMERn == DUALTIMER0_1)
|
||||
TIMCLKEN0_1 = DUALTIMER_Clock_Enable;
|
||||
else if(DUALTIMERn == DUALTIMER1_0)
|
||||
TIMCLKEN1_0 = DUALTIMER_Clock_Enable;
|
||||
else if(DUALTIMERn == DUALTIMER1_1)
|
||||
TIMCLKEN1_1 = DUALTIMER_Clock_Enable;
|
||||
}
|
||||
|
||||
void DUALTIMER_ClockDisable(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
if(DUALTIMERn == DUALTIMER0_0)
|
||||
TIMCLKEN0_0 = DUALTIMER_Clock_Disable;
|
||||
else if(DUALTIMERn == DUALTIMER0_1)
|
||||
TIMCLKEN0_1 = DUALTIMER_Clock_Disable;
|
||||
else if(DUALTIMERn == DUALTIMER1_0)
|
||||
TIMCLKEN1_0 = DUALTIMER_Clock_Disable;
|
||||
else if(DUALTIMERn == DUALTIMER1_1)
|
||||
TIMCLKEN1_1 = DUALTIMER_Clock_Disable;
|
||||
}
|
||||
|
||||
void DUALTIMER_DeInit(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
DUALTIMER_Stop(DUALTIMERn);
|
||||
|
||||
DUALTIMERn->TimerLoad = 0x0;
|
||||
DUALTIMERn->TimerControl = 0x20;
|
||||
DUALTIMERn->TimerBGLoad = 0x0;
|
||||
}
|
||||
|
||||
void DUALTIMER_Init(DUALTIMER_TypeDef* DUALTIMERn, DUALTIMER_InitTypDef* DUALTIMER_InitStruct)
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
assert_param(IS_DUALTIMER_TimerMode(DUALTIMER_InitStruct->TimerControl_Mode));
|
||||
assert_param(IS_DUALTIMER_TimerPre(DUALTIMER_InitStruct->TimerControl_Pre));
|
||||
assert_param(IS_DUALTIMER_TimerSize(DUALTIMER_InitStruct->TimerControl_Size));
|
||||
assert_param(IS_DUALTIMER_OneShot(DUALTIMER_InitStruct->TimerControl_OneShot));
|
||||
|
||||
DUALTIMER_Stop(DUALTIMERn);
|
||||
|
||||
DUALTIMERn->TimerLoad = DUALTIMER_InitStruct->TimerLoad;
|
||||
|
||||
tmp = DUALTIMERn->TimerControl;
|
||||
tmp |= (DUALTIMER_InitStruct->TimerControl_Mode << DUALTIMER_TimerControl_TimerMode_Pos);
|
||||
tmp |= (DUALTIMER_InitStruct->TimerControl_Pre << DUALTIMER_TimerControl_Pre_Pos);
|
||||
tmp |= (DUALTIMER_InitStruct->TimerControl_Size << DUALTIMER_TimerControl_Size_Pos);
|
||||
tmp |= (DUALTIMER_InitStruct->TimerControl_OneShot << DUALTIMER_TimerControl_OneShot_Pos);
|
||||
//Reset values not used
|
||||
tmp &= 0xEF;
|
||||
|
||||
DUALTIMERn->TimerControl = tmp;
|
||||
}
|
||||
|
||||
void DUALTIMER_IntConfig(DUALTIMER_TypeDef* DUALTIMERn, FunctionalState state)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
if(state == ENABLE)
|
||||
DUALTIMERn->TimerControl |= (DUALTIMER_TimerControl_IntEnable << DUALTIMER_TimerControl_IntEnable_Pos);
|
||||
else
|
||||
DUALTIMERn->TimerControl &= ~(DUALTIMER_TimerControl_IntEnable << DUALTIMER_TimerControl_IntEnable_Pos);
|
||||
}
|
||||
|
||||
void DUALTIMER_IntClear(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
DUALTIMERn->TimerIntClr = DUALTIMER_Int_Clear;
|
||||
}
|
||||
|
||||
ITStatus DUALTIMER_GetIntStatus(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
return (ITStatus)DUALTIMERn->TimerMIS;
|
||||
}
|
||||
|
||||
FlagStatus DUALTIMER_GetIntEnableStatus(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
return (FlagStatus)((DUALTIMERn->TimerControl >> DUALTIMER_TimerControl_IntEnable_Pos) & 0x1);
|
||||
}
|
||||
|
||||
void DUALTIMER_Start(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
DUALTIMERn->TimerControl |= (DUALTIMER_TimerControl_TimerEnable << DUALTIMER_TimerControl_TimerEnable_Pos);
|
||||
}
|
||||
|
||||
void DUALTIMER_Stop(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
DUALTIMERn->TimerControl &= ~(DUALTIMER_TimerControl_TimerEnable << DUALTIMER_TimerControl_TimerEnable_Pos);
|
||||
}
|
||||
|
||||
uint32_t DUALTIMER_GetTimerLoad(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
return DUALTIMERn->TimerLoad;
|
||||
}
|
||||
|
||||
void DUALTIMER_SetTimerLoad(DUALTIMER_TypeDef* DUALTIMERn, uint32_t TimerLoad)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
DUALTIMERn->TimerLoad = TimerLoad;
|
||||
}
|
||||
|
||||
uint32_t DUALTIMER_GetTimerValue(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
return DUALTIMERn->TimerValue;
|
||||
}
|
||||
|
||||
uint32_t DUALTIMER_GetTimerControl(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
return DUALTIMERn->TimerControl;
|
||||
}
|
||||
|
||||
void DUALTIMER_SetTimerControl(DUALTIMER_TypeDef* DUALTIMERn, uint32_t TimerControl)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
DUALTIMERn->TimerControl = TimerControl;
|
||||
}
|
||||
|
||||
uint32_t DUALTIMER_GetTimerRIS(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
return DUALTIMERn->TimerRIS;
|
||||
}
|
||||
|
||||
uint32_t DUALTIMER_GetTimerMIS(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
return DUALTIMERn->TimerMIS;
|
||||
}
|
||||
|
||||
uint32_t DUALTIMER_GetTimerBGLoad(DUALTIMER_TypeDef* DUALTIMERn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
return DUALTIMERn->TimerBGLoad;
|
||||
}
|
||||
|
||||
void DUALTIMER_SetTimerBGLoad(DUALTIMER_TypeDef* DUALTIMERn, uint32_t TimerBGLoad)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DUALTIMER_ALL_CH(DUALTIMERn));
|
||||
|
||||
DUALTIMERn->TimerBGLoad = TimerBGLoad;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file W7500x_stdPeriph_Driver/inc/W7500x_dualtimer.h
|
||||
* @author IOP Team
|
||||
* @version V1.0.0
|
||||
* @date 01-May-2015
|
||||
* @brief This file contains all the functions prototypes for the dualtimer
|
||||
* firmware library.
|
||||
******************************************************************************
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __W7500X_DUALTIMER_H
|
||||
#define __W7500X_DUALTIMER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "W7500x.h"
|
||||
|
||||
/**********************************************************************************************/
|
||||
/**********************************************************************************************/
|
||||
// This structure and define must be in W7500x.h
|
||||
/**********************************************************************************************/
|
||||
/**********************************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t TimerLoad;
|
||||
uint32_t TimerControl_Mode;
|
||||
uint32_t TimerControl_Pre;
|
||||
uint32_t TimerControl_Size;
|
||||
uint32_t TimerControl_OneShot;
|
||||
}DUALTIMER_InitTypDef;
|
||||
|
||||
|
||||
#define IS_DUALTIMER_TimerMode(MODE) (MODE <= 1)
|
||||
#define IS_DUALTIMER_TimerPre(PREE) (PRE <= 2)
|
||||
#define IS_DUALTIMER_TimerSize(SIZE) (SIZE <= 1)
|
||||
#define IS_DUALTIMER_OneShot(ONESHOT) (ONESHOT <= 1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define DUALTIMER_Int_Clear 0x1ul
|
||||
|
||||
#define DUALTIMER_Clock_Enable 0x1ul
|
||||
#define DUALTIMER_Clock_Disable ~DUALTIMER_Clock_Enable
|
||||
|
||||
|
||||
#define IS_DUALTIMER_ALL_CH(CH) ((CH == DUALTIMER0_0) || \
|
||||
(CH == DUALTIMER0_1) || \
|
||||
(CH == DUALTIMER1_0) || \
|
||||
(CH == DUALTIMER1_1))
|
||||
|
||||
|
||||
|
||||
void DUALTIMER_ClockEnable(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
void DUALTIMER_ClockDisable(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
void DUALTIMER_DeInit(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
void DUALTIMER_Init(DUALTIMER_TypeDef* DUALTIMERn, DUALTIMER_InitTypDef* DUALTIMER_InitStruct);
|
||||
void DUALTIMER_IntConfig(DUALTIMER_TypeDef* DUALTIMERn, FunctionalState state);
|
||||
void DUALTIMER_IntClear(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
ITStatus DUALTIMER_GetIntStatus(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
FlagStatus DUALTIMER_GetIntEnableStatus(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
void DUALTIMER_Start(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
void DUALTIMER_Stop(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
uint32_t DUALTIMER_GetTimerLoad(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
void DUALTIMER_SetTimerLoad(DUALTIMER_TypeDef* DUALTIMERn, uint32_t TimerLoad);
|
||||
uint32_t DUALTIMER_GetTimerValue(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
uint32_t DUALTIMER_GetTimerControl(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
void DUALTIMER_SetTimerControl(DUALTIMER_TypeDef* DUALTIMERn, uint32_t TimerControl);
|
||||
uint32_t DUALTIMER_GetTimerRIS(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
uint32_t DUALTIMER_GetTimerMIS(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
uint32_t DUALTIMER_GetTimerBGLoad(DUALTIMER_TypeDef* DUALTIMERn);
|
||||
void DUALTIMER_SetTimerBGLoad(DUALTIMER_TypeDef* DUALTIMERn, uint32_t TimerBGLoad);
|
||||
|
||||
|
||||
|
||||
//======================= Interrupt handler ==============================
|
||||
//void DUALTIMER0_Handler();
|
||||
//void DUALTIMER1_Handler();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif //__W7500X_DUALTIMER_H
|
|
@ -176,7 +176,7 @@ uint8_t HAL_GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
|||
return bitstatus;
|
||||
}
|
||||
|
||||
uint8_t HAL_GPIO_ReadInputData(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||
uint16_t HAL_GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
|
||||
{
|
||||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
|
||||
return ((uint16_t)GPIOx->DATA);
|
||||
|
@ -286,3 +286,13 @@ void HAL_PAD_AFConfig(PAD_Type Px, uint16_t GPIO_Pin, PAD_AF_TypeDef P_AF)
|
|||
}
|
||||
}
|
||||
|
||||
void GPIO_OutEnClr(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||
{
|
||||
GPIOx->OUTENCLR = GPIO_Pin;
|
||||
}
|
||||
|
||||
void GPIO_OutEnSet(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||
{
|
||||
GPIOx->OUTENSET = GPIO_Pin;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ void HAL_GPIO_DeInit(GPIO_TypeDef* GPIOx);
|
|||
void HAL_GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
|
||||
void HAL_GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
|
||||
uint8_t HAL_GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
uint8_t HAL_GPIO_ReadInputData(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
uint16_t HAL_GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
|
||||
uint8_t HAL_GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
uint16_t HAL_GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
|
||||
void HAL_GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
|
@ -126,6 +126,9 @@ void HAL_GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
|
|||
void HAL_GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
|
||||
void HAL_PAD_AFConfig(PAD_Type Px, uint16_t Pnum, PAD_AF_TypeDef P_AF);
|
||||
|
||||
void GPIO_OutEnClr(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
void GPIO_OutEnSet(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,589 +1,290 @@
|
|||
/* mbed Microcontroller Library
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2015 WIZnet Co.,Ltd. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of ARM Limited nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************
|
||||
*/
|
||||
/*include -------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include "W7500x.h"
|
||||
|
||||
/** @defgroup I2C_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitDef;
|
||||
void i2c_loop_us(int us);
|
||||
|
||||
#define SCL GPIO_Pin_9
|
||||
#define SDA GPIO_Pin_10
|
||||
uint16_t buf[] ={0x00,0x01};
|
||||
|
||||
/**
|
||||
* @brief Initializes the I2Cx peripheral according to the specified
|
||||
* parameters in the I2C_InitStruct.
|
||||
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
||||
* @param I2C_InitStruct: pointer to a I2C_InitTypeDef structure that
|
||||
* contains the configuration information for the specified I2C peripheral.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
uint32_t I2C_Init(I2C_TypeDef* I2Cx, I2C_ConfigStruct conf)
|
||||
uint32_t I2C_Init(I2C_ConfigStruct* conf)
|
||||
{
|
||||
uint32_t mode;
|
||||
uint8_t prescale;
|
||||
uint16_t timeout;
|
||||
uint16_t slave_address;
|
||||
uint32_t scl_port_num;
|
||||
uint32_t scl_pin_index;
|
||||
uint32_t sda_port_num;
|
||||
uint32_t sda_pin_index;
|
||||
|
||||
scl_port_num = I2C_PORT(conf->scl);
|
||||
scl_pin_index = I2C_PIN_INDEX(conf->scl);
|
||||
|
||||
mode = conf.mode;
|
||||
slave_address = conf.slave_address;
|
||||
if(mode == I2C_Master)
|
||||
{
|
||||
prescale = conf.master.prescale;
|
||||
timeout = conf.master.timeout;
|
||||
sda_port_num = I2C_PORT(conf->sda);
|
||||
sda_pin_index = I2C_PIN_INDEX(conf->sda);
|
||||
|
||||
//SCL setting
|
||||
GPIO_InitDef.GPIO_Pin = scl_pin_index;
|
||||
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
|
||||
|
||||
I2C_CoreEn(I2Cx,ENABLE);
|
||||
I2C_MasterSlave(I2Cx,ENABLE);
|
||||
HAL_GPIO_Init((GPIO_TypeDef*)(GPIOA_BASE + (scl_port_num << 24)), &GPIO_InitDef);
|
||||
HAL_GPIO_SetBits((GPIO_TypeDef*)(GPIOA_BASE + (scl_port_num << 24)), scl_pin_index);
|
||||
|
||||
I2C_Prescale(I2Cx,prescale); // 0x61 //When PLL clk is 20MHz and Prescale value set 0x61, SCL is 100KHz
|
||||
I2C_TimeoutSet(I2Cx,timeout); // 0xFFFF
|
||||
|
||||
I2C_CoreEn(I2Cx,DISABLE);
|
||||
}
|
||||
else if(conf.mode == I2C_Slave)
|
||||
{
|
||||
I2C_AcknowledgeConfig(I2Cx,ENABLE);
|
||||
I2C_SetSlavAddress(I2Cx,slave_address);
|
||||
}
|
||||
//SDA setting
|
||||
GPIO_InitDef.GPIO_Pin = sda_pin_index;
|
||||
GPIO_InitDef.GPIO_Mode = GPIO_Mode_IN;
|
||||
|
||||
HAL_GPIO_Init((GPIO_TypeDef*)(GPIOA_BASE + (sda_port_num << 24)), &GPIO_InitDef);
|
||||
HAL_GPIO_ResetBits((GPIO_TypeDef*)(GPIOA_BASE + (sda_port_num << 24)), sda_pin_index);
|
||||
|
||||
//Pin muxing
|
||||
HAL_PAD_AFConfig(scl_port_num, scl_pin_index, PAD_AF1);
|
||||
HAL_PAD_AFConfig(sda_port_num, sda_pin_index, PAD_AF1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I2C_WriteBitSCL(I2C_ConfigStruct* conf, uint8_t data)
|
||||
{
|
||||
uint32_t scl_port_num = I2C_PORT(conf->scl);
|
||||
uint32_t scl_pin_index = I2C_PIN_INDEX(conf->scl);
|
||||
|
||||
if(data == 1)
|
||||
HAL_GPIO_SetBits((GPIO_TypeDef*)(GPIOA_BASE + (scl_port_num << 24)), scl_pin_index);
|
||||
else
|
||||
return ERROR;
|
||||
|
||||
|
||||
I2C_AcknowledgeConfig(I2Cx,ENABLE);
|
||||
|
||||
return SUCCESS;
|
||||
HAL_GPIO_ResetBits((GPIO_TypeDef*)(GPIOA_BASE + (scl_port_num << 24)), scl_pin_index);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void I2C_DeInit(I2C_TypeDef* I2Cx)
|
||||
void I2C_WriteBitSDA(I2C_ConfigStruct* conf, uint8_t data)
|
||||
{
|
||||
I2C_InterRst(I2Cx,ENABLE);
|
||||
I2C_CoreEn(I2Cx, ENABLE);
|
||||
I2C_InterRst(I2Cx,DISABLE);
|
||||
I2C_CoreEn(I2Cx, DISABLE);
|
||||
uint32_t sda_port_num = I2C_PORT(conf->sda);
|
||||
uint32_t sda_pin_index = I2C_PIN_INDEX(conf->sda);
|
||||
|
||||
if(data == 1)
|
||||
GPIO_OutEnClr((GPIO_TypeDef*)(GPIOA_BASE + (sda_port_num << 24)), sda_pin_index);
|
||||
else
|
||||
GPIO_OutEnSet((GPIO_TypeDef*)(GPIOA_BASE + (sda_port_num << 24)), sda_pin_index);
|
||||
|
||||
}
|
||||
|
||||
|
||||
ErrorStatus I2C_Start(I2C_TypeDef* I2Cx, uint16_t slave_address, I2C_CTR ctr)
|
||||
uint8_t I2C_ReadBitSDA(I2C_ConfigStruct* conf)
|
||||
{
|
||||
ErrorStatus ret;
|
||||
|
||||
I2C_GenerateSTART(I2Cx,ENABLE);
|
||||
I2C_SendSlaveAddress(I2Cx,slave_address,(I2C_CTR)ctr);
|
||||
I2C_GenerateSTART(I2Cx,DISABLE);
|
||||
|
||||
ret=I2C_CheckEvent(I2Cx,I2C_ACKR);
|
||||
uint32_t sda_port_num = I2C_PORT(conf->sda);
|
||||
uint32_t sda_pin_index = I2C_PIN_INDEX(conf->sda);
|
||||
|
||||
if(HAL_GPIO_ReadInputDataBit((GPIO_TypeDef*)(GPIOA_BASE + (sda_port_num << 24)), sda_pin_index))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I2C_Start(I2C_ConfigStruct* conf)
|
||||
{
|
||||
I2C_WriteBitSCL(conf, 1);
|
||||
I2C_WriteBitSDA(conf, 1);
|
||||
|
||||
I2C_WriteBitSDA(conf, 0);
|
||||
I2C_WriteBitSCL(conf, 0);
|
||||
}
|
||||
|
||||
void I2C_Stop(I2C_ConfigStruct* conf)
|
||||
{
|
||||
I2C_WriteBitSCL(conf, 0);
|
||||
I2C_WriteBitSDA(conf, 0);
|
||||
|
||||
I2C_WriteBitSCL(conf, 1);
|
||||
I2C_WriteBitSDA(conf, 1);
|
||||
}
|
||||
|
||||
uint8_t I2C_WriteByte(I2C_ConfigStruct* conf, uint8_t data)
|
||||
{
|
||||
int i;
|
||||
uint8_t ret;
|
||||
|
||||
//Write byte
|
||||
for(i=0; i<8; i++)
|
||||
{
|
||||
if((data << i) & 0x80)
|
||||
I2C_WriteBitSDA(conf, 1);
|
||||
else
|
||||
I2C_WriteBitSDA(conf, 0);
|
||||
|
||||
I2C_WriteBitSCL(conf, 1);
|
||||
I2C_WriteBitSCL(conf, 0);
|
||||
}
|
||||
//Make clk for receiving ack
|
||||
I2C_WriteBitSDA(conf, 1);
|
||||
I2C_WriteBitSCL(conf, 1);
|
||||
//Read Ack/Nack
|
||||
ret = I2C_ReadBitSDA(conf);
|
||||
|
||||
I2C_WriteBitSCL(conf, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void I2C_Stop(I2C_TypeDef* I2Cx)
|
||||
void I2C_SendACK(I2C_ConfigStruct* conf)
|
||||
{
|
||||
I2C_GenerateSTOP(I2Cx,ENABLE);
|
||||
I2C_GenerateSTOP(I2Cx,DISABLE);
|
||||
GPIO_InitDef.GPIO_Pin = GPIO_Pin_9; // Set to Pin_9 (SCL0))
|
||||
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; // Set to Mode Output
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitDef);
|
||||
HAL_PAD_AFConfig(PAD_PA,GPIO_Pin_9, PAD_AF0); // PAD Config - LED used 2nd Function
|
||||
I2C_WriteBitSDA(conf, 0);
|
||||
I2C_WriteBitSCL(conf, 1);
|
||||
|
||||
I2C_WriteBitSCL(conf, 0);
|
||||
}
|
||||
|
||||
void I2C_SendNACK(I2C_ConfigStruct* conf)
|
||||
{
|
||||
I2C_WriteBitSDA(conf, 1);
|
||||
I2C_WriteBitSCL(conf, 1);
|
||||
|
||||
I2C_WriteBitSCL(conf, 0);
|
||||
}
|
||||
|
||||
void I2C_Reset(I2C_TypeDef* I2Cx)
|
||||
uint8_t I2C_ReadByte(I2C_ConfigStruct* conf)
|
||||
{
|
||||
I2C_CoreEn(I2Cx,ENABLE);
|
||||
// Maybe, it needs a little delay
|
||||
I2C_CoreEn(I2Cx,DISABLE);
|
||||
}
|
||||
|
||||
void I2C_SendData(I2C_TypeDef* I2Cx,uint16_t Data)
|
||||
{
|
||||
I2Cx -> TXR = (uint16_t)Data;
|
||||
}
|
||||
|
||||
int8_t I2C_SendDataAck(I2C_TypeDef* I2Cx,uint16_t Data)
|
||||
{
|
||||
buf[0] = Data;
|
||||
if(buf[0] == buf[1])
|
||||
int i;
|
||||
uint8_t ret = 0;
|
||||
|
||||
I2C_WriteBitSDA(conf, 1); //out enable clear(GPIO is input)
|
||||
|
||||
//Read byte
|
||||
for(i=0; i<8; i++)
|
||||
{
|
||||
I2C_GPIO();
|
||||
WriteByte(Data);
|
||||
i2c_loop_us(1);
|
||||
GPIO_I2C();
|
||||
I2C_WriteBitSCL(conf, 1);
|
||||
ret = (ret << 1) | (I2C_ReadBitSDA(conf));
|
||||
I2C_WriteBitSCL(conf, 0);
|
||||
}
|
||||
else
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int I2C_Write(I2C_ConfigStruct* conf, uint8_t addr, uint8_t* data, uint32_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
I2C_Start(conf);
|
||||
|
||||
//Write addr
|
||||
if(I2C_WriteByte(conf, addr) != 0)
|
||||
{
|
||||
I2Cx -> TXR = (uint16_t)Data;
|
||||
if(I2C_CheckEvent(I2Cx,I2C_ACKR) == ERROR)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
buf[1] = buf[0];
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int I2C_ReceiveData(I2C_TypeDef* I2Cx, int last)
|
||||
{
|
||||
if(last)
|
||||
{
|
||||
I2C_AcknowledgeConfig(I2Cx,DISABLE);
|
||||
if( I2C_CheckEvent(I2Cx,I2C_ACKT) == ERROR ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( I2C_CheckEvent(I2Cx,I2C_ACKT) == ERROR ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (uint8_t)I2Cx -> RXR;
|
||||
}
|
||||
|
||||
|
||||
int I2C_Burst_Read(I2C_TypeDef* I2Cx, uint16_t address, uint8_t *data, int length, int stop)
|
||||
{
|
||||
int recv_cnt;
|
||||
|
||||
if( I2C_Start(I2Cx,address,I2C_READ_SA7) == ERROR){
|
||||
printf("Received NACK at address phase!!\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(recv_cnt=0;recv_cnt<length;recv_cnt++)
|
||||
//Write data
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
}
|
||||
|
||||
return recv_cnt;
|
||||
}
|
||||
|
||||
|
||||
int I2C_Burst_Write(I2C_TypeDef* I2Cx, uint16_t address, uint8_t *data, int length, int stop)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
if( I2C_Start(I2Cx,address,I2C_WRITE_SA7) == ERROR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(cnt=0;cnt<length;cnt++)
|
||||
{
|
||||
if( I2C_SendDataAck(I2Cx,data[cnt]) == ERROR )
|
||||
{
|
||||
I2C_Stop(I2Cx);
|
||||
if(I2C_WriteByte(conf, data[i]))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// If not repeated start, send stop
|
||||
if(stop)
|
||||
{
|
||||
I2C_Stop(I2Cx);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generates I2Cx communication START condition.
|
||||
* @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
|
||||
* @param NewState: NewState of the I2C START condition generation.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
* @retval None.
|
||||
*/
|
||||
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
|
||||
{
|
||||
if(NewState != DISABLE)
|
||||
{
|
||||
I2Cx->CMDR = I2C_CMDR_STA;
|
||||
}
|
||||
else
|
||||
{
|
||||
I2Cx->CMDR = I2C_CMDR_STA;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Generates I2Cx communication STOP condition.
|
||||
* @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
|
||||
* @param NewState: NewState of the I2C STOP condition generation.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
* @retval None.
|
||||
*/
|
||||
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)
|
||||
{
|
||||
if(NewState != DISABLE)
|
||||
{
|
||||
|
||||
I2Cx->CMDR = I2C_CMDR_STO;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
I2Cx->CMDR = I2C_CMDR_STO;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the specified I2C acknowledge feature.
|
||||
* @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
|
||||
* @param NewState: NewState of the I2C Acknowledgement.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
* @retval None.
|
||||
*/
|
||||
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
|
||||
{
|
||||
if(NewState != DISABLE) I2Cx -> CMDR = I2C_CMDR_ACK;
|
||||
else I2Cx -> CMDR = I2C_CMDR_ACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generates I2Cx communication REGenerateSTART condition
|
||||
* @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
|
||||
* @param NewState: NewState of the I2C Acknowledgement.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
* @retval None.
|
||||
*/
|
||||
void I2C_RESTART(I2C_TypeDef * I2Cx, FunctionalState NewState)
|
||||
{
|
||||
if(NewState != DISABLE) I2Cx->CMDR = I2C_CMDR_RESTA;
|
||||
else I2Cx->CMDR = I2C_CMDR_RESTA;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the specified I2C Core_en feature
|
||||
* @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
|
||||
* @param NewState: NewState of the I2C Acknowledgement.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
* @retval None.
|
||||
*/
|
||||
void I2C_CoreEn(I2C_TypeDef* I2Cx,FunctionalState NewState)
|
||||
{
|
||||
/*Control*/
|
||||
if(NewState != DISABLE) I2Cx -> CTR = I2C_CTR_COREEN;
|
||||
else I2Cx -> CTR = I2C_CTR_COREEN;
|
||||
}
|
||||
|
||||
|
||||
void I2C_InterEn(I2C_TypeDef* I2Cx,FunctionalState NewState)
|
||||
{
|
||||
/*Control Interrupt Enable*/
|
||||
if(NewState != DISABLE) I2Cx -> CTR = I2C_CTR_INTEREN;
|
||||
else I2Cx -> CTR = I2C_CTR_INTEREN;
|
||||
}
|
||||
|
||||
|
||||
void I2C_MasterSlave(I2C_TypeDef* I2Cx,FunctionalState NewState)
|
||||
{
|
||||
/*Control MasterSlave select*/
|
||||
if(NewState == ENABLE)
|
||||
{
|
||||
if( (I2Cx->CTR & I2C_CTR_MODE) != I2C_CTR_MODE )
|
||||
{
|
||||
I2Cx->CTR = I2C_CTR_MODE;
|
||||
}
|
||||
}
|
||||
else // DISABLE
|
||||
{
|
||||
if( (I2Cx->CTR & I2C_CTR_MODE) == I2C_CTR_MODE )
|
||||
{
|
||||
I2Cx->CTR = I2C_CTR_MODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void I2C_ControlRW(I2C_TypeDef* I2Cx,FunctionalState NewState)
|
||||
{
|
||||
/*Control Read(receive)*/
|
||||
if(NewState == ENABLE)
|
||||
{
|
||||
if( (I2Cx->CTR & I2C_CTR_CTRRWN) != I2C_CTR_CTRRWN )
|
||||
{
|
||||
I2Cx->CTR = I2C_CTR_CTRRWN;
|
||||
}
|
||||
}
|
||||
else // DISABLE
|
||||
{
|
||||
if( (I2Cx->CTR & I2C_CTR_CTRRWN) == I2C_CTR_CTRRWN )
|
||||
{
|
||||
I2Cx->CTR = I2C_CTR_CTRRWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void I2C_ControlEn(I2C_TypeDef* I2Cx,FunctionalState NewState)
|
||||
{
|
||||
/*Control*/
|
||||
if(NewState == ENABLE)
|
||||
{
|
||||
if( (I2Cx->CTR & I2C_CTR_CTEN) != I2C_CTR_CTEN )
|
||||
{
|
||||
I2Cx->CTR = I2C_CTR_CTEN;
|
||||
}
|
||||
}
|
||||
else // DISABLE
|
||||
{
|
||||
if( (I2Cx->CTR & I2C_CTR_CTEN) == I2C_CTR_CTEN )
|
||||
{
|
||||
I2Cx->CTR = I2C_CTR_CTEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void I2C_InterRst(I2C_TypeDef* I2Cx,FunctionalState NewState)
|
||||
{
|
||||
/*Control*/
|
||||
if(NewState == ENABLE)
|
||||
{
|
||||
if( (I2Cx->ISCR & I2C_ISCR_RST) != I2C_ISCR_RST )
|
||||
{
|
||||
I2Cx->ISCR = I2C_ISCR_RST;
|
||||
}
|
||||
}
|
||||
else // DISABLE
|
||||
{
|
||||
if( (I2Cx->ISCR & I2C_ISCR_RST) == I2C_ISCR_RST )
|
||||
{
|
||||
I2Cx->ISCR = I2C_ISCR_RST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void I2C_Prescale(I2C_TypeDef* I2Cx,uint16_t Data)
|
||||
{
|
||||
I2Cx -> PRER = (uint16_t)Data;
|
||||
}
|
||||
|
||||
void I2C_TimeoutSet(I2C_TypeDef* I2Cx,uint16_t Data)
|
||||
{
|
||||
I2Cx -> TSR = (uint16_t)Data;
|
||||
}
|
||||
void I2C_SetSlavAddress(I2C_TypeDef* I2Cx,uint16_t Data)
|
||||
{
|
||||
I2Cx -> SADDR = (uint16_t)Data;
|
||||
}
|
||||
|
||||
|
||||
uint8_t I2C_StatusRead(I2C_TypeDef* I2Cx)
|
||||
{
|
||||
return (uint8_t)I2Cx -> SR;
|
||||
}
|
||||
|
||||
|
||||
ErrorStatus WaitEvent(I2C_TypeDef* I2Cx, uint32_t flag, FlagStatus status)
|
||||
{
|
||||
int Timeout=0,loopcnt=0;
|
||||
|
||||
Timeout = I2Cx->TSR;
|
||||
if(status == SET)
|
||||
{
|
||||
for(loopcnt=Timeout; loopcnt>0; loopcnt--)
|
||||
{
|
||||
if( ((I2Cx->SR) & flag) == flag )
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(loopcnt=Timeout; loopcnt>0; loopcnt--)
|
||||
{
|
||||
if( ((I2Cx->SR) & flag) != flag )
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks whether the specified I2C flag is set or not.
|
||||
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
||||
* @param I2C_EVENT: specifies the event to be checked.
|
||||
*/
|
||||
ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx,I2C_SR sr)
|
||||
{
|
||||
switch(sr)
|
||||
{
|
||||
case(I2C_ACKR):
|
||||
if( WaitEvent(I2Cx, I2C_SR_ACKR, SET) == ERROR) return ERROR;
|
||||
if( WaitEvent(I2Cx, I2C_SR_ACKR, RESET) == ERROR) return ERROR;
|
||||
break;
|
||||
|
||||
case(I2C_ACKT ):
|
||||
if( WaitEvent(I2Cx, I2C_SR_ACKT, SET) == ERROR) return ERROR;
|
||||
if( WaitEvent(I2Cx, I2C_SR_ACKT, RESET) == ERROR) return ERROR;
|
||||
break;
|
||||
|
||||
case(I2C_OACKR):
|
||||
if( WaitEvent(I2Cx, I2C_SR_ACKR, SET) == ERROR) return ERROR;
|
||||
break;
|
||||
|
||||
case(I2C_SACKR ):
|
||||
if( WaitEvent(I2Cx, I2C_SR_ACKR, RESET) == ERROR) return ERROR;
|
||||
break;
|
||||
|
||||
case(I2C_BT ):
|
||||
if( WaitEvent(I2Cx, I2C_SR_BT, RESET) == ERROR) return ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void I2C_SendSlaveAddress(I2C_TypeDef* I2Cx, uint8_t SlaveAddress,I2C_CTR Ctr)
|
||||
{
|
||||
switch(Ctr)
|
||||
{
|
||||
case(I2C_READ_SA7):
|
||||
I2C_SendData(I2Cx,SlaveAddress|I2C_READ);
|
||||
break;
|
||||
|
||||
|
||||
case(I2C_WRITE_SA7):
|
||||
I2C_SendData(I2Cx,SlaveAddress|I2C_WRITE);
|
||||
break;
|
||||
|
||||
case(I2C_CTRWRITE_SA7):
|
||||
case(I2C_CTRREAD_SA7):
|
||||
I2C_SendData(I2Cx,SlaveAddress);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int8_t I2C_Restart_Structure(I2C_TypeDef * I2Cx,uint32_t SlaveAddress,I2C_CTR Ctr)
|
||||
{
|
||||
|
||||
I2C_RESTART(I2Cx,ENABLE);
|
||||
I2C_SendSlaveAddress(I2Cx,SlaveAddress,Ctr);
|
||||
if((I2C_CheckEvent(I2Cx,I2C_OACKR)) == ERROR )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
I2C_RESTART(I2Cx,DISABLE);
|
||||
if((I2C_CheckEvent(I2Cx,I2C_SACKR)) == ERROR)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
I2C_Stop(conf);
|
||||
|
||||
/**
|
||||
* @brief Reads the specified I2C register and returns its value.
|
||||
* @param I2C_Register: specifies the register to read.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg I2C_Register_CR1: CR1 register.
|
||||
* @arg I2C_Register_CR2: CR2 register.
|
||||
* @arg I2C_Register_OAR1: OAR1 register.
|
||||
* @arg I2C_Register_OAR2: OAR2 register.
|
||||
* @arg I2C_Register_DR: DR register.
|
||||
* @arg I2C_Register_SR1: SR1 register.
|
||||
* @arg I2C_Register_SR2: SR2 register.
|
||||
* @arg I2C_Register_CCR: CCR register.
|
||||
* @arg I2C_Register_TRISE: TRISE register.
|
||||
* @retval The value of the read register.
|
||||
*/
|
||||
uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register)
|
||||
{
|
||||
__IO uint32_t tmp = 0;
|
||||
|
||||
|
||||
tmp = (uint32_t) I2Cx;
|
||||
tmp += I2C_Register;
|
||||
|
||||
/* Return the selected register value */
|
||||
return (*(__IO uint16_t *) tmp);
|
||||
return 0;//success
|
||||
}
|
||||
|
||||
int I2C_WriteRepeated(I2C_ConfigStruct* conf, uint8_t addr, uint8_t* data, uint32_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
void I2C_GPIO(void )
|
||||
{
|
||||
GPIO_InitDef.GPIO_Pin = GPIO_Pin_9; // Set to Pin_9 (SCL0))
|
||||
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; // Set to Mode Output
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitDef);
|
||||
HAL_PAD_AFConfig(PAD_PA,GPIO_Pin_9, PAD_AF1); // PAD Config - LED used 2nd Function
|
||||
|
||||
GPIO_InitDef.GPIO_Pin = GPIO_Pin_10; // Set to Pin_9 (SCL0))
|
||||
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; // Set to Mode Output
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitDef);
|
||||
HAL_PAD_AFConfig(PAD_PA,GPIO_Pin_10, PAD_AF1); // PAD Config - LED used 2nd Function
|
||||
|
||||
}
|
||||
void GPIO_I2C(void )
|
||||
{
|
||||
GPIO_InitDef.GPIO_Pin = GPIO_Pin_9; // Set to Pin_9 (SCL0))
|
||||
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; // Set to Mode Output
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitDef);
|
||||
HAL_PAD_AFConfig(PAD_PA,GPIO_Pin_9, PAD_AF0); // PAD Config - LED used 2nd Function
|
||||
|
||||
GPIO_InitDef.GPIO_Pin = GPIO_Pin_10; // Set to Pin_10 (SDA0))
|
||||
GPIO_InitDef.GPIO_Mode = GPIO_Mode_IN; // Set to Mode Output
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitDef);
|
||||
HAL_PAD_AFConfig(PAD_PA,GPIO_Pin_10, PAD_AF0); // PAD Config - LED used 2nd Functio
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WriteByte(uint8_t val)
|
||||
{
|
||||
int i;
|
||||
GPIO_TypeDef* GPIOx;
|
||||
GPIOx = GPIOA;
|
||||
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
if((val << i) & 0x80){
|
||||
digitalWrite(GPIOx,SDA, Bit_SET);
|
||||
}else{
|
||||
digitalWrite(GPIOx,SDA, Bit_RESET);
|
||||
}
|
||||
i2c_loop_us(1);
|
||||
digitalWrite(GPIOx,SCL, Bit_SET);
|
||||
i2c_loop_us(2);
|
||||
digitalWrite(GPIOx,SCL, Bit_RESET);
|
||||
}
|
||||
digitalWrite(GPIOx,SDA, Bit_SET);
|
||||
i2c_loop_us(1);
|
||||
digitalWrite(GPIOx,SCL, Bit_SET);
|
||||
i2c_loop_us(2);
|
||||
digitalWrite(GPIOx,SCL, Bit_RESET);
|
||||
}
|
||||
|
||||
|
||||
void digitalWrite(GPIO_TypeDef* GPIOx,uint16_t pin, uint16_t val)
|
||||
{
|
||||
I2C_Start(conf);
|
||||
|
||||
if(val == Bit_SET)
|
||||
//Write addr
|
||||
if(I2C_WriteByte(conf, addr) != 0)
|
||||
{
|
||||
GPIOx -> OUTENCLR = pin;
|
||||
printf("Received NACK at address phase!!\r\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
|
||||
//Write data
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
GPIOx -> OUTENSET |= pin;
|
||||
|
||||
if(I2C_WriteByte(conf, data[i]))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;//success
|
||||
}
|
||||
|
||||
|
||||
void i2c_loop_us(int us)
|
||||
int I2C_Read(I2C_ConfigStruct* conf, uint8_t addr, uint8_t* data, uint32_t len)
|
||||
{
|
||||
volatile uint32_t delay = us; // approximate loops per ms at 24 MHz, Debug config
|
||||
for(; delay != 0; delay--)
|
||||
__NOP();
|
||||
}
|
||||
void i2c_loop_ms(int count) {
|
||||
i2c_loop_us(count*1000);
|
||||
int i;
|
||||
|
||||
I2C_Start(conf);
|
||||
|
||||
//Write addr | read command
|
||||
if(I2C_WriteByte(conf, (addr | 1)) != 0)
|
||||
{
|
||||
printf("Received NACK at address phase!!\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Read data
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
data[i] = I2C_ReadByte(conf);
|
||||
|
||||
if( i == (len - 1) )
|
||||
I2C_SendNACK(conf);
|
||||
else
|
||||
I2C_SendACK(conf);
|
||||
}
|
||||
|
||||
I2C_Stop(conf);
|
||||
|
||||
return 0;//success
|
||||
}
|
||||
|
||||
int I2C_ReadRepeated(I2C_ConfigStruct* conf, uint8_t addr, uint8_t* data, uint32_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
I2C_Start(conf);
|
||||
|
||||
//Write addr | read command
|
||||
if(I2C_WriteByte(conf, (addr | 1)) != 0)
|
||||
{
|
||||
printf("Received NACK at address phase!!\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Read data
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
data[i] = I2C_ReadByte(conf);
|
||||
|
||||
if( i == (len - 1) )
|
||||
I2C_SendNACK(conf);
|
||||
else
|
||||
I2C_SendACK(conf);
|
||||
}
|
||||
|
||||
return 0;//success
|
||||
}
|
||||
|
||||
|
|
|
@ -27,210 +27,55 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*include -------------------------------------*/
|
||||
#include "W7500x.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
I2C_WRITE_SA7=0,
|
||||
I2C_READ_SA7,
|
||||
I2C_CTRWRITE_SA7,
|
||||
I2C_CTRREAD_SA7,
|
||||
} I2C_CTR;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
I2C_ACKR=0,
|
||||
I2C_ACKT,
|
||||
I2C_OACKR,
|
||||
I2C_SACKR,
|
||||
I2C_BT,
|
||||
} I2C_SR;
|
||||
#ifndef __W7500X_I2C_H
|
||||
#define __W7500X_I2C_H
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
INT_ACKR=-1,
|
||||
INT_ACKT=-2,
|
||||
INT_NACKR=-3,
|
||||
INT_NACKT=-4,
|
||||
INT_BT=-5,
|
||||
} I2C_ERROR;
|
||||
|
||||
|
||||
/**
|
||||
*@
|
||||
*/
|
||||
/** @defgroup I2C_registers
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define I2C_Register_PRER ((uint8_t)0x00)
|
||||
#define I2C_Register_CTR ((uint8_t)0x04)
|
||||
#define I2C_Register_CMDR ((uint8_t)0x08)
|
||||
#define I2C_Register_SR ((uint8_t)0x0C)
|
||||
#define I2C_Register_TSR ((uint8_t)0x10)
|
||||
#define I2C_Register_SADDR ((uint8_t)0x14)
|
||||
#define I2C_Register_TXR ((uint8_t)0x18)
|
||||
#define I2C_Register_RXR ((uint8_t)0x1C)
|
||||
#define I2C_Register_ISR ((uint8_t)0x20)
|
||||
#define I2C_Register_ISCR ((uint8_t)0x24)
|
||||
#define I2C_Register_ISMR ((uint8_t)0x28)
|
||||
#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_PRER) || \
|
||||
((REGISTER) == I2C_Register_CTR) || \
|
||||
((REGISTER) == I2C_Register_CMDR) || \
|
||||
((REGISTER) == I2C_Register_SR) || \
|
||||
((REGISTER) == I2C_Register_TSR) || \
|
||||
((REGISTER) == I2C_Register_SADDR) || \
|
||||
((REGISTER) == I2C_Register_TXR) || \
|
||||
((REGISTER) == I2C_Register_RXR) || \
|
||||
((REGISTER) == I2C_Register_ISR)|| \
|
||||
((REGISTER) == I2C_Register_ISCR)| \
|
||||
((REGISTER) == I2C_Register_ISMR))
|
||||
|
||||
/** @defgroup I2C_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/* I2C COREEN mask */
|
||||
#define I2C_CTR_COREEN_DIS ((uint16_t)0xFF7F)
|
||||
|
||||
/* I2C INTEREN mask */
|
||||
#define I2C_CTR_INTEREN_DIS ((uint16_t)0xFFBF)
|
||||
|
||||
/* I2C MODE(M/SN) mask */
|
||||
#define I2C_CTR_MODE_SLAVE ((uint16_t)0xFFDF)
|
||||
|
||||
/* I2C ADDR10(10/7N) mask */
|
||||
#define I2C_CTR_ADDR10_7BIT ((uint16_t)0xFFEF)
|
||||
|
||||
/* I2C CTRRWN(R/WN) mask */
|
||||
#define I2C_CTR_CTRRWN_DIS ((uint16_t)0xFFF7)
|
||||
|
||||
/* I2C CTREN mask */
|
||||
#define I2C_CTR_CTEN_DIS ((uint16_t)0xFFFB)
|
||||
|
||||
|
||||
/* I2C START mask */
|
||||
#define I2C_CMDR_START_DIS ((uint16_t)0xFF7F)
|
||||
|
||||
/* I2C STOP mask */
|
||||
#define I2C_CMDR_STOP_DIS ((uint16_t)0xFFBF)
|
||||
|
||||
/* I2C ACK mask */
|
||||
#define I2C_CMDR_ACK_NAK ((uint16_t)0xFFDF)
|
||||
|
||||
/* I2C RESTART mask */
|
||||
#define I2C_CMDR_RESTA_DIS ((uint16_t)0xFFEF)
|
||||
|
||||
/* I2C INTERRUPT RESET mask */
|
||||
#define I2C_ISCR_RST_DIS ((uint16_t)0xFFFE)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define I2C_WRITE 0
|
||||
#define I2C_READ 1
|
||||
#define I2C_RWSEL(NewState) (((NewState) == I2C_WRITE)|| \
|
||||
((NewState) == I2C_READ))
|
||||
|
||||
|
||||
#define I2C_Ack_Enable (0x01ul << 5)
|
||||
#define I2C_Ack_Disable (0x00ul << 5)
|
||||
#define IS_I2C_ACK_NewState(NewState) (((NewState) == I2C_Ack_Enable) || \
|
||||
((NewState) == I2C_Ack_Disable))
|
||||
|
||||
#define I2C_MASTER_MODE (0x01ul << 5 ) // 0x20
|
||||
#define I2C_SLAVE_MODE (0x00ul << 5 ) // 0x20
|
||||
#define IS_I2C_MODE(MODE) ((MODE) == I2C_MASTER_MODE)|| \
|
||||
(MODE) == I2C_SLAVE_MODE))
|
||||
|
||||
#define I2C_CTR_MODE (0x01ul << 5 ) // 0x20
|
||||
|
||||
#define SLAVE_ADDR10 0x208
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
I2C_Master = I2C_MASTER_MODE,
|
||||
I2C_Slave = I2C_SLAVE_MODE
|
||||
}I2C_MODE;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t prescale;
|
||||
uint16_t timeout;
|
||||
I2C_CTR control;
|
||||
}I2C_MasterConfStruct;
|
||||
|
||||
typedef enum {
|
||||
I2C_PA_5 = 0x05,
|
||||
I2C_PA_6 = 0x06,
|
||||
I2C_PA_9 = 0x09,
|
||||
I2C_PA_10 = 0x0A,
|
||||
I2C_PC_4 = 0x24,
|
||||
I2C_PC_5 = 0x25,
|
||||
I2C_PC_8 = 0x28,
|
||||
// Not connected
|
||||
I2C_NC = (int)0xFFFFFFFF
|
||||
} I2C_PinName;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t mode;
|
||||
uint16_t slave_address; // only on slave mode
|
||||
I2C_MasterConfStruct master;
|
||||
I2C_PinName scl;
|
||||
I2C_PinName sda;
|
||||
}I2C_ConfigStruct;
|
||||
|
||||
|
||||
/** @defgroup I2C_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
#define I2C_PORT(X) (((uint32_t)(X) >> 4) & 0xF) // port number (0=A, 1=B, 2=C, 3=D)
|
||||
#define I2C_PIN_INDEX(X) (1 << ((uint32_t)(X) & 0xF)) // pin index : flag bit
|
||||
|
||||
uint32_t I2C_Init (I2C_TypeDef* I2Cx, I2C_ConfigStruct conf);
|
||||
void setFrequency (I2C_TypeDef* I2Cx, uint8_t prescale);
|
||||
void I2C_DeInit (I2C_TypeDef* I2Cx);
|
||||
uint32_t I2C_Init(I2C_ConfigStruct* conf);
|
||||
|
||||
ErrorStatus I2C_Start (I2C_TypeDef* I2Cx, uint16_t slave_address, I2C_CTR ctr);
|
||||
void I2C_Stop (I2C_TypeDef* I2Cx);
|
||||
void I2C_Reset (I2C_TypeDef* I2Cx);
|
||||
void I2C_WriteBitSDA(I2C_ConfigStruct* conf, uint8_t data);
|
||||
void I2C_WriteBitSCL(I2C_ConfigStruct* conf, uint8_t data);
|
||||
uint8_t I2C_ReadBitSDA(I2C_ConfigStruct* conf);
|
||||
|
||||
void I2C_SendData (I2C_TypeDef* I2Cx,uint16_t Data);
|
||||
int8_t I2C_SendDataAck (I2C_TypeDef* I2Cx,uint16_t Data);
|
||||
int I2C_ReceiveData (I2C_TypeDef* I2Cx, int last);
|
||||
void I2C_SendACK(I2C_ConfigStruct* conf);
|
||||
void I2C_SendNACK(I2C_ConfigStruct* conf);
|
||||
|
||||
int I2C_Burst_Read (I2C_TypeDef* I2Cx, uint16_t address, uint8_t *data, int length, int stop);
|
||||
int I2C_Burst_Write (I2C_TypeDef* I2Cx, uint16_t address, uint8_t *data, int length, int stop);
|
||||
uint8_t I2C_WriteByte(I2C_ConfigStruct* conf, uint8_t data);
|
||||
uint8_t I2C_ReadByte(I2C_ConfigStruct* conf);
|
||||
|
||||
void I2C_GenerateSTART (I2C_TypeDef* I2Cx, FunctionalState NewState);
|
||||
void I2C_GenerateSTOP (I2C_TypeDef* I2Cx, FunctionalState NewState);
|
||||
void I2C_Start(I2C_ConfigStruct* conf);
|
||||
void I2C_Stop(I2C_ConfigStruct* conf);
|
||||
|
||||
void I2C_AcknowledgeConfig (I2C_TypeDef* I2Cx, FunctionalState NewState);
|
||||
void I2C_RESTART (I2C_TypeDef * I2Cx, FunctionalState NewState);
|
||||
int I2C_Write(I2C_ConfigStruct* conf, uint8_t addr, uint8_t* data, uint32_t len);
|
||||
int I2C_WriteRepeated(I2C_ConfigStruct* conf, uint8_t addr, uint8_t* data, uint32_t len);
|
||||
int I2C_Read(I2C_ConfigStruct* conf, uint8_t addr, uint8_t* data, uint32_t len);
|
||||
int I2C_ReadRepeated(I2C_ConfigStruct* conf, uint8_t addr, uint8_t* data, uint32_t len);
|
||||
|
||||
void I2C_CoreEn (I2C_TypeDef* I2Cx,FunctionalState NewState);
|
||||
void I2C_InterEn (I2C_TypeDef* I2Cx,FunctionalState NewState);
|
||||
void I2C_MasterSlave(I2C_TypeDef* I2Cx,FunctionalState NewState);
|
||||
void I2C_ControlRW (I2C_TypeDef* I2Cx,FunctionalState NewState);
|
||||
void I2C_ControlEn (I2C_TypeDef* I2Cx,FunctionalState NewState);
|
||||
|
||||
void I2C_InterRst (I2C_TypeDef* I2Cx,FunctionalState NewState);
|
||||
void I2C_Prescale (I2C_TypeDef* I2Cx,uint16_t Data);
|
||||
void I2C_TimeoutSet (I2C_TypeDef* I2Cx,uint16_t Data);
|
||||
void I2C_SetSlavAddress (I2C_TypeDef* I2Cx,uint16_t Data);
|
||||
uint8_t I2C_StatusRead (I2C_TypeDef* I2Cx);
|
||||
|
||||
ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx,I2C_SR sr);
|
||||
|
||||
void I2C_MasterInit (I2C_TypeDef * I2Cx,uint8_t Prescale,uint16_t Timeout,I2C_CTR Ctr);
|
||||
void I2C_SlaveInit (I2C_TypeDef * I2Cx,FunctionalState NewState, uint16_t data);
|
||||
void I2C_SendSlaveAddress (I2C_TypeDef* I2Cx, uint8_t SlaveAddress,I2C_CTR Ctr);
|
||||
|
||||
int8_t I2C_Restart_Structure(I2C_TypeDef * I2Cx,uint32_t SlaveAddress,I2C_CTR Ctr);
|
||||
uint16_t I2C_ReadRegister (I2C_TypeDef* I2Cx, uint8_t I2C_Register);
|
||||
|
||||
void I2C_GPIO(void);
|
||||
void GPIO_I2C(void );
|
||||
|
||||
void WriteByte(uint8_t val);
|
||||
|
||||
void digitalWrite(GPIO_TypeDef* GPIOx,uint16_t pin, uint16_t val);
|
||||
uint16_t digitalRead(GPIO_TypeDef* GPIOx,uint16_t pin);
|
||||
void i2c_loop_us(int us);
|
||||
void i2c_loop_ms(int count) ;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif //__W7500X_I2C_H
|
||||
|
||||
|
|
|
@ -185,49 +185,50 @@ const PinMap PinMap_SPI_SSEL[] = {
|
|||
/************PWM***************/
|
||||
const PinMap PinMap_PWM[] = {
|
||||
{P0_0, PWM_0, 1}, {P0_0, PWM_0, 2}, {P0_0, PWM_4, 3},
|
||||
{P0_1, PWM_0, 3}, {P0_1, PWM_1, 1}, {P0_1, PWM_4, 2},
|
||||
{P0_2, PWM_1, 2}, {P0_2, PWM_2, 1}, {P0_2, PWM_5, 3},
|
||||
{P0_3, PWM_1, 3}, {P0_3, PWM_3, 1}, {P0_3, PWM_5, 2},
|
||||
{P0_4, PWM_2, 2}, {P0_4, PWM_4, 1}, {P0_4, PWM_6, 3},
|
||||
{P0_5, PWM_2, 3}, {P0_5, PWM_5, 1}, {P0_5, PWM_6, 2},
|
||||
{P0_6, PWM_3, 2}, {P0_6, PWM_6, 1}, {P0_6, PWM_7, 3},
|
||||
{P0_7, PWM_3, 3}, {P0_7, PWM_7, 1}, {P0_7, PWM_7, 2},
|
||||
{P0_1, PWM_1, 1}, {P0_1, PWM_4, 2}, {P0_1, PWM_0, 3},
|
||||
{P0_2, PWM_2, 1}, {P0_2, PWM_1, 2}, {P0_2, PWM_5, 3},
|
||||
{P0_3, PWM_3, 1}, {P0_3, PWM_5, 2}, {P0_3, PWM_1, 3},
|
||||
{P0_4, PWM_4, 1}, {P0_4, PWM_2, 2}, {P0_4, PWM_6, 3},
|
||||
{P0_5, PWM_5, 1}, {P0_5, PWM_6, 2}, {P0_5, PWM_2, 3},
|
||||
{P0_6, PWM_6, 1}, {P0_6, PWM_3, 2}, {P0_6, PWM_7, 3},
|
||||
{P0_7, PWM_7, 1}, {P0_7, PWM_7, 2}, {P0_7, PWM_3, 3},
|
||||
|
||||
{P1_0, PWM_0, 1}, {P1_0, PWM_0, 2}, {P1_0, PWM_4, 3},
|
||||
{P1_1, PWM_0, 3}, {P1_1, PWM_1, 1}, {P1_1, PWM_4, 2},
|
||||
{P1_2, PWM_1, 2}, {P1_2, PWM_2, 1}, {P1_2, PWM_5, 3},
|
||||
{P1_3, PWM_1, 3}, {P1_3, PWM_3, 1}, {P1_3, PWM_5, 2},
|
||||
{P1_4, PWM_2, 2}, {P1_4, PWM_4, 1}, {P1_4, PWM_6, 3},
|
||||
{P1_5, PWM_2, 3}, {P1_5, PWM_5, 1}, {P1_5, PWM_6, 2},
|
||||
{P1_6, PWM_3, 2}, {P1_6, PWM_6, 1}, {P1_6, PWM_7, 3},
|
||||
{P1_7, PWM_3, 3}, {P1_7, PWM_7, 1}, {P1_7, PWM_7, 2},
|
||||
{P1_1, PWM_1, 1}, {P1_1, PWM_4, 2}, {P1_1, PWM_0, 3},
|
||||
{P1_2, PWM_2, 1}, {P1_2, PWM_1, 2}, {P1_2, PWM_5, 3},
|
||||
{P1_3, PWM_3, 1}, {P1_3, PWM_5, 2}, {P1_3, PWM_1, 3},
|
||||
{P1_4, PWM_4, 1}, {P1_4, PWM_2, 2}, {P1_4, PWM_6, 3},
|
||||
{P1_5, PWM_5, 1}, {P1_5, PWM_6, 2}, {P1_5, PWM_2, 3},
|
||||
{P1_6, PWM_6, 1}, {P1_6, PWM_3, 2}, {P1_6, PWM_7, 3},
|
||||
{P1_7, PWM_7, 1}, {P1_7, PWM_7, 2}, {P1_7, PWM_3, 3},
|
||||
|
||||
{P2_0, PWM_0, 1}, {P2_0, PWM_0, 2}, {P2_0, PWM_4, 3},
|
||||
{P2_1, PWM_0, 3}, {P2_1, PWM_1, 1}, {P2_1, PWM_4, 2},
|
||||
{P2_2, PWM_1, 2}, {P2_2, PWM_2, 1}, {P2_2, PWM_5, 3},
|
||||
{P2_3, PWM_1, 3}, {P2_3, PWM_3, 1}, {P2_3, PWM_5, 2},
|
||||
{P2_4, PWM_2, 2}, {P2_4, PWM_4, 1}, {P2_4, PWM_6, 3},
|
||||
{P2_5, PWM_2, 3}, {P2_5, PWM_5, 1}, {P2_5, PWM_6, 2},
|
||||
{P2_6, PWM_3, 2}, {P2_6, PWM_6, 1}, {P2_6, PWM_7, 3},
|
||||
{P2_7, PWM_3, 3}, {P2_7, PWM_7, 1}, {P2_7, PWM_7, 2},
|
||||
{P2_1, PWM_1, 1}, {P2_1, PWM_4, 2}, {P2_1, PWM_0, 3},
|
||||
{P2_2, PWM_2, 1}, {P2_2, PWM_1, 2}, {P2_2, PWM_5, 3},
|
||||
{P2_3, PWM_3, 1}, {P2_3, PWM_5, 2}, {P2_3, PWM_1, 3},
|
||||
{P2_4, PWM_4, 1}, {P2_4, PWM_2, 2}, {P2_4, PWM_6, 3},
|
||||
{P2_5, PWM_5, 1}, {P2_5, PWM_6, 2}, {P2_5, PWM_2, 3},
|
||||
{P2_6, PWM_6, 1}, {P2_6, PWM_3, 2}, {P2_6, PWM_7, 3},
|
||||
{P2_7, PWM_7, 1}, {P2_7, PWM_7, 2}, {P2_7, PWM_3, 3},
|
||||
|
||||
{P6_0, PWM_0, 1}, {P6_0, PWM_0, 2}, {P6_0, PWM_4, 3},
|
||||
{P6_1, PWM_0, 3}, {P6_1, PWM_1, 1}, {P6_1, PWM_4, 2},
|
||||
{P6_2, PWM_1, 2}, {P6_2, PWM_2, 1}, {P6_2, PWM_5, 3},
|
||||
{P6_3, PWM_1, 3}, {P6_3, PWM_3, 1}, {P6_3, PWM_5, 2},
|
||||
{P6_4, PWM_2, 2}, {P6_4, PWM_4, 1}, {P6_4, PWM_6, 3},
|
||||
{P6_5, PWM_2, 3}, {P6_5, PWM_5, 1}, {P6_5, PWM_6, 2},
|
||||
{P6_6, PWM_3, 2}, {P6_6, PWM_6, 1}, {P6_6, PWM_7, 3},
|
||||
{P6_7, PWM_3, 3}, {P6_7, PWM_7, 1}, {P6_7, PWM_7, 2},
|
||||
|
||||
{P6_1, PWM_1, 1}, {P6_1, PWM_4, 2}, {P6_1, PWM_0, 3},
|
||||
{P6_2, PWM_2, 1}, {P6_2, PWM_1, 2}, {P6_2, PWM_5, 3},
|
||||
{P6_3, PWM_3, 1}, {P6_3, PWM_5, 2}, {P6_3, PWM_1, 3},
|
||||
{P6_4, PWM_4, 1}, {P6_4, PWM_2, 2}, {P6_4, PWM_6, 3},
|
||||
{P6_5, PWM_5, 1}, {P6_5, PWM_6, 2}, {P6_5, PWM_2, 3},
|
||||
{P6_6, PWM_6, 1}, {P6_6, PWM_3, 2}, {P6_6, PWM_7, 3},
|
||||
{P6_7, PWM_7, 1}, {P6_7, PWM_7, 2}, {P6_7, PWM_3, 3},
|
||||
|
||||
{P7_0, PWM_0, 1}, {P7_0, PWM_0, 2}, {P7_0, PWM_4, 3},
|
||||
{P7_1, PWM_0, 3}, {P7_1, PWM_1, 1}, {P7_1, PWM_4, 2},
|
||||
{P7_2, PWM_1, 2}, {P7_2, PWM_2, 1}, {P7_2, PWM_5, 3},
|
||||
{P7_3, PWM_1, 3}, {P7_3, PWM_3, 1}, {P7_3, PWM_5, 2},
|
||||
{P7_4, PWM_2, 2}, {P7_4, PWM_4, 1}, {P7_4, PWM_6, 3},
|
||||
{P7_5, PWM_2, 3}, {P7_5, PWM_5, 1}, {P7_5, PWM_6, 2},
|
||||
{P7_6, PWM_3, 2}, {P7_6, PWM_6, 1}, {P7_6, PWM_7, 3},
|
||||
{P7_7, PWM_3, 3}, {P7_7, PWM_7, 1}, {P7_7, PWM_7, 2},
|
||||
{P7_1, PWM_1, 1}, {P7_1, PWM_4, 2}, {P7_1, PWM_0, 3},
|
||||
{P7_2, PWM_2, 1}, {P7_2, PWM_1, 2}, {P7_2, PWM_5, 3},
|
||||
{P7_3, PWM_3, 1}, {P7_3, PWM_5, 2}, {P7_3, PWM_1, 3},
|
||||
{P7_4, PWM_4, 1}, {P7_4, PWM_2, 2}, {P7_4, PWM_6, 3},
|
||||
{P7_5, PWM_5, 1}, {P7_5, PWM_6, 2}, {P7_5, PWM_2, 3},
|
||||
{P7_6, PWM_6, 1}, {P7_6, PWM_3, 2}, {P7_6, PWM_7, 3},
|
||||
{P7_7, PWM_7, 1}, {P7_7, PWM_7, 2}, {P7_7, PWM_3, 3},
|
||||
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
|
|
|
@ -52,55 +52,31 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
// Check if there is a pulse train already active on this port
|
||||
int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin*4))) >> (port_pin*4);
|
||||
if((pin_func > 0) && (pin_func < 4)) {
|
||||
// Search through PinMap_PWM to find the active PT
|
||||
while(pwm.pin != (PinName)NC) {
|
||||
if((pwm.pin == pin) && (pwm.function == pin_func)) {
|
||||
break;
|
||||
}
|
||||
pwm = PinMap_PWM[++i];
|
||||
}
|
||||
MBED_ASSERT((pin_func < 1) || (pin_func > 3));
|
||||
|
||||
} else {
|
||||
// Search through PinMap_PWM to find an available PT
|
||||
int i = 0;
|
||||
while(pwm.pin != (PinName)NC && (i > -1)) {
|
||||
pwm = PinMap_PWM[i++];
|
||||
if(pwm.pin == pin) {
|
||||
// Check each instance of PT
|
||||
while(1) {
|
||||
// Check to see if this PT instance is already in use
|
||||
if((((mxc_pt_regs_t*)pwm.peripheral)->rate_length &
|
||||
MXC_F_PT_RATE_LENGTH_MODE)) {
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
// If all instances are in use, overwrite the last
|
||||
pwm = PinMap_PWM[++i];
|
||||
if(pwm.pin != pin) {
|
||||
pwm = PinMap_PWM[--i];
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// Search through PinMap_PWM to find the pin
|
||||
while(pwm.pin != pin) {
|
||||
pwm = PinMap_PWM[++i];
|
||||
}
|
||||
|
||||
// Make sure we found an available PWM generator
|
||||
MBED_ASSERT(pwm.pin != (PinName)NC);
|
||||
// Find a free PT instance on this pin
|
||||
while(pwm.pin == pin) {
|
||||
|
||||
// Disable all pwm output
|
||||
MXC_PTG->ctrl = 0;
|
||||
// Check to see if this PT instance is free
|
||||
if((((mxc_pt_regs_t*)pwm.peripheral)->rate_length &
|
||||
MXC_F_PT_RATE_LENGTH_MODE)) {
|
||||
break;
|
||||
}
|
||||
|
||||
pwm = PinMap_PWM[++i];
|
||||
|
||||
// Raise an assertion if we can not allocate another PT instance.
|
||||
MBED_ASSERT(pwm.pin == pin);
|
||||
}
|
||||
|
||||
// Enable the clock
|
||||
MXC_CLKMAN->clk_ctrl_2_pt = MXC_E_CLKMAN_CLK_SCALE_ENABLED;
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin*4)));
|
||||
|
||||
// Set the obj pointer to the propper PWM instance
|
||||
obj->pwm = (mxc_pt_regs_t*)pwm.peripheral;
|
||||
|
||||
|
@ -120,6 +96,9 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pwmout_period_us(obj, 20000);
|
||||
pwmout_write (obj, 0);
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin*4)));
|
||||
|
||||
// Enable the global pwm
|
||||
MXC_PTG->ctrl = MXC_F_PT_CTRL_ENABLE_ALL;
|
||||
}
|
||||
|
|
|
@ -129,31 +129,32 @@ const PinMap PinMap_SPI_SSEL[] = {
|
|||
/************PWM***************/
|
||||
const PinMap PinMap_PWM[] = {
|
||||
{P0_0, PWM_0, 1}, {P0_0, PWM_0, 2}, {P0_0, PWM_4, 3},
|
||||
{P0_1, PWM_0, 3}, {P0_1, PWM_1, 1}, {P0_1, PWM_4, 2},
|
||||
{P0_2, PWM_1, 2}, {P0_2, PWM_2, 1}, {P0_2, PWM_5, 3},
|
||||
{P0_3, PWM_1, 3}, {P0_3, PWM_3, 1}, {P0_3, PWM_5, 2},
|
||||
{P0_4, PWM_2, 2}, {P0_4, PWM_4, 1}, {P0_4, PWM_6, 3},
|
||||
{P0_5, PWM_2, 3}, {P0_5, PWM_5, 1}, {P0_5, PWM_6, 2},
|
||||
{P0_6, PWM_3, 2}, {P0_6, PWM_6, 1}, {P0_6, PWM_7, 3},
|
||||
{P0_7, PWM_3, 3}, {P0_7, PWM_7, 1}, {P0_7, PWM_7, 2},
|
||||
{P0_1, PWM_1, 1}, {P0_1, PWM_4, 2}, {P0_1, PWM_0, 3},
|
||||
{P0_2, PWM_2, 1}, {P0_2, PWM_1, 2}, {P0_2, PWM_5, 3},
|
||||
{P0_3, PWM_3, 1}, {P0_3, PWM_5, 2}, {P0_3, PWM_1, 3},
|
||||
{P0_4, PWM_4, 1}, {P0_4, PWM_2, 2}, {P0_4, PWM_6, 3},
|
||||
{P0_5, PWM_5, 1}, {P0_5, PWM_6, 2}, {P0_5, PWM_2, 3},
|
||||
{P0_6, PWM_6, 1}, {P0_6, PWM_3, 2}, {P0_6, PWM_7, 3},
|
||||
{P0_7, PWM_7, 1}, {P0_7, PWM_7, 2}, {P0_7, PWM_3, 3},
|
||||
|
||||
{P1_0, PWM_0, 1}, {P1_0, PWM_0, 2}, {P1_0, PWM_4, 3},
|
||||
{P1_1, PWM_0, 3}, {P1_1, PWM_1, 1}, {P1_1, PWM_4, 2},
|
||||
{P1_2, PWM_1, 2}, {P1_2, PWM_2, 1}, {P1_2, PWM_5, 3},
|
||||
{P1_3, PWM_1, 3}, {P1_3, PWM_3, 1}, {P1_3, PWM_5, 2},
|
||||
{P1_4, PWM_2, 2}, {P1_4, PWM_4, 1}, {P1_4, PWM_6, 3},
|
||||
{P1_5, PWM_2, 3}, {P1_5, PWM_5, 1}, {P1_5, PWM_6, 2},
|
||||
{P1_6, PWM_3, 2}, {P1_6, PWM_6, 1}, {P1_6, PWM_7, 3},
|
||||
{P1_7, PWM_3, 3}, {P1_7, PWM_7, 1}, {P1_7, PWM_7, 2},
|
||||
{P1_1, PWM_1, 1}, {P1_1, PWM_4, 2}, {P1_1, PWM_0, 3},
|
||||
{P1_2, PWM_2, 1}, {P1_2, PWM_1, 2}, {P1_2, PWM_5, 3},
|
||||
{P1_3, PWM_3, 1}, {P1_3, PWM_5, 2}, {P1_3, PWM_1, 3},
|
||||
{P1_4, PWM_4, 1}, {P1_4, PWM_2, 2}, {P1_4, PWM_6, 3},
|
||||
{P1_5, PWM_5, 1}, {P1_5, PWM_6, 2}, {P1_5, PWM_2, 3},
|
||||
{P1_6, PWM_6, 1}, {P1_6, PWM_3, 2}, {P1_6, PWM_7, 3},
|
||||
{P1_7, PWM_7, 1}, {P1_7, PWM_7, 2}, {P1_7, PWM_3, 3},
|
||||
|
||||
{P2_0, PWM_0, 1}, {P2_0, PWM_0, 2}, {P2_0, PWM_4, 3},
|
||||
{P2_1, PWM_0, 3}, {P2_1, PWM_1, 1}, {P2_1, PWM_4, 2},
|
||||
{P2_2, PWM_1, 2}, {P2_2, PWM_2, 1}, {P2_2, PWM_5, 3},
|
||||
{P2_3, PWM_1, 3}, {P2_3, PWM_3, 1}, {P2_3, PWM_5, 2},
|
||||
{P2_4, PWM_2, 2}, {P2_4, PWM_4, 1}, {P2_4, PWM_6, 3},
|
||||
{P2_5, PWM_2, 3}, {P2_5, PWM_5, 1}, {P2_5, PWM_6, 2},
|
||||
{P2_6, PWM_3, 2}, {P2_6, PWM_6, 1}, {P2_6, PWM_7, 3},
|
||||
{P2_7, PWM_3, 3}, {P2_7, PWM_7, 1}, {P2_7, PWM_7, 2},
|
||||
{P2_1, PWM_1, 1}, {P2_1, PWM_4, 2}, {P2_1, PWM_0, 3},
|
||||
{P2_2, PWM_2, 1}, {P2_2, PWM_1, 2}, {P2_2, PWM_5, 3},
|
||||
{P2_3, PWM_3, 1}, {P2_3, PWM_5, 2}, {P2_3, PWM_1, 3},
|
||||
{P2_4, PWM_4, 1}, {P2_4, PWM_2, 2}, {P2_4, PWM_6, 3},
|
||||
{P2_5, PWM_5, 1}, {P2_5, PWM_6, 2}, {P2_5, PWM_2, 3},
|
||||
{P2_6, PWM_6, 1}, {P2_6, PWM_3, 2}, {P2_6, PWM_7, 3},
|
||||
{P2_7, PWM_7, 1}, {P2_7, PWM_7, 2}, {P2_7, PWM_3, 3},
|
||||
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
|
|
|
@ -52,55 +52,31 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
// Check if there is a pulse train already active on this port
|
||||
int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin*4))) >> (port_pin*4);
|
||||
if((pin_func > 0) && (pin_func < 4)) {
|
||||
// Search through PinMap_PWM to find the active PT
|
||||
while(pwm.pin != (PinName)NC) {
|
||||
if((pwm.pin == pin) && (pwm.function == pin_func)) {
|
||||
break;
|
||||
}
|
||||
pwm = PinMap_PWM[++i];
|
||||
}
|
||||
MBED_ASSERT((pin_func < 1) || (pin_func > 3));
|
||||
|
||||
} else {
|
||||
// Search through PinMap_PWM to find an available PT
|
||||
int i = 0;
|
||||
while(pwm.pin != (PinName)NC && (i > -1)) {
|
||||
pwm = PinMap_PWM[i++];
|
||||
if(pwm.pin == pin) {
|
||||
// Check each instance of PT
|
||||
while(1) {
|
||||
// Check to see if this PT instance is already in use
|
||||
if((((mxc_pt_regs_t*)pwm.peripheral)->rate_length &
|
||||
MXC_F_PT_RATE_LENGTH_MODE)) {
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
// If all instances are in use, overwrite the last
|
||||
pwm = PinMap_PWM[++i];
|
||||
if(pwm.pin != pin) {
|
||||
pwm = PinMap_PWM[--i];
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// Search through PinMap_PWM to find the pin
|
||||
while(pwm.pin != pin) {
|
||||
pwm = PinMap_PWM[++i];
|
||||
}
|
||||
|
||||
// Make sure we found an available PWM generator
|
||||
MBED_ASSERT(pwm.pin != (PinName)NC);
|
||||
// Find a free PT instance on this pin
|
||||
while(pwm.pin == pin) {
|
||||
|
||||
// Disable all pwm output
|
||||
MXC_PTG->ctrl = 0;
|
||||
// Check to see if this PT instance is free
|
||||
if((((mxc_pt_regs_t*)pwm.peripheral)->rate_length &
|
||||
MXC_F_PT_RATE_LENGTH_MODE)) {
|
||||
break;
|
||||
}
|
||||
|
||||
pwm = PinMap_PWM[++i];
|
||||
|
||||
// Raise an assertion if we can not allocate another PT instance.
|
||||
MBED_ASSERT(pwm.pin == pin);
|
||||
}
|
||||
|
||||
// Enable the clock
|
||||
MXC_CLKMAN->clk_ctrl_2_pt = MXC_E_CLKMAN_CLK_SCALE_ENABLED;
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin*4)));
|
||||
|
||||
// Set the obj pointer to the propper PWM instance
|
||||
obj->pwm = (mxc_pt_regs_t*)pwm.peripheral;
|
||||
|
||||
|
@ -120,6 +96,9 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pwmout_period_us(obj, 20000);
|
||||
pwmout_write (obj, 0);
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin*4)));
|
||||
|
||||
// Enable the global pwm
|
||||
MXC_PTG->ctrl = MXC_F_PT_CTRL_ENABLE_ALL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
S110/S120/S130 license agreement
|
||||
|
||||
NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT
|
||||
|
||||
License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120 and S130 Bluetooth SoftDevice software packages ("SoftDevice").
|
||||
You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before
|
||||
downloading, installing and/or using any software or content in the SoftDevice provided herewith.
|
||||
|
||||
YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS
|
||||
OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF
|
||||
THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS.
|
||||
|
||||
IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE
|
||||
INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE.
|
||||
|
||||
1. Grant of License
|
||||
Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license
|
||||
("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated
|
||||
in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this
|
||||
agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit.
|
||||
|
||||
2. Title
|
||||
Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and
|
||||
other intellectual property rights in and to the SoftDevice.
|
||||
|
||||
3. No Modifications or Reverse Engineering
|
||||
Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code
|
||||
parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code.
|
||||
|
||||
4. Distribution Restrictions
|
||||
Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party.
|
||||
Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein.
|
||||
Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee
|
||||
necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making
|
||||
such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice.
|
||||
|
||||
5. No Other Rights
|
||||
Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be
|
||||
contrary to this Agreement.
|
||||
|
||||
6. Fees
|
||||
Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to
|
||||
comply with the Agreement.
|
||||
|
||||
7. DISCLAIMER OF WARRANTY
|
||||
THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS
|
||||
LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR
|
||||
THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE
|
||||
IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE
|
||||
REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE.
|
||||
LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S
|
||||
INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT.
|
||||
|
||||
8. No Support
|
||||
Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how,
|
||||
bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice.
|
||||
|
||||
9. Limitation of Liability
|
||||
In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of
|
||||
procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any
|
||||
special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract,
|
||||
tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers,
|
||||
licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or
|
||||
limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to
|
||||
USD 50.
|
||||
|
||||
10. Breach of Contract
|
||||
Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably
|
||||
attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both
|
||||
direct and indirect costs for Nordic and its licensors.
|
||||
|
||||
11. Indemnity
|
||||
Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and
|
||||
agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which
|
||||
is not due to causes for which Nordic is responsible.
|
||||
|
||||
12. Governing Law
|
||||
This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett.
|
||||
|
||||
13. Assignment
|
||||
Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic.
|
||||
|
||||
14. Termination
|
||||
Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this
|
||||
Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any
|
||||
other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology.
|
||||
|
||||
15. Third party beneficiaries
|
||||
Nordic’s licensors are intended third party beneficiaries under this Agreement.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,198 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2013 Nordic Semiconductor
|
||||
*
|
||||
* 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 MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
typedef enum {
|
||||
p0 = 0,
|
||||
p1 = 1,
|
||||
p2 = 2,
|
||||
p3 = 3,
|
||||
p4 = 4,
|
||||
p5 = 5,
|
||||
p6 = 6,
|
||||
p7 = 7,
|
||||
p8 = 8,
|
||||
p9 = 9,
|
||||
p10 = 10,
|
||||
p11 = 11,
|
||||
p12 = 12,
|
||||
p13 = 13,
|
||||
p14 = 14,
|
||||
p15 = 15,
|
||||
p16 = 16,
|
||||
p17 = 17,
|
||||
p18 = 18,
|
||||
p19 = 19,
|
||||
p20 = 20,
|
||||
p21 = 21,
|
||||
p22 = 22,
|
||||
p23 = 23,
|
||||
p24 = 24,
|
||||
p25 = 25,
|
||||
p26 = 26,
|
||||
p27 = 27,
|
||||
p28 = 28,
|
||||
p29 = 29,
|
||||
p30 = 30,
|
||||
|
||||
//NORMAL PINS...
|
||||
P0_0 = p0,
|
||||
P0_1 = p1,
|
||||
P0_2 = p2,
|
||||
P0_3 = p3,
|
||||
P0_4 = p4,
|
||||
P0_5 = p5,
|
||||
P0_6 = p6,
|
||||
P0_7 = p7,
|
||||
|
||||
P0_8 = p8,
|
||||
P0_9 = p9,
|
||||
P0_10 = p10,
|
||||
P0_11 = p11,
|
||||
P0_12 = p12,
|
||||
P0_13 = p13,
|
||||
P0_14 = p14,
|
||||
P0_15 = p15,
|
||||
|
||||
P0_16 = p16,
|
||||
P0_17 = p17,
|
||||
P0_18 = p18,
|
||||
P0_19 = p19,
|
||||
P0_20 = p20,
|
||||
P0_21 = p21,
|
||||
P0_22 = p22,
|
||||
P0_23 = p23,
|
||||
|
||||
P0_24 = p24,
|
||||
P0_25 = p25,
|
||||
P0_26 = p26,
|
||||
P0_27 = p27,
|
||||
P0_28 = p28,
|
||||
P0_29 = p29,
|
||||
P0_30 = p30,
|
||||
|
||||
//PADS
|
||||
PAD3 = p1,
|
||||
PAD2 = p2,
|
||||
PAD1 = p3,
|
||||
|
||||
|
||||
//LED MATRIX COLS
|
||||
COL1 = p4,
|
||||
COL2 = p5,
|
||||
COL3 = p6,
|
||||
COL4 = p7,
|
||||
COL5 = p8,
|
||||
COL6 = p9,
|
||||
COL7 = p10,
|
||||
COL8 = p11,
|
||||
COL9 = p12,
|
||||
|
||||
//LED MATRIX ROWS
|
||||
ROW1 = p13,
|
||||
ROW2 = p14,
|
||||
ROW3 = p15,
|
||||
|
||||
//NORMAL PIN (NO SPECIFIED FUNCTIONALITY)
|
||||
//PIN_16
|
||||
|
||||
// BUTTON A
|
||||
BUTTON_A = p17,
|
||||
|
||||
|
||||
//NORMAL PIN (NO SPECIFIED FUNCTIONALITY)
|
||||
//PIN_18
|
||||
|
||||
//TARGET RESET
|
||||
TGT_NRESET = p19,
|
||||
|
||||
//NORMAL PIN (NO SPECIFIED FUNCTIONALITY)
|
||||
//PIN_20
|
||||
|
||||
//MASTER OUT SLAVE IN
|
||||
MOSI = p21,
|
||||
|
||||
//MASTER IN SLAVE OUT
|
||||
MISO = p22,
|
||||
|
||||
//SERIAL CLOCK
|
||||
SCK = p23,
|
||||
|
||||
// RX AND TX PINS
|
||||
TGT_TX = p24,
|
||||
TGT_RX = p25,
|
||||
|
||||
//BUTTON B
|
||||
BUTTON_B = p26,
|
||||
|
||||
//ACCEL INTERRUPT PINS (MMA8653FC)
|
||||
ACCEL_INT2 = p27,
|
||||
ACCEL_INT1 = p28,
|
||||
|
||||
//MAGENETOMETER INTERRUPT PIN (MAG3110)
|
||||
MAG_INT1 = p29,
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF,
|
||||
|
||||
RX_PIN_NUMBER = TGT_RX,
|
||||
TX_PIN_NUMBER = TGT_TX,
|
||||
CTS_PIN_NUMBER = 31, //unused ** REQUIRES A PROPER FIX **
|
||||
RTS_PIN_NUMBER = 31, //unused
|
||||
|
||||
// mBed interface Pins
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
USBRX = RX_PIN_NUMBER,
|
||||
|
||||
LED1 = PAD1,
|
||||
LED2 = PAD2,
|
||||
LED3 = PAD3,
|
||||
LED4 = P0_16,
|
||||
|
||||
//SDA (SERIAL DATA LINE)
|
||||
I2C_SDA0 = p30,
|
||||
|
||||
//SCL (SERIAL CLOCK LINE)
|
||||
I2C_SCL0 = p0
|
||||
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,57 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* 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 MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
#define DEVICE_PORTIN 1
|
||||
#define DEVICE_PORTOUT 1
|
||||
#define DEVICE_PORTINOUT 1
|
||||
|
||||
#define DEVICE_INTERRUPTIN 1
|
||||
|
||||
#define DEVICE_ANALOGIN 1
|
||||
#define DEVICE_ANALOGOUT 0
|
||||
|
||||
#define DEVICE_SERIAL 1
|
||||
|
||||
#define DEVICE_I2C 1
|
||||
#define DEVICE_I2CSLAVE 0
|
||||
|
||||
#define DEVICE_SPI 1
|
||||
#define DEVICE_SPISLAVE 1
|
||||
|
||||
#define DEVICE_CAN 0
|
||||
|
||||
#define DEVICE_RTC 0
|
||||
|
||||
#define DEVICE_ETHERNET 0
|
||||
|
||||
#define DEVICE_PWMOUT 1
|
||||
|
||||
#define DEVICE_SEMIHOST 0
|
||||
#define DEVICE_LOCALFILESYSTEM 0
|
||||
|
||||
#define DEVICE_SLEEP 1
|
||||
|
||||
#define DEVICE_DEBUG_AWARENESS 0
|
||||
|
||||
#define DEVICE_STDIO_MESSAGES 0
|
||||
|
||||
#define DEVICE_ERROR_PATTERN 1
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -158,6 +158,9 @@ typedef enum {
|
|||
I2C_SCL = P0_21,
|
||||
I2C_SDA = P0_22,
|
||||
|
||||
I2C_SCL0 = P0_21, //required definition for the i2c patch
|
||||
I2C_SDA0 = P0_22, //required definition for the i2c patch
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "i2c_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "twi_master.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
// nRF51822's I2C_0 and SPI_0 (I2C_1, SPI_1 and SPIS1) share the same address.
|
||||
|
@ -53,7 +54,8 @@ void twi_master_init(i2c_t *obj, PinName sda, PinName scl, int frequency)
|
|||
|
||||
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
|
||||
{
|
||||
NRF_TWI_Type *i2c;
|
||||
twi_master_init_and_clear();
|
||||
NRF_TWI_Type *i2c = NULL;
|
||||
|
||||
if (i2c0_spi0_peripheral.usage == I2C_SPI_PERIPHERAL_FOR_I2C &&
|
||||
i2c0_spi0_peripheral.sda_mosi == (uint8_t)sda &&
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
#ifndef TWI_MASTER_CONFIG
|
||||
#define TWI_MASTER_CONFIG
|
||||
|
||||
#include "PinNames.h"
|
||||
|
||||
#define TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER (I2C_SCL0)
|
||||
#define TWI_MASTER_CONFIG_DATA_PIN_NUMBER (I2C_SDA0)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,303 @@
|
|||
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "twi_master.h"
|
||||
#include "twi_config.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf_delay.h"
|
||||
|
||||
/* Max cycles approximately to wait on RXDREADY and TXDREADY event,
|
||||
* This is optimized way instead of using timers, this is not power aware. */
|
||||
#define MAX_TIMEOUT_LOOPS (20000UL) /**< MAX while loops to wait for RXD/TXD event */
|
||||
|
||||
static bool twi_master_write(uint8_t * data, uint8_t data_length, bool issue_stop_condition)
|
||||
{
|
||||
uint32_t timeout = MAX_TIMEOUT_LOOPS; /* max loops to wait for EVENTS_TXDSENT event*/
|
||||
|
||||
if (data_length == 0)
|
||||
{
|
||||
/* Return false for requesting data of size 0 */
|
||||
return false;
|
||||
}
|
||||
|
||||
NRF_TWI1->TXD = *data++;
|
||||
NRF_TWI1->TASKS_STARTTX = 1;
|
||||
|
||||
/** @snippet [TWI HW master write] */
|
||||
while (true)
|
||||
{
|
||||
while (NRF_TWI1->EVENTS_TXDSENT == 0 && NRF_TWI1->EVENTS_ERROR == 0 && (--timeout))
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
if (timeout == 0 || NRF_TWI1->EVENTS_ERROR != 0)
|
||||
{
|
||||
// Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at
|
||||
// Product Anomaly Notification document found at
|
||||
// https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads
|
||||
NRF_TWI1->EVENTS_ERROR = 0;
|
||||
NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
|
||||
NRF_TWI1->POWER = 0;
|
||||
nrf_delay_us(5);
|
||||
NRF_TWI1->POWER = 1;
|
||||
NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
|
||||
|
||||
(void)twi_master_init_and_clear();
|
||||
|
||||
return false;
|
||||
}
|
||||
NRF_TWI1->EVENTS_TXDSENT = 0;
|
||||
if (--data_length == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
NRF_TWI1->TXD = *data++;
|
||||
}
|
||||
/** @snippet [TWI HW master write] */
|
||||
|
||||
if (issue_stop_condition)
|
||||
{
|
||||
NRF_TWI1->EVENTS_STOPPED = 0;
|
||||
NRF_TWI1->TASKS_STOP = 1;
|
||||
/* Wait until stop sequence is sent */
|
||||
while(NRF_TWI1->EVENTS_STOPPED == 0)
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Function for read by twi_master.
|
||||
*/
|
||||
static bool twi_master_read(uint8_t * data, uint8_t data_length, bool issue_stop_condition)
|
||||
{
|
||||
uint32_t timeout = MAX_TIMEOUT_LOOPS; /* max loops to wait for RXDREADY event*/
|
||||
|
||||
if (data_length == 0)
|
||||
{
|
||||
/* Return false for requesting data of size 0 */
|
||||
return false;
|
||||
}
|
||||
else if (data_length == 1)
|
||||
{
|
||||
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_STOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_SUSPEND;
|
||||
}
|
||||
|
||||
NRF_PPI->CHENSET = PPI_CHENSET_CH0_Msk;
|
||||
NRF_TWI1->EVENTS_RXDREADY = 0;
|
||||
NRF_TWI1->TASKS_STARTRX = 1;
|
||||
|
||||
/** @snippet [TWI HW master read] */
|
||||
while (true)
|
||||
{
|
||||
while (NRF_TWI1->EVENTS_RXDREADY == 0 && NRF_TWI1->EVENTS_ERROR == 0 && (--timeout))
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
NRF_TWI1->EVENTS_RXDREADY = 0;
|
||||
|
||||
if (timeout == 0 || NRF_TWI1->EVENTS_ERROR != 0)
|
||||
{
|
||||
// Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at
|
||||
// Product Anomaly Notification document found at
|
||||
// https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads
|
||||
NRF_TWI1->EVENTS_ERROR = 0;
|
||||
NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
|
||||
NRF_TWI1->POWER = 0;
|
||||
nrf_delay_us(5);
|
||||
NRF_TWI1->POWER = 1;
|
||||
NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
|
||||
|
||||
(void)twi_master_init_and_clear();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
*data++ = NRF_TWI1->RXD;
|
||||
|
||||
/* Configure PPI to stop TWI master before we get last BB event */
|
||||
if (--data_length == 1)
|
||||
{
|
||||
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_STOP;
|
||||
}
|
||||
|
||||
if (data_length == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at
|
||||
// Product Anomaly Notification document found at
|
||||
// https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads
|
||||
nrf_delay_us(20);
|
||||
NRF_TWI1->TASKS_RESUME = 1;
|
||||
}
|
||||
/** @snippet [TWI HW master read] */
|
||||
|
||||
/* Wait until stop sequence is sent */
|
||||
while(NRF_TWI1->EVENTS_STOPPED == 0)
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
NRF_TWI1->EVENTS_STOPPED = 0;
|
||||
|
||||
NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for detecting stuck slaves (SDA = 0 and SCL = 1) and tries to clear the bus.
|
||||
*
|
||||
* @return
|
||||
* @retval false Bus is stuck.
|
||||
* @retval true Bus is clear.
|
||||
*/
|
||||
static bool twi_master_clear_bus(void)
|
||||
{
|
||||
uint32_t twi_state;
|
||||
bool bus_clear;
|
||||
uint32_t clk_pin_config;
|
||||
uint32_t data_pin_config;
|
||||
|
||||
// Save and disable TWI hardware so software can take control over the pins.
|
||||
twi_state = NRF_TWI1->ENABLE;
|
||||
NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
|
||||
|
||||
clk_pin_config = \
|
||||
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER];
|
||||
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = \
|
||||
(GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
|
||||
| (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
|
||||
| (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
|
||||
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
|
||||
| (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
|
||||
data_pin_config = \
|
||||
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER];
|
||||
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = \
|
||||
(GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
|
||||
| (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
|
||||
| (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
|
||||
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
|
||||
| (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
|
||||
TWI_SDA_HIGH();
|
||||
TWI_SCL_HIGH();
|
||||
TWI_DELAY();
|
||||
|
||||
if ((TWI_SDA_READ() == 1) && (TWI_SCL_READ() == 1))
|
||||
{
|
||||
bus_clear = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint_fast8_t i;
|
||||
bus_clear = false;
|
||||
|
||||
// Clock max 18 pulses worst case scenario(9 for master to send the rest of command and 9
|
||||
// for slave to respond) to SCL line and wait for SDA come high.
|
||||
for (i=18; i--;)
|
||||
{
|
||||
TWI_SCL_LOW();
|
||||
TWI_DELAY();
|
||||
TWI_SCL_HIGH();
|
||||
TWI_DELAY();
|
||||
|
||||
if (TWI_SDA_READ() == 1)
|
||||
{
|
||||
bus_clear = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = clk_pin_config;
|
||||
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = data_pin_config;
|
||||
|
||||
NRF_TWI1->ENABLE = twi_state;
|
||||
|
||||
return bus_clear;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Function for initializing the twi_master.
|
||||
*/
|
||||
bool twi_master_init_and_clear(void)
|
||||
{
|
||||
/* To secure correct signal levels on the pins used by the TWI
|
||||
master when the system is in OFF mode, and when the TWI master is
|
||||
disabled, these pins must be configured in the GPIO peripheral.
|
||||
*/
|
||||
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = \
|
||||
(GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
|
||||
| (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
|
||||
| (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
|
||||
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
|
||||
| (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
|
||||
|
||||
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = \
|
||||
(GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
|
||||
| (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
|
||||
| (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
|
||||
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
|
||||
| (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
|
||||
|
||||
NRF_TWI1->EVENTS_RXDREADY = 0;
|
||||
NRF_TWI1->EVENTS_TXDSENT = 0;
|
||||
NRF_TWI1->PSELSCL = TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER;
|
||||
NRF_TWI1->PSELSDA = TWI_MASTER_CONFIG_DATA_PIN_NUMBER;
|
||||
NRF_TWI1->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos;
|
||||
NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TWI1->EVENTS_BB;
|
||||
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_SUSPEND;
|
||||
NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk;
|
||||
NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
|
||||
|
||||
return twi_master_clear_bus();
|
||||
}
|
||||
|
||||
|
||||
/** @brief Function for transfer by twi_master.
|
||||
*/
|
||||
bool twi_master_transfer(uint8_t address,
|
||||
uint8_t * data,
|
||||
uint8_t data_length,
|
||||
bool issue_stop_condition)
|
||||
{
|
||||
bool transfer_succeeded = false;
|
||||
if (data_length > 0 && twi_master_clear_bus())
|
||||
{
|
||||
NRF_TWI1->ADDRESS = (address >> 1);
|
||||
|
||||
if ((address & TWI_READ_BIT))
|
||||
{
|
||||
transfer_succeeded = twi_master_read(data, data_length, issue_stop_condition);
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer_succeeded = twi_master_write(data, data_length, issue_stop_condition);
|
||||
}
|
||||
}
|
||||
return transfer_succeeded;
|
||||
}
|
||||
|
||||
/*lint --flb "Leave library region" */
|
|
@ -0,0 +1,108 @@
|
|||
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWI_MASTER_H
|
||||
#define TWI_MASTER_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*lint ++flb "Enter library region" */
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** @file
|
||||
* @brief Software controlled TWI Master driver.
|
||||
*
|
||||
*
|
||||
* @defgroup lib_driver_twi_master Software controlled TWI Master driver
|
||||
* @{
|
||||
* @ingroup nrf_drivers
|
||||
* @brief Software controlled TWI Master driver.
|
||||
*
|
||||
* Supported features:
|
||||
* - Repeated start
|
||||
* - No multi-master
|
||||
* - Only 7-bit addressing
|
||||
* - Supports clock stretching (with optional SMBus style slave timeout)
|
||||
* - Tries to handle slaves stuck in the middle of transfer
|
||||
*/
|
||||
|
||||
#define TWI_READ_BIT (0x01) //!< If this bit is set in the address field, transfer direction is from slave to master.
|
||||
|
||||
#define TWI_ISSUE_STOP ((bool)true) //!< Parameter for @ref twi_master_transfer
|
||||
#define TWI_DONT_ISSUE_STOP ((bool)false) //!< Parameter for @ref twi_master_transfer
|
||||
|
||||
/* These macros are needed to see if the slave is stuck and we as master send dummy clock cycles to end its wait */
|
||||
/*lint -e717 -save "Suppress do {} while (0) for these macros" */
|
||||
/*lint ++flb "Enter library region" */
|
||||
#define TWI_SCL_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while(0) /*!< Pulls SCL line high */
|
||||
#define TWI_SCL_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while(0) /*!< Pulls SCL line low */
|
||||
#define TWI_SDA_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while(0) /*!< Pulls SDA line high */
|
||||
#define TWI_SDA_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while(0) /*!< Pulls SDA line low */
|
||||
#define TWI_SDA_INPUT() do { NRF_GPIO->DIRCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while(0) /*!< Configures SDA pin as input */
|
||||
#define TWI_SDA_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while(0) /*!< Configures SDA pin as output */
|
||||
#define TWI_SCL_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while(0) /*!< Configures SCL pin as output */
|
||||
/*lint -restore */
|
||||
|
||||
#define TWI_SDA_READ() ((NRF_GPIO->IN >> TWI_MASTER_CONFIG_DATA_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SDA */
|
||||
#define TWI_SCL_READ() ((NRF_GPIO->IN >> TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SCL */
|
||||
|
||||
#define TWI_DELAY() nrf_delay_us(4) /*!< Time to wait when pin states are changed. For fast-mode the delay can be zero and for standard-mode 4 us delay is sufficient. */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for initializing TWI bus IO pins and checks if the bus is operational.
|
||||
*
|
||||
* Both pins are configured as Standard-0, No-drive-1 (open drain).
|
||||
*
|
||||
* @return
|
||||
* @retval true TWI bus is clear for transfers.
|
||||
* @retval false TWI bus is stuck.
|
||||
*/
|
||||
bool twi_master_init_and_clear(void);
|
||||
|
||||
/**
|
||||
* @brief Function for transferring data over TWI bus.
|
||||
*
|
||||
* If TWI master detects even one NACK from the slave or timeout occurs, STOP condition is issued
|
||||
* and the function returns false.
|
||||
* Bit 0 (@ref TWI_READ_BIT) in the address parameter controls transfer direction;
|
||||
* - If 1, master reads data_length number of bytes from the slave
|
||||
* - If 0, master writes data_length number of bytes to the slave.
|
||||
*
|
||||
* @note Make sure at least data_length number of bytes is allocated in data if TWI_READ_BIT is set.
|
||||
* @note @ref TWI_ISSUE_STOP
|
||||
*
|
||||
* @param address Data transfer direction (LSB) / Slave address (7 MSBs).
|
||||
* @param data Pointer to data.
|
||||
* @param data_length Number of bytes to transfer.
|
||||
* @param issue_stop_condition If @ref TWI_ISSUE_STOP, STOP condition is issued before exiting function. If @ref TWI_DONT_ISSUE_STOP, STOP condition is not issued before exiting function. If transfer failed for any reason, STOP condition will be issued in any case.
|
||||
* @return
|
||||
* @retval true Data transfer succeeded without errors.
|
||||
* @retval false Data transfer failed.
|
||||
*/
|
||||
bool twi_master_transfer(uint8_t address, uint8_t *data, uint8_t data_length, bool issue_stop_condition);
|
||||
|
||||
/**
|
||||
*@}
|
||||
**/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*lint --flb "Leave library region" */
|
||||
#endif //TWI_MASTER_H
|
|
@ -159,10 +159,11 @@ void RTC1_IRQHandler(void)
|
|||
NRF_RTC1->EVENTS_OVRFLW = 0;
|
||||
NRF_RTC1->EVTENCLR = RTC_EVTEN_OVRFLW_Msk;
|
||||
}
|
||||
if (NRF_RTC1->EVENTS_COMPARE[0] && us_ticker_callbackPending && ((int)(us_ticker_callbackTimestamp - rtc1_getCounter()) <= 0)) {
|
||||
if (NRF_RTC1->EVENTS_COMPARE[0]) {
|
||||
NRF_RTC1->EVENTS_COMPARE[0] = 0;
|
||||
NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk;
|
||||
invokeCallback();
|
||||
if (us_ticker_callbackPending && ((int)(us_ticker_callbackTimestamp - rtc1_getCounter()) <= 0))
|
||||
invokeCallback();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -196,8 +196,18 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
obj->uart->CFG = (data_bits << 2)
|
||||
|
||||
// First disable the the usart as described in documentation and then enable while updating CFG
|
||||
|
||||
// 24.6.1 USART Configuration register
|
||||
// Remark: If software needs to change configuration values, the following sequence should
|
||||
// be used: 1) Make sure the USART is not currently sending or receiving data. 2) Disable
|
||||
// the USART by writing a 0 to the Enable bit (0 may be written to the entire register). 3)
|
||||
// Write the new configuration value, with the ENABLE bit set to 1.
|
||||
obj->uart->CFG &= ~(1 << 0);
|
||||
|
||||
obj->uart->CFG = (1 << 0) // this will enable the usart
|
||||
| (data_bits << 2)
|
||||
| (paritysel << 4)
|
||||
| (stop_bits << 6);
|
||||
}
|
||||
|
|
|
@ -230,7 +230,17 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
break;
|
||||
}
|
||||
|
||||
obj->uart->CFG = (data_bits << 2)
|
||||
// First disable the the usart as described in documentation and then enable while updating CFG
|
||||
|
||||
// 24.6.1 USART Configuration register
|
||||
// Remark: If software needs to change configuration values, the following sequence should
|
||||
// be used: 1) Make sure the USART is not currently sending or receiving data. 2) Disable
|
||||
// the USART by writing a 0 to the Enable bit (0 may be written to the entire register). 3)
|
||||
// Write the new configuration value, with the ENABLE bit set to 1.
|
||||
obj->uart->CFG &= ~(1 << 0);
|
||||
|
||||
obj->uart->CFG = (1 << 0) // this will enable the usart
|
||||
| (data_bits << 2)
|
||||
| (paritysel << 4)
|
||||
| (stop_bits << 6);
|
||||
}
|
||||
|
|
|
@ -241,9 +241,9 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
|
||||
TimHandle.Init.Period = us - 1;
|
||||
if (APBxCLKDivider == RCC_HCLK_DIV1)
|
||||
TimHandle.Init.Prescaler = (uint16_t)((PclkFreq*2) / 1000000) - 1; // 1 µs tick
|
||||
TimHandle.Init.Prescaler = (uint16_t)((PclkFreq) / 1000000) - 1; // 1 µs tick
|
||||
else
|
||||
TimHandle.Init.Prescaler = (uint16_t)((PclkFreq) / 1000000) - 1; // 1 µs tick
|
||||
TimHandle.Init.Prescaler = (uint16_t)((PclkFreq)*2 / 1000000) - 1; // 1 µs tick
|
||||
TimHandle.Init.ClockDivision = 0;
|
||||
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
HAL_TIM_PWM_Init(&TimHandle);
|
||||
|
|
|
@ -62,6 +62,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
if (obj->pwm == PWM_9) __HAL_RCC_TIM9_CLK_ENABLE();
|
||||
if (obj->pwm == PWM_10) __HAL_RCC_TIM10_CLK_ENABLE();
|
||||
if (obj->pwm == PWM_11) __HAL_RCC_TIM11_CLK_ENABLE();
|
||||
if (obj->pwm == PWM_12) __HAL_RCC_TIM12_CLK_ENABLE();
|
||||
if (obj->pwm == PWM_13) __HAL_RCC_TIM13_CLK_ENABLE();
|
||||
if (obj->pwm == PWM_14) __HAL_RCC_TIM14_CLK_ENABLE();
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#define DEVICE_LOWPOWERTIMER 1
|
||||
|
||||
#define DEVICE_ERROR_PATTERN 1
|
||||
|
||||
#include "objects.h"
|
||||
#include "device_peripherals.h"
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#define PWM_TIMER_CLOCK cmuClock_TIMER2
|
||||
#define PWM_ROUTE TIMER_ROUTE_LOCATION_LOC1
|
||||
|
||||
/* USB */
|
||||
#define USB_TIMER USB_TIMER1
|
||||
|
||||
/* Clocks */
|
||||
|
||||
/* Clock definitions */
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#define DEVICE_LOWPOWERTIMER 1
|
||||
|
||||
#define DEVICE_ERROR_PATTERN 1
|
||||
|
||||
// Redefine OPEN_MAX from sys_limits.h to save on RAM.
|
||||
// Effect: maximum amount of file handlers = OPEN_MAX
|
||||
// This is not going to have an impact, since this is a RAM-limited part anyway.
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#define PWM_TIMER_CLOCK cmuClock_TIMER0
|
||||
#define PWM_ROUTE TIMER_ROUTE_LOCATION_LOC0
|
||||
|
||||
/* USB */
|
||||
#define USB_TIMER USB_TIMER2
|
||||
|
||||
/* Clocks */
|
||||
|
||||
/* Clock definitions */
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#define DEVICE_LOWPOWERTIMER 1
|
||||
|
||||
#define DEVICE_ERROR_PATTERN 1
|
||||
|
||||
#include "objects.h"
|
||||
#include "Modules.h"
|
||||
#include "device_peripherals.h"
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#define PWM_TIMER_CLOCK cmuClock_TIMER2
|
||||
#define PWM_ROUTE TIMER_ROUTE_LOCATION_LOC1
|
||||
|
||||
/* USB */
|
||||
#define USB_TIMER USB_TIMER1
|
||||
|
||||
/* Clocks */
|
||||
|
||||
/* Clock definitions */
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#define DEVICE_LOWPOWERTIMER 1
|
||||
|
||||
#define DEVICE_ERROR_PATTERN 1
|
||||
|
||||
#include "objects.h"
|
||||
#include "Modules.h"
|
||||
#include "device_peripherals.h"
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#define PWM_TIMER_CLOCK cmuClock_TIMER2
|
||||
#define PWM_ROUTE TIMER_ROUTE_LOCATION_LOC1
|
||||
|
||||
/* USB */
|
||||
#define USB_TIMER USB_TIMER1
|
||||
|
||||
/* Clocks */
|
||||
|
||||
/* Clock definitions */
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#define DEVICE_LOWPOWERTIMER 1
|
||||
|
||||
#define DEVICE_ERROR_PATTERN 1
|
||||
|
||||
// Redefine OPEN_MAX from sys_limits.h to save on RAM.
|
||||
// Effect: maximum amount of file handlers = OPEN_MAX
|
||||
// This is not going to have an impact, since this is a RAM-limited part anyway.
|
||||
|
|
|
@ -63,11 +63,17 @@ const PinMap PinMap_UART_RX[] = {
|
|||
//*** I2C ***
|
||||
const PinMap PinMap_I2C_SDA[] = {
|
||||
{PA_10, I2C_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
|
||||
{PC_9, I2C_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
|
||||
{PC_5, I2C_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
|
||||
{PA_6, I2C_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_I2C_SCL[] = {
|
||||
{PA_9, I2C_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
|
||||
{PC_8, I2C_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
|
||||
{PC_4, I2C_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
|
||||
{PC_5, I2C_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
|
|
|
@ -81,7 +81,9 @@ struct spi_s {
|
|||
};
|
||||
|
||||
struct i2c_s {
|
||||
I2CName i2c;
|
||||
I2CName I2Cx;
|
||||
PinName sda;
|
||||
PinName scl;
|
||||
uint16_t ADDRESS;
|
||||
uint16_t is_setAddress;
|
||||
};
|
||||
|
|
|
@ -47,303 +47,135 @@
|
|||
#define FLAG_TIMEOUT ((int)0x1000)
|
||||
#define LONG_TIMEOUT ((int)0xFFFF)
|
||||
|
||||
I2C_TypeDef * I2cHandle;
|
||||
|
||||
int i2c0_inited = 0;
|
||||
int i2c1_inited = 0;
|
||||
|
||||
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
|
||||
{
|
||||
// Determine the I2C to use
|
||||
I2C_ConfigStruct conf;
|
||||
|
||||
//Determine the I2C to use
|
||||
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
|
||||
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
|
||||
|
||||
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
|
||||
MBED_ASSERT(obj->i2c != (I2CName)NC);
|
||||
|
||||
// Enable I2C1 clock and pinout if not done
|
||||
if ((obj->i2c == I2C_0) && !i2c0_inited) {
|
||||
i2c0_inited = 1;
|
||||
// Configure I2C pins
|
||||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
pin_mode(sda, PullUp);
|
||||
pin_mode(scl, PullUp);
|
||||
}
|
||||
|
||||
// Enable I2C2 clock and pinout if not done
|
||||
if ((obj->i2c == I2C_1) && !i2c1_inited) {
|
||||
i2c1_inited = 1;
|
||||
// Configure I2C pins
|
||||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
pin_mode(sda, PullUp);
|
||||
pin_mode(scl, PullUp);
|
||||
}
|
||||
|
||||
// Reset to clear pending flags if any
|
||||
i2c_reset(obj);
|
||||
|
||||
// I2C configuration
|
||||
i2c_frequency(obj, 100000); // 100 kHz per default
|
||||
obj->I2Cx = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
|
||||
MBED_ASSERT(obj->I2Cx != (I2CName)NC);
|
||||
|
||||
obj->sda = sda;
|
||||
obj->scl = scl;
|
||||
obj->ADDRESS = 0x0;
|
||||
obj->is_setAddress = 0;
|
||||
|
||||
conf.sda = (I2C_PinName)obj->sda;
|
||||
conf.scl = (I2C_PinName)obj->scl;
|
||||
|
||||
I2C_Init(&conf);
|
||||
}
|
||||
|
||||
void i2c_frequency(i2c_t *obj, int hz)
|
||||
{
|
||||
//MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
|
||||
MBED_ASSERT((hz == 100000));
|
||||
I2cHandle = (I2C_TypeDef *)(obj->i2c);
|
||||
|
||||
// wait before init
|
||||
I2C_ConfigStruct conf;
|
||||
|
||||
conf.mode = I2C_Master;
|
||||
conf.master.timeout = LONG_TIMEOUT;
|
||||
conf.master.prescale = 0x61; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
|
||||
|
||||
// Common settings: I2C clock = 48 MHz, Analog filter = ON, Digital filter coefficient = 0
|
||||
// switch (hz) {
|
||||
// case 100000:
|
||||
// conf.master.prescale = 0x61; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
|
||||
// break;
|
||||
// case 400000:
|
||||
// break;
|
||||
// case 1000000:
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
// I2C configuration
|
||||
I2C_Init(I2cHandle, conf);
|
||||
|
||||
}
|
||||
|
||||
inline int i2c_start(i2c_t *obj)
|
||||
{
|
||||
obj->is_setAddress = 0;
|
||||
|
||||
I2C_ConfigStruct conf;
|
||||
conf.sda = (I2C_PinName)obj->sda;
|
||||
conf.scl = (I2C_PinName)obj->scl;
|
||||
|
||||
I2C_Start(&conf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int i2c_stop(i2c_t *obj)
|
||||
{
|
||||
I2cHandle = (I2C_TypeDef *)(obj->i2c);
|
||||
|
||||
// Generate the STOP condition
|
||||
I2C_Stop(I2cHandle);
|
||||
I2C_Reset(I2cHandle);
|
||||
{
|
||||
I2C_ConfigStruct conf;
|
||||
conf.sda = (I2C_PinName)obj->sda;
|
||||
conf.scl = (I2C_PinName)obj->scl;
|
||||
|
||||
obj->is_setAddress = 0;
|
||||
I2C_Stop(&conf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
|
||||
{
|
||||
I2cHandle = (I2C_TypeDef *)(obj->i2c);
|
||||
int count;
|
||||
int value;
|
||||
I2C_ConfigStruct conf;
|
||||
|
||||
conf.sda = (I2C_PinName)obj->sda;
|
||||
conf.scl = (I2C_PinName)obj->scl;
|
||||
|
||||
if(!obj->is_setAddress)
|
||||
{
|
||||
if( I2C_Start(I2cHandle, address, I2C_READ_SA7) == ERROR )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
obj->is_setAddress = 1;
|
||||
obj->ADDRESS = address;
|
||||
|
||||
if(stop)
|
||||
{
|
||||
if(I2C_Read(&conf, address, data, length) != 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
I2C_Restart_Structure(I2cHandle, address, I2C_READ_SA7);
|
||||
obj->ADDRESS = address;
|
||||
}
|
||||
|
||||
// Read all bytes
|
||||
for (count = 0; count < (length-1); count++) {
|
||||
if( (value = i2c_byte_read(obj, 0)) == -1) {
|
||||
return value;
|
||||
}
|
||||
data[count] = (char)value;
|
||||
}
|
||||
|
||||
if(stop){
|
||||
if( (value = i2c_byte_read(obj, 1)) == -1) {
|
||||
return value;
|
||||
}
|
||||
data[count] = (char)value;
|
||||
|
||||
i2c_stop(obj);
|
||||
obj->is_setAddress =1;
|
||||
count++;
|
||||
}
|
||||
else{
|
||||
if( (value = i2c_byte_read(obj, 0)) == -1) {
|
||||
|
||||
return value;
|
||||
}
|
||||
data[count] = (char)value;
|
||||
count++;
|
||||
if(I2C_ReadRepeated(&conf, address, data, length) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return count;
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
|
||||
{
|
||||
I2cHandle = (I2C_TypeDef *)(obj->i2c);
|
||||
int count =0;
|
||||
I2C_ConfigStruct conf;
|
||||
|
||||
if(!obj->is_setAddress)
|
||||
{
|
||||
if( I2C_Start(I2cHandle, address, I2C_WRITE_SA7) == ERROR )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
obj->is_setAddress = 1;
|
||||
obj->ADDRESS = address;
|
||||
}
|
||||
conf.sda = (I2C_PinName)obj->sda;
|
||||
conf.scl = (I2C_PinName)obj->scl;
|
||||
|
||||
|
||||
if(stop)
|
||||
{
|
||||
if(I2C_Write(&conf, address, data, length) != 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
I2C_Restart_Structure(I2cHandle, address, I2C_WRITE_SA7);
|
||||
obj->ADDRESS = address;
|
||||
|
||||
if(I2C_WriteRepeated(&conf, address, data, length) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (count = 0; count < length; count++) {
|
||||
i2c_byte_write(obj, data[count]);
|
||||
wait_us(1);
|
||||
}
|
||||
|
||||
|
||||
if(length == 0x00)
|
||||
{
|
||||
I2C_GPIO();
|
||||
i2c_byte_write(obj, 0xff);
|
||||
GPIO_I2C();
|
||||
}
|
||||
// If not repeated start, send stop
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_reset(obj);
|
||||
|
||||
}
|
||||
return count;
|
||||
return length;
|
||||
}
|
||||
|
||||
int i2c_byte_read(i2c_t *obj, int last)
|
||||
{
|
||||
I2cHandle = (I2C_TypeDef *)(obj->i2c);
|
||||
|
||||
return I2C_ReceiveData(I2cHandle, last);
|
||||
uint8_t ret;
|
||||
I2C_ConfigStruct conf;
|
||||
|
||||
conf.sda = (I2C_PinName)obj->sda;
|
||||
conf.scl = (I2C_PinName)obj->scl;
|
||||
|
||||
ret = I2C_ReadByte(&conf);
|
||||
|
||||
if(last)
|
||||
I2C_SendNACK(&conf);
|
||||
else
|
||||
I2C_SendACK(&conf);
|
||||
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
int i2c_byte_write(i2c_t *obj, int data)
|
||||
{
|
||||
I2cHandle = (I2C_TypeDef *)(obj->i2c);
|
||||
return I2C_SendDataAck(I2cHandle,(uint8_t)data);
|
||||
I2C_ConfigStruct conf;
|
||||
|
||||
conf.sda = (I2C_PinName)obj->sda;
|
||||
conf.scl = (I2C_PinName)obj->scl;
|
||||
|
||||
if(I2C_WriteByte(&conf, (uint8_t)data)) // NACK
|
||||
return 0;
|
||||
else //ack
|
||||
return 1;
|
||||
}
|
||||
|
||||
void i2c_reset(i2c_t *obj)
|
||||
{
|
||||
I2cHandle = (I2C_TypeDef *)(obj->i2c);
|
||||
|
||||
I2C_Reset(I2cHandle);
|
||||
|
||||
}
|
||||
|
||||
//#if DEVICE_I2CSLAVE
|
||||
//
|
||||
//void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
|
||||
//{
|
||||
// I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
|
||||
// uint16_t tmpreg = 0;
|
||||
//
|
||||
// // disable
|
||||
// i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
|
||||
// // Get the old register value
|
||||
// tmpreg = i2c->OAR1;
|
||||
// // Reset address bits
|
||||
// tmpreg &= 0xFC00;
|
||||
// // Set new address
|
||||
// tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
|
||||
// // Store the new register value
|
||||
// i2c->OAR1 = tmpreg;
|
||||
// // enable
|
||||
// i2c->OAR1 |= I2C_OAR1_OA1EN;
|
||||
//}
|
||||
//
|
||||
//void i2c_slave_mode(i2c_t *obj, int enable_slave)
|
||||
//{
|
||||
// I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
|
||||
// uint16_t tmpreg;
|
||||
//
|
||||
// // Get the old register value
|
||||
// tmpreg = i2c->OAR1;
|
||||
//
|
||||
// // Enable / disable slave
|
||||
// if (enable_slave == 1) {
|
||||
// tmpreg |= I2C_OAR1_OA1EN;
|
||||
// } else {
|
||||
// tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
|
||||
// }
|
||||
//
|
||||
// // Set new mode
|
||||
// i2c->OAR1 = tmpreg;
|
||||
//}
|
||||
//
|
||||
//// See I2CSlave.h
|
||||
//#define NoData 0 // the slave has not been addressed
|
||||
//#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
|
||||
//#define WriteGeneral 2 // the master is writing to all slave
|
||||
//#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
|
||||
//
|
||||
//int i2c_slave_receive(i2c_t *obj)
|
||||
//{
|
||||
// I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
|
||||
// int retValue = NoData;
|
||||
//
|
||||
// if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
|
||||
// if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
|
||||
// if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_DIR) == 1)
|
||||
// retValue = ReadAddressed;
|
||||
// else
|
||||
// retValue = WriteAddressed;
|
||||
//
|
||||
// __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return (retValue);
|
||||
//}
|
||||
//
|
||||
//int i2c_slave_read(i2c_t *obj, char *data, int length)
|
||||
//{
|
||||
// char size = 0;
|
||||
//
|
||||
// while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
|
||||
//
|
||||
// return size;
|
||||
//}
|
||||
//
|
||||
//int i2c_slave_write(i2c_t *obj, const char *data, int length)
|
||||
//{
|
||||
// char size = 0;
|
||||
// I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
|
||||
//
|
||||
// do {
|
||||
// i2c_byte_write(obj, data[size]);
|
||||
// size++;
|
||||
// } while (size < length);
|
||||
//
|
||||
// return size;
|
||||
//}
|
||||
//
|
||||
//
|
||||
//#endif // DEVICE_I2CSLAVE
|
||||
|
||||
#endif // DEVICE_I2C
|
||||
|
|
|
@ -33,9 +33,12 @@
|
|||
#include "PeripheralNames.h"
|
||||
#include "system_W7500x.h"
|
||||
|
||||
#define TIMER_0 DUALTIMER0_0
|
||||
#define TIMER_1 PWM_CH1
|
||||
#define TIMER_IRQn DUALTIMER0_IRQn
|
||||
|
||||
static PWM_TimerModeInitTypeDef TimMasterHandle_CH3;
|
||||
static PWM_TimerModeInitTypeDef TimMasterHandle_CH2;
|
||||
static PWM_TimerModeInitTypeDef TimerInitType;
|
||||
static DUALTIMER_InitTypDef TimerHandler;
|
||||
|
||||
static int us_ticker_inited = 0;
|
||||
|
||||
|
@ -43,17 +46,12 @@ static int us_ticker_inited = 0;
|
|||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
void PWM2_Handler(void)
|
||||
|
||||
void DUALTIMER0_Handler(void)
|
||||
{
|
||||
uint32_t IntFlag = 0;
|
||||
|
||||
IntFlag = PWM_CHn_GetIntFlagStatus(PWM_CH2);
|
||||
|
||||
/* If overflow interrupt is occurred */
|
||||
if( (IntFlag & PWM_CHn_IER_OI_Msk) != 0 )
|
||||
if(DUALTIMER_GetIntStatus(DUALTIMER0_0))
|
||||
{
|
||||
/* Clear overflow interrupt */
|
||||
PWM_CH2_ClearOverflowInt();
|
||||
DUALTIMER_IntClear(DUALTIMER0_0);
|
||||
us_ticker_irq_handler();
|
||||
}
|
||||
}
|
||||
|
@ -68,66 +66,69 @@ void us_ticker_init(void)
|
|||
us_ticker_inited = 1;
|
||||
|
||||
SystemCoreClockUpdate();
|
||||
TimMasterHandle_CH3.PWM_CHn_PR = (GetSystemClock() / 1000000) -1;
|
||||
TimMasterHandle_CH3.PWM_CHn_LR = 0xFFFFFFFF;
|
||||
TimMasterHandle_CH3.PWM_CHn_PDMR = 1;
|
||||
TimerInitType.PWM_CHn_PR = (GetSystemClock() / 1000000) -1;
|
||||
TimerInitType.PWM_CHn_LR = 0xFFFFFFFF;
|
||||
TimerInitType.PWM_CHn_PDMR = 1;
|
||||
|
||||
PWM_TimerModeInit(PWM_CH3, &TimMasterHandle_CH3);
|
||||
PWM_CHn_Start(PWM_CH3);
|
||||
PWM_TimerModeInit(TIMER_1, &TimerInitType);
|
||||
PWM_CHn_Start(TIMER_1);
|
||||
}
|
||||
|
||||
|
||||
uint32_t us_ticker_read()
|
||||
{
|
||||
if (!us_ticker_inited) us_ticker_init();
|
||||
|
||||
return (PWM_CH3->TCR);
|
||||
return (TIMER_1->TCR);
|
||||
}
|
||||
|
||||
|
||||
void us_ticker_set_interrupt(timestamp_t timestamp)
|
||||
{
|
||||
int32_t dev = 0;
|
||||
|
||||
if (!us_ticker_inited)
|
||||
{
|
||||
us_ticker_init();
|
||||
}
|
||||
|
||||
dev = (int32_t)(timestamp - (us_ticker_read() + 150));
|
||||
dev = (int32_t)(timestamp - us_ticker_read());
|
||||
dev = dev * ((GetSystemClock() / 1000000) / 16);
|
||||
|
||||
if(dev <= 0)
|
||||
{
|
||||
us_ticker_irq_handler();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
DUALTIMER_ClockEnable(TIMER_0);
|
||||
DUALTIMER_Stop(TIMER_0);
|
||||
|
||||
TimerHandler.TimerControl_Mode = DUALTIMER_TimerControl_Periodic;
|
||||
TimerHandler.TimerControl_OneShot = DUALTIMER_TimerControl_OneShot;
|
||||
TimerHandler.TimerControl_Pre = DUALTIMER_TimerControl_Pre_16;
|
||||
TimerHandler.TimerControl_Size = DUALTIMER_TimerControl_Size_32;
|
||||
|
||||
TimerHandler.TimerLoad = (uint32_t)dev;
|
||||
|
||||
DUALTIMER_Init(TIMER_0, &TimerHandler);
|
||||
|
||||
DUALTIMER_IntConfig(TIMER_0, ENABLE);
|
||||
|
||||
NVIC_EnableIRQ(TIMER_IRQn);
|
||||
|
||||
DUALTIMER_Start(TIMER_0);
|
||||
|
||||
|
||||
PWM_CHn_Stop(PWM_CH2);
|
||||
|
||||
SystemCoreClockUpdate();
|
||||
TimMasterHandle_CH2.PWM_CHn_PR = (GetSystemClock() / 1000000) -1;
|
||||
TimMasterHandle_CH2.PWM_CHn_LR = dev;
|
||||
|
||||
TimMasterHandle_CH2.PWM_CHn_UDMR = 0;
|
||||
TimMasterHandle_CH2.PWM_CHn_PDMR = 0;
|
||||
|
||||
NVIC_EnableIRQ(PWM2_IRQn);
|
||||
|
||||
PWM_CHn_IntConfig(PWM_CH2, PWM_CHn_IER_OIE, ENABLE);
|
||||
PWM_IntConfig(PWM_CH2, ENABLE);
|
||||
PWM_TimerModeInit(PWM_CH2, &TimMasterHandle_CH2);
|
||||
|
||||
PWM_CHn_Start(PWM_CH2);
|
||||
}
|
||||
|
||||
void us_ticker_disable_interrupt(void)
|
||||
{
|
||||
NVIC_DisableIRQ(PWM2_IRQn);
|
||||
|
||||
PWM_CHn_IntConfig(PWM_CH2, PWM_CHn_IER_OIE, DISABLE);
|
||||
PWM_IntConfig(PWM_CH2, DISABLE);
|
||||
NVIC_DisableIRQ(TIMER_IRQn);
|
||||
|
||||
DUALTIMER_IntConfig(TIMER_0, DISABLE);
|
||||
}
|
||||
|
||||
void us_ticker_clear_interrupt(void)
|
||||
{
|
||||
PWM_CHn_ClearInt(PWM_CH2, PWM_CHn_IER_OIE);
|
||||
DUALTIMER_IntClear(TIMER_0);
|
||||
}
|
||||
|
|
|
@ -24,17 +24,14 @@ static void rza1_recv_task(void *arg) {
|
|||
struct eth_hdr *ethhdr;
|
||||
u16_t recv_size;
|
||||
struct pbuf *p;
|
||||
struct pbuf *q;
|
||||
|
||||
while (1) {
|
||||
sys_arch_sem_wait(&recv_ready_sem, 0);
|
||||
recv_size = ethernet_receive();
|
||||
if (recv_size != 0) {
|
||||
p = pbuf_alloc(PBUF_RAW, recv_size, PBUF_POOL);
|
||||
p = pbuf_alloc(PBUF_RAW, recv_size, PBUF_RAM);
|
||||
if (p != NULL) {
|
||||
for (q = p; q != NULL; q = q->next) {
|
||||
(void)ethernet_read((char *)q->payload, q->len);
|
||||
}
|
||||
(void)ethernet_read((char *)p->payload, p->len);
|
||||
ethhdr = p->payload;
|
||||
switch (htons(ethhdr->type)) {
|
||||
case ETHTYPE_IP:
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mbed.h"
|
||||
#include "Arguments.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ PinName parse_pins(const char *str) {
|
|||
, NC, NC, NC, NC, NC, NC, NC, NC, p41, p42, p43, p44, p45, p46};
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC812) || defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_LPC1114)
|
||||
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC812) || defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_LPC1114) || defined(TARGET_RZ_A1H)
|
||||
if (str[0] == 'P') { // Pn_n
|
||||
uint32_t port = str[1] - '0';
|
||||
uint32_t pin = str[3] - '0'; // Pn_n
|
||||
|
|
|
@ -42,7 +42,7 @@ Thread::Thread(void (*task)(void const *argument), void *argument,
|
|||
}
|
||||
|
||||
//Fill the stack with a magic word for maximum usage checking
|
||||
for (int i = 0; i < (stack_size / sizeof(uint32_t)); i++) {
|
||||
for (uint32_t i = 0; i < (stack_size / sizeof(uint32_t)); i++) {
|
||||
_thread_def.stack_pointer[i] = 0xE25A2EA5;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
colorama
|
||||
pyserial
|
||||
prettytable
|
||||
Jinja2
|
||||
IntelHex
|
|
@ -91,6 +91,8 @@ OFFICIAL_MBED_LIBRARY_BUILD = (
|
|||
('RBLAB_BLENANO', ('ARM', 'GCC_ARM')),
|
||||
('WALLBOT_BLE', ('ARM', 'GCC_ARM')),
|
||||
('DELTA_DFCM_NNN40', ('ARM', 'GCC_ARM')),
|
||||
('NRF51_MICROBIT', ('ARM',)),
|
||||
('NRF51_MICROBIT_B', ('ARM',)),
|
||||
|
||||
('LPC11U68', ('ARM', 'uARM','GCC_ARM','GCC_CR', 'IAR')),
|
||||
('OC_MBUINO', ('ARM', 'uARM', 'GCC_ARM', 'IAR')),
|
||||
|
|
|
@ -27,57 +27,63 @@ import sys
|
|||
# "libs" can contain "dsp", "rtos", "eth", "usb_host", "usb", "ublox", "fat"
|
||||
|
||||
build_list = (
|
||||
{ "target": "LPC1768", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "eth", "usb_host", "usb", "ublox", "fat"] },
|
||||
{ "target": "LPC2368", "toolchains": "GCC_ARM", "libs": ["fat"] },
|
||||
{ "target": "LPC2460", "toolchains": "GCC_ARM", "libs": ["rtos", "usb_host", "usb", "fat"] },
|
||||
{ "target": "LPC11U24", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "OC_MBUINO", "toolchains": "GCC_ARM", "libs": ["fat"] },
|
||||
{ "target": "LPC1768", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "eth", "usb_host", "usb", "ublox", "fat"] },
|
||||
{ "target": "LPC2368", "toolchains": "GCC_ARM", "libs": ["fat"] },
|
||||
{ "target": "LPC2460", "toolchains": "GCC_ARM", "libs": ["rtos", "usb_host", "usb", "fat"] },
|
||||
{ "target": "LPC11U24", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "OC_MBUINO", "toolchains": "GCC_ARM", "libs": ["fat"] },
|
||||
|
||||
{ "target": "LPC11U24_301", "toolchains": "GCC_ARM", "libs": ["fat"] },
|
||||
{ "target": "LPC11U24_301", "toolchains": "GCC_ARM", "libs": ["fat"] },
|
||||
|
||||
{ "target": "NUCLEO_L053R8", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_L152RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F030R8", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "NUCLEO_F070RB", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "NUCLEO_F072RB", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F091RC", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F103RB", "toolchains": "GCC_ARM", "libs": ["rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F302R8", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F303RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F334R8", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F401RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F411RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_L053R8", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_L152RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F030R8", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "NUCLEO_F070RB", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "NUCLEO_F072RB", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F091RC", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F103RB", "toolchains": "GCC_ARM", "libs": ["rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F302R8", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F303RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F334R8", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F401RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NUCLEO_F411RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
|
||||
{ "target": "MTS_MDOT_F405RG", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos"] },
|
||||
{ "target": "MTS_MDOT_F411RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos"] },
|
||||
{ "target": "MTS_MDOT_F405RG", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos"] },
|
||||
{ "target": "MTS_MDOT_F411RE", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos"] },
|
||||
{ "target": "MTS_DRAGONFLY_F411RE", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "ARCH_MAX", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "ARCH_MAX", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
|
||||
{ "target": "DISCO_F051R8", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "DISCO_F334C8", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "DISCO_F401VC", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "DISCO_F407VG", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "DISCO_F429ZI", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "DISCO_F746NG", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "DISCO_F051R8", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "DISCO_F334C8", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "DISCO_F401VC", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "DISCO_F407VG", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "DISCO_F429ZI", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "DISCO_F746NG", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
|
||||
{ "target": "LPC1114", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "LPC11U35_401", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "UBLOX_C027", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "LPC11U35_501", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "LPC11U68", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "LPC11U37H_401", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "LPC1114", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "LPC11U35_401", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "UBLOX_C027", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "LPC11U35_501", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "LPC11U68", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "LPC11U37H_401", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
|
||||
{ "target": "KL05Z", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "KL25Z", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "KL43Z", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "KL46Z", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "K20D50M", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "TEENSY3_1", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "K64F", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "LPC4088", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "ARCH_PRO", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "LPC1549", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NRF51822", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "KL05Z", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "KL25Z", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "KL43Z", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "KL46Z", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "K20D50M", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "TEENSY3_1", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
{ "target": "K64F", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "LPC4088", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] },
|
||||
{ "target": "ARCH_PRO", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "LPC1549", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] },
|
||||
{ "target": "NRF51822", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] },
|
||||
|
||||
{ "target": "EFM32ZG_STK3200", "toolchains": "GCC_ARM", "libs": ["dsp"] },
|
||||
{ "target": "EFM32HG_STK3400", "toolchains": "GCC_ARM", "libs": ["dsp", "usb"] },
|
||||
{ "target": "EFM32LG_STK3600", "toolchains": "GCC_ARM", "libs": ["dsp", "usb"] },
|
||||
{ "target": "EFM32GG_STK3700", "toolchains": "GCC_ARM", "libs": ["dsp", "usb"] },
|
||||
{ "target": "EFM32WG_STK3800", "toolchains": "GCC_ARM", "libs": ["dsp", "usb"] },
|
||||
)
|
||||
|
||||
################################################################################
|
||||
|
|
|
@ -1088,7 +1088,7 @@ Exporter IDE/Platform Support
|
|||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>✓</td>
|
||||
<td>-</td>
|
||||
<td>✓</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
|
@ -1145,4 +1145,4 @@ Exporter IDE/Platform Support
|
|||
</table>
|
||||
Total IDEs: 9
|
||||
<br>Total platforms: 94
|
||||
<br>Total permutations: 288
|
||||
<br>Total permutations: 288
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>{{name}}</name>
|
||||
<comment>This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-Code-Red</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></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/{{name}}/Debug}</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.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
{% extends "codered_project_common.tmpl" %}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
{% extends "codered_cproject_common.tmpl" %}
|
||||
|
||||
{% block core %}cm0{% endblock %}
|
|
@ -0,0 +1,3 @@
|
|||
{% extends "codered_cproject_common.tmpl" %}
|
||||
|
||||
{% block core %}cm3{% endblock %}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>{{name}}</name>
|
||||
<comment>This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-Code-Red</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></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/{{name}}/Debug}</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.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
{% extends "codered_project_common.tmpl" %}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>{{name}}</name>
|
||||
<comment>This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-Code-Red</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></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/{{name}}/Debug}</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.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
{% extends "codered_project_common.tmpl" %}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>{{name}}</name>
|
||||
<comment>This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-Code-Red</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></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/{{name}}/Debug}</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.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
{% extends "codered_project_common.tmpl" %}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>{{name}}</name>
|
||||
<comment>This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-Code-Red</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></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/{{name}}/Debug}</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.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
{% extends "codered_project_common.tmpl" %}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>{{name}}</name>
|
||||
<comment>This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-Code-Red</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></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/{{name}}/Debug}</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.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
{% extends "codered_project_common.tmpl" %}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>{{name}}</name>
|
||||
<comment>This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-Code-Red</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></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/{{name}}/Debug}</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.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
{% extends "codered_project_common.tmpl" %}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>{{name}}</name>
|
||||
<comment>This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-Code-Red</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></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/{{name}}/Debug}</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.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
{% extends "codered_project_common.tmpl" %}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue