Merge pull request #5 from mbedmicro/master

Update my fork with original
pull/1277/head
David H 2015-08-14 13:25:26 +10:00
commit 57463eaef0
119 changed files with 26463 additions and 26716 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 ) */

View File

@ -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 ) */

View File

@ -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 ) */

View File

@ -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 ) */

View File

@ -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

View File

@ -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

View File

@ -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

View 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;
}

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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() {

View File

@ -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;
}

View File

@ -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

View File

@ -16,7 +16,7 @@
#ifndef MBED_H
#define MBED_H
#define MBED_LIBRARY_VERSION 103
#define MBED_LIBRARY_VERSION 104
#include "platform.h"

View File

@ -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)

View File

@ -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++) {

View File

@ -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)
}
}

View File

@ -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")
}

View File

@ -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.
}

View File

@ -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 */

View File

@ -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;

View File

@ -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
/******************************************************************************/
/* */

View File

@ -4,6 +4,7 @@
#include "W7500x_uart.h"
#include "W7500x_i2c.h"
#include "W7500x_adc.h"
#include "W7500x_dualtimer.h"
#include "system_W7500x.h"

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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}
};

View File

@ -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;
}

View File

@ -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}
};

View File

@ -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;
}

View File

@ -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 LICENSEES
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 Licensees 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
Nordics licensors are intended third party beneficiaries under this Agreement.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 &&

View File

@ -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

View File

@ -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" */

View File

@ -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

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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();

View File

@ -50,6 +50,8 @@
#define DEVICE_LOWPOWERTIMER 1
#define DEVICE_ERROR_PATTERN 1
#include "objects.h"
#include "device_peripherals.h"

View File

@ -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 */

View File

@ -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.

View File

@ -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 */

View File

@ -50,6 +50,8 @@
#define DEVICE_LOWPOWERTIMER 1
#define DEVICE_ERROR_PATTERN 1
#include "objects.h"
#include "Modules.h"
#include "device_peripherals.h"

View File

@ -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 */

View File

@ -50,6 +50,8 @@
#define DEVICE_LOWPOWERTIMER 1
#define DEVICE_ERROR_PATTERN 1
#include "objects.h"
#include "Modules.h"
#include "device_peripherals.h"

View File

@ -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 */

View File

@ -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.

View File

@ -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}
};

View File

@ -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;
};

View File

@ -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

View File

@ -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);
}

View File

@ -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:

View File

@ -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"

View File

@ -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

View File

@ -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

5
requirements.txt Normal file
View File

@ -0,0 +1,5 @@
colorama
pyserial
prettytable
Jinja2
IntelHex

View File

@ -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')),

View File

@ -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"] },
)
################################################################################

View File

@ -1088,7 +1088,7 @@ Exporter IDE/Platform Support
<td>-</td>
<td>-</td>
<td>&#10003;</td>
<td>-</td>
<td>&#10003;</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

View File

@ -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

View File

@ -0,0 +1,3 @@
{% extends "codered_cproject_common.tmpl" %}
{% block core %}cm0{% endblock %}

View File

@ -0,0 +1,3 @@
{% extends "codered_cproject_common.tmpl" %}
{% block core %}cm3{% endblock %}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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