123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- /***********************************************************************************
- Filename: usb_standard_request.c
- Description: Handle USB standard requests.
- ***********************************************************************************/
- /// \addtogroup module_usb_standard_requests
- /// @{
- #include "usb_firmware_library_headers.h"
- #include "hal_types.h"
- #include "hal_board.h"
- /** \brief Processes the \ref GET_STATUS request (returns status for the specified recipient)
- *
- * The recipient bits in \ref USB_SETUP_HEADER.requestType specify the desired recipient. This is either the
- * (one and only) device, a specific interface, or a specific endpoint. Some of the status bits can be
- * changed with the SET_FEATURE and CLEAR_FEATURE requests.
- *
- * <b>Parameters</b>:
- * - VALUE: Always 0
- * - INDEX: Depends upon the recipient:
- * - DEVICE: Always 0
- * - INTERFACE: Interface number
- * - ENDPOINT: Endpoint address
- * - LENGTH: Always 2
- *
- * <b>Data (IN)</b>:
- * Depends upon the recipient (the bit field illustrations are MSB first, LSB last):
- * - DEVICE: <tt>00000000.000000RS</tt>, where R(1) = DEVICE_REMOTE_WAKEUP and S(0) = SELF_POWERED
- * - INTERFACE: <tt>00000000.00000000</tt> (all bits are reserved)
- * - ENDPOINT: <tt>00000000.0000000H</tt>, where H(0) = ENDPOINT_HALT
- */
- void usbsrGetStatus(void)
- {
- uint8 endpoint;
- static uint16 __xdata status;
- // Common sanity check
- if (usbSetupHeader.value || HI_UINT16(usbSetupHeader.index) || (usbSetupHeader.length != 2)) {
- usbfwData.ep0Status = EP_STALL;
- // Return status for device, interface, or endpoint
- } else {
- switch (usbSetupHeader.requestType) {
- // Device status:
- // Bit 0: Self powered
- // Bit 1: Remote wake-up allowed
- case RT_IN_DEVICE:
- // Sanity check
- if (LO_UINT16(usbSetupHeader.index)) {
- usbfwData.ep0Status = EP_STALL;
- // Get the bit values from the USBFW_DATA struct
- } else {
- // Self powered?
- status = usbfwData.selfPowered ? 0x0001 : 0x0000;
- // Remote wakeup?
- if (usbfwData.remoteWakeup) status |= 0x0002;
- }
- break;
- // Interface status:
- // All bits are reserved
- case RT_IN_INTERFACE:
- // Sanity check
- if (usbfwData.usbState != DEV_CONFIGURED) {
- usbfwData.ep0Status = EP_STALL;
- } else {
- status = 0x0000;
- }
- break;
- // Endpoint status:
- // Bit 0: Endpoint halted
- case RT_IN_ENDPOINT:
- endpoint = LO_UINT16(usbSetupHeader.index) & 0x7F;
- // Sanity check
- if ((usbfwData.usbState != DEV_CONFIGURED) || (endpoint > 5)) {
- usbfwData.ep0Status = EP_STALL;
- // Translate endpoint address to status index and return the status
- } else {
- // IN
- if (LO_UINT16(usbSetupHeader.index) & 0x80) {
- status = (usbfwData.pEpInStatus[endpoint - 1] == EP_HALT) ? 0x0001 : 0x0000;
- // OUT
- } else {
- status = (usbfwData.pEpOutStatus[endpoint - 1] == EP_HALT) ? 0x0001 : 0x0000;
- }
- }
- break;
- default:
- usbfwData.ep0Status = EP_STALL;
- break;
- }
- if (usbfwData.ep0Status != EP_STALL) {
- // Send it
- usbSetupData.pBuffer = (uint8 __generic *)&status;
- usbSetupData.bytesLeft = 2;
- usbfwData.ep0Status = EP_TX;
- }
- }
- } // usbsrGetStatus
- /** \brief Internal function used for the very similar \ref SET_FEATURE and \ref CLEAR_FEATURE requests
- *
- * This function either sets or clears the specified feature on the specified recipient.
- *
- * \param[in] set
- * When TRUE, the feature is set. When FALSE, the feature is cleared.
- *
- * \return
- * TRUE if the selected feature is supported by the USB library. FALSE to indicate that
- * \ref usbsrHookClearFeature() or \ref usbsrHookSetFeature() must be called.
- */
- static uint8 ChangeFeature(uint8 set)
- {
- uint8 endpoint;
- // Sanity check
- if (usbSetupHeader.length || (usbfwData.usbState != DEV_CONFIGURED) && (usbSetupHeader.index != 0)) {
- usbfwData.ep0Status = EP_STALL;
- // Handle based on recipient
- } else {
- switch (usbSetupHeader.requestType & RT_MASK_RECIP) {
- // Device
- case RT_RECIP_DEV:
- // Sanity check
- if (LO_UINT16(usbSetupHeader.value) != DEVICE_REMOTE_WAKEUP) {
- return FALSE;
- } else {
- usbfwData.remoteWakeup = set;
- usbsrHookProcessEvent(set ? USBSR_EVENT_REMOTE_WAKEUP_ENABLED : USBSR_EVENT_REMOTE_WAKEUP_DISABLED, 0);
- }
- break;
- // Endpoint
- case RT_RECIP_IF:
- return FALSE;
- // Endpoint
- case RT_RECIP_EP:
- endpoint = LO_UINT16(usbSetupHeader.index) & 0x7F;
- // Sanity check
- if (LO_UINT16(usbSetupHeader.value) != ENDPOINT_HALT) {
- return FALSE;
- } else if (endpoint > 5) {
- usbfwData.ep0Status = EP_STALL;
- } else {
- USBFW_SELECT_ENDPOINT(endpoint);
- // IN
- if (LO_UINT16(usbSetupHeader.index) & 0x80) {
- USBCSIL = set ? USBCSIL_SEND_STALL : USBCSIL_CLR_DATA_TOG;
- usbfwData.pEpInStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE;
- usbsrHookProcessEvent(set ? USBSR_EVENT_EPIN_STALL_SET : USBSR_EVENT_EPIN_STALL_CLEARED, endpoint);
- // OUT
- } else {
- USBCSOL = set ? USBCSOL_SEND_STALL : USBCSOL_CLR_DATA_TOG;
- usbfwData.pEpOutStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE;
- usbsrHookProcessEvent(set ? USBSR_EVENT_EPOUT_STALL_SET : USBSR_EVENT_EPOUT_STALL_CLEARED, endpoint);
- }
- USBFW_SELECT_ENDPOINT(0);
- }
- break;
- default:
- usbfwData.ep0Status = EP_STALL;
- break;
- }
- }
- return TRUE;
- } // ChangeFeature
- /** \brief Processes the \ref CLEAR_FEATURE request (clears or disables a specific feature)
- *
- * The feature selector value must be appropriate to the recipient.
- *
- * <b>Parameters</b>:
- * - VALUE: Feature selector:
- * - \c DEVICE_REMOTE_WAKEUP(1): Enable remote wakeup
- * - \c ENDPOINT_HALT(0): Clear the halt feature for the specified endpoint (not endpoint 0!)
- * - INDEX: Depends upon the recipient:
- * - DEVICE: Always 0
- * - INTERFACE: Interface number
- * - ENDPOINT: Endpoint address
- * - LENGTH: Always 0
- */
- void usbsrClearFeature()
- {
- if (!ChangeFeature(FALSE)) {
- usbsrHookClearFeature();
- }
- } // usbsrClearFeature
- /** \brief Processes the \ref SET_FEATURE request (sets or enables a specific feature)
- *
- * The feature selector value must be appropriate to the recipient.
- *
- * <b>Parameters</b>:
- * - VALUE: Feature selector:
- * - \c DEVICE_REMOTE_WAKEUP(1): Enable remote wakeup
- * - \c ENDPOINT_HALT(0): Set the halt feature for the specified endpoint (not endpoint 0!)
- * - INDEX: Depends upon the recipient:
- * - DEVICE: Always 0
- * - INTERFACE: Interface number
- * - ENDPOINT: Endpoint address
- * - LENGTH: Always 0
- */
- void usbsrSetFeature(void)
- {
- if (!ChangeFeature(TRUE)) {
- usbsrHookSetFeature();
- }
- } // usbsrSetFeature
- /** \brief Processes the \ref SET_ADDRESS request (sets the device address for all future device
- * accesses)
- *
- * If the value is between 1 and 127 and the device is in the default state, it will enter the address
- * state. If it already is in the address state, it starts to use the newly-specified address.
- *
- * If the value is 0 and the device is in the address state, it will enter the default state. If it
- * already is in the default state, nothing happens.
- *
- * <b>Parameters</b>:
- * - VALUE: The device address (0-127)
- * - INDEX: Always 0
- * - LENGTH: Always 0
- */
- void usbsrSetAddress(void)
- {
- // Sanity check
- if (usbSetupHeader.index || usbSetupHeader.length || HI_UINT16(usbSetupHeader.value) || (LO_UINT16(usbSetupHeader.value) & 0x80)) {
- usbfwData.ep0Status = EP_STALL;
- // Update the device address
- } else {
- USBADDR = LO_UINT16(usbSetupHeader.value);
- if (LO_UINT16(usbSetupHeader.value) != 0) {
- if (usbfwData.usbState == DEV_DEFAULT) usbfwData.usbState = DEV_ADDRESS;
- } else {
- if (usbfwData.usbState == DEV_ADDRESS) usbfwData.usbState = DEV_DEFAULT;
- }
- }
- } // usbsrSetAddress
- /** \brief Processes the \ref GET_DESCRIPTOR request (returns the specified USB descriptor)
- *
- * The \ref module_usb_descriptor_parser module is used to locate device, configuration and string
- * descriptors. Note that configuration descriptors also include interface, endpoint and other
- * "similar" descriptor types (e.g. HID descriptor), with the total descriptor length specified by
- * the \ref USB_CONFIGURATION_DESCRIPTOR.wTotalLength field.
- *
- * Other descriptor types that are not returned with the configuration descriptor, must be defined in
- * the usbDescriptorMarker.pUsbDescLut lookup-table. This table specifies the values of the VALUE and INDEX fields, and
- * gives a pointer to the descriptor along with it's length.
- *
- * <b>Parameters</b>:
- * - VALUE.MSB: Descriptor type
- * - VALUE.LSB: Descriptor index
- * - INDEX: 0, or language ID for string descriptors (currently not supported)
- * - LENGTH: Descriptor length (either the requested number of bytes, or the length of the descriptor,
- * whichever is the smallest)
- *
- * <b>Data (IN)</b>:
- * The descriptor(s)
- */
- void usbsrGetDescriptor(void)
- {
- uint8 n;
- // Which descriptor?
- switch (HI_UINT16(usbSetupHeader.value)) {
- // Device descriptor
- case DESC_TYPE_DEVICE:
- usbSetupData.pBuffer = (uint8 __code*) usbdpGetDeviceDesc();
- usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX];
- break;
- // Configuration descriptor
- case DESC_TYPE_CONFIG:
- usbSetupData.pBuffer = (uint8 __code*) usbdpGetConfigurationDesc(0, LO_UINT16(usbSetupHeader.value));
- usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_CONFIG_LENGTH_LSB_IDX] +
- usbSetupData.pBuffer[DESC_CONFIG_LENGTH_MSB_IDX] * 256;
- break;
- // String descriptor
- case DESC_TYPE_STRING:
- // TODO: Implement language ID
- usbSetupData.pBuffer = (uint8 *)usbdpGetStringDesc(LO_UINT16(usbSetupHeader.value));
- usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX];
- break;
- // Other descriptor type
- default:
- // Perform a table search (on index and value)
- usbSetupData.pBuffer = NULL;
- for (n = 0; n < ((uint16)usbDescriptorMarker.pUsbDescLutEnd - (uint16)usbDescriptorMarker.pUsbDescLut) / sizeof(DESC_LUT_INFO); n++) {
- if ((usbDescriptorMarker.pUsbDescLut[n].valueMsb == HI_UINT16(usbSetupHeader.value))
- && (usbDescriptorMarker.pUsbDescLut[n].valueLsb == LO_UINT16(usbSetupHeader.value))
- && (usbDescriptorMarker.pUsbDescLut[n].indexMsb == HI_UINT16(usbSetupHeader.index))
- && (usbDescriptorMarker.pUsbDescLut[n].indexLsb == LO_UINT16(usbSetupHeader.index)) )
- {
- usbSetupData.pBuffer = usbDescriptorMarker.pUsbDescLut[n].pDescStart;
- usbSetupData.bytesLeft = usbDescriptorMarker.pUsbDescLut[n].length;
- }
- }
- }
- // Stall EP0 if no descriptor was found
- if (usbSetupData.pBuffer == NULL) usbfwData.ep0Status = EP_STALL;
- if (usbfwData.ep0Status != EP_STALL) {
- // Limit the returned descriptor size (the PC wants to know about sizes before
- // polling the complete descriptors)
- if (usbSetupData.bytesLeft > usbSetupHeader.length) {
- usbSetupData.bytesLeft = usbSetupHeader.length;
- }
- usbfwData.ep0Status = EP_TX;
- }
- } // usbsrGetDescriptor
- /** \brief Internally used function that configures all endpoints for the specified interface
- *
- * The new endpoint setup overwrites the old, without any warning. Unused endpoints keep their current
- * setup. The user is responsible for ensuring that no endpoint buffers overwrite each other, and that
- * interfaces do not cause conflicts. The pUsbDblbufLutInfo table must contain an entry for each
- * interface descriptor to define endpoint double-buffering.
- *
- * \param[in] *pInterface
- * A pointer to the interface descriptor
- */
- static void ConfigureEndpoints(USB_INTERFACE_DESCRIPTOR __code *pInterface)
- {
- uint8 n;
- uint16 maxpRegValue;
- uint8 csRegValue;
- uint8 endpoint;
- USB_ENDPOINT_DESCRIPTOR __code *pEndpoint;
- DBLBUF_LUT_INFO __code *pUsbDblbufLutInfo;
- // Locate the double buffer settings
- if (pInterface->bNumEndpoints) {
- pUsbDblbufLutInfo = (DBLBUF_LUT_INFO __code*) usbDescriptorMarker.pUsbDblbufLut;
- while (pUsbDblbufLutInfo->pInterface != pInterface) {
- pUsbDblbufLutInfo++;
- }
- }
- // For each endpoint in this interface
- for (n = 0; n < pInterface->bNumEndpoints; n++) {
- if (pEndpoint = usbdpFindNext(DESC_TYPE_ENDPOINT, 0)) {
- // Get the endpoint index
- endpoint = pEndpoint->bEndpointAddress & 0x0F;
- USBFW_SELECT_ENDPOINT(endpoint);
- csRegValue = 0x00;
- maxpRegValue = (pEndpoint->wMaxPacketSize + 7) >> 3;
- // For IN endpoints...
- if (pEndpoint->bEndpointAddress & 0x80) {
- // Clear data toggle, and flush twice (due to double buffering)
- USBCSIL = USBCSIL_CLR_DATA_TOG | USBCSIL_FLUSH_PACKET;
- USBCSIL = USBCSIL_FLUSH_PACKET;
- // USBCSIH
- if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSIH_ISO; // ISO flag
- if (pUsbDblbufLutInfo->inMask & (1 << endpoint)) csRegValue |= USBCSIH_IN_DBL_BUF; // Double buffering
- USBCSIH = csRegValue;
- // Max transfer size
- USBMAXI = maxpRegValue;
- // Endpoint status
- usbfwData.pEpInStatus[endpoint - 1] = EP_IDLE;
- // For OUT endpoints...
- } else {
- // Clear data toggle, and flush twice (due to double buffering)
- USBCSOL = USBCSOL_CLR_DATA_TOG | USBCSOL_FLUSH_PACKET;
- USBCSOL = USBCSOL_FLUSH_PACKET;
- // USBCSOH
- if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSOH_ISO; // ISO flag
- if (pUsbDblbufLutInfo->outMask & (1 << endpoint)) csRegValue |= USBCSOH_OUT_DBL_BUF; // Double buffering
- USBCSOH = csRegValue;
- // Max transfer size
- USBMAXO = maxpRegValue;
- // Endpoint status
- usbfwData.pEpOutStatus[endpoint - 1] = EP_IDLE;
- }
- USBFW_SELECT_ENDPOINT(0);
- }
- }
- } // ConfigureEndpoints
- /** \brief Processes the \ref GET_CONFIGURATION request (returns the current device configuration value)
- *
- * If the returned value is 0, the device is not configured (not in the configured state)
- *
- * <b>Parameters</b>:
- * - VALUE: Always 0
- * - INDEX: Always 0
- * - LENGTH: Always 1
- *
- * <b>Data (IN)</b>:
- * The non-zero \ref USB_CONFIGURATION_DESCRIPTOR.bConfigurationValue of the currently selected
- * configuration.
- */
- void usbsrGetConfiguration(void)
- {
- // Sanity check
- if (usbSetupHeader.value || usbSetupHeader.index || (usbSetupHeader.length != 1)) {
- usbfwData.ep0Status = EP_STALL;
- // Return the current configuration
- } else {
- usbSetupData.pBuffer = &usbfwData.configurationValue;
- usbSetupData.bytesLeft = 1;
- usbfwData.ep0Status = EP_TX;
- }
- } // usbsrGetConfiguration
- /** \brief Processes the \ref SET_CONFIGURATION request (sets the device configuration)
- *
- * The configuration value must either be 0, in which case the device enters the address state, or it
- * must match a configuration value from one of the USB configuration descriptors. If there is a match,
- * the device enters the configured state.
- *
- * This request resets all interfaces to alternate setting 0, and uses the \c ConfigureEndpoints()
- * function to automatically setup all endpoint registers.
- *
- * <b>Parameters</b>:
- * - VALUE: The configuration value (0-255)
- * - INDEX: Always 0
- * - LENGTH: Always 0
- */
- void usbsrSetConfiguration(void)
- {
- uint8 n;
- USB_CONFIGURATION_DESCRIPTOR __code *pConfiguration;
- USB_INTERFACE_DESCRIPTOR __code *pInterface;
- // Sanity check
- if ((usbfwData.usbState == DEV_DEFAULT) || usbSetupHeader.index || usbSetupHeader.length || HI_UINT16(usbSetupHeader.value)) {
- usbfwData.ep0Status = EP_STALL;
- // Default endpoint setup
- } else {
- usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGING, 0);
- // Configure relevant endpoints
- if (LO_UINT16(usbSetupHeader.value)) {
- // Find the correct configuration descriptor...
- pConfiguration = usbdpGetConfigurationDesc(LO_UINT16(usbSetupHeader.value), 0);
- // If it exists...
- if (pConfiguration) {
- usbfwData.usbState = DEV_CONFIGURED;
- usbfwData.configurationValue = LO_UINT16(usbSetupHeader.value);
- // For each interface...
- for (n = 0; n < pConfiguration->bNumInterfaces; n++) {
- usbfwData.pAlternateSetting[n] = 0x00;
- // Look only for alternate setting 0
- do {
- pInterface = usbdpFindNext(DESC_TYPE_INTERFACE, 0);
- } while (pInterface->bAlternateSetting != usbfwData.pAlternateSetting[n]);
- // Configure all endpoints in this interface
- ConfigureEndpoints(pInterface);
- }
- // If not, then stall the endpoint
- } else {
- usbfwData.ep0Status = EP_STALL;
- }
- // Unconfigure endpoints
- } else {
- usbfwData.configurationValue = LO_UINT16(usbSetupHeader.value);
- usbfwData.usbState = DEV_ADDRESS;
- usbfwSetAllEpStatus(EP_HALT);
- }
- usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGED, 0);
- }
- } // usbsrSetConfiguration
- /** \brief Processes the \ref GET_INTERFACE request (returns the selected alternate setting for the
- * specified interface)
- *
- * Some USB devices have configurations with mutually exclusive interface settings. This request allows
- * the host to determine the currently selected alternate setting.
- *
- * <b>Parameters</b>:
- * - VALUE: Always 0
- * - INDEX: Interface number
- * - LENGTH: Always 1
- *
- * <b>Data (IN)</b>:
- * The alternate setting for the selected interface
- */
- void usbsrGetInterface(void)
- {
- // Sanity check
- if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_IN_INTERFACE) || usbSetupHeader.value || (usbSetupHeader.length != 1)) {
- usbfwData.ep0Status = EP_STALL;
- // Return the current alternate setting
- } else {
- usbSetupData.pBuffer = &usbfwData.pAlternateSetting[usbSetupHeader.index];
- usbSetupData.bytesLeft = 1;
- usbfwData.ep0Status = EP_TX;
- }
- } // usbsrGetInterface
- /** \brief Processes the \ref SET_INTERFACE request (selects an alternate setting for the specified
- * interface)
- *
- * Some USB devices have configurations with mutually exclusive interface settings. This request allows
- * the host to select the desired alternate setting.
- *
- * This function uses the \c ConfigureEndpoints() to automatically setup the relevant endpoint
- * registers.
- *
- * <b>Parameters</b>:
- * - VALUE: Alternate setting
- * - INDEX: Interface number
- * - LENGTH: Always 0
- */
- void usbsrSetInterface(void)
- {
- USB_INTERFACE_DESCRIPTOR __code *pInterface;
- // Sanity check
- if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_OUT_INTERFACE) || usbSetupHeader.length) {
- usbfwData.ep0Status = EP_STALL;
- // Verify that the desired alternate setting is available, and then make the switch
- } else {
- if (pInterface = usbdpGetInterfaceDesc(usbfwData.configurationValue, usbSetupHeader.index, usbSetupHeader.value)) {
- usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGING, usbSetupHeader.index);
- usbfwData.pAlternateSetting[usbSetupHeader.index] = usbSetupHeader.value;
- // Configure all endpoints in this interface
- ConfigureEndpoints(pInterface);
- usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGED, usbSetupHeader.index);
- // This interface does not exist
- } else {
- usbfwData.ep0Status = EP_STALL;
- }
- }
- } // usbsrSetInterface
- //@}
- /*
- +------------------------------------------------------------------------------
- | Copyright 2004-2010 Texas Instruments Incorporated. All rights reserved.
- |
- | IMPORTANT: Your use of this Software is limited to those specific rights
- | granted under the terms of a software license agreement between the user who
- | downloaded the software, his/her employer (which must be your employer) and
- | Texas Instruments Incorporated (the "License"). You may not use this Software
- | unless you agree to abide by the terms of the License. The License limits
- | your use, and you acknowledge, that the Software may not be modified, copied
- | or distributed unless embedded on a Texas Instruments microcontroller or used
- | solely and exclusively in conjunction with a Texas Instruments radio
- | frequency transceiver, which is integrated into your product. Other than for
- | the foregoing purpose, you may not use, reproduce, copy, prepare derivative
- | works of, modify, distribute, perform, display or sell this Software and/or
- | its documentation for any purpose.
- |
- | YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
- | PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
- | INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
- | NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
- | TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
- | NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
- | LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING
- | BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
- | CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
- | SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
- | (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
- |
- | Should you have any questions regarding your right to use this Software,
- | contact Texas Instruments Incorporated at www.TI.com.
- |
- +------------------------------------------------------------------------------
- */
|