author | Max Groening <m-groening@ti.com> | |
Wed, 26 Feb 2014 22:59:17 +0000 (23:59 +0100) | ||
committer | Max Groening <m-groening@ti.com> | |
Wed, 26 Feb 2014 22:59:17 +0000 (23:59 +0100) |
58 files changed:
diff --git a/BSL_Comm.c b/BSL_Comm.c
--- /dev/null
+++ b/BSL_Comm.c
@@ -0,0 +1,106 @@
+/*
+ * BSL_Comm.c
+ *
+ * The I2C state machine.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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 "BSL_Comm.h"
+#include "descriptors.h"
+#include "USB_API\USB_Common\types.h" // Basic Type declarations
+#include "USB_API\USB_CDC_API\UsbCdc.h" // USB-specific functions
+
+// Description:
+// Analyzes incoming usbdata
+// return: I2C write trigger
+unsigned int length = 0;
+unsigned char state = SWAIT;
+
+unsigned char CoreCommand[256];
+unsigned char i = 0;
+
+extern volatile BYTE bDataReceiveCompleted_event[]; // data receive completed event
+
+unsigned char UART_FSM(BYTE* dataBuffer)
+{
+ unsigned int retvalue = 0;
+
+ switch(state)
+ {
+ case(SWAIT): // wait for UART_HEADER to start the data sequence
+ USBCDC_receiveData(dataBuffer, UART_HEADER_LENGTH, CDC0_INTFNUM);
+ if(dataBuffer[0] == UART_HEADER)
+ {
+ length = 0;
+ state = SSTART;
+ }
+ else if (dataBuffer[0] == UART_CMD_HEADER)
+ {
+ state = SCMD;
+ }
+
+ retvalue = 0;
+ break;
+ case(SSTART): // read in length bytes
+ bDataReceiveCompleted_event[0] = FALSE;
+ USBCDC_receiveData(dataBuffer + UART_HEADER_LENGTH, UART_LENGTH_LENGTH, CDC0_INTFNUM);
+ while (bDataReceiveCompleted_event[0] == FALSE){}; // wait until data received
+ length = ((unsigned char) dataBuffer[1 + UART_HEADER_LENGTH] << 8) | dataBuffer[0 + UART_HEADER_LENGTH];
+ state = SDATA;
+ retvalue = 0;
+ break;
+ case(SDATA): // read in all data (length bytes) plus CRC
+ bDataReceiveCompleted_event[0] = FALSE;
+ USBCDC_receiveData(dataBuffer + UART_HEADER_LENGTH + UART_LENGTH_LENGTH, length + UART_CRC_LENGTH, CDC0_INTFNUM);
+ while (bDataReceiveCompleted_event[0] == FALSE){};
+
+ USBCDC_rejectData(CDC0_INTFNUM); // discard leftover bytes
+
+ state = SWAIT;
+ retvalue = UART_HEADER_LENGTH + UART_LENGTH_LENGTH + length + UART_CRC_LENGTH;
+ break;
+
+ case SCMD:
+ USBCDC_receiveData(dataBuffer, UART_CMD_LENGTH, CDC0_INTFNUM);
+ retvalue = dataBuffer[0];
+ state = SWAIT;
+ break;
+
+ default:
+ state = SWAIT;
+ retvalue = 0;
+ break;
+ }
+ return retvalue;
+}
diff --git a/BSL_Comm.h b/BSL_Comm.h
--- /dev/null
+++ b/BSL_Comm.h
@@ -0,0 +1,62 @@
+/*
+ * BSL_Comm.h
+ *
+ * The I2C state machine.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+#ifndef BSL_COMM_H_
+#define BSL_COMM_H_
+#include "USB_API/USB_Common/types.h" // Basic Type declarations
+
+#define UART_HEADER 0x80
+#define UART_CMD_HEADER 0xA0
+#define UART_HEADER_LENGTH 1 // length in byte
+#define UART_LENGTH_LENGTH 2 // length in byte
+#define UART_CRC_LENGTH 2 // length in byte
+#define UART_CMD_LENGTH 1 // length in byte
+
+// define STATES
+#define SWAIT 0x00
+#define SSTART 0x01
+#define SLENGTH 0x02
+#define SDATA 0x03
+#define SSEND 0x04
+#define SCMD 0x05
+
+
+
+unsigned char UART_FSM(BYTE *dataBuffer);
+
+#endif /*BSL_COMM_H_*/
diff --git a/F5xx_F6xx_Core_Lib/HAL_FLASH.c b/F5xx_F6xx_Core_Lib/HAL_FLASH.c
--- /dev/null
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ *
+ * HAL_FLASH.c
+ * Flash Library for flash memory controller of MSP430F5xx/6xx family
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Created: Version 1.0 11/24/2009
+ * Updated: Version 2.0 01/18/2011
+ *
+ ******************************************************************************/
+
+#include "msp430.h"
+#include "HAL_FLASH.h"
+
+void Flash_SegmentErase(uint16_t *Flash_ptr)
+{
+ FCTL3 = FWKEY; // Clear Lock bit
+ FCTL1 = FWKEY + ERASE; // Set Erase bit
+ *Flash_ptr = 0; // Dummy write to erase Flash seg
+ while (FCTL3 & BUSY); // test busy
+ FCTL1 = FWKEY; // Clear WRT bit
+ FCTL3 = FWKEY + LOCK; // Set LOCK bit
+}
+
+uint8_t Flash_EraseCheck(uint16_t *Flash_ptr, uint16_t len)
+{
+ uint16_t i;
+
+ for (i = 0; i < len; i++) { // was erasing successfull?
+ if (*(Flash_ptr + i) != 0xFF) {
+ return FLASH_STATUS_ERROR;
+ }
+ }
+
+ return FLASH_STATUS_OK;
+}
+
+void FlashWrite_8(uint8_t *Data_ptr, uint8_t *Flash_ptr, uint16_t count)
+{
+ FCTL3 = FWKEY; // Clear Lock bit
+ FCTL1 = FWKEY+WRT; // Enable byte/word write mode
+
+ while (count > 0) {
+ while (FCTL3 & BUSY); // test busy
+ *Flash_ptr++ = *Data_ptr++; // Write to Flash
+ count--;
+ }
+
+ FCTL1 = FWKEY; // Clear write bit
+ FCTL3 = FWKEY + LOCK; // Set LOCK bit
+}
+
+void FlashWrite_16(uint16_t *Data_ptr, uint16_t *Flash_ptr, uint16_t count)
+{
+ FCTL3 = FWKEY; // Clear Lock bit
+ FCTL1 = FWKEY+WRT; // Enable byte/word write mode
+
+ while (count > 0) {
+ while (FCTL3 & BUSY); // test busy
+ *Flash_ptr++ = *Data_ptr++; // Write to Flash
+ count--;
+ }
+
+ FCTL1 = FWKEY; // Clear Erase bit
+ FCTL3 = FWKEY + LOCK; // Set LOCK bit
+}
+
+void FlashWrite_32(uint32_t *Data_ptr, uint32_t *Flash_ptr, uint16_t count)
+{
+ FCTL3 = FWKEY; // Clear Lock bit
+ FCTL1 = FWKEY + BLKWRT; // Enable long-word write
+
+ while (count > 0) {
+ while (FCTL3 & BUSY); // test busy
+ *Flash_ptr++ = *Data_ptr++; // Write to Flash
+ count--;
+ }
+
+ FCTL1 = FWKEY; // Clear Erase bit
+ FCTL3 = FWKEY + LOCK; // Set LOCK bit
+}
+
+void FlashMemoryFill_32(uint32_t value, uint32_t *Flash_ptr, uint16_t count)
+{
+ FCTL3 = FWKEY; // Clear Lock bit
+ FCTL1 = FWKEY + BLKWRT; // Enable long-word write
+
+ while (count > 0) {
+ while (FCTL3 & BUSY); // test busy
+ *Flash_ptr++ = value; // Write to Flash
+ count--;
+ }
+
+ FCTL1 = FWKEY; // Clear Erase bit
+ FCTL3 = FWKEY + LOCK; // Set LOCK bit
+}
diff --git a/F5xx_F6xx_Core_Lib/HAL_FLASH.h b/F5xx_F6xx_Core_Lib/HAL_FLASH.h
--- /dev/null
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ *
+ * HAL_FLASH.h
+ * Flash Library for flash memory controller of MSP430F5xx/6xx family
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Created: Version 1.0 11/24/2009
+ * Updated: Version 2.0 01/18/2011
+ *
+ ******************************************************************************/
+
+#ifndef HAL_FLASH_H
+#define HAL_FLASH_H
+
+#include <stdint.h>
+
+//******************************************************************************
+// Defines
+//******************************************************************************
+
+#define FLASH_STATUS_OK 0
+#define FLASH_STATUS_ERROR 1
+
+/*******************************************************************************
+ * \brief Erase a single segment of the flash memory
+ *
+ * \param *Flash_ptr Pointer into the flash segment to erase
+ ******************************************************************************/
+extern void Flash_SegmentErase(uint16_t *Flash_ptr);
+
+/*******************************************************************************
+ * \brief Erase Check of the flash memory
+ *
+ * \param *Flash_ptr Pointer into the flash segment to erase
+ * \param len give the len in word
+ ******************************************************************************/
+extern uint8_t Flash_EraseCheck(uint16_t *Flash_ptr, uint16_t len);
+
+/*******************************************************************************
+ * \brief Write data into the flash memory (Byte format)
+ *
+ * \param *Data_ptr Pointer to the Data to write
+ * \param *Flash_ptr Pointer into the flash to write data to
+ * \param count number of data to write
+ ******************************************************************************/
+extern void FlashWrite_8(uint8_t *Data_ptr, uint8_t *Flash_ptr, uint16_t count);
+
+/*******************************************************************************
+ * \brief Write data into the flash memory (Word format)
+ *
+ * \param *Data_ptr Pointer to the Data to write
+ * \param *Flash_ptr Pointer into the flash to write data to
+ * \param count number of data to write
+ ******************************************************************************/
+extern void FlashWrite_16(uint16_t *Data_ptr, uint16_t *Flash_ptr, uint16_t count);
+
+/*******************************************************************************
+ * \brief Write data into the flash memory (Long format)
+ *
+ * \param *Data_ptr Pointer to the Data to write
+ * \param *Flash_ptr Pointer into the flash to write data to
+ * \param count number of data to write
+ ******************************************************************************/
+extern void FlashWrite_32(uint32_t *Data_ptr, uint32_t *Flash_ptr, uint16_t count);
+
+/*******************************************************************************
+ * \brief Fill data into the flash memory (Long format)
+ *
+ * \param value Pointer to the Data to write
+ * \param *Flash_ptr pointer into the flash to write data to
+ * \param count number of data to write (= byte * 4)
+ ******************************************************************************/
+extern void FlashMemoryFill_32(uint32_t value, uint32_t *Flash_ptr, uint16_t count);
+
+#endif /* HAL_FLASH_H */
diff --git a/F5xx_F6xx_Core_Lib/HAL_MACROS.h b/F5xx_F6xx_Core_Lib/HAL_MACROS.h
--- /dev/null
@@ -0,0 +1,51 @@
+/* ****************************************************************************
+ *
+ * HAL_MACROS.h
+ * Flash Library for flash memory controller of MSP430F5xx/6xx family
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Created: Version 1.0 11/24/2009
+ * Updated: Version 2.0 12/15/2010
+ *
+******************************************************************************/
+
+#ifndef HAL_MACROS_H
+#define HAL_MACROS_H
+
+/*
+ * This macro is for use by other macros to form a fully valid C statement.
+ */
+#define st(x) do { x } while (__LINE__ == -1)
+
+#endif /* HAL_MACROS_H */
diff --git a/F5xx_F6xx_Core_Lib/HAL_PMAP.c b/F5xx_F6xx_Core_Lib/HAL_PMAP.c
--- /dev/null
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ *
+ * HAL_PMAP.c
+ * Port Mapper Library for PMAP controller of MSP430F5xx/6xx family
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Created: Version 1.0 11/24/2009
+ * Updated: Version 2.0 12/15/2010
+ *
+ ******************************************************************************/
+
+#include "msp430.h"
+#include "HAL_PMAP.h"
+
+// Check and define PMAP function only if the device has port mapping capability
+// Note: This macro is defined in the device-specific header file if this
+// feature is available on a given MSP430.
+#ifdef __MSP430_HAS_PORT_MAPPING__
+
+void configure_ports(const uint8_t *port_mapping, uint8_t *PxMAPy,
+ uint8_t num_of_ports, uint8_t port_map_reconfig)
+{
+ uint16_t i;
+
+ // Store current interrupt state, then disable all interrupts
+ uint16_t globalInterruptState = __get_SR_register() & GIE;
+ __disable_interrupt();
+
+ // Get write-access to port mapping registers:
+ PMAPPWD = PMAPPW;
+
+ if (port_map_reconfig) {
+ // Allow reconfiguration during runtime:
+ PMAPCTL = PMAPRECFG;
+ }
+
+ // Configure Port Mapping:
+ for (i = 0; i < num_of_ports * 8; i++) {
+ PxMAPy[i] = port_mapping[i];
+ }
+
+ // Disable write-access to port mapping registers:
+ PMAPPWD = 0;
+
+ // Restore previous interrupt state
+ __bis_SR_register(globalInterruptState);
+}
+
+#endif /* __MSP430_HAS_PORT_MAPPING__ */
diff --git a/F5xx_F6xx_Core_Lib/HAL_PMAP.h b/F5xx_F6xx_Core_Lib/HAL_PMAP.h
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ *
+ * HAL_PMAP.h
+ * Port Mapper Library for PMAP controller of MSP430F5xx/6xx family
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Created: Version 1.0 11/24/2009
+ * Updated: Version 2.0 12/15/2010
+ *
+ ******************************************************************************/
+
+#ifndef HAL_PMAP_H
+#define HAL_PMAP_H
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * \brief Configures the MSP430 Port Mapper
+ *
+ * \param *port_mapping Pointer to init Data
+ * \param PxMAPy Pointer start of first Port Mapper to initialize
+ * \param num_of_ports Number of Ports to initialize
+ * \param port_map_reconfig Flag to enable/disable reconfiguration
+ *
+ ******************************************************************************/
+extern void configure_ports(const uint8_t *port_mapping, uint8_t *PxMAPy,
+ uint8_t num_of_ports, uint8_t port_map_reconfig);
+
+#endif /* HAL_PMAP_H */
diff --git a/F5xx_F6xx_Core_Lib/HAL_PMM.c b/F5xx_F6xx_Core_Lib/HAL_PMM.c
--- /dev/null
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ *
+ * HAL_PMM.c
+ * Power Management Module Library for MSP430F5xx/6xx family
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Created: Version 1.0 11/24/2009
+ * Updated: Version 2.0 12/15/2010
+ * Modified SetVcoreUp() and SetVcoreDown() functions
+ *
+ ******************************************************************************/
+
+#include "msp430.h"
+#include "HAL_PMM.h"
+
+#define _HAL_PMM_DISABLE_SVML_
+#define _HAL_PMM_DISABLE_SVSL_
+#define _HAL_PMM_DISABLE_FULL_PERFORMANCE_
+
+#ifdef _HAL_PMM_DISABLE_SVML_
+#define _HAL_PMM_SVMLE SVMLE
+#else
+#define _HAL_PMM_SVMLE 0
+#endif
+
+#ifdef _HAL_PMM_DISABLE_SVSL_
+#define _HAL_PMM_SVSLE SVSLE
+#else
+#define _HAL_PMM_SVSLE 0
+#endif
+
+#ifdef _HAL_PMM_DISABLE_FULL_PERFORMANCE_
+#define _HAL_PMM_SVSFP SVSLFP
+#define _HAL_PMM_SVMFP SVMLFP
+#else
+#define _HAL_PMM_SVSFP 0
+#define _HAL_PMM_SVMFP 0
+#endif
+
+/*******************************************************************************
+ * \brief Increase Vcore by one level
+ *
+ * \param level Level to which Vcore needs to be increased
+ * \return status Success/failure
+ ******************************************************************************/
+static uint16_t SetVCoreUp(uint8_t level)
+{
+ uint16_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
+
+ // The code flow for increasing the Vcore has been altered to work around
+ // the erratum FLASH37.
+ // Please refer to the Errata sheet to know if a specific device is affected
+ // DO NOT ALTER THIS FUNCTION
+
+ // Open PMM registers for write access
+ PMMCTL0_H = 0xA5;
+
+ // Disable dedicated Interrupts
+ // Backup all registers
+ PMMRIE_backup = PMMRIE;
+ PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE |
+ SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE );
+ SVSMHCTL_backup = SVSMHCTL;
+ SVSMLCTL_backup = SVSMLCTL;
+
+ // Clear flags
+ PMMIFG = 0;
+
+ // Set SVM highside to new level and check if a VCore increase is possible
+ SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
+
+ // Wait until SVM highside is settled
+ while ((PMMIFG & SVSMHDLYIFG) == 0);
+
+ // Clear flag
+ PMMIFG &= ~SVSMHDLYIFG;
+
+ // Check if a VCore increase is possible
+ if ((PMMIFG & SVMHIFG) == SVMHIFG) { // -> Vcc is too low for a Vcore increase
+ // recover the previous settings
+ PMMIFG &= ~SVSMHDLYIFG;
+ SVSMHCTL = SVSMHCTL_backup;
+
+ // Wait until SVM highside is settled
+ while ((PMMIFG & SVSMHDLYIFG) == 0);
+
+ // Clear all Flags
+ PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
+
+ PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
+ PMMCTL0_H = 0x00; // Lock PMM registers for write access
+ return PMM_STATUS_ERROR; // return: voltage not set
+ }
+
+ // Set also SVS highside to new level
+ // Vcc is high enough for a Vcore increase
+ SVSMHCTL |= (SVSHRVL0 * level);
+
+ // Wait until SVM highside is settled
+ while ((PMMIFG & SVSMHDLYIFG) == 0);
+
+ // Clear flag
+ PMMIFG &= ~SVSMHDLYIFG;
+
+ // Set VCore to new level
+ PMMCTL0_L = PMMCOREV0 * level;
+
+ // Set SVM, SVS low side to new level
+ SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);
+
+ // Wait until SVM, SVS low side is settled
+ while ((PMMIFG & SVSMLDLYIFG) == 0);
+
+ // Clear flag
+ PMMIFG &= ~SVSMLDLYIFG;
+ // SVS, SVM core and high side are now set to protect for the new core level
+
+ // Restore Low side settings
+ // Clear all other bits _except_ level settings
+ SVSMLCTL &= (SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);
+
+ // Clear level settings in the backup register,keep all other bits
+ SVSMLCTL_backup &= ~(SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);
+
+ // Restore low-side SVS monitor settings
+ SVSMLCTL |= SVSMLCTL_backup;
+
+ // Restore High side settings
+ // Clear all other bits except level settings
+ SVSMHCTL &= (SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);
+
+ // Clear level settings in the backup register,keep all other bits
+ SVSMHCTL_backup &= ~(SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);
+
+ // Restore backup
+ SVSMHCTL |= SVSMHCTL_backup;
+
+ // Wait until high side, low side settled
+ while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0));
+
+ // Clear all Flags
+ PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
+
+ PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
+ PMMCTL0_H = 0x00; // Lock PMM registers for write access
+
+ return PMM_STATUS_OK;
+}
+
+/*******************************************************************************
+ * \brief Decrease Vcore by one level
+ *
+ * \param level Level to which Vcore needs to be decreased
+ * \return status Success/failure
+ ******************************************************************************/
+static uint16_t SetVCoreDown(uint8_t level)
+{
+ uint16_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
+
+ // The code flow for decreasing the Vcore has been altered to work around
+ // the erratum FLASH37.
+ // Please refer to the Errata sheet to know if a specific device is affected
+ // DO NOT ALTER THIS FUNCTION
+
+ // Open PMM registers for write access
+ PMMCTL0_H = 0xA5;
+
+ // Disable dedicated Interrupts
+ // Backup all registers
+ PMMRIE_backup = PMMRIE;
+ PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE |
+ SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE );
+ SVSMHCTL_backup = SVSMHCTL;
+ SVSMLCTL_backup = SVSMLCTL;
+
+ // Clear flags
+ PMMIFG &= ~(SVMHIFG | SVSMHDLYIFG | SVMLIFG | SVSMLDLYIFG);
+
+ // Set SVM, SVS high & low side to new settings in normal mode
+ SVSMHCTL = SVMHE | (SVSMHRRL0 * level) | SVSHE | (SVSHRVL0 * level);
+ SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);
+
+ // Wait until SVM high side and SVM low side is settled
+ while ((PMMIFG & SVSMHDLYIFG) == 0 || (PMMIFG & SVSMLDLYIFG) == 0);
+
+ // Clear flags
+ PMMIFG &= ~(SVSMHDLYIFG + SVSMLDLYIFG);
+ // SVS, SVM core and high side are now set to protect for the new core level
+
+ // Set VCore to new level
+ PMMCTL0_L = PMMCOREV0 * level;
+
+ // Restore Low side settings
+ // Clear all other bits _except_ level settings
+ SVSMLCTL &= (SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);
+
+ // Clear level settings in the backup register,keep all other bits
+ SVSMLCTL_backup &= ~(SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);
+
+ // Restore low-side SVS monitor settings
+ SVSMLCTL |= SVSMLCTL_backup;
+
+ // Restore High side settings
+ // Clear all other bits except level settings
+ SVSMHCTL &= (SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);
+
+ // Clear level settings in the backup register, keep all other bits
+ SVSMHCTL_backup &= ~(SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);
+
+ // Restore backup
+ SVSMHCTL |= SVSMHCTL_backup;
+
+ // Wait until high side, low side settled
+ while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0));
+
+ // Clear all Flags
+ PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
+
+ PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
+ PMMCTL0_H = 0x00; // Lock PMM registers for write access
+ return PMM_STATUS_OK; // Return: OK
+}
+
+uint16_t SetVCore(uint8_t level)
+{
+ uint16_t actlevel;
+ uint16_t status = 0;
+
+ level &= PMMCOREV_3; // Set Mask for Max. level
+ actlevel = (PMMCTL0 & PMMCOREV_3); // Get actual VCore
+ // step by step increase or decrease
+ while (((level != actlevel) && (status == 0)) || (level < actlevel)) {
+ if (level > actlevel) {
+ status = SetVCoreUp(++actlevel);
+ }
+ else {
+ status = SetVCoreDown(--actlevel);
+ }
+ }
+
+ return status;
+}
diff --git a/F5xx_F6xx_Core_Lib/HAL_PMM.h b/F5xx_F6xx_Core_Lib/HAL_PMM.h
--- /dev/null
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ *
+ * HAL_PMM.h
+ * Power Management Module Library for MSP430F5xx/6xx family
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Created: Version 1.0 11/24/2009
+ * Updated: Version 2.0 12/15/2010
+ *
+ ******************************************************************************/
+
+#ifndef HAL_PMM_H
+#define HAL_PMM_H
+
+#include <stdint.h>
+#include "HAL_MACROS.h"
+
+/*******************************************************************************
+ * Macros
+ ******************************************************************************/
+#define ENABLE_SVSL() st(PMMCTL0_H = 0xA5; SVSMLCTL |= SVSLE; PMMCTL0_H = 0x00;)
+#define DISABLE_SVSL() st(PMMCTL0_H = 0xA5; SVSMLCTL &= ~SVSLE; PMMCTL0_H = 0x00;)
+#define ENABLE_SVML() st(PMMCTL0_H = 0xA5; SVSMLCTL |= SVMLE; PMMCTL0_H = 0x00;)
+#define DISABLE_SVML() st(PMMCTL0_H = 0xA5; SVSMLCTL &= ~SVMLE; PMMCTL0_H = 0x00;)
+#define ENABLE_SVSH() st(PMMCTL0_H = 0xA5; SVSMHCTL |= SVSHE; PMMCTL0_H = 0x00;)
+#define DISABLE_SVSH() st(PMMCTL0_H = 0xA5; SVSMHCTL &= ~SVSHE; PMMCTL0_H = 0x00;)
+#define ENABLE_SVMH() st(PMMCTL0_H = 0xA5; SVSMHCTL |= SVMHE; PMMCTL0_H = 0x00;)
+#define DISABLE_SVMH() st(PMMCTL0_H = 0xA5; SVSMHCTL &= ~SVMHE; PMMCTL0_H = 0x00;)
+#define ENABLE_SVSL_SVML() st(PMMCTL0_H = 0xA5; SVSMLCTL |= (SVSLE + SVMLE); PMMCTL0_H = 0x00;)
+#define DISABLE_SVSL_SVML() st(PMMCTL0_H = 0xA5; SVSMLCTL &= ~(SVSLE + SVMLE); PMMCTL0_H = 0x00;)
+#define ENABLE_SVSH_SVMH() st(PMMCTL0_H = 0xA5; SVSMHCTL |= (SVSHE + SVMHE); PMMCTL0_H = 0x00;)
+#define DISABLE_SVSH_SVMH() st(PMMCTL0_H = 0xA5; SVSMHCTL &= ~(SVSHE + SVMHE); PMMCTL0_H = 0x00;)
+
+#define ENABLE_SVSL_RESET() st(PMMCTL0_H = 0xA5; PMMRIE |= SVSLPE; PMMCTL0_H = 0x00;)
+#define DISABLE_SVSL_RESET() st(PMMCTL0_H = 0xA5; PMMRIE &= ~SVSLPE; PMMCTL0_H = 0x00;)
+#define ENABLE_SVML_INTERRUPT() st(PMMCTL0_H = 0xA5; PMMRIE |= SVMLIE; PMMCTL0_H = 0x00;)
+#define DISABLE_SVML_INTERRUPT() st(PMMCTL0_H = 0xA5; PMMRIE &= ~SVMLIE; PMMCTL0_H = 0x00;)
+#define ENABLE_SVSH_RESET() st(PMMCTL0_H = 0xA5; PMMRIE |= SVSHPE; PMMCTL0_H = 0x00;)
+#define DISABLE_SVSH_RESET() st(PMMCTL0_H = 0xA5; PMMRIE &= ~SVSHPE; PMMCTL0_H = 0x00;)
+#define ENABLE_SVMH_INTERRUPT() st(PMMCTL0_H = 0xA5; PMMRIE |= SVMHIE; PMMCTL0_H = 0x00;)
+#define DISABLE_SVMH_INTERRUPT() st(PMMCTL0_H = 0xA5; PMMRIE &= ~SVMHIE; PMMCTL0_H = 0x00;)
+#define CLEAR_PMM_IFGS() st(PMMCTL0_H = 0xA5; PMMIFG = 0; PMMCTL0_H = 0x00;)
+
+// These settings use SVSH/LACE = 0
+#define SVSL_ENABLED_IN_LPM_FAST_WAKE() st(PMMCTL0_H = 0xA5; SVSMLCTL |= (SVSLFP+SVSLMD); SVSMLCTL &= ~SVSMLACE; PMMCTL0_H = 0x00;)
+#define SVSL_ENABLED_IN_LPM_SLOW_WAKE() st(PMMCTL0_H = 0xA5; SVSMLCTL |= SVSLMD; SVSMLCTL &= ~(SVSLFP+SVSMLACE); PMMCTL0_H = 0x00;)
+
+#define SVSL_DISABLED_IN_LPM_FAST_WAKE() st(PMMCTL0_H = 0xA5; SVSMLCTL |= SVSLFP; SVSMLCTL &= ~(SVSLMD+SVSMLACE); PMMCTL0_H = 0x00;)
+#define SVSL_DISABLED_IN_LPM_SLOW_WAKE() st(PMMCTL0_H = 0xA5; SVSMLCTL &= ~(SVSLFP+SVSMLACE+SVSLMD); PMMCTL0_H = 0x00;)
+
+#define SVSH_ENABLED_IN_LPM_NORM_PERF() st(PMMCTL0_H = 0xA5; SVSMHCTL |= SVSHMD; SVSMHCTL &= ~(SVSMHACE+SVSHFP); PMMCTL0_H = 0x00;)
+#define SVSH_ENABLED_IN_LPM_FULL_PERF() st(PMMCTL0_H = 0xA5; SVSMHCTL |= (SVSHMD+SVSHFP); SVSMHCTL &= ~SVSMHACE; PMMCTL0_H = 0x00;)
+
+#define SVSH_DISABLED_IN_LPM_NORM_PERF() st(PMMCTL0_H = 0xA5; SVSMHCTL &= ~(SVSMHACE+SVSHFP+SVSHMD);PMMCTL0_H = 0x00;)
+#define SVSH_DISABLED_IN_LPM_FULL_PERF() st(PMMCTL0_H = 0xA5; SVSMHCTL |= SVSHFP; SVSMHCTL &= ~(SVSMHACE+SVSHMD); PMMCTL0_H = 0x00;)
+
+// These setting use SVSH/LACE = 1
+#define SVSL_OPTIMIZED_IN_LPM_FAST_WAKE() st(PMMCTL0_H = 0xA5; SVSMLCTL |= (SVSLFP+SVSLMD+SVSMLACE); PMMCTL0_H = 0x00;)
+#define SVSH_OPTIMIZED_IN_LPM_FULL_PERF() st(PMMCTL0_H = 0xA5; SVSMHCTL |= (SVSHMD+SVSHFP+SVSMHACE); PMMCTL0_H = 0x00;)
+
+/*******************************************************************************
+ * Defines
+ ******************************************************************************/
+#define PMM_STATUS_OK 0
+#define PMM_STATUS_ERROR 1
+
+/*******************************************************************************
+ * \brief Set Vcore to expected level
+ *
+ * \param level Level to which Vcore needs to be increased/decreased
+ * \return status Success/failure
+ ******************************************************************************/
+extern uint16_t SetVCore(uint8_t level);
+
+#endif /* HAL_PMM_H */
diff --git a/F5xx_F6xx_Core_Lib/HAL_TLV.c b/F5xx_F6xx_Core_Lib/HAL_TLV.c
--- /dev/null
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ *
+ * HAL_TLV.c
+ * Provides Functions to Read the TLV Data Section of the MSP430 Devices
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Updated: Version 2.0 01/17/2011
+ *
+ ******************************************************************************/
+
+#include "msp430.h"
+#include "HAL_TLV.h"
+
+void Get_TLV_Info(uint8_t tag, uint8_t instance, uint8_t *length, uint16_t **data_address)
+{
+ char *TLV_address = (char *)TLV_START; // TLV Structure Start Address
+
+ while((TLV_address < (char *)TLV_END)
+ && ((*TLV_address != tag) || instance) // check for tag and instance
+ && (*TLV_address != TLV_TAGEND)) // do range check first
+ {
+ if (*TLV_address == tag) instance--; // repeat till requested instance is reached
+ TLV_address += *(TLV_address + 1) + 2; // add (Current TAG address + LENGTH) + 2
+ }
+
+ if (*TLV_address == tag) // Check if Tag match happened..
+ {
+ *length = *(TLV_address + 1); // Return length = Address + 1
+ *data_address = (uint16_t *)(TLV_address + 2); // Return address of first data/value info = Address + 2
+ }
+ else // If there was no tag match and the end of TLV structure was reached..
+ {
+ *length = 0; // Return 0 for TAG not found
+ *data_address = 0; // Return 0 for TAG not found
+ }
+}
+
+uint16_t Get_Device_Type(void)
+{
+ uint16_t *pDeviceType = (uint16_t *)DEVICE_ID_0;
+ return pDeviceType[0]; // Return Value from TLV Table
+}
+
+uint16_t Get_TLV_Memory(uint8_t instance)
+{
+ uint8_t *pPDTAG;
+ uint8_t bPDTAG_bytes;
+ uint16_t count;
+
+ instance *= 2; // set tag for word access comparison
+
+ // TLV access Function Call
+ Get_TLV_Info(TLV_PDTAG, 0, &bPDTAG_bytes, (uint16_t **)&pPDTAG); // Get Peripheral data pointer
+
+ for (count = 0;count <= instance; count += 2)
+ {
+ if (pPDTAG[count] == 0) return 0; // Return 0 if end reached
+ if (count == instance) return (pPDTAG[count] | pPDTAG[count+1]<<8);
+ }
+
+ return 0; // Return 0: not found
+}
+
+uint16_t Get_TLV_Peripheral(uint8_t tag, uint8_t instance)
+{
+ uint8_t *pPDTAG;
+ uint8_t bPDTAG_bytes;
+ uint16_t count = 0;
+ uint16_t pcount = 0;
+
+ Get_TLV_Info(TLV_PDTAG, 0, &bPDTAG_bytes, (uint16_t **)&pPDTAG); // Get Peripheral data pointer
+
+ // read memory configuration from TLV to get offset for Peripherals
+ while (Get_TLV_Memory(count)) {
+ count++;
+ }
+
+ pcount = pPDTAG[count * 2 + 1]; // get number of Peripheral entries
+ count++; // inc count to first Periperal
+ pPDTAG += count*2; // adjust point to first address of Peripheral
+ count = 0; // set counter back to 0
+ pcount *= 2; // align pcount for work comparision
+
+ // TLV access Function Call
+ for (count = 0; count <= pcount; count += 2) {
+ if (pPDTAG[count+1] == tag) { // test if required Peripheral is found
+ if (instance > 0) { // test if required instance is found
+ instance--;
+ }
+ else {
+ return (pPDTAG[count] | pPDTAG[count + 1] << 8); // Return found data
+ }
+ }
+ }
+
+ return 0; // Return 0: not found
+}
+
+uint8_t Get_TLV_Interrupt(uint8_t tag)
+{
+ uint8_t *pPDTAG;
+ uint8_t bPDTAG_bytes;
+ uint16_t count = 0;
+ uint16_t pcount = 0;
+
+ Get_TLV_Info(TLV_PDTAG, 0, &bPDTAG_bytes, (uint16_t **)&pPDTAG); // Get Peripheral data pointer
+
+ // read memory configuration from TLV to get offset for Peripherals
+ while (Get_TLV_Memory(count))
+ {
+ count++;
+ }
+
+ pcount = pPDTAG[count * 2 + 1];
+ count++; // inc count to first Periperal
+ pPDTAG += (pcount + count) * 2; // adjust point to first address of Peripheral
+ count = 0; // set counter back to 0
+
+ // TLV access Function Call
+ for (count = 0; count <= tag; count += 2)
+ {
+ if (pPDTAG[count] == 0) return 0; // Return 0: not found/end of table
+ if (count == tag) return (pPDTAG[count]); // Return found data
+ }
+
+ return 0; // Return 0: not found
+}
diff --git a/F5xx_F6xx_Core_Lib/HAL_TLV.h b/F5xx_F6xx_Core_Lib/HAL_TLV.h
--- /dev/null
@@ -0,0 +1,228 @@
+/*******************************************************************************
+ *
+ * HAL_TLV.c
+ * Provides Functions to Read the TLV Data Section of the MSP430 Devices
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Updated: Version 2.0 01/17/2011
+ *
+ ******************************************************************************/
+
+#ifndef HAL_TLV_H
+#define HAL_TLV_H
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * Device Descriptors - Fixed Memory Locations
+ ******************************************************************************/
+#define DEVICE_ID_0 (0x1A04)
+#define DEVICE_ID_1 (0x1A05)
+
+/*******************************************************************************
+ * Data Types
+ ******************************************************************************/
+struct s_TLV_Die_Record {
+ uint8_t die_record[10];
+};
+
+struct s_TLV_ADC_Cal_Data {
+ uint16_t adc_gain_factor;
+ uint16_t adc_offset;
+ uint16_t adc_ref15_30_temp;
+ uint16_t adc_ref15_85_temp;
+ uint16_t adc_ref20_30_temp;
+ uint16_t adc_ref20_85_temp;
+ uint16_t adc_ref25_30_temp;
+ uint16_t adc_ref25_85_temp;
+};
+
+struct s_TLV_Timer_D_Cal_Data {
+ uint16_t TDH0CTL1_64;
+ uint16_t TDH0CTL1_128;
+ uint16_t TDH0CTL1_200;
+ uint16_t TDH0CTL1_256;
+};
+
+struct s_TLV_REF_Cal_Data {
+ uint16_t ref_ref15;
+ uint16_t ref_ref20;
+ uint16_t adc_ref25;
+};
+
+/*******************************************************************************
+ * Tag Defines
+ ******************************************************************************/
+#define TLV_LDTAG (0x01) /* Legacy descriptor (1xx, 2xx,
+ 4xx families) */
+#define TLV_PDTAG (0x02) /* Peripheral discovery descriptor */
+#define TLV_Reserved3 (0x03) /* Future usage */
+#define TLV_Reserved4 (0x04) /* Future usage */
+#define TLV_BLANK (0x05) /* Blank descriptor */
+#define TLV_Reserved6 (0x06) /* Future usage */
+#define TLV_Reserved7 (0x07) /* Serial Number */
+#define TLV_DIERECORD (0x08) /* Die Record */
+#define TLV_ADCCAL (0x11) /* ADC12 calibration */
+#define TLV_ADC12CAL (0x11) /* ADC12 calibration */
+#define TLV_ADC10CAL (0x13) /* ADC10 calibration */
+#define TLV_REFCAL (0x12) /* REF calibration */
+#define TLV_TIMER_D_CAL (0x15) /* Timer_Dx calibration */
+#define TLV_TAGEXT (0xFE) /* Tag extender */
+#define TLV_TAGEND (0xFF) /* Tag End of Table */
+
+/*******************************************************************************
+ * Peripheral Defines
+ ******************************************************************************/
+#define TLV_PID_NO_MODULE (0x00) /* No Module */
+#define TLV_PID_PORTMAPPING (0x10) /* Port Mapping */
+#define TLV_PID_MSP430CPUXV2 (0x23) /* MSP430CPUXV2 */
+#define TLV_PID_JTAG (0x09) /* JTAG */
+#define TLV_PID_SBW (0x0F) /* SBW */
+#define TLV_PID_EEM_XS (0x02) /* EEM X-Small */
+#define TLV_PID_EEM_S (0x03) /* EEM Small */
+#define TLV_PID_EEM_M (0x04) /* EEM Medium */
+#define TLV_PID_EEM_L (0x05) /* EEM Large */
+#define TLV_PID_PMM (0x30) /* PMM */
+#define TLV_PID_PMM_FR (0x32) /* PMM FRAM */
+#define TLV_PID_FCTL (0x39) /* Flash */
+#define TLV_PID_CRC16 (0x3C) /* CRC16 */
+#define TLV_PID_CRC16_RB (0x3D) /* CRC16 Reverse */
+#define TLV_PID_WDT_A (0x40) /* WDT_A */
+#define TLV_PID_SFR (0x41) /* SFR */
+#define TLV_PID_SYS (0x42) /* SYS */
+#define TLV_PID_RAMCTL (0x44) /* RAMCTL */
+#define TLV_PID_DMA_1 (0x46) /* DMA 1 */
+#define TLV_PID_DMA_3 (0x47) /* DMA 3 */
+#define TLV_PID_UCS (0x48) /* UCS */
+#define TLV_PID_DMA_6 (0x4A) /* DMA 6 */
+#define TLV_PID_DMA_2 (0x4B) /* DMA 2 */
+#define TLV_PID_PORT1_2 (0x51) /* Port 1 + 2 / A */
+#define TLV_PID_PORT3_4 (0x52) /* Port 3 + 4 / B */
+#define TLV_PID_PORT5_6 (0x53) /* Port 5 + 6 / C */
+#define TLV_PID_PORT7_8 (0x54) /* Port 7 + 8 / D */
+#define TLV_PID_PORT9_10 (0x55) /* Port 9 + 10 / E */
+#define TLV_PID_PORT11_12 (0x56) /* Port 11 + 12 / F */
+#define TLV_PID_PORTU (0x5E) /* Port U */
+#define TLV_PID_PORTJ (0x5F) /* Port J */
+#define TLV_PID_TA2 (0x60) /* Timer A2 */
+#define TLV_PID_TA3 (0x61) /* Timer A1 */
+#define TLV_PID_TA5 (0x62) /* Timer A5 */
+#define TLV_PID_TA7 (0x63) /* Timer A7 */
+#define TLV_PID_TB3 (0x65) /* Timer B3 */
+#define TLV_PID_TB5 (0x66) /* Timer B5 */
+#define TLV_PID_TB7 (0x67) /* Timer B7 */
+#define TLV_PID_RTC (0x68) /* RTC */
+#define TLV_PID_BT_RTC (0x69) /* BT + RTC */
+#define TLV_PID_BBS (0x6A) /* Battery Backup Switch */
+#define TLV_PID_RTC_B (0x6B) /* RTC_B */
+#define TLV_PID_TD2 (0x6C) /* Timer D2 */
+#define TLV_PID_TD3 (0x6D) /* Timer D1 */
+#define TLV_PID_TD5 (0x6E) /* Timer D5 */
+#define TLV_PID_TD7 (0x6F) /* Timer D7 */
+#define TLV_PID_TEC (0x70) /* Imer Event Control */
+#define TLV_PID_RTC_C (0x71) /* RTC_C */
+#define TLV_PID_AES (0x80) /* AES */
+#define TLV_PID_MPY16 (0x84) /* MPY16 */
+#define TLV_PID_MPY32 (0x85) /* MPY32 */
+#define TLV_PID_MPU (0x86) /* MPU */
+#define TLV_PID_USCI_AB (0x90) /* USCI_AB */
+#define TLV_PID_USCI_A (0x91) /* USCI_A */
+#define TLV_PID_USCI_B (0x92) /* USCI_B */
+#define TLV_PID_EUSCI_A (0x94) /* eUSCI_A */
+#define TLV_PID_EUSCI_B (0x95) /* eUSCI_B */
+#define TLV_PID_REF (0xA0) /* Shared Reference */
+#define TLV_PID_COMP_B (0xA8) /* COMP_B */
+#define TLV_PID_COMP_D (0xA9) /* COMP_D */
+#define TLV_PID_USB (0x98) /* USB */
+#define TLV_PID_LCD_B (0xB1) /* LCD_B */
+#define TLV_PID_LCD_C (0xB2) /* LCD_C */
+#define TLV_PID_DAC12_A (0xC0) /* DAC12_A */
+#define TLV_PID_SD16_B_1 (0xC8) /* SD16_B 1 Channel */
+#define TLV_PID_SD16_B_2 (0xC9) /* SD16_B 2 Channel */
+#define TLV_PID_SD16_B_3 (0xCA) /* SD16_B 3 Channel */
+#define TLV_PID_SD16_B_4 (0xCB) /* SD16_B 4 Channel */
+#define TLV_PID_SD16_B_5 (0xCC) /* SD16_B 5 Channel */
+#define TLV_PID_SD16_B_6 (0xCD) /* SD16_B 6 Channel */
+#define TLV_PID_SD16_B_7 (0xCE) /* SD16_B 7 Channel */
+#define TLV_PID_SD16_B_8 (0xCF) /* SD16_B 8 Channel */
+#define TLV_PID_ADC12_A (0xD1) /* ADC12_A */
+#define TLV_PID_ADC10_A (0xD3) /* ADC10_A */
+#define TLV_PID_ADC10_B (0xD4) /* ADC10_B */
+#define TLV_PID_SD16_A (0xD8) /* SD16_A */
+#define TLV_PID_TI_BSL (0xFC) /* BSL */
+
+/*******************************************************************************
+ * \brief Get Information out of the TLV Table
+ *
+ * \param tag Tag of the TLV entry
+ * \param instance Instance of the Tag of the TLV entry
+ * \param *length return: Length of the information if found
+ * \param **data_address return: start pointer of Data
+ ******************************************************************************/
+void Get_TLV_Info(uint8_t tag, uint8_t instance, uint8_t *length,
+ uint16_t **data_address);
+
+/*******************************************************************************
+ * \brief Get Device Type out of the TLV Table
+ *
+ * \return Device dependent value
+ ******************************************************************************/
+uint16_t Get_Device_Type(void);
+
+/*******************************************************************************
+ * \brief Get Memory Info out of the TLV Table
+ *
+ * \param instance Index of the Instance [0..]
+ * \return Memory Data found
+ ******************************************************************************/
+uint16_t Get_TLV_Memory(uint8_t instance);
+
+/*******************************************************************************
+ * \brief Get Peripheral Info out of the TLV Table
+ *
+ * \param tag Tag of the TLV entry
+ * \param instance Index of the Instance [0..]
+ * \return Peripheral Data found
+ ******************************************************************************/
+uint16_t Get_TLV_Peripheral(uint8_t tag, uint8_t instance);
+
+/*******************************************************************************
+ * \brief Get Interrupt Info out of the TLV Table
+ *
+ * \param tag Tag of the TLV entry
+ * \return Interrupt Data found
+ ******************************************************************************/
+uint8_t Get_TLV_Interrupt(uint8_t tag);
+
+#endif /* HAL_TLV_H */
diff --git a/F5xx_F6xx_Core_Lib/HAL_UCS.c b/F5xx_F6xx_Core_Lib/HAL_UCS.c
--- /dev/null
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ *
+ * HAL_UCS.c
+ * Provides Functions to Initialize the UCS/FLL and clock sources
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Created: Version 1.0 11/24/2009
+ * Updated: Version 2.0 12/15/2010
+ * Added Functions: XT2_Stop() and XT1_Stop()
+ * Modified all functions to preserve drive settings
+ *
+ ******************************************************************************/
+
+#include "msp430.h"
+#include "HAL_UCS.h"
+
+/*******************************************************************************
+ * Check and define required Defines
+ ******************************************************************************/
+#ifndef XT1LFOFFG // Defines if not available in header file
+#define XT1LFOFFG 0
+#endif
+
+#ifndef XT1HFOFFG // Defines if not available in header file
+#define XT1HFOFFG 0
+#endif
+
+#ifndef XT2OFFG // Defines if not available in header file
+#define XT2OFFG 0
+#endif
+
+#ifndef XTS // Defines if not available in header file
+#define XTS 0
+#endif
+
+#ifndef XT2DRIVE_3 // Defines if not available in header file
+#define XT2DRIVE_3 0
+#endif
+
+void LFXT_Start(uint16_t xtdrive)
+{
+ // If the drive setting is not already set to maximum
+ // Set it to max for LFXT startup
+ if ((UCSCTL6 & XT1DRIVE_3)!= XT1DRIVE_3) {
+ UCSCTL6_L |= XT1DRIVE1_L + XT1DRIVE0_L; // Highest drive setting for XT1startup
+ }
+
+ while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag
+ UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags fault flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ }
+
+ UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)) | (xtdrive); // set requested Drive mode
+}
+
+uint16_t LFXT_Start_Timeout(uint16_t xtdrive, uint16_t timeout)
+{
+ // If the drive setting is not already set to maximum
+ // Set it to max for LFXT startup
+ if ((UCSCTL6 & XT1DRIVE_3)!= XT1DRIVE_3) {
+ UCSCTL6_L |= XT1DRIVE1_L+XT1DRIVE0_L; // Highest drive setting for XT1startup
+ }
+
+ while ((SFRIFG1 & OFIFG) && timeout--){ // Check OFIFG fault flag
+ UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags fault flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ }
+
+ UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)) |(xtdrive); // set Drive mode
+
+ if (timeout)
+ return (UCS_STATUS_OK);
+ else
+ return (UCS_STATUS_ERROR);
+}
+
+void XT1_Start(uint16_t xtdrive)
+{
+ // Check if drive value is the expected one
+ if ((UCSCTL6 & XT1DRIVE_3) != xtdrive) {
+ UCSCTL6 &= ~XT1DRIVE_3; // Clear XT1drive field
+ UCSCTL6 |= xtdrive; // Set requested value
+ }
+
+ UCSCTL6 &= ~XT1OFF; // Enable XT1
+ UCSCTL6 |= XTS; // Enable HF mode
+
+ while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag
+ UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ }
+}
+
+uint16_t XT1_Start_Timeout(uint16_t xtdrive, uint16_t timeout)
+{
+ // Check if drive value is the expected one
+ if ((UCSCTL6 & XT1DRIVE_3) != xtdrive) {
+ UCSCTL6 &= ~XT1DRIVE_3; // Clear XT1drive field
+ UCSCTL6 |= xtdrive; // Set requested value
+ }
+
+ UCSCTL6 &= ~XT1OFF; // Enable XT1
+ UCSCTL6 |= XTS; // Enable HF mode
+
+ while ((SFRIFG1 & OFIFG) && timeout--) { // Check OFIFG fault flag
+ UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ }
+
+ if (timeout) {
+ return UCS_STATUS_OK;
+ }
+ else {
+ return UCS_STATUS_ERROR;
+ }
+}
+
+void XT1_Bypass(void)
+{
+ UCSCTL6 |= XT1BYPASS;
+
+ while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag
+ UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ }
+}
+
+void XT1_Stop(void)
+{
+ UCSCTL6 |= XT1OFF; // Switch off XT1 oscillator
+}
+
+void XT2_Start(uint16_t xtdrive)
+{
+ // Check if drive value is the expected one
+ if ((UCSCTL6 & XT2DRIVE_3) != xtdrive) {
+ UCSCTL6 &= ~XT2DRIVE_3; // Clear XT2drive field
+ UCSCTL6 |= xtdrive; // Set requested value
+ }
+
+ UCSCTL6 &= ~XT2OFF;
+
+ while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag
+ UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ }
+}
+
+uint16_t XT2_Start_Timeout(uint16_t xtdrive, uint16_t timeout)
+{
+ // Check if drive value is the expected one
+ if ((UCSCTL6 & XT2DRIVE_3) != xtdrive) {
+ UCSCTL6 &= ~XT2DRIVE_3; // Clear XT2drive field
+ UCSCTL6 |= xtdrive; // Set requested value
+ }
+
+ UCSCTL6 &= ~XT2OFF;
+
+ while ((SFRIFG1 & OFIFG) && timeout--) { // Check OFIFG fault flag
+ UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ }
+
+ if (timeout) {
+ return UCS_STATUS_OK;
+ }
+ else {
+ return UCS_STATUS_ERROR;
+ }
+}
+
+void XT2_Bypass(void)
+{
+#ifdef XT2BYPASS // On devices without XT2 this function will be empty
+ UCSCTL6 |= XT2BYPASS;
+
+ while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag
+ UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ }
+#endif
+}
+
+void XT2_Stop(void)
+{
+ UCSCTL6 |= XT2OFF; // Switch off XT2 oscillator
+}
+
+void Init_FLL_Settle(uint16_t fsystem, uint16_t ratio)
+{
+ volatile uint16_t x = ratio * 32;
+
+ Init_FLL(fsystem, ratio);
+
+ while (x--) {
+ __delay_cycles(30);
+ }
+}
+
+void Init_FLL(uint16_t fsystem, uint16_t ratio)
+{
+ uint16_t d, dco_div_bits;
+ uint16_t mode = 0;
+
+ // Save actual state of FLL loop control, then disable it. This is needed to
+ // prevent the FLL from acting as we are making fundamental modifications to
+ // the clock setup.
+ uint16_t srRegisterState = __get_SR_register() & SCG0;
+ __bic_SR_register(SCG0);
+
+ d = ratio;
+ dco_div_bits = FLLD__2; // Have at least a divider of 2
+
+ if (fsystem > 16000) {
+ d >>= 1 ;
+ mode = 1;
+ }
+ else {
+ fsystem <<= 1; // fsystem = fsystem * 2
+ }
+
+ while (d > 512) {
+ dco_div_bits = dco_div_bits + FLLD0; // Set next higher div level
+ d >>= 1;
+ }
+
+ UCSCTL0 = 0x0000; // Set DCO to lowest Tap
+
+ UCSCTL2 &= ~(0x03FF); // Reset FN bits
+ UCSCTL2 = dco_div_bits | (d - 1);
+
+ if (fsystem <= 630) // fsystem < 0.63MHz
+ UCSCTL1 = DCORSEL_0;
+ else if (fsystem < 1250) // 0.63MHz < fsystem < 1.25MHz
+ UCSCTL1 = DCORSEL_1;
+ else if (fsystem < 2500) // 1.25MHz < fsystem < 2.5MHz
+ UCSCTL1 = DCORSEL_2;
+ else if (fsystem < 5000) // 2.5MHz < fsystem < 5MHz
+ UCSCTL1 = DCORSEL_3;
+ else if (fsystem < 10000) // 5MHz < fsystem < 10MHz
+ UCSCTL1 = DCORSEL_4;
+ else if (fsystem < 20000) // 10MHz < fsystem < 20MHz
+ UCSCTL1 = DCORSEL_5;
+ else if (fsystem < 40000) // 20MHz < fsystem < 40MHz
+ UCSCTL1 = DCORSEL_6;
+ else
+ UCSCTL1 = DCORSEL_7;
+
+ while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag
+ UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ }
+
+ if (mode == 1) { // fsystem > 16000
+ SELECT_MCLK_SMCLK(SELM__DCOCLK + SELS__DCOCLK); // Select DCOCLK
+ }
+ else {
+ SELECT_MCLK_SMCLK(SELM__DCOCLKDIV + SELS__DCOCLKDIV); // Select DCODIVCLK
+ }
+
+ __bis_SR_register(srRegisterState); // Restore previous SCG0
+}
diff --git a/F5xx_F6xx_Core_Lib/HAL_UCS.h b/F5xx_F6xx_Core_Lib/HAL_UCS.h
--- /dev/null
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ *
+ * HAL_UCS.h
+ * Provides Functions to Initialize the UCS/FLL and clock sources
+ *
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ * Created: Version 1.0 11/24/2009
+ * Updated: Version 2.0 12/15/2010
+ * Added Functions: XT2_Stop() and XT1_Stop()
+ *
+ ******************************************************************************/
+
+#ifndef HAL_UCS_H
+#define HAL_UCS_H
+
+#include <stdint.h>
+#include "hal_macros.h"
+
+/*******************************************************************************
+ * Macros
+ ******************************************************************************/
+
+/* Select source for FLLREF e.g. SELECT_FLLREF(SELREF__XT1CLK) */
+#define SELECT_FLLREF(source) st(UCSCTL3 = (UCSCTL3 & ~(SELREF_7)) | (source);)
+/* Select source for ACLK e.g. SELECT_ACLK(SELA__XT1CLK) */
+#define SELECT_ACLK(source) st(UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (source);)
+/* Select source for MCLK e.g. SELECT_MCLK(SELM__XT2CLK) */
+#define SELECT_MCLK(source) st(UCSCTL4 = (UCSCTL4 & ~(SELM_7)) | (source);)
+/* Select source for SMCLK e.g. SELECT_SMCLK(SELS__XT2CLK) */
+#define SELECT_SMCLK(source) st(UCSCTL4 = (UCSCTL4 & ~(SELS_7)) | (source);)
+/* Select source for MCLK and SMCLK e.g. SELECT_MCLK_SMCLK(SELM__DCOCLK + SELS__DCOCLK) */
+#define SELECT_MCLK_SMCLK(sources) st(UCSCTL4 = (UCSCTL4 & ~(SELM_7 + SELS_7)) | (sources);)
+
+/* set ACLK/x */
+#define ACLK_DIV(x) st(UCSCTL5 = (UCSCTL5 & ~(DIVA_7)) | (DIVA__##x);)
+/* set MCLK/x */
+#define MCLK_DIV(x) st(UCSCTL5 = (UCSCTL5 & ~(DIVM_7)) | (DIVM__##x);)
+/* set SMCLK/x */
+#define SMCLK_DIV(x) st(UCSCTL5 = (UCSCTL5 & ~(DIVS_7)) | (DIVS__##x);)
+/* Select divider for FLLREF e.g. SELECT_FLLREFDIV(2) */
+#define SELECT_FLLREFDIV(x) st(UCSCTL3 = (UCSCTL3 & ~(FLLREFDIV_7))|(FLLREFDIV__##x);)
+
+/*******************************************************************************
+ * Defines
+ ******************************************************************************/
+#define UCS_STATUS_OK 0
+#define UCS_STATUS_ERROR 1
+
+/*******************************************************************************
+ * \brief Startup routine for 32kHz Crystal on LFXT1
+ *
+ * \param xtdrive Bits defining the LFXT drive mode after startup
+ ******************************************************************************/
+extern void LFXT_Start(uint16_t xtdrive);
+
+/*******************************************************************************
+ * \brief Startup routine for 32kHz Crystal on LFXT1 with timeout counter
+ *
+ * \param xtdrive Bits defining the LFXT drive mode after startup
+ * \param timeout Value for the timeout counter
+ ******************************************************************************/
+extern uint16_t LFXT_Start_Timeout(uint16_t xtdrive, uint16_t timeout);
+
+/*******************************************************************************
+ * \brief Startup routine for XT1
+ *
+ * \param xtdrive Bits defining the XT drive mode
+ ******************************************************************************/
+extern void XT1_Start(uint16_t xtdrive);
+
+/*******************************************************************************
+ * \brief Startup routine for XT1 with timeout counter
+ *
+ * \param xtdrive Bits defining the XT drive mode
+ * \param timeout Value for the timeout counter
+ ******************************************************************************/
+extern uint16_t XT1_Start_Timeout(uint16_t xtdrive, uint16_t timeout);
+
+/*******************************************************************************
+ * \brief Use XT1 in Bypasss mode
+ ******************************************************************************/
+extern void XT1_Bypass(void);
+
+/*******************************************************************************
+ * \brief Stop XT1 oscillator
+ ******************************************************************************/
+extern void XT1_Stop(void);
+
+/*******************************************************************************
+ * \brief Startup routine for XT2
+ *
+ * \param xtdrive Bits defining the XT drive mode
+ ******************************************************************************/
+extern void XT2_Start(uint16_t xtdrive);
+
+/*******************************************************************************
+ * \brief Startup routine for XT2 with timeout counter
+ *
+ * \param xtdrive Bits defining the XT drive mode
+ * \param timeout Value for the timeout counter
+ ******************************************************************************/
+extern uint16_t XT2_Start_Timeout(uint16_t xtdrive, uint16_t timeout);
+
+/*******************************************************************************
+ * \brief Use XT2 in Bypasss mode for MCLK
+ ******************************************************************************/
+extern void XT2_Bypass(void);
+
+/*******************************************************************************
+ * \brief Stop XT2 oscillator
+ ******************************************************************************/
+extern void XT2_Stop(void);
+
+/*******************************************************************************
+ * \brief Initializes FLL of the UCS and wait till settled before allowing
+ * code execution to resume. The use of this function is preferred
+ * over the use of Init_FLL().
+ *
+ * \param fsystem Required system frequency (MCLK) in kHz
+ * \param ratio Ratio between fsystem and FLLREFCLK
+ ******************************************************************************/
+extern void Init_FLL_Settle(uint16_t fsystem, uint16_t ratio);
+
+/*******************************************************************************
+ * \brief Initializes FLL of the UCS
+ *
+ * \param fsystem Required system frequency (MCLK) in kHz
+ * \param ratio Ratio between fsystem and FLLREFCLK
+ ******************************************************************************/
+extern void Init_FLL(uint16_t fsystem, uint16_t ratio);
+
+#endif /* HAL_UCS_H */
diff --git a/I2C.c b/I2C.c
--- /dev/null
+++ b/I2C.c
@@ -0,0 +1,347 @@
+/*
+ * I2C.c
+ *
+ * The I2C communication functions and BSL invoke sequence.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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 <stdint.h>
+#include "I2C.h"
+#include "uart.h"
+#include "msp430.h"
+#include "main.h"
+
+unsigned char *PTxData; // Pointer to TX data
+int TXByteCtr;
+unsigned char *PRxData; // Pointer to RX data
+int RXByteCtr;
+unsigned char RxBuffer[256];
+
+unsigned char ACK = 0;
+unsigned int rxlength = 0;
+
+#define UART_HEADER 0x80
+#define UART_HEADER_LENGTH 1 // length in byte
+#define UART_LENGTH_LENGTH 2 // length in byte
+#define UART_CRC_LENGTH 2 // length in byte
+
+#define TIMEOUT_RECEPTION 1000000
+
+enum
+{
+ I2C_IDLE,
+ I2C_RECEIVING,
+ I2C_RECEIVE_COMPLETE,
+ I2C_TRANSMITTING,
+ I2C_TRANSMIT_COMPLETE,
+ I2C_ERROR
+} I2C_Status_e;
+
+void InvokeBSLSequence(void)
+{
+ PJDIR |= (RESET_PIN | TEST_PIN);
+ Delay(INVOKE_DELAY);
+ // invoke BSL, classic
+ //Start: all high
+ PJOUT = RESET_PIN+TEST_PIN+TCK_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ //Delay(INVOKE_DELAY);
+
+ //Step 1
+ //RESET LOW
+ //TEST LOW
+ //TCK HIGHT
+ //PJOUT = TCK_PIN;
+ //Delay(INVOKE_DELAY);
+
+ //Step 2
+ //RESET LOW
+ //TEST HIGH
+ //TCK LOW
+ PJOUT = TEST_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ //Step 3
+ //RESET LOW
+ //TEST LOW
+ //TCK HIGH
+ //PJOUT = 0;
+ //Delay(INVOKE_DELAY);
+ //Delay(20);
+
+ //Step 4
+ //RESET LOW
+ //TEST HIGH
+ //TCK LOW
+ //PJOUT = TEST_PIN;
+ //Delay(INVOKE_DELAY);
+
+ //Step 5
+ //RESET HIGH
+ //TEST HIGH
+ //TCK LOW
+ PJOUT = TEST_PIN + RESET_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ //Step 6
+ //RESET HIGH
+ //TEST LOW
+ //TCK HIGH
+ PJOUT = RESET_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+}
+
+
+//! Initialization of the USCI Module for I2C
+int8_t InitI2C(unsigned char eeprom_i2c_address, uint32_t bitrate)
+{
+ int8_t ret =1;
+
+ //Simple port mapping
+ __disable_interrupt(); // Disable Interrupts before altering Port Mapping registers
+ PMAPKEYID = PMAPKEY;
+ P4MAP4 = PM_UCB0SCL;
+ P4MAP5 = PM_UCB0SDA;
+ PMAPKEYID = 0;
+ __enable_interrupt();
+
+ UCB0CTL1 = UCSWRST; // Enable SW reset
+
+ UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
+ UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
+
+
+ switch(bitrate)
+ {
+ case 100001:
+ P1OUT ^= (BIT0|BIT1);
+ InvokeBSLSequence();
+ P1OUT |= (BIT0);
+ UCB0BR0 = SCL_CLOCK_DIV(100000); // set prescaler
+ break;
+ case 100000:
+ P1OUT |= (BIT0);
+ UCB0BR0 = SCL_CLOCK_DIV(100000); // set prescaler
+ break;
+ case 400001:
+ P1OUT ^= (BIT0|BIT1);
+ InvokeBSLSequence();
+ P1OUT |= (BIT1);
+ UCB0BR0 = SCL_CLOCK_DIV(400000); // set prescaler
+ break;
+ case 400000:
+ P1OUT |= (BIT1);
+ UCB0BR0 = SCL_CLOCK_DIV(400000); // set prescaler
+ break;
+ default:
+ ret = 1;
+ }
+
+ UCB0BR1 = 0;
+ UCB0I2CSA = eeprom_i2c_address; // Set slave address
+
+ I2C_PORT_SEL |= SDA_PIN + SCL_PIN; // select module function for the used I2C pins
+
+ UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
+
+ PRxData = RxBuffer; // Incase no receive buffer is assigned
+
+ if(UCB0STAT & UCBBUSY) // test if bus to be free
+ { // otherwise a manual Clock on is generated
+ I2C_PORT_SEL &= ~SCL_PIN; // Select Port function for SCL
+ I2C_PORT_OUT &= ~SCL_PIN; //
+ I2C_PORT_DIR |= SCL_PIN; // drive SCL low
+ I2C_PORT_SEL |= SDA_PIN + SCL_PIN; // select module function for the used I2C pins
+ };
+
+ I2C_Status_e = I2C_IDLE;
+
+ return ret;
+}
+
+int16_t i2cSendMessage(unsigned char* I2cMessage, int messageLength)
+{
+ UCB0IE &= ~UCRXIE; // disable RX ready interrupt
+ UCB0IFG &= ~(UCTXIFG + UCSTPIFG + UCNACKIFG); // clear TX ready and stop interrupt flag
+ UCB0IE |= UCTXIE | UCNACKIE; // enable TX ready interrupt
+
+ PTxData = (unsigned char *)I2cMessage; // TX array start address
+
+ TXByteCtr = messageLength ; // Load TX byte counter
+
+ I2C_Status_e = I2C_TRANSMITTING;
+ UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
+ // while (UCB0CTL1 & UCTXSTT); // Start condition sent?
+ // while (UCB0STAT & UCBBUSY); // wait for bus to be free !!!!!
+ // UCB0IE &= ~UCSTPIE; // disable STOP interrupt
+
+ while(I2C_Status_e == I2C_TRANSMITTING);
+
+ if(I2C_Status_e == I2C_TRANSMIT_COMPLETE)
+ {
+ // check for commands that doesn't require an ack
+ PTxData = (unsigned char *)I2cMessage; // TX array start address
+
+ if((*(PTxData + UART_HEADER_LENGTH + UART_LENGTH_LENGTH) == 0x1B))
+ return 0;
+ else
+ return 1;
+ }
+ else if(I2C_Status_e == I2C_ERROR)
+ {
+ return -1;
+ }
+
+ return -1;
+
+}
+
+// returns number of received bytes
+int16_t i2cReceiveMessage(unsigned char* I2cMessage)
+{
+ uint32_t timeout;
+
+ UCB0CTL1 &= ~UCTR;
+ UCB0IE |= UCRXIE; // Enable RX interrupt
+
+ PRxData = (unsigned char *)I2cMessage; // Start of RX buffer
+ RXByteCtr = 1; // Load RX byte counter
+
+ ACK = 0;
+ I2C_Status_e = I2C_RECEIVING;
+ UCB0CTL1 |= UCTXSTT;
+ //__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts
+ // Remain in LPM0 until all data
+ // is RX'd
+ timeout = TIMEOUT_RECEPTION;
+ while((I2C_Status_e == I2C_RECEIVING) && (timeout-- != 0x00));
+
+ if((timeout == 0) || (I2C_Status_e == I2C_ERROR))
+ {
+ i2cStopSending();
+ timeout = TIMEOUT_RECEPTION;
+ while((UCB0CTL1 & UCTXSTP) && (timeout-- != 0));
+ }
+
+ if(I2C_Status_e == I2C_RECEIVE_COMPLETE)
+ {
+ return (rxlength > 0) ? 1 + I2C_HEADER_LENGTH + I2C_LENGTH_LENGTH + rxlength + I2C_CRC_LENGTH : 1 + I2C_HEADER_LENGTH + I2C_LENGTH_LENGTH;
+ }
+ else
+ return -1;
+
+}
+
+void i2cStopSending(void)
+{
+ UCB0CTL1 |= UCTXSTP;
+}
+
+// ISR for I2C
+#pragma vector = USCI_B0_VECTOR
+__interrupt void USCI_B0_ISR(void)
+{
+ switch(__even_in_range(UCB0IV,USCI_I2C_UCTXIFG))
+ {
+ case USCI_NONE: break; // Vector 0: No interrupts
+ case USCI_I2C_UCALIFG: break; // Vector 2: UCALIFG
+ case USCI_I2C_UCNACKIFG:
+ I2C_Status_e = I2C_ERROR;
+ break; // Vector 4: NACKIFG
+ case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG
+ case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG
+ case USCI_I2C_UCRXIFG: // Vector 10: RXIFG
+
+ if (ACK == 0)
+ {
+ *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData
+ if(*(PRxData-1) != BSL_RESPONSE_ACK)
+ {
+ UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
+ }
+ else
+ {
+ ACK = 1;
+ RXByteCtr = I2C_HEADER_LENGTH + I2C_LENGTH_LENGTH; // receives the next three bytes
+ rxlength = 0;
+ }
+ }
+ else
+ {
+ RXByteCtr--; // Decrement RX byte counter
+ if(RXByteCtr)
+ {
+ *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData
+ if((RXByteCtr == 1) && (rxlength > 0)) // Only one byte left?
+ UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
+ }
+ else if(rxlength == 0)
+ {
+ *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData
+ rxlength = ((unsigned int) *(PRxData-1) << 8) | *(PRxData-2);
+ if(rxlength == 0) UCB0CTL1 |= UCTXSTP; // stop receiving if no bytes required
+ RXByteCtr = rxlength + I2C_CRC_LENGTH;
+ }
+ else
+ {
+ *PRxData = UCB0RXBUF; // Move final RX data to PRxData
+ I2C_Status_e = I2C_RECEIVE_COMPLETE;
+ //__bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
+ }
+ }
+ break;
+ case USCI_I2C_UCTXIFG: // Vector 12: TXIFG
+ if(TXByteCtr) // Check TX byte counter
+ {
+ UCB0TXBUF = *PTxData++; // Load TX buffer
+ TXByteCtr--; // Decrement TX byte counter
+ }
+ else
+ {
+ //UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
+ I2C_Status_e = I2C_TRANSMIT_COMPLETE;
+ //__bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
+ }
+ break;
+ default:
+ break;
+ }
+}
diff --git a/I2C.h b/I2C.h
--- /dev/null
+++ b/I2C.h
@@ -0,0 +1,94 @@
+/*
+ * I2C.h
+ *
+ * The I2C communication functions and BSL invoke sequence.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+#ifndef I2C_H_
+#define I2C_H_
+
+#include <stdint.h>
+
+#define BSL_SLAVE_ADDR 0x70
+
+#define I2C_PORT_SEL P4SEL
+#define I2C_PORT_OUT P4OUT
+#define I2C_PORT_REN P4REN
+#define I2C_PORT_DIR P4DIR
+
+#define SDA_PIN BIT5
+#define SCL_PIN BIT4
+#define SCL_CLOCK_DIV(X) (USB_MCLK_FREQ/X)
+
+#define RESET_HIGH {PJOUT |= BIT1;}
+#define RESET_LOW {PJOUT &= ~BIT1;}
+#define TEST_HIGH {PJOUT |= BIT2;}
+#define TEST_LOW {PJOUT &= ~BIT2;}
+#define RESET_PIN BIT1
+#define TEST_PIN BIT2
+#define TCK_PIN BIT3
+
+#define INVOKE_DELAY 1000
+
+// Timing for Pin Toggling during BSL Entry Sequence
+// TEST PIN reset time = 10us (must be less than 15us)
+#define BSL_ENTRY_SEQUENCE_TIME 50
+
+//#define BSL_PORT_DIR P6DIR
+//#define BSL_PORT_OUT P6OUT
+//#define BSL_RESET_PIN (BIT0 + BIT1)
+//#define BSL_TEST_PIN BIT2
+
+#define BSL_RESPONSE_ACK 0x00
+#define BSL_NO_RESPONSE_REQUIRED 0xAE
+
+#define BSL_ERROR_HEADER_INCORRECT 0x51
+#define BSL_ERROR_INCORRECT_RESPONSE_CRC 0xA0
+#define BSL_ERROR_OK 0x00
+
+#define I2C_HEADER 0x80
+#define I2C_HEADER_LENGTH 1 // length in byte
+#define I2C_LENGTH_LENGTH 2 // length in byte
+#define I2C_CRC_LENGTH 2 // length in byte
+
+
+// Init I2C module B0 and according port settings
+int8_t InitI2C(unsigned char eeprom_i2c_address, uint32_t bitrate);
+int16_t i2cSendMessage(unsigned char* I2cMessage, int messageLength);
+int16_t i2cReceiveMessage(unsigned char* I2cMessage);
+void i2cBslEntrySequence(void);
+void i2cStopSending(void);
+
+#endif /*I2C_H_*/
diff --git a/LICENSE.txt b/LICENSE.txt
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2012, Texas Instruments
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * 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.
+ * Neither the name of the Texas Instruments Incorporated 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 TEXAS INSTRUMENTS 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.
\ No newline at end of file
diff --git a/MSP430-BSL_2.1_Manifest.htm b/MSP430-BSL_2.1_Manifest.htm
--- /dev/null
@@ -0,0 +1,1447 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml"
+xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 14">
+<meta name=Originator content="Microsoft Word 14">
+<link rel=File-List href="MSP430-BSL_2.1_Manifest_files/filelist.xml">
+<link rel=Edit-Time-Data href="MSP430-BSL_2.1_Manifest_files/editdata.mso">
+<!--[if !mso]>
+<style>
+v\:* {behavior:url(#default#VML);}
+o\:* {behavior:url(#default#VML);}
+w\:* {behavior:url(#default#VML);}
+.shape {behavior:url(#default#VML);}
+</style>
+<![endif]-->
+<title>ASP Software Manifest</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Subject>Software Manifest</o:Subject>
+ <o:Author>Texas Instruments, Incorporated</o:Author>
+ <o:Keywords>Manifest Open Source License</o:Keywords>
+ <o:Description>This document lists the licensing for a specific software release.</o:Description>
+ <o:LastAuthor>Groening, Max</o:LastAuthor>
+ <o:Revision>2</o:Revision>
+ <o:TotalTime>57</o:TotalTime>
+ <o:LastPrinted>2011-06-27T13:49:00Z</o:LastPrinted>
+ <o:Created>2014-02-18T09:34:00Z</o:Created>
+ <o:LastSaved>2014-02-18T09:34:00Z</o:LastSaved>
+ <o:Pages>4</o:Pages>
+ <o:Words>747</o:Words>
+ <o:Characters>4258</o:Characters>
+ <o:Category>Manifest</o:Category>
+ <o:Company>Texas Instruments</o:Company>
+ <o:Lines>35</o:Lines>
+ <o:Paragraphs>9</o:Paragraphs>
+ <o:CharactersWithSpaces>4996</o:CharactersWithSpaces>
+ <o:Version>14.00</o:Version>
+ </o:DocumentProperties>
+ <o:OfficeDocumentSettings>
+ <o:RelyOnVML/>
+ <o:AllowPNG/>
+ <o:TargetScreenSize>800x600</o:TargetScreenSize>
+ </o:OfficeDocumentSettings>
+</xml><![endif]-->
+<link rel=dataStoreItem href="MSP430-BSL_2.1_Manifest_files/item0001.xml"
+target="MSP430-BSL_2.1_Manifest_files/props002.xml">
+<link rel=dataStoreItem href="MSP430-BSL_2.1_Manifest_files/item0003.xml"
+target="MSP430-BSL_2.1_Manifest_files/props004.xml">
+<link rel=dataStoreItem href="MSP430-BSL_2.1_Manifest_files/item0005.xml"
+target="MSP430-BSL_2.1_Manifest_files/props006.xml">
+<link rel=themeData href="MSP430-BSL_2.1_Manifest_files/themedata.thmx">
+<link rel=colorSchemeMapping
+href="MSP430-BSL_2.1_Manifest_files/colorschememapping.xml">
+<!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:TrackMoves>false</w:TrackMoves>
+ <w:TrackFormatting/>
+ <w:PunctuationKerning/>
+ <w:ValidateAgainstSchemas/>
+ <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
+ <w:IgnoreMixedContent>false</w:IgnoreMixedContent>
+ <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
+ <w:DoNotPromoteQF/>
+ <w:LidThemeOther>EN-US</w:LidThemeOther>
+ <w:LidThemeAsian>X-NONE</w:LidThemeAsian>
+ <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
+ <w:Compatibility>
+ <w:BreakWrappedTables/>
+ <w:SnapToGridInCell/>
+ <w:WrapTextWithPunct/>
+ <w:UseAsianBreakRules/>
+ <w:DontGrowAutofit/>
+ <w:DontUseIndentAsNumberingTabStop/>
+ <w:FELineBreak11/>
+ <w:WW11IndentRules/>
+ <w:DontAutofitConstrainedTables/>
+ <w:AutofitLikeWW11/>
+ <w:HangulWidthLikeWW11/>
+ <w:UseNormalStyleForList/>
+ <w:DontVertAlignCellWithSp/>
+ <w:DontBreakConstrainedForcedTables/>
+ <w:DontVertAlignInTxbx/>
+ <w:Word11KerningPairs/>
+ <w:CachedColBalance/>
+ </w:Compatibility>
+ <m:mathPr>
+ <m:mathFont m:val="Cambria Math"/>
+ <m:brkBin m:val="before"/>
+ <m:brkBinSub m:val="--"/>
+ <m:smallFrac m:val="off"/>
+ <m:dispDef/>
+ <m:lMargin m:val="0"/>
+ <m:rMargin m:val="0"/>
+ <m:defJc m:val="centerGroup"/>
+ <m:wrapIndent m:val="1440"/>
+ <m:intLim m:val="subSup"/>
+ <m:naryLim m:val="undOvr"/>
+ </m:mathPr></w:WordDocument>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false"
+ DefSemiHidden="false" DefQFormat="false" LatentStyleCount="267">
+ <w:LsdException Locked="true" QFormat="true" Name="Normal"/>
+ <w:LsdException Locked="true" QFormat="true" Name="heading 1"/>
+ <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true"
+ QFormat="true" Name="heading 2"/>
+ <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true"
+ QFormat="true" Name="heading 3"/>
+ <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true"
+ QFormat="true" Name="heading 4"/>
+ <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true"
+ QFormat="true" Name="heading 5"/>
+ <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true"
+ QFormat="true" Name="heading 6"/>
+ <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true"
+ QFormat="true" Name="heading 7"/>
+ <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true"
+ QFormat="true" Name="heading 8"/>
+ <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true"
+ QFormat="true" Name="heading 9"/>
+ <w:LsdException Locked="true" Name="toc 1"/>
+ <w:LsdException Locked="true" Name="toc 2"/>
+ <w:LsdException Locked="true" Name="toc 3"/>
+ <w:LsdException Locked="true" Name="toc 4"/>
+ <w:LsdException Locked="true" Name="toc 5"/>
+ <w:LsdException Locked="true" Name="toc 6"/>
+ <w:LsdException Locked="true" Name="toc 7"/>
+ <w:LsdException Locked="true" Name="toc 8"/>
+ <w:LsdException Locked="true" Name="toc 9"/>
+ <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true"
+ QFormat="true" Name="caption"/>
+ <w:LsdException Locked="true" QFormat="true" Name="Title"/>
+ <w:LsdException Locked="true" QFormat="true" Name="Subtitle"/>
+ <w:LsdException Locked="true" QFormat="true" Name="Strong"/>
+ <w:LsdException Locked="true" QFormat="true" Name="Emphasis"/>
+ <w:LsdException Locked="false" Priority="99" Name="HTML Preformatted"/>
+ <w:LsdException Locked="true" Name="Table Grid"/>
+ <w:LsdException Locked="false" Priority="99" SemiHidden="true"
+ Name="Placeholder Text"/>
+ <w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/>
+ <w:LsdException Locked="false" Priority="60" Name="Light Shading"/>
+ <w:LsdException Locked="false" Priority="61" Name="Light List"/>
+ <w:LsdException Locked="false" Priority="62" Name="Light Grid"/>
+ <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/>
+ <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/>
+ <w:LsdException Locked="false" Priority="65" Name="Medium List 1"/>
+ <w:LsdException Locked="false" Priority="66" Name="Medium List 2"/>
+ <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/>
+ <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/>
+ <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/>
+ <w:LsdException Locked="false" Priority="70" Name="Dark List"/>
+ <w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/>
+ <w:LsdException Locked="false" Priority="72" Name="Colorful List"/>
+ <w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/>
+ <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/>
+ <w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/>
+ <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/>
+ <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/>
+ <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/>
+ <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/>
+ <w:LsdException Locked="false" Priority="99" SemiHidden="true" Name="Revision"/>
+ <w:LsdException Locked="false" Priority="34" QFormat="true"
+ Name="List Paragraph"/>
+ <w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/>
+ <w:LsdException Locked="false" Priority="30" QFormat="true"
+ Name="Intense Quote"/>
+ <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/>
+ <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/>
+ <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/>
+ <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/>
+ <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/>
+ <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/>
+ <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/>
+ <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/>
+ <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/>
+ <w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/>
+ <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/>
+ <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/>
+ <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/>
+ <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/>
+ <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/>
+ <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/>
+ <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/>
+ <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/>
+ <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/>
+ <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/>
+ <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/>
+ <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/>
+ <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/>
+ <w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/>
+ <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/>
+ <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/>
+ <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/>
+ <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/>
+ <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/>
+ <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/>
+ <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/>
+ <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/>
+ <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/>
+ <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/>
+ <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/>
+ <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/>
+ <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/>
+ <w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/>
+ <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/>
+ <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/>
+ <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/>
+ <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/>
+ <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/>
+ <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/>
+ <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/>
+ <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/>
+ <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/>
+ <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/>
+ <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/>
+ <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/>
+ <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/>
+ <w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/>
+ <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/>
+ <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/>
+ <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/>
+ <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/>
+ <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/>
+ <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/>
+ <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/>
+ <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/>
+ <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/>
+ <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/>
+ <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/>
+ <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/>
+ <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/>
+ <w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/>
+ <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/>
+ <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/>
+ <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/>
+ <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/>
+ <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/>
+ <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/>
+ <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/>
+ <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/>
+ <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/>
+ <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/>
+ <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/>
+ <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/>
+ <w:LsdException Locked="false" Priority="19" QFormat="true"
+ Name="Subtle Emphasis"/>
+ <w:LsdException Locked="false" Priority="21" QFormat="true"
+ Name="Intense Emphasis"/>
+ <w:LsdException Locked="false" Priority="31" QFormat="true"
+ Name="Subtle Reference"/>
+ <w:LsdException Locked="false" Priority="32" QFormat="true"
+ Name="Intense Reference"/>
+ <w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/>
+ <w:LsdException Locked="false" Priority="37" SemiHidden="true"
+ UnhideWhenUsed="true" Name="Bibliography"/>
+ <w:LsdException Locked="false" Priority="39" SemiHidden="true"
+ UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/>
+ </w:LatentStyles>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+ @font-face
+ {font-family:Wingdings;
+ panose-1:5 0 0 0 0 0 0 0 0 0;
+ mso-font-charset:2;
+ mso-generic-font-family:auto;
+ mso-font-pitch:variable;
+ mso-font-signature:0 268435456 0 0 -2147483648 0;}
+@font-face
+ {font-family:"MS Mincho";
+ panose-1:2 2 6 9 4 2 5 8 3 4;
+ mso-font-alt:"\FF2D\FF33 \660E\671D";
+ mso-font-charset:128;
+ mso-generic-font-family:modern;
+ mso-font-pitch:fixed;
+ mso-font-signature:-536870145 1791491579 18 0 131231 0;}
+@font-face
+ {font-family:"MS Mincho";
+ panose-1:2 2 6 9 4 2 5 8 3 4;
+ mso-font-alt:"\FF2D\FF33 \660E\671D";
+ mso-font-charset:128;
+ mso-generic-font-family:modern;
+ mso-font-pitch:fixed;
+ mso-font-signature:-536870145 1791491579 18 0 131231 0;}
+@font-face
+ {font-family:Cambria;
+ panose-1:2 4 5 3 5 4 6 3 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:roman;
+ mso-font-pitch:variable;
+ mso-font-signature:-536870145 1073743103 0 0 415 0;}
+@font-face
+ {font-family:Tahoma;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-520081665 -1073717157 41 0 66047 0;}
+@font-face
+ {font-family:"\@MS Mincho";
+ panose-1:2 2 6 9 4 2 5 8 3 4;
+ mso-font-charset:128;
+ mso-generic-font-family:modern;
+ mso-font-pitch:fixed;
+ mso-font-signature:-536870145 1791491579 18 0 131231 0;}
+ /* Style Definitions */
+ p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;}
+h1
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 1 Char";
+ mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:16.0pt;
+ font-family:"Cambria","serif";
+ mso-font-kerning:16.0pt;}
+p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-link:"Footnote Text Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;}
+p.MsoHeader, li.MsoHeader, div.MsoHeader
+ {mso-style-unhide:no;
+ mso-style-link:"Header Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;}
+p.MsoFooter, li.MsoFooter, div.MsoFooter
+ {mso-style-unhide:no;
+ mso-style-link:"Footer Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.0in right 6.0in;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;}
+span.MsoFootnoteReference
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-parent:"";
+ font-family:"Times New Roman","serif";
+ mso-bidi-font-family:"Times New Roman";
+ vertical-align:super;}
+p.MsoBodyText, li.MsoBodyText, div.MsoBodyText
+ {mso-style-unhide:no;
+ mso-style-link:"Body Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;}
+p.MsoBlockText, li.MsoBlockText, div.MsoBlockText
+ {mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:1.0in;
+ margin-bottom:6.0pt;
+ margin-left:1.0in;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;}
+p.MsoDocumentMap, li.MsoDocumentMap, div.MsoDocumentMap
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-link:"Document Map Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ background:navy;
+ font-size:10.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;}
+pre
+ {mso-style-priority:99;
+ mso-style-link:"HTML Preformatted Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Courier New";
+ mso-fareast-font-family:"Times New Roman";}
+p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-link:"Balloon Text Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:8.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;}
+p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;}
+p.EditorsComment, li.EditorsComment, div.EditorsComment
+ {mso-style-name:"Editors Comment";
+ mso-style-unhide:no;
+ mso-style-parent:"Block Text";
+ mso-style-next:"Body Text";
+ margin-top:0in;
+ margin-right:1.0in;
+ margin-bottom:6.0pt;
+ margin-left:1.0in;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:11.0pt;
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+span.BodyTextChar
+ {mso-style-name:"Body Text Char";
+ mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"";
+ mso-style-link:"Body Text";
+ font-family:"Arial","sans-serif";
+ mso-ascii-font-family:Arial;
+ mso-hansi-font-family:Arial;
+ mso-bidi-font-family:Arial;
+ mso-font-kerning:11.0pt;}
+p.StyleEditorsCommentCustomColorRGB51153255, li.StyleEditorsCommentCustomColorRGB51153255, div.StyleEditorsCommentCustomColorRGB51153255
+ {mso-style-name:"Style Editors Comment + Custom Color\(RGB\(51153255\)\)";
+ mso-style-update:auto;
+ mso-style-unhide:no;
+ mso-style-parent:"Editors Comment";
+ margin-top:0in;
+ margin-right:1.0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ color:#3399FF;
+ mso-font-kerning:11.0pt;
+ font-style:italic;}
+p.1Para, li.1Para, div.1Para
+ {mso-style-name:1_Para;
+ mso-style-unhide:no;
+ mso-style-parent:"";
+ mso-style-link:"1_Para Char";
+ margin-top:10.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ text-align:justify;
+ line-height:11.0pt;
+ mso-line-height-rule:exactly;
+ mso-pagination:widow-orphan lines-together;
+ font-size:10.0pt;
+ font-family:"Arial","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-font-kerning:10.0pt;}
+span.1ParaChar
+ {mso-style-name:"1_Para Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"";
+ mso-style-link:1_Para;
+ font-family:"Arial","sans-serif";
+ mso-ascii-font-family:Arial;
+ mso-hansi-font-family:Arial;
+ mso-bidi-font-family:Arial;
+ mso-font-kerning:10.0pt;
+ mso-ansi-language:EN-US;
+ mso-fareast-language:EN-US;
+ mso-bidi-language:AR-SA;}
+span.HeaderChar
+ {mso-style-name:"Header Char";
+ mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"";
+ mso-style-link:Header;
+ font-family:"Arial","sans-serif";
+ mso-ascii-font-family:Arial;
+ mso-hansi-font-family:Arial;
+ mso-bidi-font-family:Arial;
+ mso-font-kerning:11.0pt;}
+span.FooterChar
+ {mso-style-name:"Footer Char";
+ mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"";
+ mso-style-link:Footer;
+ font-family:"Arial","sans-serif";
+ mso-ascii-font-family:Arial;
+ mso-hansi-font-family:Arial;
+ mso-bidi-font-family:Arial;
+ mso-font-kerning:11.0pt;}
+span.FootnoteTextChar
+ {mso-style-name:"Footnote Text Char";
+ mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"";
+ mso-style-link:"Footnote Text";
+ font-family:"Arial","sans-serif";
+ mso-ascii-font-family:Arial;
+ mso-hansi-font-family:Arial;
+ mso-bidi-font-family:Arial;
+ mso-font-kerning:11.0pt;}
+span.DocumentMapChar
+ {mso-style-name:"Document Map Char";
+ mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"";
+ mso-style-link:"Document Map";
+ mso-ansi-font-size:1.0pt;
+ font-family:"Arial","sans-serif";
+ mso-bidi-font-family:Arial;
+ mso-font-kerning:11.0pt;}
+span.BalloonTextChar
+ {mso-style-name:"Balloon Text Char";
+ mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"";
+ mso-style-link:"Balloon Text";
+ mso-ansi-font-size:1.0pt;
+ font-family:"Arial","sans-serif";
+ mso-bidi-font-family:Arial;
+ mso-font-kerning:11.0pt;}
+span.HTMLPreformattedChar
+ {mso-style-name:"HTML Preformatted Char";
+ mso-style-priority:99;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"";
+ mso-style-link:"HTML Preformatted";
+ font-family:"Courier New";
+ mso-ascii-font-family:"Courier New";
+ mso-hansi-font-family:"Courier New";
+ mso-bidi-font-family:"Courier New";}
+span.Heading1Char
+ {mso-style-name:"Heading 1 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"";
+ mso-style-link:"Heading 1";
+ mso-ansi-font-size:16.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Cambria","serif";
+ mso-ascii-font-family:Cambria;
+ mso-fareast-font-family:"Times New Roman";
+ mso-hansi-font-family:Cambria;
+ mso-bidi-font-family:"Times New Roman";
+ mso-font-kerning:16.0pt;
+ font-weight:bold;}
+ /* Page Definitions */
+ @page
+ {mso-footnote-separator:url("MSP430-BSL_2.1_Manifest_files/header.htm") fs;
+ mso-footnote-continuation-separator:url("MSP430-BSL_2.1_Manifest_files/header.htm") fcs;
+ mso-endnote-separator:url("MSP430-BSL_2.1_Manifest_files/header.htm") es;
+ mso-endnote-continuation-separator:url("MSP430-BSL_2.1_Manifest_files/header.htm") ecs;}
+@page WordSection1
+ {size:11.0in 8.5in;
+ mso-page-orientation:landscape;
+ margin:1.25in 1.0in 1.25in 1.0in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-header:url("MSP430-BSL_2.1_Manifest_files/header.htm") h1;
+ mso-footer:url("MSP430-BSL_2.1_Manifest_files/header.htm") f1;
+ mso-paper-source:0;}
+div.WordSection1
+ {page:WordSection1;}
+ /* List Definitions */
+ @list l0
+ {mso-list-id:38015523;
+ mso-list-type:hybrid;
+ mso-list-template-ids:-214113684 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
+@list l0:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:39.0pt;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l0:level2
+ {mso-level-number-format:bullet;
+ mso-level-text:o;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:75.0pt;
+ text-indent:-.25in;
+ font-family:"Courier New";}
+@list l0:level3
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0A7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:111.0pt;
+ text-indent:-.25in;
+ font-family:Wingdings;}
+@list l0:level4
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:147.0pt;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l0:level5
+ {mso-level-number-format:bullet;
+ mso-level-text:o;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:183.0pt;
+ text-indent:-.25in;
+ font-family:"Courier New";}
+@list l0:level6
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0A7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:219.0pt;
+ text-indent:-.25in;
+ font-family:Wingdings;}
+@list l0:level7
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:255.0pt;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l0:level8
+ {mso-level-number-format:bullet;
+ mso-level-text:o;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:291.0pt;
+ text-indent:-.25in;
+ font-family:"Courier New";}
+@list l0:level9
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0A7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:327.0pt;
+ text-indent:-.25in;
+ font-family:Wingdings;}
+@list l1
+ {mso-list-id:391467054;
+ mso-list-type:hybrid;
+ mso-list-template-ids:-595312894 747925636 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
+@list l1:level1
+ {mso-level-start-at:0;
+ mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:21.0pt;
+ text-indent:-.25in;
+ font-family:Symbol;
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:Arial;}
+@list l1:level2
+ {mso-level-number-format:bullet;
+ mso-level-text:o;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:57.0pt;
+ text-indent:-.25in;
+ font-family:"Courier New";}
+@list l1:level3
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0A7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:93.0pt;
+ text-indent:-.25in;
+ font-family:Wingdings;}
+@list l1:level4
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:129.0pt;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l1:level5
+ {mso-level-number-format:bullet;
+ mso-level-text:o;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:165.0pt;
+ text-indent:-.25in;
+ font-family:"Courier New";}
+@list l1:level6
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0A7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:201.0pt;
+ text-indent:-.25in;
+ font-family:Wingdings;}
+@list l1:level7
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:237.0pt;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l1:level8
+ {mso-level-number-format:bullet;
+ mso-level-text:o;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:273.0pt;
+ text-indent:-.25in;
+ font-family:"Courier New";}
+@list l1:level9
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0A7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:309.0pt;
+ text-indent:-.25in;
+ font-family:Wingdings;}
+@list l2
+ {mso-list-id:1123617149;
+ mso-list-type:hybrid;
+ mso-list-template-ids:1975024626 747925636 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
+@list l2:level1
+ {mso-level-start-at:0;
+ mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ margin-left:21.0pt;
+ text-indent:-.25in;
+ font-family:Symbol;
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:Arial;}
+@list l2:level2
+ {mso-level-number-format:bullet;
+ mso-level-text:o;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:"Courier New";}
+@list l2:level3
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0A7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Wingdings;}
+@list l2:level4
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l2:level5
+ {mso-level-number-format:bullet;
+ mso-level-text:o;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:"Courier New";}
+@list l2:level6
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0A7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Wingdings;}
+@list l2:level7
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l2:level8
+ {mso-level-number-format:bullet;
+ mso-level-text:o;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:"Courier New";}
+@list l2:level9
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0A7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Wingdings;}
+ol
+ {margin-bottom:0in;}
+ul
+ {margin-bottom:0in;}
+-->
+</style>
+<!--[if gte mso 10]>
+<style>
+ /* Style Definitions */
+ table.MsoNormalTable
+ {mso-style-name:"Table Normal";
+ mso-tstyle-rowband-size:0;
+ mso-tstyle-colband-size:0;
+ mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-parent:"";
+ mso-padding-alt:0in 5.4pt 0in 5.4pt;
+ mso-para-margin:0in;
+ mso-para-margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Times New Roman","serif";}
+table.MsoTableGrid
+ {mso-style-name:"Table Grid";
+ mso-tstyle-rowband-size:0;
+ mso-tstyle-colband-size:0;
+ mso-style-unhide:no;
+ border:solid windowtext 1.0pt;
+ mso-border-alt:solid windowtext .5pt;
+ mso-padding-alt:0in 5.4pt 0in 5.4pt;
+ mso-border-insideh:.5pt solid windowtext;
+ mso-border-insidev:.5pt solid windowtext;
+ mso-para-margin:0in;
+ mso-para-margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Times New Roman","serif";}
+</style>
+<![endif]--><!--[if gte mso 9]><xml>
+ <o:shapedefaults v:ext="edit" spidmax="3074"/>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <o:shapelayout v:ext="edit">
+ <o:idmap v:ext="edit" data="1"/>
+ </o:shapelayout></xml><![endif]-->
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=WordSection1>
+
+<p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='font-size:12.0pt'><v:shapetype id="_x0000_t75"
+ coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe"
+ filled="f" stroked="f">
+ <v:stroke joinstyle="miter"/>
+ <v:formulas>
+ <v:f eqn="if lineDrawn pixelLineWidth 0"/>
+ <v:f eqn="sum @0 1 0"/>
+ <v:f eqn="sum 0 0 @1"/>
+ <v:f eqn="prod @2 1 2"/>
+ <v:f eqn="prod @3 21600 pixelWidth"/>
+ <v:f eqn="prod @3 21600 pixelHeight"/>
+ <v:f eqn="sum @0 0 1"/>
+ <v:f eqn="prod @6 1 2"/>
+ <v:f eqn="prod @7 21600 pixelWidth"/>
+ <v:f eqn="sum @8 21600 0"/>
+ <v:f eqn="prod @7 21600 pixelHeight"/>
+ <v:f eqn="sum @10 21600 0"/>
+ </v:formulas>
+ <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
+ <o:lock v:ext="edit" aspectratio="t"/>
+</v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:180pt;
+ height:24.75pt'>
+ <v:imagedata src="MSP430-BSL_2.1_Manifest_files/image001.png" o:title="hdr_ti_logo"/>
+</v:shape><span
+style='mso-spacerun:yes'>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
+</span>February 13, 2014<o:p></o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></b></p>
+
+<p class=MsoNormal><v:line id="_x0000_s1028" style='position:absolute;flip:y;
+ z-index:251657728;mso-position-horizontal-relative:page;
+ mso-position-vertical-relative:page' from="396pt,-17.65pt" to="396pt,342.9pt"
+ strokecolor="white">
+ <w:wrap anchorx="page" anchory="page"/>
+ <w:anchorlock/>
+</v:line><b style='mso-bidi-font-weight:normal'><span style='font-size:12.0pt'>MSP430-BSL
+Manifest<o:p></o:p></span></b></p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='font-size:12.0pt'>Legend (explanation of the fields in the
+Manifest Table below)<o:p></o:p></span></b></p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<table class=MsoNormalTable border=1 cellspacing=0 cellpadding=0
+ style='border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;
+ mso-yfti-tbllook:480;mso-padding-alt:0in 5.4pt 0in 5.4pt;mso-border-insideh:
+ .5pt solid windowtext;mso-border-insidev:.5pt solid windowtext'>
+ <tr style='mso-yfti-irow:0;mso-yfti-firstrow:yes'>
+ <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt;
+ mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Software Name <o:p></o:p></b></p>
+ </td>
+ <td width=748 valign=top style='width:560.7pt;border:solid windowtext 1.0pt;
+ border-left:none;mso-border-left-alt:solid windowtext .5pt;mso-border-alt:
+ solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'>The name of the application or file</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:1'>
+ <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt;
+ border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Version <o:p></o:p></b></p>
+ </td>
+ <td width=748 valign=top style='width:560.7pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt;
+ mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'>Version of the application or file</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:2'>
+ <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt;
+ border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>License Type<o:p></o:p></b></p>
+ </td>
+ <td width=748 valign=top style='width:560.7pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt;
+ mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'>Type of license(s) under which TI will be providing software
+ to the licensee (e.g. BSD, GPLv2, TI TSPA License, TI Commercial License).
+ See Open Source Reference License Disclaimer in the Disclaimers Section.</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:3'>
+ <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt;
+ border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location <o:p></o:p></b></p>
+ </td>
+ <td width=748 valign=top style='width:560.7pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt;
+ mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'>The directory name and path on the media (or in an
+ archive) where the Software is located.</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:4'>
+ <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt;
+ border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Delivered As<o:p></o:p></b></p>
+ </td>
+ <td width=748 valign=top style='width:560.7pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt;
+ mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'>This field will either be \93Source\94, \93Binary\94 or
+ \93Source and Binary\94 and is the form the content of the Software is delivered
+ in.<span style='mso-spacerun:yes'>Â </span>If the Software is delivered in an
+ archive format, this field applies to the contents of the archive. If the
+ word Limited is used with Source, as in \93Limited Source\94 or \93Limited Source
+ and Binary\94 then only portions of the Source for the application are
+ provided.</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:5'>
+ <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt;
+ border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Modified by TI<o:p></o:p></b></p>
+ </td>
+ <td width=748 valign=top style='width:560.7pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt;
+ mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'>This field will either be \93Yes\94 or \93No\94. A \93Yes\94 means
+ TI has made changes to the Software. A \93No\94 means TI has not made any
+ changes. Note: This field is not applicable for Software \93Obtained from\94 TI.</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:6;mso-yfti-lastrow:yes'>
+ <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt;
+ border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Obtained from<o:p></o:p></b></p>
+ </td>
+ <td width=748 valign=top style='width:560.7pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt;
+ mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'>This field specifies from where or from whom TI
+ obtained the Software. It may be a URL to an Open Source site, a 3<sup>rd</sup>
+ party licensor, or TI (if TI developed the software). If this field contains
+ a link to Open Source software, the date TI downloaded the Software is also
+ recorded. See Links Disclaimer in the Disclaimers Section.</p>
+ </td>
+ </tr>
+</table>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='font-size:12.0pt'>DISCLAIMERS<o:p></o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><u>Export Control Classification Number (ECCN)<o:p></o:p></u></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p>
+
+<p class=MsoNormal style='margin-left:.5in;mso-outline-level:1'>Any use of ECCNs
+listed in the Manifest is at the user\92s risk and without recourse to TI. <span
+style='mso-spacerun:yes'>Â Â </span>Your company, as the exporter of record, is
+responsible for determining the correct classification of any item at the time
+of export. Any export classification by TI of Software is for TI\92s internal use
+only and shall not be construed as a representation or warranty regarding the
+proper export classification for such Software or whether an export license or
+other documentation is required for exporting such Software<b style='mso-bidi-font-weight:
+normal'><span style='font-size:12.0pt'>.<span style='mso-spacerun:yes'>Â
+</span><o:p></o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><u>Links in the Manifest<o:p></o:p></u></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p>
+
+<p class=1Para style='margin-left:.5in'>Any links appearing on this Manifest
+(for example in the \93Obtained from\94 field) were verified at the time the
+Manifest was created. TI makes no guarantee that any listed links will remain
+active in the future.</p>
+
+<p class=1Para><b style='mso-bidi-font-weight:normal'><u>Open Source License
+References<o:p></o:p></u></b></p>
+
+<p class=1Para style='margin-left:.5in'>Your company is responsible for
+confirming the applicable license terms for any open source Software listed in
+this Manifest that was not \93Obtained from\94 TI.<span style='mso-spacerun:yes'>Â
+</span>Any open source license specified in this Manifest for Software that was
+not \93Obtained from\94 TI is for TI\92s internal use only and shall not be construed
+as a representation or warranty regarding the proper open source license terms
+for such Software.</p>
+
+<b style='mso-bidi-font-weight:normal'><span style='font-size:12.0pt;
+font-family:"Arial","sans-serif";mso-fareast-font-family:"Times New Roman";
+mso-font-kerning:11.0pt;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
+mso-bidi-language:AR-SA'><br clear=all style='mso-special-character:line-break;
+page-break-before:always'>
+</span></b>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='font-size:12.0pt'>Export Information<o:p></o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></b></p>
+
+<p class=MsoNormal><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning:
+0pt;mso-fareast-language:JA'>ECCN for Software included in this release: EAR99<o:p></o:p></span></p>
+
+<p class=MsoNormal><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning:
+0pt;mso-fareast-language:JA'><o:p> </o:p></span></p>
+
+<p class=MsoNormal><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning:
+0pt;mso-fareast-language:JA'>ECCN for Technology (e.g., user documentation,
+specifications) included in this release: EAR99<o:p></o:p></span></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='font-size:12.0pt'>Manifest<o:p></o:p></span></b></p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal>See Legend above for a description of the columns and
+possible values.</p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<table class=MsoNormalTable border=1 cellspacing=0 cellpadding=0 width=865
+ style='width:648.85pt;border-collapse:collapse;border:none;mso-border-alt:
+ solid windowtext .5pt;mso-yfti-tbllook:480;mso-padding-alt:0in 5.4pt 0in 5.4pt;
+ mso-border-insideh:.75pt solid windowtext;mso-border-insidev:.75pt solid windowtext'>
+ <thead>
+ <tr style='mso-yfti-irow:0;mso-yfti-firstrow:yes;page-break-inside:avoid'>
+ <td width=115 valign=top style='width:1.2in;border:solid windowtext 1.0pt;
+ mso-border-top-alt:.5pt;mso-border-left-alt:.5pt;mso-border-bottom-alt:.75pt;
+ mso-border-right-alt:.75pt;mso-border-color-alt:windowtext;mso-border-style-alt:
+ solid;background:#E6E6E6;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight:
+ normal'>Software Name<o:p></o:p></b></p>
+ </td>
+ <td width=76 valign=top style='width:56.9pt;border:solid windowtext 1.0pt;
+ border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-alt:
+ solid windowtext .75pt;mso-border-top-alt:solid windowtext .5pt;background:
+ #E6E6E6;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight:
+ normal'>Version<o:p></o:p></b></p>
+ </td>
+ <td width=89 valign=top style='width:66.4pt;border:solid windowtext 1.0pt;
+ border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-alt:
+ solid windowtext .75pt;mso-border-top-alt:solid windowtext .5pt;background:
+ #E6E6E6;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight:
+ normal'>License Type<o:p></o:p></b></p>
+ </td>
+ <td width=84 valign=top style='width:63.0pt;border:solid windowtext 1.0pt;
+ border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-alt:
+ solid windowtext .75pt;mso-border-top-alt:solid windowtext .5pt;background:
+ #E6E6E6;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight:
+ normal'>Delivered <o:p></o:p></b></p>
+ <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight:
+ normal'>As <o:p></o:p></b></p>
+ </td>
+ <td width=108 valign=top style='width:81.0pt;border:solid windowtext 1.0pt;
+ border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-alt:
+ solid windowtext .75pt;mso-border-top-alt:solid windowtext .5pt;background:
+ #E6E6E6;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight:
+ normal'>Modified by <o:p></o:p></b></p>
+ <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight:
+ normal'>TI <o:p></o:p></b></p>
+ </td>
+ <td width=394 colspan=2 valign=top style='width:295.15pt;border:solid windowtext 1.0pt;
+ border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-top-alt:
+ .5pt;mso-border-left-alt:.75pt;mso-border-bottom-alt:.75pt;mso-border-right-alt:
+ .5pt;mso-border-color-alt:windowtext;mso-border-style-alt:solid;background:
+ #E6E6E6;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:3.0pt;mso-outline-level:1'><b
+ style='mso-bidi-font-weight:normal'><span style='font-size:9.0pt'><o:p> </o:p></span></b></p>
+ </td>
+ </tr>
+ </thead>
+ <tr style='mso-yfti-irow:1;page-break-inside:avoid'>
+ <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt;
+ border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt:
+ solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding:
+ 0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>MSP430-BSL</p>
+ </td>
+ <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none;
+ border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>2.1</p>
+ </td>
+ <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none;
+ border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>BSD 3-Clause</p>
+ </td>
+ <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none;
+ border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>Source</p>
+ </td>
+ <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none;
+ border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>yes</p>
+ </td>
+ <td width=104 valign=top style='width:77.9pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p>
+ </td>
+ <td width=290 valign=top style='width:217.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal><installed path>/*</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:2;page-break-inside:avoid'>
+ <td width=104 valign=top style='width:77.9pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span
+ style='font-size:9.0pt'>Obtained from</span></b></p>
+ </td>
+ <td width=290 valign=top style='width:217.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>TI</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:3;page-break-inside:avoid'>
+ <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt;
+ border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-top-alt:
+ .75pt;mso-border-left-alt:.5pt;mso-border-bottom-alt:.5pt;mso-border-right-alt:
+ .75pt;mso-border-color-alt:windowtext;mso-border-style-alt:solid;padding:
+ 0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>MSP430 USB Stack and Examples</p>
+ </td>
+ <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none;
+ border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal><o:p> </o:p></p>
+ </td>
+ <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none;
+ border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>BSD 3-Clause</p>
+ </td>
+ <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none;
+ border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>Source</p>
+ </td>
+ <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none;
+ border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>yes</p>
+ </td>
+ <td width=104 valign=top style='width:77.9pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p>
+ </td>
+ <td width=290 valign=top style='width:217.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal><installed path>/F5xx_F6xx_Core_Lib/*</p>
+ <p class=MsoNormal><installed path>/usb/*</p>
+ <p class=MsoNormal><installed path>/USB_API/*</p>
+ <p class=MsoNormal><installed path>/USB_config/*</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:4;mso-yfti-lastrow:yes;page-break-inside:avoid'>
+ <td width=104 valign=top style='width:77.9pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt;
+ padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom:
+ 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span
+ style='font-size:9.0pt'>Obtained from</span></b></p>
+ </td>
+ <td width=290 valign=top style='width:217.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt;
+ mso-border-top-alt:.75pt;mso-border-left-alt:.75pt;mso-border-bottom-alt:
+ .5pt;mso-border-right-alt:.5pt;mso-border-color-alt:windowtext;mso-border-style-alt:
+ solid;padding:0in 5.4pt 0in 5.4pt'>
+ <p class=MsoNormal>TI</p>
+ </td>
+ </tr>
+</table>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='font-size:12.0pt'>Credits<o:p></o:p></span></b></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><span style='mso-bidi-font-size:
+12.0pt'><o:p> </o:p></span></p>
+
+<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
+normal'><span style='font-size:12.0pt'>Licenses<o:p></o:p></span></b></p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal>Copyright (C) 2014 Texas Instruments Incorporated -
+http://www.ti.com/ </p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal>Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following conditions are
+met:</p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal style='margin-left:21.0pt;text-indent:-.25in;mso-list:l2 level1 lfo3'><![if !supportLists]><span
+style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
+Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>
+</span></span></span><![endif]>Redistributions of source code must retain the
+above copyright notice, this list of conditions and the following disclaimer.</p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal style='margin-left:21.0pt;text-indent:-.25in;mso-list:l2 level1 lfo3'><![if !supportLists]><span
+style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
+Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>
+</span></span></span><![endif]>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.</p>
+
+<p class=MsoListParagraph style='margin-left:0in'><o:p> </o:p></p>
+
+<p class=MsoNormal style='margin-left:21.0pt;text-indent:-.25in;mso-list:l2 level1 lfo3'><![if !supportLists]><span
+style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
+Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>
+</span></span></span><![endif]>Neither the name of Texas Instruments Incorporated
+nor the names of its contributors may be used to endorse or promote products
+derived from this software without specific prior written permission.</p>
+
+<p class=MsoNormal><o:p> </o:p></p>
+
+<p class=MsoNormal>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED ARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.</p>
+
+<p class=MsoNormal><span style='mso-bidi-font-size:12.0pt'><o:p> </o:p></span></p>
+
+</div>
+
+</body>
+
+</html>
diff --git a/README.md b/README.md
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+MSPBSL_USB_Tool
+===============
+
+This firmware is designed to allow USB to UART communication for the purpose of programming an MSP430 BootStrapLoader. It requires special hardware, described below.
+
+This firmware is based on the MSP430 CDC UART Bridge, which can be found in the USB developer package: http://www.ti.com/tool/msp430usbdevpack
+
+Hardware to run this firmware can be found here: https://www.olimex.com/Products/MSP430/BSL/MSP430-BSL/
+
+Schematics are available here: https://www.olimex.com/Products/MSP430/BSL/MSP430-BSL/resources/MSP430-BSL_Rev_B.pdf
+
+Note: When downloading the firmware via ZIP, the linebreaks in the text files might be incompatible with your OS. This is particularly important if you plan to use the text file output image with a tool to write the firmware onto the Rocket. Some TI provided tools require windows-format linebreaks, whereas the Zip web download comes in UNIX-style. This can be worked around in two ways:
+
+- Fetch the source code using GIT running on your host OS, having it automatically change the formatting
+- Manually change the linebreaks in the downloaded TXT file.
diff --git a/USB_API/USB_CDC_API/UsbCdc.c b/USB_API/USB_CDC_API/UsbCdc.c
--- /dev/null
@@ -0,0 +1,1015 @@
+/*
+ * UsbCdc.c
+ *
+ * CDC specific USB functions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (CDC Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: UsbCdc.c, File Version 1.01 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2008/09/03 born |
+| RSTO 2008/09/19 Changed USBCDC_sendData to send more then 64bytes|
+| RSTO 2008/12/23 enhancements of CDC API |
+| RSTO 2008/05/19 updated USBCDC_intfStatus() |
+| RSTO 2009/05/26 added USBCDC_bytesInUSBBuffer() |
+| RSTO 2009/05/28 changed USBCDC_sendData() |
+| RSTO 2009/07/17 updated USBCDC_bytesInUSBBuffer() |
+| RSTO 2009/10/21 move __disable_interrupt() before |
+| checking for suspend |
+| MSP,Biju 2009/12/28 Fix for the bug "Download speed is slow" |
++----------------------------------------------------------------------------*/
+#include <descriptors.h>
+
+#ifdef _CDC_
+
+
+#include "../USB_Common/device.h"
+#include "../USB_Common/types.h" // Basic Type declarations
+#include "../USB_Common/defMSP430USB.h"
+#include "../USB_Common/usb.h" // USB-specific Data Structures
+#include "../USB_CDC_API/UsbCdc.h"
+
+#include <string.h>
+#include "uart.h"
+#include "baudrateselect.h"
+
+// Local Macros
+#define INTFNUM_OFFSET(X) (X - CDC0_INTFNUM) // Get the CDC offset
+
+static struct _CdcParams
+{
+ ULONG lBaudrate; // holds baudrate
+ BYTE bDataBits; // holds Data Bits
+ BYTE bStopBits; // holds Stopa Bits
+ BYTE bParity; // holds Parity
+}CdcParams[CDC_NUM_INTERFACES];
+
+static struct _CdcWrite
+{
+ WORD nCdcBytesToSend; // holds counter of bytes to be sent
+ WORD nCdcBytesToSendLeft; // holds counter how many bytes is still to be sent
+ const BYTE* pUsbBufferToSend; // holds the buffer with data to be sent
+ BYTE bCurrentBufferXY; // is 0 if current buffer to write data is X, or 1 if current buffer is Y
+ BYTE bZeroPacketSent; // = FALSE;
+ BYTE last_ByteSend;
+} CdcWriteCtrl[CDC_NUM_INTERFACES];
+
+static struct _CdcRead
+{
+ BYTE *pUserBuffer; // holds the current position of user's receiving buffer. If NULL- no receiving operation started
+ BYTE *pCurrentEpPos; // current positon to read of received data from curent EP
+ WORD nBytesToReceive; // holds how many bytes was requested by receiveData() to receive
+ WORD nBytesToReceiveLeft; // holds how many bytes is still requested by receiveData() to receive
+ BYTE * pCT1; // holds current EPBCTxx register
+ BYTE * pCT2; // holds next EPBCTxx register
+ BYTE * pEP2; // holds addr of the next EP buffer
+ BYTE nBytesInEp; // how many received bytes still available in current EP
+ BYTE bCurrentBufferXY; // indicates which buffer is used by host to transmit data via OUT endpoint3
+} CdcReadCtrl[CDC_NUM_INTERFACES];
+
+extern WORD wUsbEventMask;
+
+//function pointers
+extern VOID *(*USB_TX_memcpy)(VOID * dest, const VOID * source, size_t count);
+extern VOID *(*USB_RX_memcpy)(VOID * dest, const VOID * source, size_t count);
+
+
+/*----------------------------------------------------------------------------+
+| Global Variables |
++----------------------------------------------------------------------------*/
+
+extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
+extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
+
+
+VOID CdcResetData()
+{
+
+ // indicates which buffer is used by host to transmit data via OUT endpoint3 - X buffer is first
+ //CdcReadCtrl[intfIndex].bCurrentBufferXY = X_BUFFER;
+
+ memset(&CdcWriteCtrl, 0, sizeof(CdcWriteCtrl));
+ memset(&CdcReadCtrl, 0, sizeof(CdcReadCtrl));
+
+}
+
+/*
+Sends data over interface intfNum, of size size and starting at address data.
+Returns: kUSBCDC_sendStarted
+ kUSBCDC_sendComplete
+ kUSBCDC_intfBusyError
+*/
+BYTE USBCDC_sendData(const BYTE* data, WORD size, BYTE intfNum)
+{
+ BYTE edbIndex;
+ unsigned short bGIE;
+
+ edbIndex= stUsbHandle[intfNum].edb_Index;
+
+ if (size == 0)
+ {
+ return kUSBCDC_generalError;
+ }
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ // data can not be read because of USB suspended
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBCDC_busNotAvailable;
+ }
+
+ if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft != 0)
+ {
+ // the USB still sends previous data, we have to wait
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBCDC_intfBusyError;
+ }
+
+ //This function generate the USB interrupt. The data will be sent out from interrupt
+
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = size;
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft = size;
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend = data;
+
+ //trigger Endpoint Interrupt - to start send operation
+ USBIEPIFG |= 1<<(edbIndex+1); //IEPIFGx;
+
+ __bis_SR_register(bGIE); //restore interrupt status
+
+ return kUSBCDC_sendStarted;
+}
+
+#define EP_MAX_PACKET_SIZE_CDC 0x40
+
+//this function is used only by USB interrupt
+BOOL CdcToHostFromBuffer(BYTE intfNum)
+{
+ BYTE byte_count, nTmp2;
+ BYTE * pEP1;
+ BYTE * pEP2;
+ BYTE * pCT1;
+ BYTE * pCT2;
+ BYTE bWakeUp = FALSE; //TRUE for wake up after interrupt
+ BYTE edbIndex;
+
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft == 0) // do we have somtething to send?
+ {
+ if (!CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent) // zero packet was not yet sent
+ {
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent = TRUE;
+
+ if(CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend == EP_MAX_PACKET_SIZE_CDC)
+ {
+ if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER)
+ {
+ tInputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0;
+ }
+ else
+ {
+ tInputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0;
+ }
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1)&0x01; //switch buffer
+ }
+
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = 0; // nothing to send
+
+ //call event callback function
+ if (wUsbEventMask & kUSB_sendCompletedEvent)
+ {
+ bWakeUp = USBCDC_handleSendCompleted(intfNum);
+ }
+
+ } // if (!bSentZeroPacket)
+
+ return bWakeUp;
+ }
+
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent = FALSE; // zero packet will be not sent: we have data
+
+ if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER)
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+
+ //second EP buffer
+ pEP2 = (BYTE*)stUsbHandle[intfNum].iep_Y_Buffer;
+ pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+ else
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].iep_Y_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+
+ //second EP buffer
+ pEP2 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
+ pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+
+ // how many byte we can send over one endpoint buffer
+ byte_count = (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft > EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC : CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft;
+ nTmp2 = *pCT1;
+
+ if(nTmp2 & EPBCNT_NAK)
+ {
+ USB_TX_memcpy(pEP1, CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend, byte_count); // copy data into IEP3 X or Y buffer
+ *pCT1 = byte_count; // Set counter for usb In-Transaction
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1)&0x01; //switch buffer
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft -= byte_count;
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend += byte_count; // move buffer pointer
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend = byte_count;
+
+ //try to send data over second buffer
+ nTmp2 = *pCT2;
+ if ((CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft > 0) && // do we have more data to send?
+ (nTmp2 & EPBCNT_NAK)) // if the second buffer is free?
+ {
+ // how many byte we can send over one endpoint buffer
+ byte_count = (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft > EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC : CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft;
+
+ USB_TX_memcpy(pEP2, CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend, byte_count); // copy data into IEP3 X or Y buffer
+ *pCT2 = byte_count; // Set counter for usb In-Transaction
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1)&0x01; //switch buffer
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft -= byte_count;
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend += byte_count; //move buffer pointer
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend = byte_count;
+ }
+ }
+ return bWakeUp;
+}
+
+/*
+Aborts an active send operation on interface intfNum.
+Returns the number of bytes that were sent prior to the abort, in size.
+*/
+BYTE USBCDC_abortSend(WORD* size, BYTE intfNum)
+{
+ unsigned short bGIE;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ __disable_interrupt(); //disable interrupts - atomic operation
+
+ *size = (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend - CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft);
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = 0;
+ CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft = 0;
+
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSB_succeed;
+}
+
+// This function copies data from OUT endpoint into user's buffer
+// Arguments:
+// pEP - pointer to EP to copy from
+// pCT - pointer to pCT control reg
+//
+VOID CopyUsbToBuff(BYTE* pEP, BYTE* pCT, BYTE intfNum)
+{
+ BYTE nCount;
+
+ // how many byte we can get from one endpoint buffer
+ nCount = (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp) ? CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp : CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;
+
+ USB_RX_memcpy(CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer, pEP, nCount); // copy data from OEP3 X or Y buffer
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft -= nCount;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer += nCount; // move buffer pointer
+ // to read rest of data next time from this place
+
+ if (nCount == CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp) // all bytes are copied from receive buffer?
+ {
+ //switch current buffer
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1) &0x01;
+
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
+
+ //clear NAK, EP ready to receive data
+ *pCT = 0x00;
+ }
+ else
+ {
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp -= nCount;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = pEP + nCount;
+ }
+}
+
+/*
+Receives data over interface intfNum, of size size, into memory starting at address data.
+Returns:
+ kUSBCDC_receiveStarted if the receiving process started.
+ kUSBCDC_receiveCompleted all requested date are received.
+ kUSBCDC_receiveInProgress previous receive opereation is in progress. The requested receive operation can be not started.
+ kUSBCDC_generalError error occurred.
+*/
+BYTE USBCDC_receiveData(BYTE* data, WORD size, BYTE intfNum)
+{
+ BYTE nTmp1;
+ BYTE edbIndex;
+ unsigned short bGIE;
+
+ edbIndex=stUsbHandle[intfNum].edb_Index;
+
+ if ((size == 0) || // read size is 0
+ (data == NULL))
+ {
+ return kUSBCDC_generalError;
+ }
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ // data can not be read because of USB suspended
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBCDC_busNotAvailable;
+ }
+
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL) // receive process already started
+ {
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBCDC_intfBusyError;
+ }
+
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive = size; // bytes to receive
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = size; // left bytes to receive
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = data; // set user receive buffer
+
+ //read rest of data from buffer, if any
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0)
+ {
+ // copy data from pEP-endpoint into User's buffer
+ CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos, CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);
+
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // the Receive opereation is completed
+ {
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ if (wUsbEventMask & kUSB_receiveCompletedEvent)
+ {
+ USBCDC_handleReceiveCompleted(intfNum); // call event handler in interrupt context
+ }
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBCDC_receiveCompleted; // receive completed
+ }
+
+ // check other EP buffer for data - exchange pCT1 with pCT2
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 == &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX)
+ {
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ }
+ else
+ {
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ }
+
+ nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
+ //try read data from second buffer
+ if (nTmp1 & EPBCNT_NAK) // if the second buffer has received data?
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; // holds how many valid bytes in the EP buffer
+ CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos, CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);
+ }
+
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // the Receive opereation is completed
+ {
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ if (wUsbEventMask & kUSB_receiveCompletedEvent)
+ {
+ USBCDC_handleReceiveCompleted(intfNum); // call event handler in interrupt context
+ }
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBCDC_receiveCompleted; // receive completed
+ }
+ } //read rest of data from buffer, if any
+
+ //read 'fresh' data, if available
+ nTmp1 = 0;
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER) //this is current buffer
+ {
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK) //this buffer has a valid data packet
+ {
+ //this is the active EP buffer
+ //pEP1
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+
+ //second EP buffer
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ nTmp1 = 1; //indicate that data is available
+ }
+ }
+ else
+ {// Y_BUFFER
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK)
+ {
+ //this is the active EP buffer
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+
+ //second EP buffer
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ nTmp1 = 1; //indicate that data is available
+ }
+ }
+
+ if (nTmp1)
+ {
+ // how many byte we can get from one endpoint buffer
+ nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
+ while(nTmp1 == 0)
+ {
+ nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
+ }
+
+ if(nTmp1 & EPBCNT_NAK)
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; // holds how many valid bytes in the EP buffer
+
+ CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos, CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);
+
+ nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
+ //try read data from second buffer
+ if ((CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > 0) && // do we have more data to send?
+ (nTmp1 & EPBCNT_NAK)) // if the second buffer has received data?
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; // holds how many valid bytes in the EP buffer
+ CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2, CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2, intfNum);
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
+ }
+ }
+ }
+
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // the Receive opereation is completed
+ {
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ if (wUsbEventMask & kUSB_receiveCompletedEvent)
+ {
+ USBCDC_handleReceiveCompleted(intfNum); // call event handler in interrupt context
+ }
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBCDC_receiveCompleted;
+ }
+
+ //interrupts enable
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBCDC_receiveStarted;
+}
+
+
+//this function is used only by USB interrupt.
+//It fills user receiving buffer with received data
+BOOL CdcToBufferFromHost(BYTE intfNum)
+{
+ BYTE * pEP1;
+ BYTE nTmp1;
+ BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt
+
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // do we have somtething to receive?
+ {
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ return bWakeUp;
+ }
+
+ // No data to receive...
+ if (!((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX |
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY)
+ & 0x80))
+ {
+ return bWakeUp;
+ }
+
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER) //X is current buffer
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+
+ //second EP buffer
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+ else
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+
+ //second EP buffer
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+
+ // how many byte we can get from one endpoint buffer
+ nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
+
+ if(nTmp1 & EPBCNT_NAK)
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; // holds how many valid bytes in the EP buffer
+
+ CopyUsbToBuff(pEP1, CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);
+
+ nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
+ //try read data from second buffer
+ if ((CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > 0) && // do we have more data to send?
+ (nTmp1 & EPBCNT_NAK)) // if the second buffer has received data?
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; // holds how many valid bytes in the EP buffer
+ CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2, CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2, intfNum);
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
+ }
+ }
+
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // the Receive opereation is completed
+ {
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ if (wUsbEventMask & kUSB_receiveCompletedEvent)
+ {
+ bWakeUp = USBCDC_handleReceiveCompleted(intfNum);
+ }
+
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp) // Is not read data still available in the EP?
+ {
+ if (wUsbEventMask & kUSB_dataReceivedEvent)
+ {
+ bWakeUp = USBCDC_handleDataReceived(intfNum);
+ }
+ }
+ }
+ return bWakeUp;
+}
+
+// helper for USB interrupt handler
+BOOL CdcIsReceiveInProgress(BYTE intfNum)
+{
+ return (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL);
+}
+
+
+/*
+Aborts an active receive operation on interface intfNum.
+ Returns the number of bytes that were received and transferred
+ to the data location established for this receive operation.
+*/
+BYTE USBCDC_abortReceive(WORD* size, BYTE intfNum)
+{
+ //interrupts disable
+ unsigned short bGIE;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+
+ *size = 0; //set received bytes count to 0
+
+ //is receive operation underway?
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer)
+ {
+ //how many bytes are already received?
+ *size = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive - CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;
+
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = 0;
+ }
+
+ //restore interrupt status
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSB_succeed;
+}
+
+/*
+This function rejects payload data that has been received from the host.
+*/
+BYTE USBCDC_rejectData(BYTE intfNum)
+{
+ BYTE edbIndex;
+ unsigned short bGIE;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if (bFunctionSuspended)
+ {
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBCDC_busNotAvailable;
+ }
+
+ //Is receive operation underway?
+ // - do not flush buffers if any operation still active.
+ if (!CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer)
+ {
+ BYTE tmp1 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK;
+ BYTE tmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK;
+
+ if (tmp1 ^ tmp2) // switch current buffer if any and only ONE of buffers is full
+ {
+ //switch current buffer
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1) &0x01;
+ }
+
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0; //flush buffer X
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0; //flush buffer Y
+ CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0; // indicates that no more data available in the EP
+ }
+
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSB_succeed;
+}
+
+/*
+This function indicates the status of the itnerface intfNum.
+ If a send operation is active for this interface,
+ the function also returns the number of bytes that have been transmitted to the host.
+ If a receiver operation is active for this interface, the function also returns
+ the number of bytes that have been received from the host and are waiting at the assigned address.
+
+returns kUSBCDC_waitingForSend (indicates that a call to USBCDC_SendData()
+ has been made, for which data transfer has not been completed)
+
+returns kUSBCDC_waitingForReceive (indicates that a receive operation
+ has been initiated, but not all data has yet been received)
+
+returns kUSBCDC_dataWaiting (indicates that data has been received
+ from the host, waiting in the USB receive buffers)
+*/
+BYTE USBCDC_intfStatus(BYTE intfNum, WORD* bytesSent, WORD* bytesReceived)
+{
+ BYTE ret = 0;
+ unsigned short bGIE;
+ BYTE edbIndex;
+
+ *bytesSent = 0;
+ *bytesReceived = 0;
+
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ __disable_interrupt(); //disable interrupts - atomic operation
+
+ // Is send operation underway?
+ if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft != 0)
+ {
+ ret |= kUSBCDC_waitingForSend;
+ *bytesSent = CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend - CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft;
+ }
+
+ //Is receive operation underway?
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL)
+ {
+ ret |= kUSBCDC_waitingForReceive;
+ *bytesReceived = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive - CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;
+ }
+ else // receive operation not started
+ {
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if (!bFunctionSuspended)
+ {
+ if((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK) | //any of buffers has a valid data packet
+ (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK))
+ {
+ ret |= kUSBCDC_dataWaiting;
+ }
+ }
+ }
+
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ // if suspended or not enumerated - report no other tasks pending
+ ret = kUSBCDC_busNotAvailable;
+ }
+
+ //restore interrupt status
+ __bis_SR_register(bGIE); //restore interrupt status
+
+ __no_operation();
+ return ret;
+}
+
+/*
+Returns how many bytes are in the buffer are received and ready to be read.
+*/
+BYTE USBCDC_bytesInUSBBuffer(BYTE intfNum)
+{
+ BYTE bTmp1 = 0;
+ unsigned short bGIE;
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ __bis_SR_register(bGIE); //restore interrupt status
+ // if suspended or not enumerated - report 0 bytes available
+ return 0;
+ }
+
+ if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0) // If a RX operation is underway, part of data may was read of the OEP buffer
+ {
+ bTmp1 = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp;
+ if (*CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & EPBCNT_NAK) // the next buffer has a valid data packet
+ {
+ bTmp1 += *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & 0x7F;
+ }
+ }
+ else
+ {
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK) //this buffer has a valid data packet
+ {
+ bTmp1 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & 0x7F;
+ }
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK) //this buffer has a valid data packet
+ {
+ bTmp1 += tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & 0x7F;
+ }
+ }
+
+ __bis_SR_register(bGIE); //restore interrupt status
+ return bTmp1;
+}
+
+
+//----------------------------------------------------------------------------
+// Line Coding Structure
+// dwDTERate | 4 | Data terminal rate, in bits per second
+// bCharFormat | 1 | Stop bits, 0 = 1 Stop bit, 1 = 1,5 Stop bits, 2 = 2 Stop bits
+// bParityType | 1 | Parity, 0 = None, 1 = Odd, 2 = Even, 3= Mark, 4 = Space
+// bDataBits | 1 | Data bits (5,6,7,8,16)
+//----------------------------------------------------------------------------
+VOID usbGetLineCoding0(VOID)
+{
+ abUsbRequestReturnData[6] = CdcParams[CDC0_INTFNUM].bDataBits; // Data bits = 8
+ abUsbRequestReturnData[5] = CdcParams[CDC0_INTFNUM].bParity; // No Parity
+ abUsbRequestReturnData[4] = CdcParams[CDC0_INTFNUM].bStopBits; // Stop bits = 1
+
+ abUsbRequestReturnData[3] = CdcParams[CDC0_INTFNUM].lBaudrate >> 24;
+ abUsbRequestReturnData[2] = CdcParams[CDC0_INTFNUM].lBaudrate >> 16;
+ abUsbRequestReturnData[1] = CdcParams[CDC0_INTFNUM].lBaudrate >> 8;
+ abUsbRequestReturnData[0] = CdcParams[CDC0_INTFNUM].lBaudrate;
+
+ wBytesRemainingOnIEP0 = 0x07; // amount of data to be send over EP0 to host
+ usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]); // send data to host
+}
+
+#if CDC_NUM_INTERFACES >= 2
+//----------------------------------------------------------------------------
+VOID usbGetLineCoding1(VOID)
+{
+ abUsbRequestReturnData[6] = CdcParams[CDC1_INTFNUM].bDataBits; // Data bits = 8
+ abUsbRequestReturnData[5] = CdcParams[CDC1_INTFNUM].bParity; // No Parity
+ abUsbRequestReturnData[4] = CdcParams[CDC1_INTFNUM].bStopBits; // Stop bits = 1
+
+ abUsbRequestReturnData[3] = CdcParams[CDC1_INTFNUM].lBaudrate >> 24;
+ abUsbRequestReturnData[2] = CdcParams[CDC1_INTFNUM].lBaudrate >> 16;
+ abUsbRequestReturnData[1] = CdcParams[CDC1_INTFNUM].lBaudrate >> 8;
+ abUsbRequestReturnData[0] = CdcParams[CDC1_INTFNUM].lBaudrate;
+
+ wBytesRemainingOnIEP0 = 0x07; // amount of data to be send over EP0 to host
+ usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]); // send data to host
+}
+#endif
+
+#if CDC_NUM_INTERFACES >= 3
+//----------------------------------------------------------------------------
+VOID usbGetLineCoding2(VOID)
+{
+ abUsbRequestReturnData[6] = CdcParams[CDC2_INTFNUM].bDataBits; // Data bits = 8
+ abUsbRequestReturnData[5] = CdcParams[CDC2_INTFNUM].bParity; // No Parity
+ abUsbRequestReturnData[4] = CdcParams[CDC2_INTFNUM].bStopBits; // Stop bits = 1
+
+ abUsbRequestReturnData[3] = CdcParams[CDC2_INTFNUM].lBaudrate >> 24;
+ abUsbRequestReturnData[2] = CdcParams[CDC2_INTFNUM].lBaudrate >> 16;
+ abUsbRequestReturnData[1] = CdcParams[CDC2_INTFNUM].lBaudrate >> 8;
+ abUsbRequestReturnData[0] = CdcParams[CDC2_INTFNUM].lBaudrate;
+
+ wBytesRemainingOnIEP0 = 0x07; // amount of data to be send over EP0 to host
+ usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]); // send data to host
+}
+#endif
+//----------------------------------------------------------------------------
+
+VOID usbSetLineCoding0(VOID)
+{
+ usbReceiveDataPacketOnEP0((PBYTE) &abUsbRequestIncomingData); // receive data over EP0 from Host
+}
+
+//----------------------------------------------------------------------------
+#if CDC_NUM_INTERFACES >= 2
+VOID usbSetLineCoding1(VOID)
+{
+ usbReceiveDataPacketOnEP0((PBYTE) &abUsbRequestIncomingData); // receive data over EP0 from Host
+}
+#endif
+//----------------------------------------------------------------------------
+#if CDC_NUM_INTERFACES >= 3
+VOID usbSetLineCoding2(VOID)
+{
+ usbReceiveDataPacketOnEP0((PBYTE) &abUsbRequestIncomingData); // receive data over EP0 from Host
+}
+#endif
+//----------------------------------------------------------------------------
+#define SET_DTR0 P4OUT |= 0x08
+#define CLR_DTR0 P4OUT &= ~0x08
+#define CLR_RTS0 {P4OUT |= 0x04 ;P2OUT &= ~0x01;}
+#define SET_RTS0 {P4OUT &= ~0x04;P2OUT |= 0x01;}
+
+VOID usbSetControlLineState0(VOID)
+{
+#ifdef UART_BASED
+ if ((tSetupPacket.wValue & 0x03) == 0x03)
+ {
+ CLR_RTS0;
+ SET_RTS0;
+ CLR_RTS0;
+ SET_DTR0;
+ __delay_cycles(50);
+ SET_RTS0;
+ }
+ else
+ {
+ SET_RTS0;
+ CLR_DTR0;
+ __delay_cycles(50);
+ }
+#endif
+ usbSendZeroLengthPacketOnIEP0(); // Send ZLP for status stage
+}
+#if CDC_NUM_INTERFACES >= 2
+VOID usbSetControlLineState1(VOID)
+{
+ if (tSetupPacket.wValue & 0x01)
+ {SET_DTR1;}
+ else
+ {CLR_DTR1;}
+ if (tSetupPacket.wValue & 0x02)
+ {SET_RTS1;}
+ else
+ {CLR_RTS1;}
+ usbSendZeroLengthPacketOnIEP0(); // Send ZLP for status stage
+}
+#endif
+#if CDC_NUM_INTERFACES >= 3
+VOID usbSetControlLineState2(VOID)
+{
+ if (tSetupPacket.wValue & 0x01)
+ SET_DTR2;
+ else
+ CLR_DTR2;
+ if (tSetupPacket.wValue & 0x02)
+ SET_RTS2;
+ else
+ CLR_RTS2;
+ usbSendZeroLengthPacketOnIEP0(); // Send ZLP for status stage
+}
+#endif
+//----------------------------------------------------------------------------
+
+VOID Handler_SetLineCoding0(VOID)
+{
+ // Baudrate Settings
+ CdcParams[CDC0_INTFNUM].lBaudrate = (ULONG)abUsbRequestIncomingData[3] << 24 |
+ (ULONG)abUsbRequestIncomingData[2]<<16 | (ULONG)abUsbRequestIncomingData[1]<<8 |
+ abUsbRequestIncomingData[0];
+
+ // Stop bits
+ CdcParams[CDC0_INTFNUM].bStopBits = abUsbRequestIncomingData[4];
+ // Parit
+ CdcParams[CDC0_INTFNUM].bParity = abUsbRequestIncomingData[5];
+ // Data bits
+ CdcParams[CDC0_INTFNUM].bDataBits = abUsbRequestIncomingData[6];
+ #ifdef UART0_INTFNUM
+ if(!InitUart0(CdcParams[CDC0_INTFNUM].lBaudrate))
+ CdcParams[CDC0_INTFNUM].lBaudrate = 0;
+ #elif defined (I2C_BASED)
+ if (!BaudrateSelect(CdcParams[CDC0_INTFNUM].lBaudrate))
+ CdcParams[CDC0_INTFNUM].lBaudrate = 0;
+ #else
+ CdcParams[CDC0_INTFNUM].lBaudrate = 0;
+ #endif
+}
+
+//----------------------------------------------------------------------------
+VOID Handler_SetLineCoding1(VOID)
+{
+#if CDC_NUM_INTERFACES >= 2
+ // Baudrate Settings
+ CdcParams[CDC1_INTFNUM].lBaudrate = (ULONG)abUsbRequestIncomingData[3] << 24 |
+ (ULONG)abUsbRequestIncomingData[2]<<16 | (ULONG)abUsbRequestIncomingData[1]<<8 |
+ abUsbRequestIncomingData[0];
+
+ // Stop bits
+ CdcParams[CDC1_INTFNUM].bStopBits = abUsbRequestIncomingData[4];
+ // Parit
+ CdcParams[CDC1_INTFNUM].bParity = abUsbRequestIncomingData[5];
+ // Data bits
+ CdcParams[CDC1_INTFNUM].bDataBits = abUsbRequestIncomingData[6];
+
+ #ifdef UART1_INTFNUM
+ if(!InitUart1(CdcParams[CDC1_INTFNUM].lBaudrate))
+ CdcParams[CDC1_INTFNUM].lBaudrate = 0;
+ #else
+ CdcParams[CDC1_INTFNUM].lBaudrate = 0;
+ #endif
+#endif
+}
+//----------------------------------------------------------------------------
+VOID Handler_SetLineCoding2(VOID)
+{
+#if CDC_NUM_INTERFACES >= 3
+ // Baudrate Settings
+ CdcParams[CDC2_INTFNUM].lBaudrate = (ULONG)abUsbRequestIncomingData[3] << 24 |
+ (ULONG)abUsbRequestIncomingData[2]<<16 |(ULONG)abUsbRequestIncomingData[1]<<8 |
+ abUsbRequestIncomingData[0];
+
+ // Stop bits
+ CdcParams[CDC2_INTFNUM].bStopBits = abUsbRequestIncomingData[4];
+ // Parit
+ CdcParams[CDC2_INTFNUM].bParity = abUsbRequestIncomingData[5];
+ // Data bits
+ CdcParams[CDC2_INTFNUM].bDataBits = abUsbRequestIncomingData[6];
+
+ #ifdef UART1_INTFNUM
+ if(!InitUart1(CdcParams[CDC2_INTFNUM].lBaudrate))
+ CdcParams[CDC2_INTFNUM].lBaudrate = 0;
+ #else
+ CdcParams[CDC2_INTFNUM].lBaudrate = 0;
+ #endif
+#endif
+}
+#endif //ifdef _CDC_
+
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_CDC_API/UsbCdc.h b/USB_API/USB_CDC_API/UsbCdc.h
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * UsbCdc.h
+ *
+ * CDC specific USB functions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (CDC Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: UsbCdc.h, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2008/09/03 born |
+| RSTO 2008/12/23 enhancements of CDC API |
+| RSTO 2009/05/15 added param to USBCDC_rejectData() |
+| RSTO 2009/05/26 added USBCDC_bytesInUSBBuffer() |
+| MSP,Biju 2009/12/03 file versioning started |
+| |
++----------------------------------------------------------------------------*/
+#ifndef _UsbCdc_H_
+#define _UsbCdc_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#define kUSBCDC_sendStarted 0x01
+#define kUSBCDC_sendComplete 0x02
+#define kUSBCDC_intfBusyError 0x03
+#define kUSBCDC_receiveStarted 0x04
+#define kUSBCDC_receiveCompleted 0x05
+#define kUSBCDC_receiveInProgress 0x06
+#define kUSBCDC_generalError 0x07
+#define kUSBCDC_busNotAvailable 0x08
+
+
+/*----------------------------------------------------------------------------
+These functions can be used in application
++----------------------------------------------------------------------------*/
+
+/*
+Sends data over interface intfNum, of size size and starting at address data.
+ Returns: kUSBCDC_sendStarted
+ kUSBCDC_sendComplete
+ kUSBCDC_intfBusyError
+*/
+BYTE USBCDC_sendData(const BYTE* data, WORD size, BYTE intfNum);
+
+/*
+Receives data over interface intfNum, of size size, into memory starting at address data.
+*/
+BYTE USBCDC_receiveData(BYTE* data, WORD size, BYTE intfNum);
+
+/*
+Aborts an active receive operation on interface intfNum.
+ size: the number of bytes that were received and transferred
+ to the data location established for this receive operation.
+*/
+BYTE USBCDC_abortReceive(WORD* size, BYTE intfNum);
+
+
+#define kUSBCDC_noDataWaiting 1 //returned by USBCDC_rejectData() if no data pending
+
+/*
+This function rejects payload data that has been received from the host.
+*/
+BYTE USBCDC_rejectData(BYTE intfNum);
+
+/*
+Aborts an active send operation on interface intfNum. Returns the number of bytes that were sent prior to the abort, in size.
+*/
+BYTE USBCDC_abortSend(WORD* size, BYTE intfNum);
+
+
+#define kUSBCDC_waitingForSend 0x01
+#define kUSBCDC_waitingForReceive 0x02
+#define kUSBCDC_dataWaiting 0x04
+#define kUSBCDC_busNotAvailable 0x08
+#define kUSB_allCdcEvents 0xFF
+
+/*
+This function indicates the status of the interface intfNum.
+ If a send operation is active for this interface,
+ the function also returns the number of bytes that have been transmitted to the host.
+ If a receiver operation is active for this interface, the function also returns
+ the number of bytes that have been received from the host and are waiting at the assigned address.
+
+returns kUSBCDC_waitingForSend (indicates that a call to USBCDC_SendData()
+ has been made, for which data transfer has not been completed)
+
+returns kUSBCDC_waitingForReceive (indicates that a receive operation
+ has been initiated, but not all data has yet been received)
+
+returns kUSBCDC_dataWaiting (indicates that data has been received
+ from the host, waiting in the USB receive buffers)
+*/
+BYTE USBCDC_intfStatus(BYTE intfNum, WORD* bytesSent, WORD* bytesReceived);
+
+/*
+Returns how many bytes are in the buffer are received and ready to be read.
+*/
+BYTE USBCDC_bytesInUSBBuffer(BYTE intfNum);
+
+
+/*----------------------------------------------------------------------------
+Event-Handling routines
++----------------------------------------------------------------------------*/
+
+/*
+This event indicates that data has been received for interface intfNum, but no data receive operation is underway.
+returns TRUE to keep CPU awake
+*/
+BYTE USBCDC_handleDataReceived(BYTE intfNum);
+
+/*
+This event indicates that a send operation on interface intfNum has just been completed.
+returns TRUE to keep CPU awake
+*/
+BYTE USBCDC_handleSendCompleted(BYTE intfNum);
+
+/*
+This event indicates that a receive operation on interface intfNum has just been completed.
+returns TRUE to keep CPU awake
+*/
+BYTE USBCDC_handleReceiveCompleted(BYTE intfNum);
+
+
+/*----------------------------------------------------------------------------
+These functions is to be used ONLY by USB stack, and not by application
++----------------------------------------------------------------------------*/
+
+/**
+Send a packet with the settings of the second uart back to the usb host
+*/
+VOID usbGetLineCoding0(VOID);
+VOID usbGetLineCoding1(VOID);
+VOID usbGetLineCoding2(VOID);
+
+/**
+Prepare EP0 to receive a packet with the settings for the second uart
+*/
+VOID usbSetLineCoding0(VOID);
+VOID usbSetLineCoding1(VOID);
+VOID usbSetLineCoding2(VOID);
+
+/**
+Function set or reset RTS
+*/
+VOID usbSetControlLineState0(VOID);
+VOID usbSetControlLineState1(VOID);
+VOID usbSetControlLineState2(VOID);
+
+/**
+Readout the settings (send from usb host) for the second uart
+*/
+VOID Handler_SetLineCoding0(VOID);
+VOID Handler_SetLineCoding1(VOID);
+VOID Handler_SetLineCoding2(VOID);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //_UsbCdc_H_
diff --git a/USB_API/USB_Common/UsbIsr.h b/USB_API/USB_Common/UsbIsr.h
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * UsbIsr.h
+ *
+ * USB ISR routines
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (CDC/HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: UsbIsr.h, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2008/09/03 born |
+| RSTO 2008/12/23 enhancements of CDC API |
++----------------------------------------------------------------------------*/
+
+#ifndef _ISR_H_
+#define _ISR_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+Handle incoming setup packet.
+returns TRUE to keep CPU awake
+*/
+BYTE SetupPacketInterruptHandler(VOID);
+
+/**
+Handle VBuss on signal.
+*/
+VOID PWRVBUSonHandler(VOID);
+
+/**
+Handle VBuss off signal.
+*/
+VOID PWRVBUSoffHandler(VOID);
+
+/**
+Handle In-requests from control pipe.
+*/
+VOID IEP0InterruptHandler(VOID);
+
+/**
+Handle Out-requests from control pipe.
+*/
+VOID OEP0InterruptHandler(VOID);
+
+/*----------------------------------------------------------------------------+
+| End of header file |
++----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _ISR_H_ */
+
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_Common/defMSP430USB.h b/USB_API/USB_Common/defMSP430USB.h
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * defMSP430USB.h
+ *
+ * Contains USB Constants, Type Definitions & Macros
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (CDC/HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: defMSP430USB.h, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| Description: |
+| Contains USB Constants, Type Definitions & Macros |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2008/09/03 born |
+| MSP,Biju 2009/10/21 Changes for composite support |
+| MSP,Biju 2009/12/03 file versioning started |
++----------------------------------------------------------------------------*/
+
+#ifndef _defMSP430USB_H
+#define _defMSP430USB_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*----------------------------------------------------------------------------+
+| Constant Definitions |
++----------------------------------------------------------------------------*/
+#define YES 1
+#define NO 0
+
+#define TRUE 1
+#define FALSE 0
+
+#define NOERR 0
+#define ERR 1
+
+#define NO_ERROR 0
+#define ERROR 1
+
+#define DISABLE 0
+#define ENABLE 1
+
+
+/*----------------------------------------------------------------------------+
+| USB Constants, Type Definition & Macro |
++----------------------------------------------------------------------------*/
+
+// USB related Constant
+#define MAX_ENDPOINT_NUMBER 0x07 // A maximum of 7 endpoints is available
+#define EP0_MAX_PACKET_SIZE 0x08
+#define EP0_PACKET_SIZE 0x08
+#define EP_MAX_PACKET_SIZE 0x40
+
+// Base addresses of transmit and receive buffers
+#define OEP1_X_BUFFER_ADDRESS 0x1C00 // Input Endpoint 1 X Buffer Base-address
+#define OEP1_Y_BUFFER_ADDRESS 0x1C40 // Input Endpoint 1 Y Buffer Base-address
+#define IEP1_X_BUFFER_ADDRESS 0x1C80 // Output Endpoint 1 X Buffer Base-address
+#define IEP1_Y_BUFFER_ADDRESS 0x1CC0 // Output Endpoint 1 Y Buffer Base-address
+
+#define OEP2_X_BUFFER_ADDRESS 0x1D00 // Input Endpoint 2 X Buffer Base-address
+#define OEP2_Y_BUFFER_ADDRESS 0x1D40 // Input Endpoint 2 Y Buffer Base-address
+#define IEP2_X_BUFFER_ADDRESS 0x1D80 // Output Endpoint 2 X Buffer Base-address
+#define IEP2_Y_BUFFER_ADDRESS 0x1DC0 // Output Endpoint 2 Y Buffer Base-address
+
+#define OEP3_X_BUFFER_ADDRESS 0x1E00 // Input Endpoint 2 X Buffer Base-address
+#define OEP3_Y_BUFFER_ADDRESS 0x1E40 // Input Endpoint 2 Y Buffer Base-address
+#define IEP3_X_BUFFER_ADDRESS 0x1E80 // Output Endpoint 2 X Buffer Base-address
+#define IEP3_Y_BUFFER_ADDRESS 0x1EC0 // Output Endpoint 2 Y Buffer Base-address
+
+#define OEP4_X_BUFFER_ADDRESS 0x1F00 // Input Endpoint 2 X Buffer Base-address
+#define OEP4_Y_BUFFER_ADDRESS 0x1F40 // Input Endpoint 2 Y Buffer Base-address
+#define IEP4_X_BUFFER_ADDRESS 0x1F80 // Output Endpoint 2 X Buffer Base-address
+#define IEP4_Y_BUFFER_ADDRESS 0x1FC0 // Output Endpoint 2 Y Buffer Base-address
+
+#define OEP5_X_BUFFER_ADDRESS 0x2000 // Input Endpoint 2 X Buffer Base-address
+#define OEP5_Y_BUFFER_ADDRESS 0x2040 // Input Endpoint 2 Y Buffer Base-address
+#define IEP5_X_BUFFER_ADDRESS 0x2080 // Output Endpoint 2 X Buffer Base-address
+#define IEP5_Y_BUFFER_ADDRESS 0x20C0 // Output Endpoint 2 Y Buffer Base-address
+
+#define OEP6_X_BUFFER_ADDRESS 0x2100 // Input Endpoint 2 X Buffer Base-address
+#define OEP6_Y_BUFFER_ADDRESS 0x2140 // Input Endpoint 2 Y Buffer Base-address
+#define IEP6_X_BUFFER_ADDRESS 0x2180 // Output Endpoint 2 X Buffer Base-address
+#define IEP6_Y_BUFFER_ADDRESS 0x21C0 // Output Endpoint 2 Y Buffer Base-address
+
+#define OEP7_X_BUFFER_ADDRESS 0x2200 // Input Endpoint 2 X Buffer Base-address
+#define OEP7_Y_BUFFER_ADDRESS 0x2240 // Input Endpoint 2 Y Buffer Base-address
+#define IEP7_X_BUFFER_ADDRESS 0x2280 // Output Endpoint 2 X Buffer Base-address
+#define IEP7_Y_BUFFER_ADDRESS 0x22C0 // Output Endpoint 2 Y Buffer Base-address
+
+#define X_BUFFER 0
+#define Y_BUFFER 1
+
+//Macros for end point numbers
+#define EP1 1
+#define EP2 2
+#define EP3 3
+#define EP4 4
+#define EP5 5
+#define EP6 6
+#define EP7 7
+
+// addresses of pipes for endpoints
+#define EP1_OUT_ADDR 0x01 //address for endpoint 1
+#define EP2_OUT_ADDR 0x02 //address for endpoint 2
+#define EP3_OUT_ADDR 0x03 //address for endpoint 3
+#define EP4_OUT_ADDR 0x04 //address for endpoint 4
+#define EP5_OUT_ADDR 0x05 //address for endpoint 5
+#define EP6_OUT_ADDR 0x06 //address for endpoint 6
+#define EP7_OUT_ADDR 0x07 //address for endpoint 7
+
+//Input end points
+#define EP1_IN_ADDR 0x81 //address for endpoint 1
+#define EP2_IN_ADDR 0x82 //address for endpoint 2
+#define EP3_IN_ADDR 0x83 //address for endpoint 3
+#define EP4_IN_ADDR 0x84 //address for endpoint 4
+#define EP5_IN_ADDR 0x85 //address for endpoint 5
+#define EP6_IN_ADDR 0x86 //address for endpoint 6
+#define EP7_IN_ADDR 0x87 //address for endpoint 7
+
+
+// EDB Data Structure
+typedef struct _tEDB
+{
+ BYTE bEPCNF; // Endpoint Configuration
+ BYTE bEPBBAX; // Endpoint X Buffer Base Address
+ BYTE bEPBCTX; // Endpoint X Buffer byte Count
+ BYTE bSPARE0; // no used
+ BYTE bSPARE1; // no used
+ BYTE bEPBBAY; // Endpoint Y Buffer Base Address
+ BYTE bEPBCTY; // Endpoint Y Buffer byte Count
+ BYTE bEPSIZXY; // Endpoint XY Buffer Size
+} tEDB, *tpEDB;
+
+typedef struct _tEDB0
+{
+ BYTE bIEPCNFG; // Input Endpoint 0 Configuration Register
+ BYTE bIEPBCNT; // Input Endpoint 0 Buffer Byte Count
+ BYTE bOEPCNFG; // Output Endpoint 0 Configuration Register
+ BYTE bOEPBCNT; // Output Endpoint 0 Buffer Byte Count
+} tEDB0, *tpEDB0;
+
+// EndPoint Desciptor Block Bits
+#define EPCNF_USBIE 0x04 // USB Interrupt on Transaction Completion. Set By MCU
+ // 0:No Interrupt, 1:Interrupt on completion
+#define EPCNF_STALL 0x08 // USB Stall Condition Indication. Set by UBM
+ // 0: No Stall, 1:USB Install Condition
+#define EPCNF_DBUF 0x10 // Double Buffer Enable. Set by MCU
+ // 0: Primary Buffer Only(x-buffer only), 1:Toggle Bit Selects Buffer
+
+#define EPCNF_TOGGLE 0x20 // USB Toggle bit. This bit reflects the toggle sequence bit of DATA0 and DATA1.
+
+#define EPCNF_UBME 0x80 // UBM Enable or Disable bit. Set or Clear by MCU.
+ // 0:UBM can't use this endpoint
+ // 1:UBM can use this endpoint
+#define EPBCNT_BYTECNT_MASK 0x7F // MASK for Buffer Byte Count
+#define EPBCNT_NAK 0x80 // NAK, 0:No Valid in buffer, 1:Valid packet in buffer
+
+//definitions for MSP430 USB-module
+#define START_OF_USB_BUFFER 0x1C00
+
+// input and output buffers for EP0
+#define USBIEP0BUF 0x2378
+#define USBOEP0BUF 0x2370
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*_defMSP430USB_H */
diff --git a/USB_API/USB_Common/device.h b/USB_API/USB_Common/device.h
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * device.h
+ *
+ * Device family definitions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (CDC/HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: device.h, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| Description: |
+| This file is included in other source code files |
+| and this only one place to change the included device header |
++----------------------------------------------------------------------------*/
+
+
+#include <msp430.h>
+
+#if defined (__MSP430F6638__) || defined (__MSP430F6637__) || defined (__MSP430F6636__) || \
+ defined (__MSP430F6635__) || defined (__MSP430F6634__) || defined (__MSP430F6633__) || \
+ defined (__MSP430F6632__) || defined (__MSP430F6631__) || defined (__MSP430F6630__) || \
+ defined (__MSP430F5638__) || defined (__MSP430F5637__) || defined (__MSP430F5636__) || \
+ defined (__MSP430F5635__) || defined (__MSP430F5634__) || defined (__MSP430F5633__) || \
+ defined (__MSP430F5632__) || defined (__MSP430F5631__) || defined (__MSP430F5630__)
+ #define __MSP430F563x_F663x
+#elif defined (__MSP430F5510__) || defined (__MSP430F5509__) || defined (__MSP430F5508__) || \
+ defined (__MSP430F5507__) || defined (__MSP430F5506__) || defined (__MSP430F5505__) || \
+ defined (__MSP430F5504__) || defined (__MSP430F5503__) || defined (__MSP430F5502__) || \
+ defined (__MSP430F5501__) || defined (__MSP430F5500__)
+ #define __MSP430F550x
+#elif defined (__MSP430F5529) || defined (__MSP430F5528__) || defined (__MSP430F5527__) || \
+ defined (__MSP430F5526__) || defined (__MSP430F5525__) || defined (__MSP430F5524__) || \
+ defined (__MSP430F5522__) || defined (__MSP430F5521__) || defined (__MSP430F5519__) || \
+ defined (__MSP430F5517__) || defined (__MSP430F5515__) || defined (__MSP430F5514__) || \
+ defined (__MSP430F5513__)
+ #define __MSP430F552x
+#else
+ #error Define a constant of format __MSP430Fxxxx__ within the projects preprocessor settings,
+ according to the device being used.
+#endif
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_Common/dma.c b/USB_API/USB_Common/dma.c
--- /dev/null
+++ b/USB_API/USB_Common/dma.c
@@ -0,0 +1,213 @@
+/*
+ * dma.c
+ *
+ * DMA transfer functions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (HID/CDC Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: dma.c, File Version 1.02 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2009/03/03 born |
+| RSTO 2009/04/08 Redefine memcpy() |
+| RSTO 2009/04/16 use 16 bit access to DMA regs |
+| RSTO 2009/09/18 fixed trigger selection for DMA with bit set |
+| RSTO 2009/11/03 do not transfer via DMA if length is zero |
+| MSP,Biju 2009/12/03 Review comments addressed, file versioning |
+| started |
+| RSTO 2010/01/08 added support for large mem model |
++----------------------------------------------------------------------------*/
+
+#include "../USB_Common/device.h"
+#include "../USB_Common/types.h" // Basic Type declarations
+#include "../USB_Common/defMSP430USB.h"
+#include <descriptors.h>
+#include <string.h>
+
+#ifdef __REGISTER_MODEL__
+/* for IAR */
+# if __REGISTER_MODEL__ == __REGISTER_MODEL_REG20__
+# define __DMA_ACCESS_REG__ (void __data20 *)
+# else
+# define __DMA_ACCESS_REG__ (unsigned short)
+# endif
+#else
+/* for CCS */
+# define __DMA_ACCESS_REG__ (__SFR_FARPTR)(unsigned long)
+#endif
+
+//function pointers
+VOID *(*USB_TX_memcpy)(VOID * dest, const VOID * source, size_t count);
+VOID *(*USB_RX_memcpy)(VOID * dest, const VOID * source, size_t count);
+
+VOID * memcpyDMA0(VOID * dest, const VOID * source, size_t count);
+VOID * memcpyDMA1(VOID * dest, const VOID * source, size_t count);
+VOID * memcpyDMA2(VOID * dest, const VOID * source, size_t count);
+
+// NOTE: this functin works only with data in the area <64k (small memory model)
+VOID * memcpyV(VOID * dest, const VOID * source, size_t count)
+{
+ WORD i;
+ volatile BYTE bTmp;
+ for (i=0; i<count; i++)
+ {
+ bTmp = *((BYTE*)source +i);
+ *((BYTE*)dest +i) = bTmp;
+ }
+ return dest;
+}
+
+//this function inits the DMA
+VOID USB_initMemcpy(VOID)
+{
+ USB_TX_memcpy = memcpyV;
+ USB_RX_memcpy = memcpyV;
+
+ switch (USB_DMA_CHAN)
+ {
+ case 0:
+ DMACTL0 &= ~DMA0TSEL_31; // DMA0 is triggered by DMAREQ
+ DMACTL0 |= DMA0TSEL_0; // DMA0 is triggered by DMAREQ
+ DMA0CTL = (DMADT_1 + DMASBDB + DMASRCINCR_3 + // configure block transfer (byte-wise) with increasing source
+ DMADSTINCR_3 ); // and destination address
+ DMACTL4 |= ENNMI; // enable NMI interrupt
+ USB_TX_memcpy = memcpyDMA0;
+ USB_RX_memcpy = memcpyDMA0;
+ break;
+ case 1:
+ DMACTL0 &= ~DMA1TSEL_31; // DMA1 is triggered by DMAREQ
+ DMACTL0 |= DMA1TSEL_0; // DMA1 is triggered by DMAREQ
+ DMA1CTL = (DMADT_1 + DMASBDB + DMASRCINCR_3 + // configure block transfer (byte-wise) with increasing source
+ DMADSTINCR_3 ); // and destination address
+ DMACTL4 |= ENNMI; // enable NMI interrupt
+ USB_TX_memcpy = memcpyDMA1;
+ USB_RX_memcpy = memcpyDMA1;
+ break;
+ case 2:
+ DMACTL0 &= ~DMA2TSEL_31; // DMA2 is triggered by DMAREQ
+ DMACTL0 |= DMA2TSEL_0; // DMA2 is triggered by DMAREQ
+ DMA2CTL = (DMADT_1 + DMASBDB + DMASRCINCR_3 + // configure block transfer (byte-wise) with increasing source
+ DMADSTINCR_3 ); // and destination address
+ DMACTL4 |= ENNMI; // enable NMI interrupt
+ USB_TX_memcpy = memcpyDMA2;
+ USB_RX_memcpy = memcpyDMA2;
+ break;
+ }
+}
+
+// this functions starts DMA transfer to/from USB memory into/from RAM
+// Using DMA0
+// Support only for data in <64k memory area.
+VOID * memcpyDMA0(VOID * dest, const VOID * source, size_t count)
+{
+ if (count == 0) // do nothing if zero bytes to transfer
+ {
+ return dest;
+ }
+
+ DMA0DA = __DMA_ACCESS_REG__ dest; // set destination for DMAx
+ DMA0SA = __DMA_ACCESS_REG__ source; // set source for DMAx
+ DMA0SZ = count; // how many bytes to transfer
+
+ DMA0CTL |= DMAEN; // enable DMAx
+ DMA0CTL |= DMAREQ; // trigger DMAx
+
+ //wait for DMA transfer finished
+ while (!(DMA0CTL & DMAIFG));
+
+ DMA0CTL &= ~DMAEN; // disable DMAx
+ return dest;
+}
+
+// this functions starts DMA transfer to/from USB memory into/from RAM
+// Using DMA1
+// Support only for data in <64k memory area.
+VOID * memcpyDMA1(VOID * dest, const VOID * source, size_t count)
+{
+ if (count == 0) // do nothing if zero bytes to transfer
+ {
+ return dest;
+ }
+
+ DMA1DA = __DMA_ACCESS_REG__ dest; // set destination for DMAx
+ DMA1SA = __DMA_ACCESS_REG__ source; // set source for DMAx
+ DMA1SZ = count; // how many bytes to transfer
+
+ DMA1CTL |= DMAEN; // enable DMAx
+ DMA1CTL |= DMAREQ; // trigger DMAx
+
+ //wait for DMA transfer finished
+ while (!(DMA1CTL & DMAIFG));
+
+ DMA1CTL &= ~DMAEN; // disable DMAx
+ return dest;
+}
+
+// this functions starts DMA transfer to/from USB memory into/from RAM
+// Using DMA2
+// Support only for data in <64k memory area.
+VOID * memcpyDMA2(VOID * dest, const VOID * source, size_t count)
+{
+ if (count == 0) // do nothing if zero bytes to transfer
+ {
+ return dest;
+ }
+
+ DMA2DA = __DMA_ACCESS_REG__ dest; // set destination for DMAx
+ DMA2SA = __DMA_ACCESS_REG__ source; // set source for DMAx
+ DMA2SZ = count; // how many bytes to transfer
+
+ DMA2CTL |= DMAEN; // enable DMAx
+ DMA2CTL |= DMAREQ; // trigger DMAx
+
+ //wait for DMA transfer finished
+ while (!(DMA2CTL & DMAIFG));
+
+ DMA2CTL &= ~DMAEN; // disable DMAx
+ return dest;
+}
+
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_Common/types.h b/USB_API/USB_Common/types.h
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * types.h
+ *
+ * Type definitions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+ /*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (CDC/HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: types.h, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2008/09/03 born |
+| RSTO 2009/07/17 Define __data16 for CCS |
+| |
++----------------------------------------------------------------------------*/
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef __TI_COMPILER_VERSION__
+#define __no_init
+#define __data16
+#endif
+
+/*----------------------------------------------------------------------------+
+| Include files |
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| Function Prototype |
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| Type Definition & Macro |
++----------------------------------------------------------------------------*/
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef short SHORT;
+typedef unsigned short USHORT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef void VOID;
+typedef unsigned long HANDLE;
+typedef char * PSTR;
+typedef int BOOL;
+typedef double DOUBLE;
+typedef unsigned char BYTE;
+typedef unsigned char* PBYTE;
+typedef unsigned int WORD;
+typedef unsigned long DWORD;
+typedef unsigned long* PDWORD;
+
+#define SUCCESS 0
+#define FAILURE 1
+#define VOID void
+
+// DEVICE_REQUEST Structure
+typedef struct _tDEVICE_REQUEST
+{
+ BYTE bmRequestType; // See bit definitions below
+ BYTE bRequest; // See value definitions below
+ WORD wValue; // Meaning varies with request type
+ WORD wIndex; // Meaning varies with request type
+ WORD wLength; // Number of bytes of data to transfer
+} tDEVICE_REQUEST, *ptDEVICE_REQUEST;
+
+typedef struct _tDEVICE_REQUEST_COMPARE
+{
+ BYTE bmRequestType; // See bit definitions below
+ BYTE bRequest; // See value definitions below
+ BYTE bValueL; // Meaning varies with request type
+ BYTE bValueH; // Meaning varies with request type
+ BYTE bIndexL; // Meaning varies with request type
+ BYTE bIndexH; // Meaning varies with request type
+ BYTE bLengthL; // Number of bytes of data to transfer (LSByte)
+ BYTE bLengthH; // Number of bytes of data to transfer (MSByte)
+ BYTE bCompareMask; // MSB is bRequest, if set 1, bRequest should be matched
+ VOID (*pUsbFunction)(VOID); // function pointer
+} tDEVICE_REQUEST_COMPARE, *ptDEVICE_REQUEST_COMPARE;
+
+//----------------------------------------------------------------------------
+typedef enum
+{
+ STATUS_ACTION_NOTHING,
+ STATUS_ACTION_DATA_IN,
+ STATUS_ACTION_DATA_OUT
+} tSTATUS_ACTION_LIST;
+
+typedef enum
+{
+ DISABLE,
+ ENABLE
+} tSTATUS_EN_DISABLED;
+
+typedef enum
+{
+ FALSE,
+ TRUE
+} tBOOL;
+
+/*----------------------------------------------------------------------------+
+| Constant Definition |
++----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------+
+| End of header file |
++----------------------------------------------------------------------------*/
+#ifdef __cplusplus
+}
+#endif
+#endif /* _TYPES_H_ */
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_Common/usb.c b/USB_API/USB_Common/usb.c
--- /dev/null
+++ b/USB_API/USB_Common/usb.c
@@ -0,0 +1,1323 @@
+/*
+ * usb.c
+ *
+ * Common USB functions
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (CDC/HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: usb.c, File Version 1.02 2010/06/17 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2008/09/03 born |
+| RSTO 2008/12/23 enhancements of CDC API |
+| RSTO 2009/01/12 enhancements for USB serial number |
+| RSTO 2009/05/15 added USB_connectionState() |
+| RSTO 2009/07/17 added __data16 qualifier for USB buffers |
+| RSTO 2009/08/04 workaround for PLL start up problem |
+| MSP,Biju 2009/10/20 Changes for composite support |
+| RSTO 2009/10/21 updated USB_InitSerialStringDescriptor() |
+| RSTO 2009/11/05 updated USB_connectionState() |
+| MSP,Biju 2010/07/15 Updated for MSC |
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| Include files |
++----------------------------------------------------------------------------*/
+
+#include "../USB_Common/device.h"
+#include "../USB_Common/types.h" // Basic Type declarations
+#include "../USB_Common/defMSP430USB.h"
+#include "../USB_Common/usb.h" // USB-specific Data Structures
+#include "../USB_CDC_API/UsbCdc.h"
+#include "../USB_HID_API/UsbHidReq.h"
+#include "../USB_MSC_API/UsbMscScsi.h"
+#include <descriptors.h>
+
+#include <HAL_UCS.h>
+#include <HAL_TLV.h>
+#include <string.h>
+
+/*----------------------------------------------------------------------------+
+ | Internal Constant Definition |
+ +----------------------------------------------------------------------------*/
+#define NO_MORE_DATA 0xFFFF
+#define EPBCT_NAK 0x80
+#define EPCNF_TOGLE 0x20
+
+#define DIRECTION_IN 0x80
+#define DIRECTION_OUT 0x00
+
+/*----------------------------------------------------------------------------+
+| Internal Variables |
++----------------------------------------------------------------------------*/
+
+static BYTE bConfigurationNumber; // Set to 1 when USB device has been
+ // configured, set to 0 when unconfigured
+
+static BYTE bInterfaceNumber; // interface number
+
+WORD wBytesRemainingOnIEP0; // For endpoint zero transmitter only
+ // Holds count of bytes remaining to be
+ // transmitted by endpoint 0. A value
+ // of 0 means that a 0-length data packet
+ // A value of 0xFFFF means that transfer
+ // is complete.
+
+WORD wBytesRemainingOnOEP0; // For endpoint zero transmitter only
+ // Holds count of bytes remaining to be
+ // received by endpoint 0. A value
+ // of 0 means that a 0-length data packet
+ // A value of 0xFFFF means that transfer
+ // is complete.
+
+static PBYTE pbIEP0Buffer; // A buffer pointer to input end point 0
+ // Data sent back to host is copied from
+ // this pointed memory location
+
+static PBYTE pbOEP0Buffer; // A buffer pointer to output end point 0
+ // Data sent from host is copied to
+ // this pointed memory location
+
+static BYTE bHostAskMoreDataThanAvailable=0;
+
+BYTE abUsbRequestReturnData[USB_RETURN_DATA_LENGTH];
+BYTE abUsbRequestIncomingData[USB_RETURN_DATA_LENGTH];
+
+__no_init BYTE abramSerialStringDescriptor[34];
+
+BYTE bStatusAction;
+BYTE bFunctionSuspended=FALSE; // TRUE if function is suspended
+BYTE bEnumerationStatus = 0; //is 0 if not enumerated
+
+static BYTE bRemoteWakeup;
+
+WORD wUsbEventMask; //used by USB_getEnabledEvents() and USB_setEnabledEvents()
+
+#ifdef _MSC_
+extern void USBMSC_reset(void);
+void MscResetData();
+extern BOOL bMcsCommandSupported;
+extern BOOL isMSCConfigured;
+
+extern BYTE bMscResetRequired;
+#endif
+
+/*----------------------------------------------------------------------------+
+| Global Variables |
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| Hardware Related Structure Definition |
++----------------------------------------------------------------------------*/
+
+#ifdef __IAR_SYSTEMS_ICC__
+
+#pragma location = 0x2380
+__no_init tDEVICE_REQUEST __data16 tSetupPacket;
+
+#pragma location = 0x0920
+__no_init tEDB0 __data16 tEndPoint0DescriptorBlock;
+
+#pragma location = 0x23C8
+__no_init tEDB __data16 tInputEndPointDescriptorBlock[7];
+
+#pragma location = 0x2388
+__no_init tEDB __data16 tOutputEndPointDescriptorBlock[7];
+
+#pragma location = 0x2378
+__no_init BYTE __data16 abIEP0Buffer[EP0_MAX_PACKET_SIZE];
+
+#pragma location = 0x2370
+__no_init BYTE __data16 abOEP0Buffer[EP0_MAX_PACKET_SIZE];
+
+#pragma location = OEP1_X_BUFFER_ADDRESS
+ __no_init BYTE __data16 pbXBufferAddressEp1[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP1_Y_BUFFER_ADDRESS
+ __no_init BYTE __data16 pbYBufferAddressEp1[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP1_X_BUFFER_ADDRESS
+ __no_init BYTE __data16 pbXBufferAddressEp81[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP1_Y_BUFFER_ADDRESS
+ __no_init BYTE __data16 pbYBufferAddressEp81[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP2_X_BUFFER_ADDRESS
+ __no_init BYTE __data16 pbXBufferAddressEp2[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP2_Y_BUFFER_ADDRESS
+ __no_init BYTE __data16 pbYBufferAddressEp2[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP2_X_BUFFER_ADDRESS
+ __no_init BYTE __data16 pbXBufferAddressEp82[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP2_Y_BUFFER_ADDRESS
+ __no_init BYTE __data16 pbYBufferAddressEp82[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP3_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp3[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP3_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp3[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP3_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp83[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP3_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp83[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP4_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp4[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP4_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp4[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP4_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp84[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP4_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp84[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP5_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp5[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP5_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp5[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP5_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp85[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP5_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp85[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP6_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp6[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP6_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp6[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP6_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp86[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP6_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp86[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP7_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp7[EP_MAX_PACKET_SIZE];
+
+#pragma location = OEP7_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp7[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP7_X_BUFFER_ADDRESS
+__no_init BYTE __data16 pbXBufferAddressEp87[EP_MAX_PACKET_SIZE];
+
+#pragma location = IEP7_Y_BUFFER_ADDRESS
+__no_init BYTE __data16 pbYBufferAddressEp87[EP_MAX_PACKET_SIZE];
+
+
+
+#endif
+
+#ifdef __TI_COMPILER_VERSION__
+extern __no_init tDEVICE_REQUEST tSetupPacket;
+extern __no_init tEDB0 tEndPoint0DescriptorBlock;
+extern __no_init tEDB tInputEndPointDescriptorBlock[7];
+extern __no_init tEDB tOutputEndPointDescriptorBlock[7];
+extern __no_init BYTE abIEP0Buffer[EP0_MAX_PACKET_SIZE];
+extern __no_init BYTE abOEP0Buffer[EP0_MAX_PACKET_SIZE];
+extern __no_init BYTE pbXBufferAddressEp1[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp1[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbXBufferAddressEp81[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp81[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbXBufferAddressEp2[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp2[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbXBufferAddressEp82[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp82[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbXBufferAddressEp3[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp3[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbXBufferAddressEp83[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp83[EP_MAX_PACKET_SIZE];
+
+extern __no_init BYTE pbXBufferAddressEp4[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp4[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbXBufferAddressEp84[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp84[EP_MAX_PACKET_SIZE];
+
+extern __no_init BYTE pbXBufferAddressEp5[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp5[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbXBufferAddressEp85[EP_MAX_PACKET_SIZE];
+extern __no_init BYTE pbYBufferAddressEp85[EP_MAX_PACKET_SIZE];
+
+#endif
+
+VOID CdcResetData();
+VOID HidResetData();
+
+VOID USB_InitSerialStringDescriptor(VOID);
+VOID USB_initMemcpy(VOID);
+
+//----------------------------------------------------------------------------
+BYTE USB_init(VOID)
+{
+ WORD bGIE = __get_SR_register() &GIE; //save interrupt status
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+
+ // configuration of USB module
+ USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
+
+ USBPHYCTL = PUSEL; // use DP and DM as USB terminals (not needed because an external PHY is connected to port 9)
+
+ USBPWRCTL = VUSBEN + SLDOAON; // enable primary and secondary LDO (3.3 and 1.8 V)
+ {
+ volatile unsigned int i;
+ for (i =0; i < USB_MCLK_FREQ/1000*2/10; i++); // wait some time for LDOs (1ms delay)
+ }
+
+ USBPWRCTL = VUSBEN + SLDOAON + VBONIE; // enable interrupt VBUSon
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+
+ //reset events mask
+ wUsbEventMask = 0;
+
+ //init Serial Number
+#if (USB_STR_INDEX_SERNUM != 0)
+ USB_InitSerialStringDescriptor();
+#endif
+
+ // init memcpy() function: DMA or non-DMA
+ USB_initMemcpy();
+#ifdef _MSC_
+ MscResetCtrlLun();
+#endif
+
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSB_succeed;
+}
+
+//----------------------------------------------------------------------------
+// This function will be compiled only if
+#if (USB_STR_INDEX_SERNUM != 0)
+VOID USB_InitSerialStringDescriptor(VOID)
+{
+ BYTE i,j,hexValue;
+ PBYTE pbSerNum;
+ BYTE bBytes;
+
+ j=1; // we start with second byte, first byte (lenght) will be filled later
+ pbSerNum=0;
+ abramSerialStringDescriptor[j++] = DESC_TYPE_STRING;
+
+ // TLV access Function Call
+ Get_TLV_Info(TLV_DIERECORD, 0, (uint8_t *)&bBytes, (uint16_t **)&pbSerNum); //The die record used for serial number
+ if (bBytes == 0) // no serial number available
+ {
+ // use 00 as serial number = no serial number available
+ abramSerialStringDescriptor[0] = 4; //length
+ abramSerialStringDescriptor[j++] = 0; // no serial number available
+ abramSerialStringDescriptor[j++] = 0; // no serial number available
+ }
+ else
+ {
+ for(i=0; (i<bBytes)&&(i<8); i++,pbSerNum++)
+ {
+ hexValue = (*pbSerNum & 0xF0)>> 4;
+ if(hexValue < 10 ) abramSerialStringDescriptor[j++] = (hexValue + '0');
+ else abramSerialStringDescriptor[j++] = (hexValue + 55);
+ abramSerialStringDescriptor[j++] = 0x00; // needed for UNI-Code
+
+ hexValue = (*pbSerNum & 0x0F);
+ if(hexValue < 10 ) abramSerialStringDescriptor[j++] = (hexValue + '0');
+ else abramSerialStringDescriptor[j++] = (hexValue + 55);
+ abramSerialStringDescriptor[j++] = 0x00; // needed for UNI-Code
+ }
+ abramSerialStringDescriptor[0] = i*4 +2; // calculate the length
+ }
+}
+#endif
+
+//----------------------------------------------------------------------------
+
+BYTE USB_enable()
+{
+ volatile unsigned int i;
+ volatile unsigned int j = 0;
+
+ if (!(USBPWRCTL & USBBGVBV)) // check USB Bandgap and VBUS valid
+ {
+ return kUSB_generalError;
+ }
+
+ if ((USBCNF & USB_EN) &&
+ (USBPLLCTL & UPLLEN))
+ {
+ return kUSB_succeed; // exit if PLL is already enalbed
+ }
+
+ USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
+ XT2_Start(XT2DRIVE_3);
+ USBPLLDIVB = USB_XT_FREQ; // Settings desired frequency
+
+ USBPLLCTL = UPFDEN + UPLLEN; // Select XT1 as Ref / Select PLL for USB / Discrim. on, enable PLL
+
+ //Wait some time till PLL is settled
+ do
+ {
+ USBPLLIR = 0x0000; // make sure no interrupts can occur on PLL-module
+
+#ifdef __MSP430F6638
+ //wait 1 ms till enable USB
+ for (i =0; i < USB_MCLK_FREQ/1000*1/10; i++);
+#else
+ //wait 1/2 ms till enable USB
+ for (i =0; i < USB_MCLK_FREQ/1000* 1/2 /10; i++);
+#endif
+
+ if (j++ > 10)
+ {
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+ return kUSB_generalError;
+ }
+ }while (USBPLLIR != 0);
+
+ USBCNF |= USB_EN; // enable USB module
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+ return kUSB_succeed;
+}
+
+/*
+Disables the USB module and PLL.
+*/
+BYTE USB_disable(VOID)
+{
+ USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
+ USBCNF = 0; // disable USB module
+ USBPLLCTL &= ~UPLLEN; // disable PLL
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+ bEnumerationStatus = 0x00; // device is not enumerated
+ bFunctionSuspended = FALSE;// device is not suspended
+ return kUSB_succeed;
+}
+
+/*
+Enables/disables various USB events.
+*/
+BYTE USB_setEnabledEvents(WORD events)
+{
+ wUsbEventMask = events;
+ return kUSB_succeed;
+}
+
+/*
+Returns which events are enabled and which are disabled.
+*/
+WORD USB_getEnabledEvents()
+{
+ return wUsbEventMask;
+}
+
+/*
+Reset USB-SIE and global variables.
+*/
+BYTE USB_reset()
+{
+ int i;
+ USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
+
+ //reset should be on the bus after this!
+ bEnumerationStatus = 0x00; // Device not enumerated yet
+ bFunctionSuspended = FALSE; // Device is not in suspend mode
+
+ bRemoteWakeup = DISABLE;
+
+ bConfigurationNumber = 0x00; // device unconfigured
+ bInterfaceNumber = 0x00;
+
+ // FRSTE handling:
+ // Clear FRSTE in the RESRIFG interrupt service routine before re-configuring USB control registers.
+ // Set FRSTE at the beginning of SUSRIFG, SETUP, IEPIFG.EP0 and OEPIFG.EP0 interrupt service routines.
+ USBCTL = 0; // Function Reset Connection disable (FRSTE)
+
+ wBytesRemainingOnIEP0 = NO_MORE_DATA;
+ wBytesRemainingOnOEP0 = NO_MORE_DATA;
+ bStatusAction = STATUS_ACTION_NOTHING;
+
+ //The address reset normally will be done automatically during bus function reset
+ USBFUNADR = 0x00; // reset address of USB device (unconfigured)
+
+ /* Set settings for EP0 */
+ // NAK both 0 endpoints and enable endpoint 0 interrupt
+ tEndPoint0DescriptorBlock.bIEPBCNT = EPBCNT_NAK;
+ tEndPoint0DescriptorBlock.bOEPBCNT = EPBCNT_NAK;
+ tEndPoint0DescriptorBlock.bIEPCNFG = EPCNF_USBIE | EPCNF_UBME | EPCNF_STALL; // 8 byte data packet
+ tEndPoint0DescriptorBlock.bOEPCNFG = EPCNF_USBIE | EPCNF_UBME | EPCNF_STALL; // 8 byte data packet
+
+ USBOEPIE = USB_OUTEP_INT_EN;
+ USBIEPIE = USB_INEP_INT_EN;
+
+ // loop for initialization all of used enpoints
+ for(i=0; i < (CDC_NUM_INTERFACES + HID_NUM_INTERFACES + MSC_NUM_INTERFACES); i++)
+ {
+ BYTE edbIndex = stUsbHandle[i].edb_Index;
+
+ /* Set settings for IEPx */
+ tInputEndPointDescriptorBlock[edbIndex].bEPCNF = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF; //double buffering
+ tInputEndPointDescriptorBlock[edbIndex].bEPBBAX = (BYTE)(((stUsbHandle[i].iep_X_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
+ tInputEndPointDescriptorBlock[edbIndex].bEPBBAY = (BYTE)(((stUsbHandle[i].iep_Y_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
+ tInputEndPointDescriptorBlock[edbIndex].bEPBCTX = EPBCNT_NAK;
+ tInputEndPointDescriptorBlock[edbIndex].bEPBCTY = EPBCNT_NAK;
+ tInputEndPointDescriptorBlock[edbIndex].bEPSIZXY = MAX_PACKET_SIZE;
+
+ /* Set settings for OEPx */
+ tOutputEndPointDescriptorBlock[edbIndex].bEPCNF = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF ; //double buffering
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBBAX = (BYTE)(((stUsbHandle[i].oep_X_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBBAY = (BYTE)(((stUsbHandle[i].oep_Y_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0x00;
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0x00;
+ tOutputEndPointDescriptorBlock[edbIndex].bEPSIZXY = MAX_PACKET_SIZE;
+
+# ifdef _CDC_
+ /* Additional interrupt end point for CDC */
+ if(stUsbHandle[i].dev_Class == CDC_CLASS)
+ {
+ // The decriptor tool always generates the managemnet endpoint before the data endpoint
+ tInputEndPointDescriptorBlock[edbIndex-1].bEPCNF = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF; //double buffering
+ tInputEndPointDescriptorBlock[edbIndex-1].bEPBBAX = (BYTE)(((stUsbHandle[i].intepEP_X_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
+ tInputEndPointDescriptorBlock[edbIndex-1].bEPBBAY = (BYTE)(((stUsbHandle[i].intepEP_Y_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
+ tInputEndPointDescriptorBlock[edbIndex-1].bEPBCTX = EPBCNT_NAK;
+ tInputEndPointDescriptorBlock[edbIndex-1].bEPBCTY = EPBCNT_NAK;
+ tInputEndPointDescriptorBlock[edbIndex-1].bEPSIZXY = MAX_PACKET_SIZE;
+ }
+# endif
+ }
+
+# ifdef _HID_
+ HidResetData(); // reset HID specific data structures
+# endif // _HID_
+
+# ifdef _MSC_
+ isMSCConfigured = FALSE;
+ USBMSC_reset();
+ MscResetData();
+# endif
+
+# ifdef _CDC_
+ CdcResetData(); // reset CDC specific data structures
+# endif // _CDC_
+
+ USBCTL = FEN; // enable function
+ USBIFG = 0; // make sure no interrupts are pending
+
+ USBIE = SETUPIE | RSTRIE | SUSRIE; // enable USB specific interrupts (setup, reset, suspend)
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+ return kUSB_succeed;
+}
+
+/*
+Instruct USB module to make itself available to the PC for connection, by pulling PUR high.
+*/
+BYTE USB_connect()
+{
+ USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
+ USBCNF |= PUR_EN; // generate rising edge on DP -> the host enumerates our device as full speed device
+ USBPWRCTL |= VBOFFIE; // enable interrupt VUSBoff
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+
+ // after this the enumeration may take place
+ __no_operation();
+ __no_operation();
+ __no_operation();
+ __no_operation();
+ __no_operation();
+ __no_operation();
+ __no_operation();
+
+ return kUSB_succeed;
+}
+
+/*
+Force a disconnect from the PC by pulling PUR low.
+*/
+BYTE USB_disconnect()
+{
+ USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
+ USBCNF &= ~PUR_EN; // disconnect pull up resistor - logical disconnect from HOST
+ USBPWRCTL &= ~VBOFFIE; // disable interrupt VUSBoff
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+ bEnumerationStatus = 0; // not enumerated
+ bFunctionSuspended = FALSE; // device is not suspended
+ return kUSB_succeed;
+}
+
+/*
+Force a remote wakeup of the USB host.
+*/
+BYTE USB_forceRemoteWakeup()
+{
+ if (bFunctionSuspended == FALSE) // device is not suspended
+ {
+ return kUSB_NotSuspended;
+ }
+ if(bRemoteWakeup == ENABLE)
+ {
+ volatile unsigned int i;
+ USBCTL |= RWUP; // USB - Device Remote Wakeup Request - this bit is self-cleaned
+ return kUSB_succeed;
+ }
+ return kUSB_generalError;
+}
+
+/*
+Returns the status of the USB connection.
+*/
+BYTE USB_connectionInfo()
+{
+ BYTE retVal = 0;
+ if (USBPWRCTL & USBBGVBV)
+ {
+ retVal |= kUSB_vbusPresent;
+ }
+
+ if (bEnumerationStatus == ENUMERATION_COMPLETE)
+ {
+ retVal |= kUSB_Enumerated;
+ }
+
+ if (USBCNF & PUR_EN)
+ {
+ retVal |= kUSB_purHigh;
+ }
+
+ if (bFunctionSuspended == TRUE)
+ {
+ retVal |= kUSB_suspended;
+ }
+ else
+ {
+ retVal |= kUSB_NotSuspended;
+ }
+ return retVal;
+}
+
+/*
+Returns the state of the USB connection.
+*/
+BYTE USB_connectionState()
+{
+ // If no VBUS present
+ if (!(USBPWRCTL & USBBGVBV))
+ {
+ return ST_USB_DISCONNECTED;
+ }
+
+ // If VBUS present, but PUR is low
+ if ((USBPWRCTL & USBBGVBV)&&(!(USBCNF & PUR_EN)))
+ {
+ return ST_USB_CONNECTED_NO_ENUM;
+ }
+
+ // If VBUS present, PUR is high, and enumeration is complete, and not suspended
+ if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
+ && (bEnumerationStatus == ENUMERATION_COMPLETE)
+ && (!(bFunctionSuspended == TRUE)))
+ {
+ return ST_ENUM_ACTIVE;
+ }
+
+ // If VBUS present, PUR is high, and enumeration is NOT complete, and suspended
+ if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
+ && (!(bEnumerationStatus == ENUMERATION_COMPLETE))
+ && (bFunctionSuspended == TRUE))
+ {
+ return ST_NOENUM_SUSPENDED;
+ }
+
+ // If VBUS present, PUR is high, and enumeration is complete, and suspended
+ if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
+ && (bEnumerationStatus == ENUMERATION_COMPLETE)
+ && (bFunctionSuspended == TRUE))
+ {
+ return ST_ENUM_SUSPENDED;
+ }
+
+ // If VBUS present, PUR is high, but no enumeration yet
+ if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
+ && (!(bEnumerationStatus == ENUMERATION_COMPLETE)))
+ {
+ return ST_ENUM_IN_PROGRESS;
+ }
+
+ return ST_ERROR;
+}
+
+//----------------------------------------------------------------------------
+
+BYTE USB_suspend(VOID)
+{
+
+ bFunctionSuspended = TRUE;
+ USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
+ USBCTL |= FRSTE; // Function Reset Connection Enable
+ USBIFG &= ~SUSRIFG; // clear interrupt flag
+
+ if(USB_DISABLE_XT_SUSPEND)
+ {
+ if (USB_PLL_XT == 2)
+ {
+ USBPLLCTL &= ~UPLLEN; // disable PLL
+ UCSCTL6 |= XT2OFF; // disable XT2
+ }
+ else
+ {
+ USBPLLCTL &= ~UPLLEN; // disable PLL
+ UCSCTL6 |= XT1OFF;
+ }
+ }
+
+ USBIE = RESRIE; // disable USB specific interrupts (setup, suspend, reset), enable resume.
+ // If the reset occured during device in suspend, the resume-interrupt will come, after - reset interrupt
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+
+ return kUSB_succeed;
+}
+
+//----------------------------------------------------------------------------
+
+BYTE USB_resume(VOID)
+{
+ USB_enable(); // enable PLL
+
+ USBIFG &= ~(RESRIFG | SUSRIFG); // clear interrupt flags
+ USBIE = SETUPIE | RSTRIE | SUSRIE; // enable USB specific interrupts (setup, reset, suspend)
+
+ bFunctionSuspended = FALSE;
+ return kUSB_succeed;
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbStallEndpoint0(VOID)
+{
+ tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL;
+ tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbClearOEP0ByteCount(VOID)
+{
+ tEndPoint0DescriptorBlock.bOEPBCNT = 0x00;
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbStallOEP0(VOID)
+{
+ // in standard USB request, there is not control write request with data stage
+ // control write, stall output endpoint 0
+ // wLength should be 0 in all cases
+ tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbSendNextPacketOnIEP0(VOID)
+{
+ BYTE bPacketSize,bIndex;
+
+ // First check if there are bytes remaining to be transferred
+ if(wBytesRemainingOnIEP0 != NO_MORE_DATA)
+ {
+ if(wBytesRemainingOnIEP0 > EP0_PACKET_SIZE)
+ {
+ // More bytes are remaining than will fit in one packet
+ // there will be More IN Stage
+ bPacketSize = EP0_PACKET_SIZE;
+ wBytesRemainingOnIEP0 -= EP0_PACKET_SIZE;
+ bStatusAction = STATUS_ACTION_DATA_IN;
+ }
+ else if (wBytesRemainingOnIEP0 < EP0_PACKET_SIZE)
+ {
+ // The remaining data will fit in one packet.
+ // This case will properly handle wBytesRemainingOnIEP0 == 0
+ bPacketSize = (BYTE)wBytesRemainingOnIEP0;
+ wBytesRemainingOnIEP0 = NO_MORE_DATA; // No more data need to be Txed
+ bStatusAction = STATUS_ACTION_NOTHING;
+ }
+ else
+ {
+ bPacketSize = EP0_PACKET_SIZE;
+ if(bHostAskMoreDataThanAvailable == TRUE)
+ {
+ wBytesRemainingOnIEP0 = 0;
+ bStatusAction = STATUS_ACTION_DATA_IN;
+ }
+ else
+ {
+ wBytesRemainingOnIEP0 = NO_MORE_DATA;
+ bStatusAction = STATUS_ACTION_NOTHING;
+ }
+ }
+
+ for(bIndex=0; bIndex<bPacketSize; bIndex++)
+ {
+ abIEP0Buffer[bIndex] = *pbIEP0Buffer;
+ pbIEP0Buffer++;
+ }
+ tEndPoint0DescriptorBlock.bIEPBCNT = bPacketSize;
+ }
+ else
+ {
+ bStatusAction = STATUS_ACTION_NOTHING;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbSendDataPacketOnEP0(PBYTE pbBuffer)
+{
+ WORD wTemp;
+
+ pbIEP0Buffer = pbBuffer;
+ wTemp = tSetupPacket.wLength;
+
+ // Limit transfer size to wLength if needed
+ // this prevent USB device sending 'more than require' data back to host
+ if(wBytesRemainingOnIEP0 >= wTemp)
+ {
+ wBytesRemainingOnIEP0 = wTemp;
+ bHostAskMoreDataThanAvailable = FALSE;
+ }
+ else
+ {
+ bHostAskMoreDataThanAvailable = TRUE;
+ }
+ usbSendNextPacketOnIEP0();
+}
+
+//----------------------------------------------------------------------------
+VOID usbReceiveNextPacketOnOEP0(VOID)
+{
+ BYTE bIndex,bByte;
+
+ bByte = tEndPoint0DescriptorBlock.bOEPBCNT & EPBCNT_BYTECNT_MASK;
+
+ if(wBytesRemainingOnOEP0 >= (WORD)bByte)
+ {
+ for(bIndex=0;bIndex<bByte;bIndex++)
+ {
+ *pbOEP0Buffer = abOEP0Buffer[bIndex];
+ pbOEP0Buffer++;
+ }
+ wBytesRemainingOnOEP0 -= (WORD)bByte;
+
+ // clear the NAK bit for next packet
+ if(wBytesRemainingOnOEP0 > 0)
+ {
+ usbClearOEP0ByteCount();
+ bStatusAction = STATUS_ACTION_DATA_OUT;
+ }
+ else
+ {
+ usbStallOEP0();
+ bStatusAction = STATUS_ACTION_NOTHING;
+ }
+ }
+ else
+ {
+ usbStallOEP0();
+ bStatusAction = STATUS_ACTION_NOTHING;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbReceiveDataPacketOnEP0(PBYTE pbBuffer)
+{
+
+ pbOEP0Buffer = pbBuffer;
+
+ wBytesRemainingOnOEP0 = tSetupPacket.wLength;
+ bStatusAction = STATUS_ACTION_DATA_OUT;
+
+ usbClearOEP0ByteCount();
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbSendZeroLengthPacketOnIEP0(VOID)
+{
+ wBytesRemainingOnIEP0 = NO_MORE_DATA;
+ bStatusAction = STATUS_ACTION_NOTHING;
+ tEndPoint0DescriptorBlock.bIEPBCNT = 0x00;
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbClearEndpointFeature(VOID)
+{
+ BYTE bEndpointNumber;
+
+ // EP is from EP1 to EP7 while C language start from 0
+ bEndpointNumber = (tSetupPacket.wIndex & EP_DESC_ADDR_EP_NUM);
+ if(bEndpointNumber == 0x00) usbSendZeroLengthPacketOnIEP0();
+ else
+ {
+ bEndpointNumber--;
+ if(bEndpointNumber < MAX_ENDPOINT_NUMBER)
+ {
+ if((tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN) == EP_DESC_ADDR_DIR_IN)
+ {
+#ifdef _MSC_
+ if (!bMscResetRequired) {
+#endif
+ tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF &= ~(EPCNF_STALL | EPCNF_TOGGLE );
+#ifdef _MSC_
+ }
+#endif
+# ifdef _MSC_
+ if (stUsbHandle[MSC0_INTFNUM].edb_Index == bEndpointNumber)
+ {
+ MscReadControl.bCurrentBufferXY = 0; //Set current buffer to X
+ bMcsCommandSupported = TRUE;
+ }
+# endif
+ }
+ else
+ {
+#ifdef _MSC_
+ if (!bMscResetRequired) {
+#endif
+ tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF &= ~(EPCNF_STALL | EPCNF_TOGGLE );
+#ifdef _MSC_
+ }
+#endif
+# ifdef _MSC_
+ if (stUsbHandle[MSC0_INTFNUM].edb_Index == bEndpointNumber)
+ {
+ MscWriteControl.bCurrentBufferXY = 0; //Set current buffer to X
+ bMcsCommandSupported = TRUE;
+ }
+# endif
+ }
+ usbSendZeroLengthPacketOnIEP0();
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbGetConfiguration(VOID)
+{
+ usbClearOEP0ByteCount(); // for status stage
+ wBytesRemainingOnIEP0 = 1;
+ usbSendDataPacketOnEP0((PBYTE)&bConfigurationNumber);
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbGetDeviceDescriptor(VOID)
+{
+ usbClearOEP0ByteCount();
+ wBytesRemainingOnIEP0 = SIZEOF_DEVICE_DESCRIPTOR;
+ usbSendDataPacketOnEP0((PBYTE) &abromDeviceDescriptor);
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbGetConfigurationDescriptor(VOID)
+{
+ usbClearOEP0ByteCount();
+ wBytesRemainingOnIEP0 = sizeof(abromConfigurationDescriptorGroup);
+ usbSendDataPacketOnEP0((PBYTE)&abromConfigurationDescriptorGroup);
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbGetStringDescriptor(VOID)
+{
+ WORD bIndex;
+ BYTE bVal = (BYTE)tSetupPacket.wValue;
+
+ usbClearOEP0ByteCount(); // for status stage
+#if (USB_STR_INDEX_SERNUM != 0)
+
+ if(bVal == 0x03)
+ {
+ wBytesRemainingOnIEP0 = abramSerialStringDescriptor[0];
+ usbSendDataPacketOnEP0((PBYTE)&abramSerialStringDescriptor);
+ }
+ else
+#endif
+ {
+ bIndex = 0x00;
+ while(bVal-- > 0x00) bIndex += abromStringDescriptor[bIndex];
+ wBytesRemainingOnIEP0 = abromStringDescriptor[bIndex];
+ usbSendDataPacketOnEP0((PBYTE)&abromStringDescriptor[bIndex]);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbGetInterface(VOID)
+{
+
+ // not fully supported, return one byte, zero
+ usbClearOEP0ByteCount(); // for status stage
+ wBytesRemainingOnIEP0 = 0x02;
+ abUsbRequestReturnData[0] = 0x00; // changed to report alternative setting byte
+ abUsbRequestReturnData[1] = bInterfaceNumber;
+ usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbGetDeviceStatus(VOID)
+{
+ if((abromConfigurationDescriptorGroup.abromConfigurationDescriptorGenric.mattributes &
+ CFG_DESC_ATTR_SELF_POWERED) == CFG_DESC_ATTR_SELF_POWERED)
+ {
+ abUsbRequestReturnData[0] = DEVICE_STATUS_SELF_POWER;
+ }
+ if(bRemoteWakeup == ENABLE)
+ {
+ abUsbRequestReturnData[0] |= DEVICE_STATUS_REMOTE_WAKEUP;
+ }
+ usbClearOEP0ByteCount(); // for status stage
+
+ // Return self power status and remote wakeup status
+ wBytesRemainingOnIEP0 = 2;
+ usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbGetInterfaceStatus(VOID)
+{
+ // check bIndexL for index number (not supported)
+ usbClearOEP0ByteCount(); // for status stage
+
+ // Return two zero bytes
+ wBytesRemainingOnIEP0 = 2;
+ abUsbRequestReturnData[0] = 0x00; // changed to support multiple interfaces
+ abUsbRequestReturnData[1] = bInterfaceNumber;
+ usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbGetEndpointStatus(VOID)
+{
+ BYTE bEndpointNumber;
+
+ // Endpoint number is bIndexL
+ bEndpointNumber = tSetupPacket.wIndex & EP_DESC_ADDR_EP_NUM;
+ if(bEndpointNumber == 0x00)
+ {
+ if((tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN) == EP_DESC_ADDR_DIR_IN)
+ {
+ // input endpoint 0
+ abUsbRequestReturnData[0] = (BYTE)(tEndPoint0DescriptorBlock.bIEPCNFG & EPCNF_STALL);
+ }
+ else
+ {
+ // output endpoint 0
+ abUsbRequestReturnData[0] = (BYTE)(tEndPoint0DescriptorBlock.bOEPCNFG & EPCNF_STALL);
+ }
+ abUsbRequestReturnData[0] = abUsbRequestReturnData[0] >> 3; // STALL is on bit 3
+ usbClearOEP0ByteCount(); // for status stage
+ wBytesRemainingOnIEP0 = 0x02;
+ usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
+ }
+ else
+ {
+ bEndpointNumber--;
+ // EP is from EP1 to EP7 while C language start from 0
+ // Firmware should NOT response if specified endpoint is not supported. (charpter 8)
+ if(bEndpointNumber < MAX_ENDPOINT_NUMBER)
+ {
+ if(tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN)
+ {
+ // input endpoint
+ abUsbRequestReturnData[0] = (BYTE)(tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF & EPCNF_STALL);
+ }else
+ {
+ // output endpoint
+ abUsbRequestReturnData[0] = (BYTE)(tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF & EPCNF_STALL);
+ }
+ } // no response if endpoint is not supported.
+ abUsbRequestReturnData[0] = abUsbRequestReturnData[0] >> 3; // STALL is on bit 3
+ usbClearOEP0ByteCount();
+ wBytesRemainingOnIEP0 = 0x02;
+ usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
+ }
+}
+
+//----------------------------------------------------------------------------
+VOID usbSetAddress(VOID)
+{
+ usbStallOEP0(); // control write without data stage
+
+ // bValueL contains device address
+ if(tSetupPacket.wValue < 128)
+ {
+ // hardware will update the address after status stage
+ // therefore, firmware can set the address now.
+ USBFUNADR = tSetupPacket.wValue;
+ usbSendZeroLengthPacketOnIEP0();
+ }
+ else
+ {
+ usbStallEndpoint0();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbSetConfiguration(VOID)
+{
+ usbStallOEP0(); // control write without data stage
+
+ // configuration number is in bValueL
+ // change the code if more than one configuration is supported
+ bConfigurationNumber = tSetupPacket.wValue;
+ usbSendZeroLengthPacketOnIEP0();
+
+ if (bConfigurationNumber == 1)
+ {
+ bEnumerationStatus = ENUMERATION_COMPLETE; // set device as enumerated
+ }
+ else
+ {
+ bEnumerationStatus = 0; //device is not configured == config # is zero
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbClearDeviceFeature(VOID)
+{
+ // bValueL contains feature selector
+ if(tSetupPacket.wValue == FEATURE_REMOTE_WAKEUP)
+ {
+ bRemoteWakeup = DISABLE;
+ usbSendZeroLengthPacketOnIEP0();
+ }
+ else
+ {
+ usbStallEndpoint0();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbSetDeviceFeature(VOID)
+{
+ // bValueL contains feature selector
+ if(tSetupPacket.wValue == FEATURE_REMOTE_WAKEUP)
+ {
+ bRemoteWakeup = ENABLE;
+ usbSendZeroLengthPacketOnIEP0();
+ }
+ else
+ {
+ usbStallEndpoint0();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbSetEndpointFeature(VOID)
+{
+ BYTE bEndpointNumber;
+
+ // wValue contains feature selector
+ // bIndexL contains endpoint number
+ // Endpoint number is in low byte of wIndex
+ if(tSetupPacket.wValue == FEATURE_ENDPOINT_STALL)
+ {
+ bEndpointNumber = tSetupPacket.wIndex & EP_DESC_ADDR_EP_NUM;
+ if(bEndpointNumber == 0x00) usbSendZeroLengthPacketOnIEP0(); // do nothing for endpoint 0
+ else
+ {
+ bEndpointNumber--;
+ // Firmware should NOT response if specified endpoint is not supported. (charpter 8)
+ if(bEndpointNumber < MAX_ENDPOINT_NUMBER)
+ {
+ if(tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN)
+ {
+ // input endpoint
+ tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF |= EPCNF_STALL;
+ }
+ else
+ {
+ // output endpoint
+ tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF |= EPCNF_STALL;
+ }
+ usbSendZeroLengthPacketOnIEP0();
+ } // no response if endpoint is not supported.
+ }
+ }
+ else
+ {
+ usbStallEndpoint0();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbSetInterface(VOID)
+{
+ // bValueL contains alternative setting
+ // bIndexL contains interface number
+ // change code if more than one interface is supported
+ usbStallOEP0(); // control write without data stage
+ bInterfaceNumber = tSetupPacket.wIndex;
+#ifdef _MSC_
+ tInputEndPointDescriptorBlock[stUsbHandle[MSC0_INTFNUM].edb_Index].bEPCNF &= ~(EPCNF_TOGGLE);
+ tOutputEndPointDescriptorBlock[stUsbHandle[MSC0_INTFNUM].edb_Index].bEPCNF &= ~(EPCNF_TOGGLE);
+ MscReadControl.bCurrentBufferXY = 0; //Set current buffer to X
+ MscWriteControl.bCurrentBufferXY = 0; //Set current buffer to X
+#endif
+ usbSendZeroLengthPacketOnIEP0();
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbInvalidRequest(VOID)
+{
+ // check if setup overwrite is set
+ // if set, do nothing since we might decode it wrong
+ // setup packet buffer could be modified by hardware if another setup packet
+ // was sent while we are deocding setup packet
+ if ((USBIFG & STPOWIFG) == 0x00)
+ {
+ usbStallEndpoint0();
+ }
+}
+
+typedef VOID (*tpF)(VOID);
+
+BYTE usbDecodeAndProcessUsbRequest(VOID)
+{
+ BYTE bMask,bResult,bTemp;
+ const BYTE* pbUsbRequestList;
+ BYTE bWakeUp = FALSE;
+ ptDEVICE_REQUEST ptSetupPacket = &tSetupPacket;
+ BYTE bRequestType,bRequest;
+ tpF lAddrOfFunction;
+
+ // point to beginning of the matrix
+ pbUsbRequestList = (PBYTE)&tUsbRequestList[0];
+
+ while(1)
+ {
+ bRequestType = *pbUsbRequestList++;
+ bRequest = *pbUsbRequestList++;
+
+ if(((bRequestType == 0xff) && (bRequest == 0xff)) ||
+ (tSetupPacket.bmRequestType == (USB_REQ_TYPE_INPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)) ||
+ (tSetupPacket.bmRequestType == (USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)))
+ {
+ pbUsbRequestList -= 2;
+ break;
+ }
+
+ if((bRequestType == tSetupPacket.bmRequestType) && (bRequest == tSetupPacket.bRequest))
+ {
+ // compare the first two
+ bResult = 0xc0;
+ bMask = 0x20;
+ // first two bytes matched, compare the rest
+ for(bTemp = 2; bTemp < 8; bTemp++)
+ {
+ if (*((BYTE*)ptSetupPacket + bTemp) == *pbUsbRequestList)
+ {
+ bResult |= bMask;
+ }
+ pbUsbRequestList++;
+ bMask = bMask >> 1;
+ }
+ // now we have the result
+ if((*pbUsbRequestList & bResult) == *pbUsbRequestList)
+ {
+ pbUsbRequestList -= 8;
+ break;
+ }
+ else
+ {
+ pbUsbRequestList += (sizeof(tDEVICE_REQUEST_COMPARE)-8);
+ }
+ }
+ else
+ {
+ pbUsbRequestList += (sizeof(tDEVICE_REQUEST_COMPARE)-2);
+ }
+ }
+
+ // if another setup packet comes before we have the chance to process current
+ // setup request, we return here without processing the request
+ // this check is not necessary but still kept here to reduce response(or simulation) time
+
+ if((USBIFG & STPOWIFG) != 0x00)
+ {
+ return bWakeUp;
+ }
+
+ // now we found the match and jump to the function accordingly.
+ lAddrOfFunction = ((tDEVICE_REQUEST_COMPARE*)pbUsbRequestList)->pUsbFunction;
+
+ // call function
+ (*lAddrOfFunction)();
+
+ // perform enumeration complete event:
+ // when SetAddress was called and USBADDR is not zero
+ if ((lAddrOfFunction == &usbSetAddress) && (USBFUNADR != 0))
+ {
+ bWakeUp = USB_handleEnumCompleteEvent();
+ }
+ return bWakeUp;
+}
+
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_Common/usb.h b/USB_API/USB_Common/usb.h
--- /dev/null
+++ b/USB_API/USB_Common/usb.h
@@ -0,0 +1,491 @@
+/*
+ * usb.h
+ *
+ * Common USB functions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (CDC/HID/MSC Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: Usb.h, File Version 1.04 2010/10/30 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2008/09/03 born |
+| RSTO 2008/12/23 enhancements of CDC API |
+| RSTO 2009/05/15 changed USB_connectionStatus() |
+| to USB_connectionInfo() |
+| RSTO 2009/05/26 remove kUSB_failedEnumEvent |
+| RSTO 2009/07/17 added __data16 qualifier for USB buffers |
+| MSP,Biju 2009/10/20 Composite support changes |
+| RSTO 2009/11/05 added event ST_NOENUM_SUSPENDED |
+| MSP,Biju 2009/12/28 macros DESC_TYPE_IAD added due to IAD |
+| support |
+| RSTO 2010/10/30 added kUSB_allXXXEvents |
++----------------------------------------------------------------------------*/
+
+#ifndef _USB_H_
+#define _USB_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*----------------------------------------------------------------------------+
+| Constant Definition |
++----------------------------------------------------------------------------*/
+#define USB_RETURN_DATA_LENGTH 8
+#define SIZEOF_DEVICE_REQUEST 0x08
+
+// Bit definitions for DEVICE_REQUEST.bmRequestType
+// Bit 7: Data direction
+#define USB_REQ_TYPE_OUTPUT 0x00 // 0 = Host sending data to device
+#define USB_REQ_TYPE_INPUT 0x80 // 1 = Device sending data to host
+
+// Bit 6-5: Type
+#define USB_REQ_TYPE_MASK 0x60 // Mask value for bits 6-5
+#define USB_REQ_TYPE_STANDARD 0x00 // 00 = Standard USB request
+#define USB_REQ_TYPE_CLASS 0x20 // 01 = Class specific
+#define USB_REQ_TYPE_VENDOR 0x40 // 10 = Vendor specific
+
+// Bit 4-0: Recipient
+#define USB_REQ_TYPE_RECIP_MASK 0x1F // Mask value for bits 4-0
+#define USB_REQ_TYPE_DEVICE 0x00 // 00000 = Device
+#define USB_REQ_TYPE_INTERFACE 0x01 // 00001 = Interface
+#define USB_REQ_TYPE_ENDPOINT 0x02 // 00010 = Endpoint
+#define USB_REQ_TYPE_OTHER 0x03 // 00011 = Other
+
+// Values for DEVICE_REQUEST.bRequest
+// Standard Device Requests
+#define USB_REQ_GET_STATUS 0
+#define USB_REQ_CLEAR_FEATURE 1
+#define USB_REQ_SET_FEATURE 3
+#define USB_REQ_SET_ADDRESS 5
+#define USB_REQ_GET_DESCRIPTOR 6
+#define USB_REQ_SET_DESCRIPTOR 7
+#define USB_REQ_GET_CONFIGURATION 8
+#define USB_REQ_SET_CONFIGURATION 9
+#define USB_REQ_GET_INTERFACE 10
+#define USB_REQ_SET_INTERFACE 11
+#define USB_REQ_SYNCH_FRAME 12
+
+// CDC CLASS Requests
+#define USB_CDC_GET_LINE_CODING 0x21
+#define USB_CDC_SET_LINE_CODING 0x20
+#define USB_CDC_SET_CONTROL_LINE_STATE 0x22
+
+// HID CLASS Requests
+#define USB_HID_REQ 0x81
+#define USB_REQ_GET_REPORT 0x01
+#define USB_REQ_GET_IDLE 0x02
+#define USB_REQ_SET_REPORT 0x09
+#define USB_REQ_SET_IDLE 0x0A
+#define USB_REQ_SET_PROTOCOL 0x0B
+#define USB_REQ_GET_PROTOCOL 0x03
+
+// MSC CLASS Requests
+#define USB_MSC_RESET_BULK 0xFF
+#define USB_MSC_GET_MAX_LUN 0xFE
+
+//HID Values for HID Report Types (tSetup.bValueH)
+#define USB_REQ_HID_INPUT 0x01
+#define USB_REQ_HID_OUTPUT 0x02
+#define USB_REQ_HID_FEATURE 0x03
+
+
+// Descriptor Type Values
+#define DESC_TYPE_DEVICE 1 // Device Descriptor (Type 1)
+#define DESC_TYPE_CONFIG 2 // Configuration Descriptor (Type 2)
+#define DESC_TYPE_STRING 3 // String Descriptor (Type 3)
+#define DESC_TYPE_INTERFACE 4 // Interface Descriptor (Type 4)
+#define DESC_TYPE_ENDPOINT 5 // Endpoint Descriptor (Type 5)
+#define DESC_TYPE_DEVICE_QUALIFIER 6 // Endpoint Descriptor (Type 6)
+#define DESC_TYPE_IAD 0x0B
+#define DESC_TYPE_HUB 0x29 // Hub Descriptor (Type 6)
+#define DESC_TYPE_HID 0x21 // HID Descriptor
+#define DESC_TYPE_REPORT 0x22 // Report Descriptor
+#define DESC_TYPE_PHYSICAL 0x23 // Physical Descriptor
+
+// Feature Selector Values
+#define FEATURE_REMOTE_WAKEUP 1 // Remote wakeup (Type 1)
+#define FEATURE_ENDPOINT_STALL 0 // Endpoint stall (Type 0)
+
+// Device Status Values
+#define DEVICE_STATUS_REMOTE_WAKEUP 0x02
+#define DEVICE_STATUS_SELF_POWER 0x01
+
+// Maximum descriptor size
+#define MAX_DESC_SIZE 256
+
+// DEVICE_DESCRIPTOR structure
+#define SIZEOF_DEVICE_DESCRIPTOR 0x12
+#define OFFSET_DEVICE_DESCRIPTOR_VID_L 0x08
+#define OFFSET_DEVICE_DESCRIPTOR_VID_H 0x09
+#define OFFSET_DEVICE_DESCRIPTOR_PID_L 0x0A
+#define OFFSET_DEVICE_DESCRIPTOR_PID_H 0x0B
+#define OFFSET_CONFIG_DESCRIPTOR_POWER 0x07
+#define OFFSET_CONFIG_DESCRIPTOR_CURT 0x08
+
+// CONFIG_DESCRIPTOR structure
+#define SIZEOF_CONFIG_DESCRIPTOR 0x09
+
+// HID DESCRIPTOR structure
+//#define SIZEOF_HID_DESCRIPTOR 0x09
+
+// Bit definitions for CONFIG_DESCRIPTOR.bmAttributes
+#define CFG_DESC_ATTR_SELF_POWERED 0x40 // Bit 6: If set, device is self powered
+#define CFG_DESC_ATTR_BUS_POWERED 0x80 // Bit 7: If set, device is bus powered
+#define CFG_DESC_ATTR_REMOTE_WAKE 0x20 // Bit 5: If set, device supports remote wakeup
+
+// INTERFACE_DESCRIPTOR structure
+#define SIZEOF_INTERFACE_DESCRIPTOR 0x09
+
+// ENDPOINT_DESCRIPTOR structure
+#define SIZEOF_ENDPOINT_DESCRIPTOR 0x07
+
+// Bit definitions for EndpointDescriptor.EndpointAddr
+#define EP_DESC_ADDR_EP_NUM 0x0F // Bit 3-0: Endpoint number
+#define EP_DESC_ADDR_DIR_IN 0x80 // Bit 7: Direction of endpoint, 1/0 = In/Out
+
+// Bit definitions for EndpointDescriptor.EndpointFlags
+#define EP_DESC_ATTR_TYPE_MASK 0x03 // Mask value for bits 1-0
+#define EP_DESC_ATTR_TYPE_CONT 0x00 // Bit 1-0: 00 = Endpoint does control transfers
+#define EP_DESC_ATTR_TYPE_ISOC 0x01 // Bit 1-0: 01 = Endpoint does isochronous transfers
+#define EP_DESC_ATTR_TYPE_BULK 0x02 // Bit 1-0: 10 = Endpoint does bulk transfers
+#define EP_DESC_ATTR_TYPE_INT 0x03 // Bit 1-0: 11 = Endpoint does interrupt transfers
+
+// Definition to indicate valid/invalid data
+#define DATA_VALID 1
+#define DATA_INVALID 0
+
+extern __no_init tDEVICE_REQUEST __data16 tSetupPacket;
+extern __no_init BYTE __data16 abIEP0Buffer[];
+extern __no_init BYTE __data16 abOEP0Buffer[];
+extern __no_init BYTE __data16 pbXBufferAddressEp1[];
+extern __no_init BYTE __data16 pbYBufferAddressEp1[];
+extern __no_init BYTE __data16 pbXBufferAddressEp81[];
+extern __no_init BYTE __data16 pbYBufferAddressEp81[];
+extern __no_init BYTE __data16 pbXBufferAddressEp2[];
+extern __no_init BYTE __data16 pbYBufferAddressEp2[];
+extern __no_init BYTE __data16 pbXBufferAddressEp82[];
+extern __no_init BYTE __data16 pbYBufferAddressEp82[];
+
+extern __no_init BYTE __data16 pbXBufferAddressEp3[];
+extern __no_init BYTE __data16 pbYBufferAddressEp3[];
+extern __no_init BYTE __data16 pbXBufferAddressEp83[];
+extern __no_init BYTE __data16 pbYBufferAddressEp83[];
+
+extern __no_init BYTE __data16 pbXBufferAddressEp4[];
+extern __no_init BYTE __data16 pbYBufferAddressEp4[];
+extern __no_init BYTE __data16 pbXBufferAddressEp84[];
+extern __no_init BYTE __data16 pbYBufferAddressEp84[];
+
+extern __no_init BYTE __data16 pbXBufferAddressEp5[];
+extern __no_init BYTE __data16 pbYBufferAddressEp5[];
+extern __no_init BYTE __data16 pbXBufferAddressEp85[];
+extern __no_init BYTE __data16 pbYBufferAddressEp85[];
+
+
+extern __no_init BYTE __data16 pbXBufferAddressEp6[];
+extern __no_init BYTE __data16 pbYBufferAddressEp6[];
+extern __no_init BYTE __data16 pbXBufferAddressEp86[];
+extern __no_init BYTE __data16 pbYBufferAddressEp86[];
+
+extern __no_init BYTE __data16 pbXBufferAddressEp7[];
+extern __no_init BYTE __data16 pbYBufferAddressEp7[];
+extern __no_init BYTE __data16 pbXBufferAddressEp87[];
+extern __no_init BYTE __data16 pbYBufferAddressEp87[];
+
+extern WORD wBytesRemainingOnIEP0;
+extern WORD wBytesRemainingOnOEP0;
+extern BYTE abUsbRequestReturnData[];
+extern BYTE abUsbRequestIncomingData[];
+extern BYTE bEnumerationStatus;
+extern BYTE bFunctionSuspended;
+
+//Function return values
+#define kUSB_succeed 0x00
+#define kUSB_generalError 0x01
+#define kUSB_notEnabled 0x02
+//#define kUSB_VbusNotPresent 0x03
+
+//return values USB_connectionInfo(), USB_connect()
+#define kUSB_vbusPresent 0x01
+#define kUSB_busActive 0x02 // frame sync packets are being received
+#define kUSB_ConnectNoVBUS 0x04
+#define kUSB_suspended 0x08
+#define kUSB_NotSuspended 0x10
+#define kUSB_Enumerated 0x20
+#define kUSB_purHigh 0x40
+
+// Parameters for function USB_setEnabledEvents()
+#define kUSB_clockFaultEvent 0x0001
+#define kUSB_VbusOnEvent 0x0002
+#define kUSB_VbusOffEvent 0x0004
+#define kUSB_UsbResetEvent 0x0008
+#define kUSB_UsbSuspendEvent 0x0010
+#define kUSB_UsbResumeEvent 0x0020
+#define kUSB_dataReceivedEvent 0x0040
+#define kUSB_sendCompletedEvent 0x0080
+#define kUSB_receiveCompletedEvent 0x0100
+#define kUSB_allUsbEvents 0x01FF
+
+// USB connection states
+#define ST_USB_DISCONNECTED 0x80
+#define ST_USB_CONNECTED_NO_ENUM 0x81
+#define ST_ENUM_IN_PROGRESS 0x82
+#define ST_ENUM_ACTIVE 0x83
+#define ST_ENUM_SUSPENDED 0x84
+//#define ST_FAILED_ENUM 0x85
+#define ST_ERROR 0x86
+#define ST_NOENUM_SUSPENDED 0x87
+
+VOID usbStallInEndpoint(BYTE);
+VOID usbStallOutEndpoint(BYTE);
+VOID usbStallEndpoint(BYTE);
+VOID usbClearOEPByteCount(BYTE);
+
+
+/*----------------------------------------------------------------------------
+These functions can be used in application
++----------------------------------------------------------------------------*/
+
+/*
+MSP430 USB Module Management functions
+*/
+
+/**
+Init the USB HW interface.
+*/
+BYTE USB_init(VOID);
+
+/**
+Init and start the USB PLL.
+*/
+BYTE USB_enable();
+
+/**
+Disables the USB module and PLL.
+*/
+BYTE USB_disable(VOID);
+
+/*
+Enables/disables various USB events.
+*/
+BYTE USB_setEnabledEvents(WORD events);
+
+/*
+Returns which events are enabled and which are disabled.
+*/
+WORD USB_getEnabledEvents();
+
+/*
+Instruct USB module to make itself available to the PC for connection, by pulling PUR high.
+*/
+BYTE USB_connect();
+
+/*
+Force a disconnect from the PC by pulling PUR low.
+*/
+BYTE USB_disconnect();
+
+/**
+Reset USB-SIE and global variables.
+*/
+BYTE USB_reset();
+
+/**
+Suspend USB.
+*/
+BYTE USB_suspend(VOID);
+
+/**
+Resume USB.
+*/
+BYTE USB_resume(VOID);
+
+/*
+Force a remote wakeup of the USB host.
+ This method can be generated only if device supports
+ remote wake-up feature in some of its configurations.
+ The method wakes-up the USB bus only if wake-up feature is enabled by the host.
+*/
+BYTE USB_forceRemoteWakeup();
+
+/*
+Returns the status of the USB connection.
+*/
+BYTE USB_connectionInfo();
+
+/*
+Returns the state of the USB connection.
+*/
+BYTE USB_connectionState();
+
+/*
+Event-Handling routines
+*/
+
+/*
+If this function gets executed, it's a sign that the output of the USB PLL has failed.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleClockEvent();
+
+/*
+If this function gets executed, it indicates that a valid voltage has just been applied to the VBUS pin.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleVbusOnEvent();
+
+/*
+If this function gets executed, it indicates that a valid voltage has just been removed from the VBUS pin.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleVbusOffEvent();
+
+/*
+If this function gets executed, it indicates that the USB host has issued a USB reset event to the device.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleResetEvent();
+
+/*
+If this function gets executed, it indicates that the USB host has chosen to suspend this device after a period of active operation.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleSuspendEvent();
+
+/*
+If this function gets executed, it indicates that the USB host has chosen to resume this device after a period of suspended operation.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleResumeEvent();
+
+/*
+If this function gets executed, it indicates that the USB host has enumerated this device :
+after host assigned the address to the device.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleEnumCompleteEvent();
+
+/**
+Send stall handshake for in- and out-endpoint0 (control pipe)
+*/
+VOID usbStallEndpoint0(VOID);
+
+/**
+Clear byte counter for endpoint0 (control pipe)
+*/
+VOID usbClearOEP0ByteCount(VOID);
+
+/**
+Send stall handshake for out-endpoint0 (control pipe)
+*/
+VOID usbStallOEP0(VOID);
+
+/**
+Send further data over control pipe if needed.
+ Function is called from control-in IRQ. Do not call from user application
+*/
+VOID usbSendNextPacketOnIEP0(VOID);
+
+/**
+Send data over control pipe to host.
+ Number of bytes to transmit should be set with
+ global varible "wBytesRemainingOnIEP0" before function is called.
+*/
+VOID usbSendDataPacketOnEP0(PBYTE pbBuffer);
+
+/**
+Receive further data from control pipe if needed.
+ Function is called from control-out IRQ. Do not call from user application
+*/
+VOID usbReceiveNextPacketOnOEP0(VOID);
+
+/**
+Receive data from control pipe.
+ Number of bytes to receive should be set with
+ global varible "wBytesRemainingOnOEP0" before function is called.
+*/
+VOID usbReceiveDataPacketOnEP0(PBYTE pbBuffer);
+
+/**
+Send zero length packet on control pipe.
+*/
+VOID usbSendZeroLengthPacketOnIEP0(VOID);
+
+/*Send data to host.*/
+BYTE MscSendData(const BYTE* data, WORD size);
+
+/**
+Decode incoming usb setup packet and call corresponding function
+ usbDecodeAndProcessUsbRequest is called from IRQ. Do not call from user application
+*/
+BYTE usbDecodeAndProcessUsbRequest(VOID);
+VOID usbClearEndpointFeature(VOID);
+VOID usbGetConfiguration(VOID);
+VOID usbGetDeviceDescriptor(VOID);
+VOID usbGetConfigurationDescriptor(VOID);
+VOID usbGetStringDescriptor(VOID);
+VOID usbGetInterface(VOID);
+VOID usbGetDeviceStatus(VOID);
+VOID usbGetEndpointStatus(VOID);
+VOID usbGetInterfaceStatus(VOID);
+VOID usbSetAddress(VOID);
+VOID usbSetConfiguration(VOID);
+VOID usbClearDeviceFeature(VOID);
+VOID usbSetDeviceFeature(VOID);
+VOID usbSetEndpointFeature(VOID);
+VOID usbSetInterface(VOID);
+VOID usbInvalidRequest(VOID);
+
+
+#define ENUMERATION_COMPLETE 0x01
+
+/*----------------------------------------------------------------------------+
+| End of header file |
++----------------------------------------------------------------------------*/
+#ifdef __cplusplus
+}
+#endif
+#endif /* _USB_H */
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_HID_API/UsbHid.c b/USB_API/USB_HID_API/UsbHid.c
--- /dev/null
@@ -0,0 +1,932 @@
+/*
+ * UsbHid.c
+ *
+ * USB HID send and receive functions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: UsbHid.c, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2009/02/20 ported from CdcHid |
+| RSTO 2009/05/19 updated USBHID_intfStatus() |
+| RSTO 2009/05/26 added USBHID_bytesInUSBBuffer() |
+| RSTO 2009/05/28 changed USBHID_sendData() |
+| RSTO 2009/06/09 updated USBHID_bytesInUSBBuffer() |
+| MSP/Biju 2009/10/21 Changes for composite support |
+| RSTO 2009/10/21 move __disable_interrupt() before |
+| checking for suspend |
++----------------------------------------------------------------------------*/
+
+#include "../USB_Common/device.h"
+#include "../USB_Common/types.h" // Basic Type declarations
+#include "../USB_Common/defMSP430USB.h"
+#include "../USB_Common/usb.h" // USB-specific Data Structures
+#include "UsbHid.h"
+#include <descriptors.h>
+#include <string.h>
+
+#ifdef _HID_
+
+//function pointers
+extern VOID *(*USB_TX_memcpy)(VOID * dest, const VOID * source, size_t count);
+extern VOID *(*USB_RX_memcpy)(VOID * dest, const VOID * source, size_t count);
+
+// Local Macros
+#define INTFNUM_OFFSET(X) (X - HID0_INTFNUM) // Get the HID offset
+
+static struct _HidWrite
+{
+ WORD nHidBytesToSend; // holds counter of bytes to be sent
+ WORD nHidBytesToSendLeft; // holds counter how many bytes is still to be sent
+ const BYTE* pHidBufferToSend; // holds the buffer with data to be sent
+ BYTE bCurrentBufferXY; // indicates which buffer is to use next for for write into IN OUT endpoint
+} HidWriteCtrl[HID_NUM_INTERFACES];
+
+static struct _HidRead
+{
+ BYTE *pUserBuffer; // holds the current position of user's receiving buffer. If NULL- no receiving operation started
+ BYTE *pCurrentEpPos; // current positon to read of received data from curent EP
+ WORD nBytesToReceive; // holds how many bytes was requested by receiveData() to receive
+ WORD nBytesToReceiveLeft; // holds how many bytes is still requested by receiveData() to receive
+ BYTE * pCT1; // holds current EPBCTxx register
+ BYTE * pCT2; // holds next EPBCTxx register
+ BYTE * pEP2; // holds addr of the next EP buffer
+ BYTE nBytesInEp; // how many received bytes still available in current EP
+ BYTE bCurrentBufferXY; // indicates which buffer is used by host to transmit data via OUT endpoint
+} HidReadCtrl[HID_NUM_INTERFACES];
+
+extern WORD wUsbEventMask;
+
+/*----------------------------------------------------------------------------+
+| Global Variables |
++----------------------------------------------------------------------------*/
+
+extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
+extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
+
+
+VOID HidCopyUsbToBuff(BYTE* pEP, BYTE* pCT, BYTE);
+
+/*----------------------------------------------------------------------------+
+| Functions' implementatin |
++----------------------------------------------------------------------------*/
+
+//resets internal HID data structure
+VOID HidResetData()
+{
+ // indicates which buffer is used by host to transmit data via OUT endpoint3 - X buffer is first
+ //HidReadCtrl[intfIndex].bCurrentBufferXY = X_BUFFER;
+
+ memset(&HidReadCtrl, 0, sizeof(HidReadCtrl));
+ memset(&HidWriteCtrl, 0, sizeof(HidWriteCtrl));
+}
+
+
+/*
+Sends a pre-built report reportData to the host.
+ Returns: kUSBHID_sendComplete
+ kUSBHID_intfBusyError
+ kUSBCDC_busNotAvailable
+*/
+BYTE USBHID_sendReport(const BYTE * reportData, BYTE intfNum)
+{
+ BYTE byte_count;
+ BYTE * pEP1;
+ BYTE * pCT1;
+
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ return kUSBHID_busNotAvailable;
+ }
+
+ if (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER)
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+ else
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].iep_Y_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+
+ byte_count = USBHID_REPORT_LENGTH; // we support only one length of report
+
+ if(*pCT1 & EPBCNT_NAK) // if this EP is empty
+ {
+ USB_TX_memcpy(pEP1, reportData, byte_count); // copy data into IEP X or Y buffer
+ *pCT1 = byte_count; // Set counter for usb In-Transaction
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1)&0x01; //switch buffer
+ return kUSBHID_sendComplete;
+ }
+ return kUSBHID_intfBusyError;
+}
+
+/*
+Receives report reportData from the host.
+Return: kUSBHID_receiveCompleted
+ kUSBHID_generalError
+ kUSBCDC_busNotAvailable
+*/
+BYTE USBHID_receiveReport(BYTE * reportData, BYTE intfNum)
+{
+ BYTE ret = kUSBHID_generalError;
+ BYTE nTmp1 = 0;
+
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ return kUSBHID_busNotAvailable;
+ }
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER) //this is current buffer
+ {
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK) //this buffer has a valid data packet
+ {
+ //this is the active EP buffer
+ //pEP1
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+
+ //second EP buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ nTmp1 = 1; //indicate that data is available
+ }
+ }
+ else // Y_BUFFER
+ {
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK)
+ {
+ //this is the active EP buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+
+ //second EP buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ nTmp1 = 1; //indicate that data is available
+ }
+ }
+
+ if (nTmp1)
+ {
+ // how many byte we can get from one endpoint buffer
+ nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
+
+ if(nTmp1 & EPBCNT_NAK)
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; // holds how many valid bytes in the EP buffer
+
+ USB_RX_memcpy(reportData, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos, nTmp1);
+ //memcpy(reportData, HidReadCtrl.pEP1, nTmp1);
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1) &0x01;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
+ *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = 0; // clear NAK, EP ready to receive data
+
+ ret = kUSBHID_receiveCompleted;
+ }
+ }
+ return ret;
+}
+
+
+/*
+Sends data over interface intfNum, of size size and starting at address data.
+Returns: kUSBHID_sendStarted
+ kUSBHID_sendComplete
+ kUSBHID_intBusyError
+*/
+BYTE USBHID_sendData(const BYTE* data, WORD size, BYTE intfNum)
+{
+ unsigned short bGIE;
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ if (size == 0)
+ {
+ return kUSBHID_generalError;
+ }
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ // data can not be read because of USB suspended
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBHID_busNotAvailable;
+ }
+
+ if (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft != 0)
+ {
+ // the USB still sends previous data, we have to wait
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBHID_intfBusyError;
+ }
+
+ //This function generate the USB interrupt. The data will be sent out from interrupt
+
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend = size;
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft = size;
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].pHidBufferToSend = data;
+
+ //trigger Endpoint Interrupt - to start send operation
+ USBIEPIFG |= 1<<(edbIndex+1); //IEPIFGx;
+
+ __bis_SR_register(bGIE); //restore interrupt status
+
+ return kUSBHID_sendStarted;
+}
+
+//this function is used only by USB interrupt
+BOOL HidToHostFromBuffer(BYTE intfNum)
+{
+ BYTE byte_count, nTmp2;
+ BYTE * pEP1;
+ BYTE * pEP2;
+ BYTE * pCT1;
+ BYTE * pCT2;
+ BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt
+
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ if (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft == 0) // do we have somtething to send?
+ {
+
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend = 0;
+
+ //call event callback function
+ if (wUsbEventMask & kUSB_sendCompletedEvent)
+ {
+ bWakeUp = USBHID_handleSendCompleted(intfNum);
+ }
+ return bWakeUp;
+ }
+
+ if(!(tInputEndPointDescriptorBlock[edbIndex].bEPCNF & EPCNF_TOGGLE))
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+
+ //second EP buffer
+ pEP2 = (BYTE*)stUsbHandle[intfNum].iep_Y_Buffer;
+ pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+ else
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].iep_Y_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+
+ //second EP buffer
+ pEP2 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
+ pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+
+ // how many byte we can send over one endpoint buffer
+ // 2 bytes a reserved: [0] - HID Report Descriptor, [1] - count of valid bytes
+ byte_count = (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft > EP_MAX_PACKET_SIZE-2) ? EP_MAX_PACKET_SIZE-2 : HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft;
+ nTmp2 = *pCT1;
+
+ if(nTmp2 & EPBCNT_NAK)
+ {
+ USB_TX_memcpy(pEP1+2, HidWriteCtrl[INTFNUM_OFFSET(intfNum)].pHidBufferToSend, byte_count); // copy data into IEP3 X or Y buffer
+ pEP1[0] = 0x3F; // set HID report descriptor: 0x3F
+ pEP1[1] = byte_count; // set HID report descriptor
+
+ // 64 bytes will be send: we use only one HID report descriptor
+ *pCT1 = 0x40; // Set counter for usb In-Transaction
+
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft -= byte_count;
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].pHidBufferToSend += byte_count; // move buffer pointer
+
+ //try to send data over second buffer
+ nTmp2 = *pCT2;
+ if ((HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft > 0) && // do we have more data to send?
+ (nTmp2 & EPBCNT_NAK)) // if the second buffer is free?
+ {
+ // how many byte we can send over one endpoint buffer
+ byte_count = (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft > EP_MAX_PACKET_SIZE-2) ? EP_MAX_PACKET_SIZE-2 : HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft;
+
+ USB_TX_memcpy(pEP2+2, HidWriteCtrl[INTFNUM_OFFSET(intfNum)].pHidBufferToSend, byte_count); // copy data into IEP3 X or Y buffer
+ pEP2[0] = 0x3F; // set HID report descriptor: 0x3F
+ pEP2[1] = byte_count; // set byte count of valid data
+
+ // 64 bytes will be send: we use only one HID report descriptor
+ *pCT2 = 0x40; // Set counter for usb In-Transaction
+
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft -= byte_count;
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].pHidBufferToSend += byte_count; // move buffer pointer
+ }
+ }
+ return bWakeUp;
+}
+
+/*
+Aborts an active send operation on interface intfNum.
+Returns the number of bytes that were sent prior to the abort, in size.
+*/
+BYTE USBHID_abortSend(WORD* size, BYTE intfNum)
+{
+ unsigned short bGIE;
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+
+ __disable_interrupt(); //disable interrupts - atomic operation
+
+ *size = (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend - HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft);
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend = 0;
+ HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft = 0;
+
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSB_succeed;
+}
+
+// This function copies data from OUT endpoint into user's buffer
+// Arguments:
+// pEP - pointer to EP to copy from
+// pCT - pointer to pCT control reg
+//
+VOID HidCopyUsbToBuff(BYTE* pEP, BYTE* pCT,BYTE intfNum)
+{
+ BYTE nCount;
+
+ // how many byte we can get from one endpoint buffer
+ nCount = (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp) ? HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp : HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;
+
+ USB_RX_memcpy(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer, pEP, nCount); // copy data from OEPx X or Y buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft -= nCount;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer += nCount; // move buffer pointer
+ // to read rest of data next time from this place
+
+ if (nCount == HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp) // all bytes are copied from receive buffer?
+ {
+ //switch current buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1) &0x01;
+
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
+
+ //clear NAK, EP ready to receive data
+ *pCT = 0;
+ }
+ else
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp -= nCount;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = pEP + nCount;
+ }
+}
+
+
+/*
+Receives data over interface intfNum, of size size, into memory starting at address data.
+Returns:
+ kUSBHID_receiveStarted if the receiving process started.
+ kUSBHID_receiveCompleted all requested date are received.
+ kUSBHID_receiveInProgress previous receive opereation is in progress. The requested receive operation can be not started.
+ kUSBHID_generalError error occurred.
+*/
+BYTE USBHID_receiveData(BYTE* data, WORD size, BYTE intfNum)
+{
+ BYTE nTmp1;
+ unsigned short bGIE;
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ if ((size == 0) || // read size is 0
+ (data == NULL))
+ {
+ return kUSBHID_generalError;
+ }
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBHID_busNotAvailable;
+ }
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL) // receive process already started
+ {
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBHID_receiveInProgress;
+ }
+
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive = size; // bytes to receive
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = size; // left bytes to receive
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = data; // set user receive buffer
+
+ //read rest of data from buffer, if any
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0)
+ {
+ // copy data from pEP-endpoint into User's buffer
+ HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum);
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // the Receive opereation is completed
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ USBHID_handleReceiveCompleted(intfNum); // call event handler in interrupt context
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBHID_receiveCompleted; // receive completed
+ }
+
+ // check other EP buffer for data - exchange pCT1 with pCT2
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 == &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX)
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ }
+ else
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ }
+ nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
+ //try read data from second buffer
+ if (nTmp1 & EPBCNT_NAK) // if the second buffer has received data?
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos+1); // holds how many valid bytes in the EP buffer
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1-2)
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1-2;
+ }
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos += 2; // here starts user data
+ HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum);
+ }
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // the Receive opereation is completed
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ USBHID_handleReceiveCompleted(intfNum); // call event handler in interrupt context
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBHID_receiveCompleted; // receive completed
+ }
+ } //read rest of data from buffer, if any
+
+ //read 'fresh' data, if available
+ nTmp1 = 0;
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER) //this is current buffer
+ {
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK) //this buffer has a valid data packet
+ {
+ //this is the active EP buffer
+ //pEP1
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+
+ //second EP buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ nTmp1 = 1; //indicate that data is available
+ }
+ }
+ else // Y_BUFFER
+ {
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK)
+ {
+ //this is the active EP buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+
+ //second EP buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ nTmp1 = 1; //indicate that data is available
+ }
+ }
+
+ if (nTmp1)
+ {
+ // how many byte we can get from one endpoint buffer
+ nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
+
+ if(nTmp1 & EPBCNT_NAK)
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos+1); // holds how many valid bytes in the EP buffer
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1-2)
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1-2;
+ }
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos += 2; // here starts user data
+ HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum);
+
+ nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
+ //try read data from second buffer
+ if ((HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > 0) && // do we have more data to receive?
+ (nTmp1 & EPBCNT_NAK)) // if the second buffer has received data?
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2+1); // holds how many valid bytes in the EP buffer
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1-2)
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1-2;
+ }
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 += 2; // here starts user data
+ HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2,intfNum);
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
+ }
+ }
+ }
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // the Receive opereation is completed
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ USBHID_handleReceiveCompleted(intfNum); // call event handler in interrupt context
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBHID_receiveCompleted;
+ }
+
+ //interrupts enable
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBHID_receiveStarted;
+}
+
+//this function is used only by USB interrupt.
+//It fills user receiving buffer with received data
+BOOL HidToBufferFromHost(BYTE intfNum)
+{
+ BYTE * pEP1;
+ BYTE nTmp1;
+ BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt
+
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // do we have somtething to receive?
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ return bWakeUp;
+ }
+
+ // No data to receive...
+ if (!((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX |
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY)
+ & 0x80))
+ {
+ return bWakeUp;
+ }
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER) //X is current buffer
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+
+ //second EP buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+ else
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+
+ //second EP buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+
+ // how many byte we can get from one endpoint buffer
+ nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
+
+ if(nTmp1 & EPBCNT_NAK)
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(pEP1+1); // holds how many valid bytes in the EP buffer
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1-2)
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1-2;
+ }
+ pEP1 += 2; // here starts user data
+ HidCopyUsbToBuff(pEP1, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum);
+
+ nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
+ //try read data from second buffer
+ if ((HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > 0) && // do we have more data to send?
+ (nTmp1 & EPBCNT_NAK)) // if the second buffer has received data?
+ {
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(pEP1+1); // holds how many valid bytes in the EP buffer
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1-2)
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1-2;
+ }
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 += 2; // here starts user data
+ HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2,intfNum);
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
+ }
+ }
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0) // the Receive opereation is completed
+ {
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; // no more receiving pending
+ if (wUsbEventMask & kUSB_receiveCompletedEvent)
+ {
+ bWakeUp = USBHID_handleReceiveCompleted(intfNum);
+ }
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp) // Is not read data still available in the EP?
+ {
+ if (wUsbEventMask & kUSB_dataReceivedEvent)
+ {
+ bWakeUp = USBHID_handleDataReceived(intfNum);
+ }
+ }
+ }
+ return bWakeUp;
+}
+
+// helper for USB interrupt handler
+BOOL HidIsReceiveInProgress(BYTE intfNum)
+{
+ return (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL);
+}
+
+
+/*
+Aborts an active receive operation on interface intfNum.
+ Returns the number of bytes that were received and transferred
+ to the data location established for this receive operation.
+*/
+BYTE USBHID_abortReceive(WORD* size, BYTE intfNum)
+{
+ unsigned short bGIE;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ __disable_interrupt(); //disable interrupts - atomic operation
+
+ *size = 0; //set received bytes count to 0
+
+ //is receive operation underway?
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer)
+ {
+ //how many bytes are already received?
+ *size = HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive - HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;
+
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = 0;
+ }
+
+ //restore interrupt status
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSB_succeed;
+}
+
+/*
+This function rejects payload data that has been received from the host.
+*/
+BYTE USBHID_rejectData(BYTE intfNum)
+{
+ unsigned short bGIE;
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+
+ //interrupts disable
+ __disable_interrupt();
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if (bFunctionSuspended)
+ {
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBHID_busNotAvailable;
+ }
+
+ //Is receive operation underway?
+ // - do not flush buffers if any operation still active.
+ if (!HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer)
+ {
+ BYTE tmp1 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK;
+ BYTE tmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK;
+
+ if (tmp1 ^ tmp2) // switch current buffer if any and only ONE of the buffers is full
+ {
+ //switch current buffer
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1) &0x01;
+ }
+
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0; //flush buffer X
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0; //flush buffer Y
+ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0; // indicates that no more data available in the EP
+ }
+
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSB_succeed;
+}
+
+/*
+This function indicates the status of the interface intfNum.
+ If a send operation is active for this interface,
+ the function also returns the number of bytes that have been transmitted to the host.
+ If a receiver operation is active for this interface, the function also returns
+ the number of bytes that have been received from the host and are waiting at the assigned address.
+
+returns kUSBHID_waitingForSend (indicates that a call to USBHID_SendData()
+ has been made, for which data transfer has not been completed)
+
+returns kUSBHID_waitingForReceive (indicates that a receive operation
+ has been initiated, but not all data has yet been received)
+
+returns kUSBHID_dataWaiting (indicates that data has been received
+ from the host, waiting in the USB receive buffers)
+*/
+BYTE USBHID_intfStatus(BYTE intfNum, WORD* bytesSent, WORD* bytesReceived)
+{
+ BYTE ret = 0;
+ unsigned short bGIE;
+ BYTE edbIndex;
+
+ *bytesSent = 0;
+ *bytesReceived = 0;
+
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ __disable_interrupt(); //disable interrupts - atomic operation
+
+ // Is send operation underway?
+ if (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft != 0)
+ {
+ ret |= kUSBHID_waitingForSend;
+ *bytesSent = HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend - HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft;
+ }
+
+ //Is receive operation underway?
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL)
+ {
+ ret |= kUSBHID_waitingForReceive;
+ *bytesReceived = HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive - HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;
+ }
+ else // not receive operation started
+ {
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if (!bFunctionSuspended)
+ {
+ if((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK) | //any of buffers has a valid data packet
+ (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK))
+ {
+ ret |= kUSBHID_dataWaiting;
+ }
+ }
+ }
+
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ // if suspended or not enumerated - report no other tasks pending
+ ret = kUSBHID_busNotAvailable;
+ }
+
+ //restore interrupt status
+ __bis_SR_register(bGIE); //restore interrupt status
+
+ return ret;
+}
+
+/*
+Returns how many bytes are in the buffer are received and ready to be read.
+*/
+BYTE USBHID_bytesInUSBBuffer(BYTE intfNum)
+{
+ BYTE bTmp1 = 0;
+ BYTE bTmp2;
+
+ BYTE edbIndex;
+ unsigned short bGIE;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+
+ //interrupts disable
+ __disable_interrupt();
+
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ // if suspended or not enumerated - report 0 bytes available
+ __bis_SR_register(bGIE); //restore interrupt status
+ return 0;
+ }
+
+ if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0) // If a RX operation is underway, part of data may was read of the OEP buffer
+ {
+ bTmp1 = HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp;
+ if (*HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & EPBCNT_NAK) // the next buffer has a valid data packet
+ {
+ bTmp2 = *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2+1); // holds how many valid bytes in the EP buffer
+ if (bTmp2 > (*HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & 0x7F) -2) // check if all data received correctly
+ {
+ bTmp1 += (*HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & 0x7F) -2;
+ }
+ else
+ {
+ bTmp1 += bTmp2;
+ }
+ }
+ }
+ else
+ {
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK) //this buffer has a valid data packet
+ {
+ bTmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & 0x7F;
+ bTmp1 = *((BYTE*)stUsbHandle[intfNum].oep_X_Buffer+1);
+ if (bTmp2-2 < bTmp1) // check if the count (second byte) is valid
+ {
+ bTmp1 = bTmp2 - 2;
+ }
+ }
+ if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK) //this buffer has a valid data packet
+ {
+ bTmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & 0x7F;
+ if (bTmp2-2 > *((BYTE*)stUsbHandle[intfNum].oep_Y_Buffer+1)) // check if the count (second byte) is valid
+ {
+ bTmp1 += *((BYTE*)stUsbHandle[intfNum].oep_Y_Buffer+1);
+ }
+ else
+ {
+ bTmp1 += bTmp2 - 2;
+ }
+ }
+ }
+
+ //interrupts enable
+ __bis_SR_register(bGIE); //restore interrupt status
+ return bTmp1;
+}
+
+#endif //ifdef _HID_
+
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_HID_API/UsbHid.h b/USB_API/USB_HID_API/UsbHid.h
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * UsbHid.h
+ *
+ * USB HID send and receive functions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: UsbHid.h, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2009/02/20 portet from UsbCdc.h |
+| RSTO 2009/05/15 added param to USBHID_rejectData() |
+| RSTO 2009/05/26 added USBHID_bytesInUSBBuffer() |
++----------------------------------------------------------------------------*/
+#ifndef _UsbHid_H_
+#define _UsbHid_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#define kUSBHID_sendStarted 0x01
+#define kUSBHID_sendComplete 0x02
+#define kUSBHID_intfBusyError 0x03
+#define kUSBHID_receiveStarted 0x04
+#define kUSBHID_receiveCompleted 0x05
+#define kUSBHID_receiveInProgress 0x06
+#define kUSBHID_generalError 0x07
+#define kUSBHID_busNotAvailable 0x08
+
+/*----------------------------------------------------------------------------
+These functions can be used in application
++----------------------------------------------------------------------------*/
+
+/*
+Sends a pre-built report reportData to the host.
+ Returns: kUSBHID_sendComplete
+ kUSBHID_intfBusyError
+ kUSBHID_busSuspended
+*/
+BYTE USBHID_sendReport(const BYTE * reportData, BYTE intfNum);
+
+/*
+Receives report reportData from the host.
+Return: kUSBHID_receiveCompleted
+ kUSBHID_generalError
+ kUSBHID_busSuspended
+*/
+BYTE USBHID_receiveReport(BYTE * reportData, BYTE intfNum);
+
+/*
+Sends data over interface intfNum, of size size and starting at address data.
+ Returns: kUSBHID_sendStarted
+ kUSBHID_sendComplete
+ kUSBHID_intfBusyError
+*/
+BYTE USBHID_sendData(const BYTE* data, WORD size, BYTE intfNum);
+
+/*
+Receives data over interface intfNum, of size size, into memory starting at address data.
+*/
+BYTE USBHID_receiveData(BYTE* data, WORD size, BYTE intfNum);
+
+/*
+Aborts an active receive operation on interface intfNum.
+ size: the number of bytes that were received and transferred
+ to the data location established for this receive operation.
+*/
+BYTE USBHID_abortReceive(WORD* size, BYTE intfNum);
+
+
+#define kUSBHID_noDataWaiting 1 //returned by USBHID_rejectData() if no data pending
+
+/*
+This function rejects payload data that has been received from the host.
+*/
+BYTE USBHID_rejectData(BYTE intfNum);
+
+/*
+Aborts an active send operation on interface intfNum. Returns the number of bytes that were sent prior to the abort, in size.
+*/
+BYTE USBHID_abortSend(WORD* size, BYTE intfNum);
+
+
+#define kUSBHID_waitingForSend 0x01
+#define kUSBHID_waitingForReceive 0x02
+#define kUSBHID_dataWaiting 0x04
+#define kUSBHID_busNotAvailable 0x08
+/*
+This function indicates the status of the interface intfNum.
+ If a send operation is active for this interface,
+ the function also returns the number of bytes that have been transmitted to the host.
+ If a receiver operation is active for this interface, the function also returns
+ the number of bytes that have been received from the host and are waiting at the assigned address.
+
+returns kUSBHID_waitingForSend (indicates that a call to USBHID_SendData()
+ has been made, for which data transfer has not been completed)
+
+returns kUSBHID_waitingForReceive (indicates that a receive operation
+ has been initiated, but not all data has yet been received)
+
+returns kUSBHID_dataWaiting (indicates that data has been received
+ from the host, waiting in the USB receive buffers)
+*/
+BYTE USBHID_intfStatus(BYTE intfNum, WORD* bytesSent, WORD* bytesReceived);
+
+/*
+Returns how many bytes are in the buffer are received and ready to be read.
+*/
+BYTE USBHID_bytesInUSBBuffer(BYTE intfNum);
+
+/*----------------------------------------------------------------------------
+Event-Handling routines
++----------------------------------------------------------------------------*/
+
+/*
+This event indicates that data has been received for port port, but no data receive operation is underway.
+returns TRUE to keep CPU awake
+*/
+BYTE USBHID_handleDataReceived(BYTE intfNum);
+
+/*
+This event indicates that a send operation on port port has just been completed.
+returns TRUE to keep CPU awake
+*/
+BYTE USBHID_handleSendCompleted(BYTE intfNum);
+
+/*
+This event indicates that a receive operation on port port has just been completed.
+returns TRUE to keep CPU awake
+*/
+BYTE USBHID_handleReceiveCompleted(BYTE intfNum);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif //_UsbHid_H_
diff --git a/USB_API/USB_HID_API/UsbHidReportHandler.c b/USB_API/USB_HID_API/UsbHidReportHandler.c
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * UsbHidReportHandler.c
+ *
+ * USB HID functions for Report Handler
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: HidReportHandler.c, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2009/03/03 born |
+| RSTO 2009/07/17 added __data16 qualifier for USB buffers |
++----------------------------------------------------------------------------*/
+
+#include "../USB_Common/device.h"
+#include "../USB_Common/types.h" // Basic Type declarations
+#include "../USB_Common/defMSP430USB.h"
+#include "../USB_Common/usb.h" // USB-specific Data Structures
+#include "UsbHidReportHandler.h"
+#include <descriptors.h>
+
+#ifdef _HID_
+
+extern __no_init tEDB0 __data16 tEndPoint0DescriptorBlock;
+extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
+extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
+
+
+//----------------------------------------------------------------------------
+
+VOID Handler_InReport(VOID)
+{
+}
+
+//----------------------------------------------------------------------------
+
+VOID Handler_InFeature(VOID)
+{
+ switch((BYTE)tSetupPacket.wValue) // tSetupPacket.wValue is contains HID-Report-ID
+ {
+ case 1:
+ // user's specified code...
+ break;
+
+ case 2:
+ // user's specified code...
+ break;
+
+ default:;
+ }
+ usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData);
+}
+
+//----------------------------------------------------------------------------
+
+VOID Handler_OutReport(VOID)
+{
+}
+
+//----------------------------------------------------------------------------
+
+VOID Handler_OutFeature(VOID)
+{
+ switch((BYTE)tSetupPacket.wValue) // tSetupPacket.wValue is contains HID-Report-ID
+ {
+ case 1:
+ // user's specified code...
+ break;
+
+ case 2:
+ // user's specified code...
+ break;
+
+ default:;
+ }
+}
+
+#endif //_HID_
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_HID_API/UsbHidReportHandler.h b/USB_API/USB_HID_API/UsbHidReportHandler.h
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * UsbHidReportHandler.h
+ *
+ * USB HID functions for Report Handler
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: HidReportHandler.h, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2009/03/03 born |
++----------------------------------------------------------------------------*/
+
+#ifndef _HidReportHandler_H_
+#define _HidReportHandler_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+Parses setup packet for report id and call function which belongs to report id
+ Called function will generate InReport.
+*/
+VOID Handler_InReport(VOID);
+
+/**
+Parses setup packet for report id and call function which belongs to report id
+Called function will generate InFeatureReport.
+*/
+VOID Handler_InFeature(VOID);
+
+/**
+Parses setup packet for report id and call function which belongs to report id.
+*/
+VOID Handler_OutReport(VOID);
+
+/**
+Parses setup packet for report id and call function which belongs to report id.
+*/
+VOID Handler_OutFeature(VOID);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //_HidReportHandler_H_
diff --git a/USB_API/USB_HID_API/UsbHidReq.c b/USB_API/USB_HID_API/UsbHidReq.c
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * UsbHidReq.c
+ *
+ * USB HID Request functions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: UsbHidReq.c, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2009/03/03 born |
+| MSP/Biju 2009/10/21 Changes for composite support |
++----------------------------------------------------------------------------*/
+
+#include "../USB_Common/device.h"
+#include "../USB_Common/types.h" // Basic Type declarations
+#include "../USB_Common/defMSP430USB.h"
+#include "../USB_Common/usb.h" // USB-specific Data Structures
+#include "UsbHidReportHandler.h"
+#include <descriptors.h>
+
+#ifdef _HID_
+
+VOID usbClearOEP0ByteCount(VOID);
+VOID usbSendDataPacketOnEP0(PBYTE pbBuffer);
+VOID usbReceiveDataPacketOnEP0(PBYTE pbBuffer);
+
+
+VOID usbGetHidDescriptor(VOID)
+{
+ static BYTE intfNum;
+ if(intfNum >= HID_NUM_INTERFACES)
+ {
+ intfNum = 0;
+ }
+ usbClearOEP0ByteCount();
+ wBytesRemainingOnIEP0 = 9;
+ usbSendDataPacketOnEP0((PBYTE)&abromConfigurationDescriptorGroup.stHid[intfNum].blength_hid_descriptor);
+ intfNum++;
+}
+
+//----------------------------------------------------------------------------
+VOID usbGetReportDescriptor(VOID)
+{
+ wBytesRemainingOnIEP0 = SIZEOF_REPORT_DESCRIPTOR;
+ usbSendDataPacketOnEP0((PBYTE)&abromReportDescriptor);
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbSetReport(VOID)
+{
+ usbReceiveDataPacketOnEP0((PBYTE) &abUsbRequestIncomingData); // receive data over EP0 from Host
+}
+
+//----------------------------------------------------------------------------
+
+VOID usbGetReport(VOID)
+{
+ switch((BYTE)tSetupPacket.wValue)
+ {
+ case USB_REQ_HID_FEATURE:
+ Handler_InFeature();
+ break;
+ case USB_REQ_HID_INPUT:
+ Handler_InReport();
+ break;
+ default:;
+ }
+}
+
+#endif //_HID_
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_HID_API/UsbHidReq.h b/USB_API/USB_HID_API/UsbHidReq.h
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * UsbHidReq.h
+ *
+ * USB HID Request functions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: UsbHidReq.h, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| WHO WHEN WHAT |
+| --- ---------- ------------------------------------------------ |
+| RSTO 2009/03/03 born |
+| MSP,Biju 2009/12/03 file versioning started |
++----------------------------------------------------------------------------*/
+
+#ifndef _UsbHidReq_H_
+#define _UsbHidReq_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/**
+Return Hid descriptor to host over control endpoint
+*/
+VOID usbGetHidDescriptor(VOID);
+/**
+Return HID report descriptor to host over control endpoint
+*/
+VOID usbGetReportDescriptor(VOID);
+
+
+/**
+Receive Out-report from host
+*/
+VOID usbSetReport(VOID);
+
+/**
+Return In-report or In-feature-report to host over interrupt endpoint
+*/
+VOID usbGetReport(VOID);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //_UsbHidReq_H_
diff --git a/USB_API/USB_MSC_API/UsbMsc.h b/USB_API/USB_MSC_API/UsbMsc.h
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * UsbMsc.h
+ *
+ * This file contains API declarations for function to use by User Application.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+ | |
+ | Texas Instruments |
+ | |
+ | MSP430 USB-Example (MSC Driver) |
+ | |
+ +-----------------------------------------------------------------------------+
+ | Source: UsbMsc.h, File Version 1.01 |
+ | Description: This file contains API declarations for function to use by |
+ | User Application. |
+ | Author: RSTO |
+ | |
+ | WHO WHEN WHAT |
+ | --- ---------- ------------------------------------------------ |
+ | RSTO 2010/10/29 Created |
+ +----------------------------------------------------------------------------*/
+#ifndef _USB_MSC_H_
+#define _USB_MSC_H_
+
+#include "UsbMscScsi.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*Return values of getState() and USBMSC_poll() API */
+#define kUSBMSC_idle 0
+#define kUSBMSC_readInProgress 1
+#define kUSBMSC_writeInProgress 2
+#define kUSBMSC_cmdBeingProcessed 3
+#define kUSBMSC_okToSleep 4
+#define kUSBMSC_processBuffer 5
+
+/*----------------------------------------------------------------------------+
+| Function Prototypes |
++----------------------------------------------------------------------------*/
+/*Function to handle the MSC SCSI state machine */
+BYTE USBMSC_poll(VOID);
+
+/* MSC functions */
+BOOL MSCToHostFromBuffer();
+BOOL MSCFromHostToBuffer();
+BYTE USBMSC_bufferProcessed(VOID);
+BYTE USBMSC_getState();
+BYTE USBMSC_updateMediaInfo(BYTE lun, struct USBMSC_mediaInfoStr *info);
+
+BYTE USBMSC_handleBufferEvent(VOID);
+BYTE USBMSC_registerBufInfo( BYTE* RWbuf_x, BYTE* RWbuf_y, WORD size);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //_USB_MSC_H_
diff --git a/USB_API/USB_MSC_API/UsbMscReq.c b/USB_API/USB_MSC_API/UsbMscReq.c
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Usb_Msc_Req.c
+ *
+ * This file contains the APIs specific to MSC class (Class specific requests)
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+ | |
+ | Texas Instruments |
+ | |
+ | MSP430 USB-Example (MSC Driver) |
+ | |
+ +-----------------------------------------------------------------------------+
+ | Source: Usb_Msc_Req.c, File Version 1.02 |
+ | Description: This file contains the APIs specific to MSC class |
+ | (Class specific requests) |
+ | Author: Biju,MSP |
+ | |
+ | WHO WHEN WHAT |
+ | --- ---------- ------------------------------------------------ |
+ | MSP 2010/02/01 born |
+ | Biju,MSP 2010/07/15 CV bug fix | |
+ +----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+ | Includes |
+ +----------------------------------------------------------------------------*/
+
+#include <descriptors.h>
+
+#ifdef _MSC_
+
+#include "../USB_Common/types.h" // Basic Type declarations
+#include "../USB_Common/device.h"
+#include "../USB_Common/defMSP430USB.h"
+#include "../USB_Common/usb.h" // USB-specific Data Structures
+#include "../USB_MSC_API/UsbMscScsi.h"
+#include "../USB_MSC_API/UsbMscReq.h"
+#include "../USB_MSC_API/UsbMsc.h"
+
+extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
+extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
+BOOL isMSCConfigured = FALSE;
+extern BYTE bMscResetRequired;
+
+/*----------------------------------------------------------------------------+
+ | Functions |
+ +----------------------------------------------------------------------------*/
+VOID USBMSC_reset(VOID)
+{
+ Msc_ResetStateMachine();
+ Msc_ResetFlags();
+ Msc_ResetStruct();
+ isMSCConfigured = TRUE;
+
+ bMscResetRequired = FALSE;
+ tInputEndPointDescriptorBlock[stUsbHandle[MSC0_INTFNUM].edb_Index].bEPCNF
+ &= ~(EPCNF_STALL | EPCNF_TOGGLE );
+ tOutputEndPointDescriptorBlock[stUsbHandle[MSC0_INTFNUM].edb_Index].bEPCNF
+ &= ~(EPCNF_STALL | EPCNF_TOGGLE );
+ usbSendZeroLengthPacketOnIEP0(); // status stage for control transfer
+}
+
+//----------------------------------------------------------------------------
+VOID Get_MaxLUN(VOID)
+{
+ BYTE maxLunNumber = MSC_MAX_LUN_NUMBER - 1;
+ wBytesRemainingOnIEP0 = 1;
+ isMSCConfigured = TRUE;
+ usbSendDataPacketOnEP0((PBYTE)&maxLunNumber);
+}
+
+#endif // _MSC_
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_MSC_API/UsbMscReq.h b/USB_API/USB_MSC_API/UsbMscReq.h
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * UsbMscReq.h
+ *
+ * This file contains function declarations of MSC class specific Request
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+ | |
+ | Texas Instruments |
+ | |
+ | MSP430 USB-Example (MSC Driver) |
+ | |
+ +-----------------------------------------------------------------------------+
+ | Source: Usb_Msc_Req.h, File Version 1.0 |
+ | Description: This file contains function declarations of MSC class specific|
+ | Requests. |
+ | Author: MSP |
+ | |
+ | WHO WHEN WHAT |
+ | --- ---------- ------------------------------------------------ |
+ | MSP 01/02/2010 born |
+ +----------------------------------------------------------------------------*/
+#ifndef _USB_MSC_REQ_H_
+#define _USB_MSC_REQ_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* MSC Class defined Request.Reset State-Machine and makes endpoints ready again*/
+VOID USBMSC_reset(VOID);
+
+/* MSC Class defined Request.Tells the host the number of supported logical units*/
+VOID Get_MaxLUN(VOID);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //_USB_MSC_REQ_H_
+
diff --git a/USB_API/USB_MSC_API/UsbMscScsi.c b/USB_API/USB_MSC_API/UsbMscScsi.c
--- /dev/null
@@ -0,0 +1,1517 @@
+/*
+ * UsbMscScsi.c
+ *
+ * This file contains the SCSI command handlers, MSC stack internal functions.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+ /*----------------------------------------------------------------------------+
+ | |
+ | Texas Instruments |
+ | |
+ | MSP430 USB-Example (MSC Driver) |
+ | |
+ +-----------------------------------------------------------------------------+
+ | Source: Msc_Scsi.c, File Version 1.03 |
+ | Description: This file contains the SCSI command handlers, MSC stack |
+ | internal functions. |
+ | Author: Biju, MSP |
+ | |
+ | WHO WHEN WHAT |
+ | --- ---------- ------------------------------------------------ |
+ | MSP 2010/02/16 Created |
+ | Biju,MSP 2010/07/15 Fixed CV bugs |
+ | RSTO 2010/10/15 Improoving READ/WRITE functionality |
+ +----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------+
+ | Includes |
+ +----------------------------------------------------------------------------*/
+#include "../USB_Common/types.h"
+#include "../USB_Common/device.h"
+#include "../USB_Common/defMSP430USB.h"
+#include "../USB_Common/usb.h"
+#include "../USB_MSC_API/UsbMscScsi.h"
+#include "../USB_MSC_API/UsbMsc.h"
+#include <descriptors.h>
+#include <string.h>
+
+#ifdef _MSC_
+
+/*----------------------------------------------------------------------------+
+ | Internal Definitions |
+ +----------------------------------------------------------------------------*/
+//Error codes
+#define RESCODE_CURRENT_ERROR 0x70
+
+#define S_NO_SENSE 0x00
+#define S_NOT_READY 0x02
+#define S_MEDIUM_ERROR 0x03
+#define S_ILLEGAL_REQUEST 0x05
+#define S_UNITATTN 0x06
+#define S_WRITE_PROTECTED 0x07
+#define S_ABORTED_COMMAND 0x0B
+
+#define ASC_NOT_READY 0x04
+#define ASCQ_NOT_READY 0x03
+
+#define ASC_MEDIUM_NOT_PRESENT 0x3A
+#define ASCQ_MEDIUM_NOT_PRESENT 0x00
+
+#define ASC_INVALID_COMMAND_OP_CODE 0x20
+#define ASCQ_INVALID_COMMAND_OP_CODE 0x00
+
+#define ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
+#define ASCQ_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x00
+
+#define ASC_INVALID_FIELD_IN_CDB 0x24
+#define ASCQ_INVALID_FIELD_IN_CDB 0x00
+
+#define ASC_INVALID_PARAMETER_LIST 0x26
+#define ASCQ_INVALID_PARAMETER_LIST 0x02
+
+#define ASC_ABORTED_DATAPHASE_ERROR 0x4B
+#define ASCQ_ABORTED_DATAPHASE_ERROR 0x00
+
+#define ASC_ILLEGAL_REQUEST 0x20
+#define ASCQ_ILLEGAL_REQUEST 0x00
+
+#define ASC_UNITATTN_READY_NOTREADY 0x28
+#define ASCQ_UNITATTN_READY_NOTREADY 0x00
+
+#define ASC_WRITE_PROTECTED 0X27
+#define ASCQ_WRITE_PROTECTED 0X00
+
+#define ASC_WRITE_FAULT 0x03
+#define ASCQ_WRITE_FAULT 0x00
+
+#define ASC_UNRECOVERED_READ 0x11
+#define ASCQ_UNRECOVERED_READ 0x00
+
+#define DIRECTION_IN 0x80
+#define DIRECTION_OUT 0x00
+
+#define EP_MAX_PACKET_SIZE 0x40
+
+/*----------------------------------------------------------------------------+
+ | Global Variables |
+ +----------------------------------------------------------------------------*/
+
+/*Variable to track command status */
+static volatile BYTE Scsi_Status = SCSI_PASSED;
+/*Flag to indicate read/write command is recieved from host */
+BOOL bMcsCommandSupported = TRUE;
+
+/*Flag to inidicate whether any CBW recieved from host*/
+BOOL bMscCbwReceived;
+extern BOOL isMSCConfigured;
+// Buffer pointers passed by application
+BYTE *xBufferAddr;
+BYTE *yBufferAddr;
+
+/* Structure internal to stack for maintaining LBA info,buffer address etc */
+USBMSC_RWbuf_Info sRwbuf;
+
+volatile DWORD Scsi_Residue;
+__no_init CBW McsCbw;
+__no_init CSW McsCsw;
+REQUEST_SENSE_RESPONSE RequestSenseResponse;
+
+VOID usbStallEndpoint(BYTE);
+BYTE Scsi_Verify_CBW();
+
+extern struct config_struct USBMSC_config;
+
+extern VOID *(*USB_TX_memcpy)(VOID * dest, const VOID * source, size_t count);
+extern VOID *(*USB_RX_memcpy)(VOID * dest, const VOID * source, size_t count);
+
+extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
+extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
+
+struct _MscWriteControl MscWriteControl;
+struct _MscReadControl MscReadControl;
+struct _MscControl MscControl;
+
+// Most non-removable media would have these initialization values
+struct _CtrlLun sCtrlLun[MSC_MAX_LUN_NUMBER];
+
+//BYTE bMediaPresent = TRUE;
+//BYTE bWriteProtected = FALSE;
+BYTE bUnitAttention = FALSE;
+BYTE bMscCbwFailed = FALSE;
+BYTE Scsi_Standard_Inquiry_Data[256];
+BYTE bMscResetRequired = FALSE;
+
+/*----------------------------------------------------------------------------+
+ | Initiliazing Command data |
+ +----------------------------------------------------------------------------*/
+struct _Scsi_Read_Capacity Scsi_Read_Capacity_10[MSC_MAX_LUN_NUMBER];
+const struct _Report_Luns Report_Luns = {{0x02,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}};
+
+BYTE Scsi_Mode_Sense_6[SCSI_MODE_SENSE_6_CMD_LEN]= {0x03,0,0,0 }; // No mode sense parameter
+
+BYTE Scsi_Mode_Sense_10[SCSI_MODE_SENSE_10_CMD_LEN]= {0,0x06,0,0,0,0,0,0 }; // No mode sense parameter
+
+BYTE Scsi_Read_Format_Capacity[SCSI_READ_FORMAT_CAPACITY_CMD_LEN] = {0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x00,0x03,0x00,0x02,0x00};
+
+/*Default values initialized for SCSI Inquiry data */
+const BYTE bScsi_Standard_Inquiry_Data[SCSI_SCSI_INQUIRY_CMD_LEN]= {
+ 0x00, // Peripheral qualifier & peripheral device type
+ 0x80, // Removable medium
+ 0x02, // Version of the standard (SPC-2)
+ 0x02, // No NormACA, No HiSup, response data format=2
+ 0x1F, // No extra parameters
+ 0x00, // No flags
+ 0x00, // 0x80 => BQue => Basic Task Management supported
+ 0x00, // No flags
+ /* 'T','I',' ',' ',' ',' ',' ',' ',
+ 'M','a','s','s',' ','S','t','o','r','a','g','e', */
+};
+
+/*----------------------------------------------------------------------------+
+ | Functions |
+ +----------------------------------------------------------------------------*/
+VOID Reset_RequestSenseResponse(VOID)
+{
+ int i;
+
+ RequestSenseResponse.ResponseCode = RESCODE_CURRENT_ERROR;
+ RequestSenseResponse.VALID = 0; // no data in the information field
+ RequestSenseResponse.Obsolete = 0x00;
+ RequestSenseResponse.SenseKey = S_NO_SENSE;
+ RequestSenseResponse.ILI = 0;
+ RequestSenseResponse.EOM = 0;
+ RequestSenseResponse.FILEMARK = 0;
+ RequestSenseResponse.Information[0] = 0x00;
+ RequestSenseResponse.Information[1] = 0x00;
+ RequestSenseResponse.Information[2] = 0x00;
+ RequestSenseResponse.Information[3] = 0x00;
+ RequestSenseResponse.AddSenseLen = 0x0a;
+ RequestSenseResponse.CmdSpecificInfo[0]= 0x00;
+ RequestSenseResponse.CmdSpecificInfo[1]= 0x00;
+ RequestSenseResponse.CmdSpecificInfo[2]= 0x00;
+ RequestSenseResponse.CmdSpecificInfo[3]= 0x00;
+ RequestSenseResponse.ASC = 0x00;
+ RequestSenseResponse.ASCQ = 0x00;
+ RequestSenseResponse.FRUC = 0x00;
+ RequestSenseResponse.SenseKeySpecific[0] = 0x00;
+ RequestSenseResponse.SenseKeySpecific[1] = 0x00;
+ RequestSenseResponse.SenseKeySpecific[2] = 0x00;
+ for (i=0; i<14; i++) {
+ RequestSenseResponse.padding[i] = 0x00;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+BYTE Check_CBW(BYTE intfNum,BYTE Dir_Dev_Exp, DWORD Bytes_Dev_Exp)
+{
+ if(McsCbw.CBWCB[0] ==SCSI_INQUIRY || McsCbw.CBWCB[0] == SCSI_REQUEST_SENSE)
+ {
+ return SUCCESS;
+ }
+
+ if(Dir_Dev_Exp == McsCbw.bmCBWFlags) // all is right. Host is sending direction as expected by device
+ {
+ if(McsCbw.dCBWDataTransferLength < Bytes_Dev_Exp) // Host expect less data to send or receive then device
+ {
+ Scsi_Status = SCSI_PHASE_ERROR;
+ Scsi_Residue =0 ;
+ if (McsCbw.bmCBWFlags == DIRECTION_IN)
+ {
+ usbStallInEndpoint(intfNum);
+ }
+ else
+ {
+ usbStallOutEndpoint(intfNum);
+ }
+ }
+ else if((McsCbw.dCBWDataTransferLength > Bytes_Dev_Exp) &&
+ (McsCbw.CBWCB[0]!=SCSI_MODE_SENSE_6) &&
+ (McsCbw.CBWCB[0]!=SCSI_MODE_SENSE_10))
+ {
+ Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = McsCbw.dCBWDataTransferLength - Bytes_Dev_Exp;
+ if (McsCbw.bmCBWFlags == DIRECTION_IN)
+ {
+ usbStallInEndpoint(intfNum);
+ }
+ else
+ {
+ usbStallOutEndpoint(intfNum);
+ }
+ }
+ else
+ {
+ return SUCCESS;
+ }
+ }
+
+ else //Direction mismatch
+ {
+ Scsi_Residue = McsCbw.dCBWDataTransferLength;
+ Scsi_Status = SCSI_FAILED;
+ if(McsCbw.bmCBWFlags == DIRECTION_IN)
+ {
+ usbStallInEndpoint(intfNum);
+ }
+ else if((McsCbw.bmCBWFlags == DIRECTION_OUT)&&(McsCbw.CBWCB[0] == SCSI_READ_10))
+ {
+ usbStallOutEndpoint(intfNum);
+ }
+ }
+
+ // Indicates a generic failure. Read/write failure/sense data is handled separately
+ if(Scsi_Status != SCSI_READWRITE_FAIL)
+ {
+
+ RequestSenseResponse.ResponseCode = RESCODE_CURRENT_ERROR;
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.AddSenseLen = 0xA0;
+ RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
+ RequestSenseResponse.ASC = ASC_INVALID_PARAMETER_LIST;
+ RequestSenseResponse.ASCQ = ASCQ_INVALID_PARAMETER_LIST;
+ }
+
+ return FAILURE;
+}
+
+//----------------------------------------------------------------------------
+BYTE Scsi_Verify_CBW()
+{
+ /*(5.2.3) Devices must consider the CBW meaningful if no reserved bits
+ are set, the LUN number indicates a LUN supported by the device,
+ bCBWCBLength is in the range of 1 through 16, and the length and
+ content of the CBWCB field are appropriate to the SubClass.
+ */
+ if((bMscResetRequired || McsCbw.dCBWSignature!=CBW_SIGNATURE) || // Check for correct CBW signature
+ ((McsCbw.bmCBWFlags!=DIRECTION_IN && McsCbw.bmCBWFlags!=DIRECTION_OUT) ||
+ (McsCbw.bCBWLUN&0xF0) || // Upper bits have to be zero
+ (McsCbw.bCBWCBLength>16))) // maximum length is 16
+
+ {
+ bMscResetRequired = TRUE;
+ usbStallEndpoint(MSC0_INTFNUM);
+ usbClearOEPByteCount(MSC0_INTFNUM);
+ Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = 0;
+ return FAILURE;
+ }
+ Scsi_Status = SCSI_PASSED;
+ return SUCCESS;
+}
+
+//----------------------------------------------------------------------------
+BYTE Scsi_Send_CSW(BYTE intfNum)
+{
+ BYTE retval=0;
+ // Populate the CSW to be sent
+ McsCsw.dCSWSignature=CSW_SIGNATURE;
+ McsCsw.dCSWTag=McsCbw.dCBWTag;
+ McsCsw.bCSWStatus=Scsi_Status;
+ McsCsw.dCSWDataResidue=Scsi_Residue;
+ retval = MscSendData((PBYTE)&McsCsw, CSW_LENGTH); //Sending CSW
+ Scsi_Status = SCSI_PASSED;
+ return retval;
+}
+//----------------------------------------------------------------------------
+
+VOID Scsi_Inquiry(BYTE intfNum)
+{
+ //int index;
+
+ //clear the inquiry array
+ memset(Scsi_Standard_Inquiry_Data, 256, 0);
+ //copy the inquiry data from flash to RAM
+
+ memcpy(Scsi_Standard_Inquiry_Data,bScsi_Standard_Inquiry_Data,SCSI_SCSI_INQUIRY_CMD_LEN);
+
+
+
+ //get the values from USB_Config
+ Scsi_Standard_Inquiry_Data[1] = USBMSC_config.LUN[McsCbw.bCBWLUN].removable;
+ memcpy(&Scsi_Standard_Inquiry_Data[8],USBMSC_config.LUN[McsCbw.bCBWLUN].t10VID,8);
+ memcpy(&Scsi_Standard_Inquiry_Data[16],USBMSC_config.LUN[McsCbw.bCBWLUN].t10PID,16);
+ memcpy(&Scsi_Standard_Inquiry_Data[32],USBMSC_config.LUN[McsCbw.bCBWLUN].t10rev,4);
+
+ if(McsCbw.dCBWDataTransferLength < SCSI_SCSI_INQUIRY_CMD_LEN)
+ {
+ if(McsCbw.dCBWDataTransferLength == 0)
+ {
+ Scsi_Residue = 0;
+ return;
+ }
+ if(SUCCESS == MscSendData((PBYTE)Scsi_Standard_Inquiry_Data, McsCbw.dCBWDataTransferLength))
+ {
+ Scsi_Residue = 0;
+ }
+ else
+ {
+ Scsi_Status = SCSI_FAILED;
+ }
+ }
+ else if(McsCbw.dCBWDataTransferLength > SCSI_SCSI_INQUIRY_CMD_LEN)
+ {
+ Reset_RequestSenseResponse();
+
+ RequestSenseResponse.ResponseCode = RESCODE_CURRENT_ERROR;
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
+ RequestSenseResponse.ASC = ASC_INVALID_FIELD_IN_CDB;
+ RequestSenseResponse.ASCQ = ASCQ_INVALID_FIELD_IN_CDB;
+ usbStallInEndpoint(intfNum);
+ Scsi_Status = SCSI_FAILED;
+ }
+ else
+ {
+ if(SUCCESS == MscSendData((PBYTE)Scsi_Standard_Inquiry_Data,SCSI_SCSI_INQUIRY_CMD_LEN))
+ {
+ Scsi_Residue = 0;
+ }
+ else
+ {
+ Scsi_Status = SCSI_FAILED;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID Scsi_Read_Capacity10(BYTE intfNum)
+{
+ if(FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_READ_CAPACITY_CMD_LEN))
+ return;
+ if(SUCCESS != MscSendData( (PBYTE)&Scsi_Read_Capacity_10[McsCbw.bCBWLUN], SCSI_READ_CAPACITY_CMD_LEN))
+ Scsi_Status = SCSI_FAILED;
+}
+
+//----------------------------------------------------------------------------
+
+VOID Scsi_Read10(BYTE intfNum)
+{
+ WORD wLBA_len;
+ unsigned short bGIE;
+ DWORD dLBA;
+
+ /* Get first LBA: convert 4 bytes into DWORD */
+ dLBA = McsCbw.CBWCB[2];
+ dLBA <<= 8;
+ dLBA += McsCbw.CBWCB[3];
+ dLBA <<= 8;
+ dLBA += McsCbw.CBWCB[4];
+ dLBA <<= 8;
+ dLBA += McsCbw.CBWCB[5];
+
+ /* Get number of requested logical blocks */
+ wLBA_len = McsCbw.CBWCB[7];
+ wLBA_len <<=8;
+ wLBA_len += McsCbw.CBWCB[8];
+
+ if(FAILURE == Check_CBW( intfNum, DIRECTION_IN, ((DWORD)wLBA_len) * MscControl.lbaSize))
+ return;
+
+ bGIE = (__get_SR_register() & GIE); //save interrupt status
+ __disable_interrupt();
+
+ // Populating stack internal structure required for READ/WRITE
+ MscReadControl.lba = dLBA; // the first LBA number.
+ MscReadControl.lbaCount = wLBA_len; // how many LBAs to read.
+
+ sRwbuf.bufferAddr = xBufferAddr;
+ sRwbuf.lun = McsCbw.bCBWLUN;
+
+ //set LBA count
+ sRwbuf.lbCount = wLBA_len > MscControl.lbaBufCapacity ? MscControl.lbaBufCapacity : wLBA_len;
+ sRwbuf.operation = kUSBMSC_READ;
+ sRwbuf.lba = dLBA;
+ sRwbuf.returnCode = kUSBMSC_RWSuccess;
+ sRwbuf.XorY = 0;
+ //buffer is prepared, let user's Application fill data.
+ USBMSC_handleBufferEvent();
+
+ __bis_SR_register(bGIE); //restore interrupt status
+}
+
+//----------------------------------------------------------------------------
+
+VOID Scsi_Write10(BYTE intfNum)
+{
+ WORD wLBA_len;
+ unsigned short bGIE;
+ /* Get first LBA: convert 4 bytes into DWORD */
+ DWORD dLBA = McsCbw.CBWCB[2];
+ dLBA <<= 8;
+ dLBA += McsCbw.CBWCB[3];
+ dLBA <<= 8;
+ dLBA += McsCbw.CBWCB[4];
+ dLBA <<= 8;
+ dLBA += McsCbw.CBWCB[5];
+
+ /* Get number of requested logical blocks */
+ wLBA_len = McsCbw.CBWCB[7];
+ wLBA_len <<=8;
+ wLBA_len += McsCbw.CBWCB[8];
+
+ if(FAILURE == Check_CBW(intfNum,DIRECTION_OUT,((DWORD)wLBA_len) * MscControl.lbaSize))
+ return;
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ __disable_interrupt();
+
+ //calculate the whole size to receive (Host to MSP430)
+ MscWriteControl.dwBytesToReceiveLeft = (DWORD)wLBA_len * MscControl.lbaSize;
+ MscWriteControl.pUserBuffer = xBufferAddr;
+ MscWriteControl.wFreeBytesLeft = MscControl.wMscUserBufferSize;
+
+ /*Populating stack internal structure required for READ/WRITE */
+ sRwbuf.bufferAddr = xBufferAddr;
+ sRwbuf.lun = McsCbw.bCBWLUN;
+ MscWriteControl.bWriteProcessing = TRUE; // indicate that we are in WRITE phase
+ sRwbuf.XorY = 0;
+ MscWriteControl.lba = dLBA;
+ MscWriteControl.wCurrentByte = 0; //reset internal variable
+ MscWriteControl.lbaCount = 0; //reset internal variable
+
+ __bis_SR_register(bGIE); //restore interrupt status
+}
+
+//----------------------------------------------------------------------------
+
+VOID Scsi_Mode_Sense6(BYTE intfNum)
+{
+ if(FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_MODE_SENSE_6_CMD_LEN))
+ return;
+ /* Fix for SDOCM00077834 - Set WP bit. WP bit is BIT7 in byte 3 */
+ Scsi_Mode_Sense_6[2] |= (sCtrlLun[McsCbw.bCBWLUN].bWriteProtected << 0x7);
+
+ if(SUCCESS != MscSendData((PBYTE)Scsi_Mode_Sense_6, SCSI_MODE_SENSE_6_CMD_LEN))
+ Scsi_Status = SCSI_FAILED;
+}
+
+//----------------------------------------------------------------------------
+
+VOID Scsi_Mode_Sense10(BYTE intfNum)
+{
+ if(FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_MODE_SENSE_10_CMD_LEN))
+ return;
+ /* Fix for SDOCM00077834 - Set WP bit. WP bit is BIT7 in byte 3 */
+ Scsi_Mode_Sense_10[4] |= (sCtrlLun[McsCbw.bCBWLUN].bWriteProtected << 0x7);
+
+ if(SUCCESS != MscSendData((PBYTE)Scsi_Mode_Sense_10, SCSI_MODE_SENSE_10_CMD_LEN))
+ Scsi_Status = SCSI_FAILED;
+}
+
+//----------------------------------------------------------------------------
+
+VOID Scsi_Request_Sense(BYTE intfNum)
+{
+ if(FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_REQ_SENSE_CMD_LEN))
+ {
+ return;
+ }
+
+ // If there is attention needed, setup the request sense response. The
+ // bUnitAttention flag is set in USBMSC_updateMediaInfo() when the volume
+ // is removed or inserted. Note that the response is different for the
+ // removed and inserted case.
+ if(bUnitAttention == TRUE)
+ {
+ // Check if the volume was removed.
+ if(sCtrlLun[McsCbw.bCBWLUN].bMediaPresent == kUSBMSC_MEDIA_NOT_PRESENT)
+ {
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_NOT_READY;
+ RequestSenseResponse.ASC = ASC_MEDIUM_NOT_PRESENT;
+ RequestSenseResponse.ASCQ = ASCQ_MEDIUM_NOT_PRESENT;
+ }
+ // Otherwise it was inserted.
+ else
+ {
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_UNITATTN;
+ RequestSenseResponse.ASC = ASC_UNITATTN_READY_NOTREADY;
+ RequestSenseResponse.ASCQ = ASCQ_UNITATTN_READY_NOTREADY;
+ }
+ }
+
+ if(McsCbw.dCBWDataTransferLength < SCSI_REQ_SENSE_CMD_LEN)
+ {
+ if(SUCCESS == MscSendData((PBYTE)&RequestSenseResponse,McsCbw.dCBWDataTransferLength))
+ {
+ Scsi_Residue = 0;
+ }
+ else
+ {
+ Scsi_Status = SCSI_FAILED;
+ }
+ }
+ else if(McsCbw.dCBWDataTransferLength > SCSI_REQ_SENSE_CMD_LEN)
+ {
+ RequestSenseResponse.AddSenseLen += (McsCbw.dCBWDataTransferLength - SCSI_REQ_SENSE_CMD_LEN);
+ if(SUCCESS == MscSendData((PBYTE)&RequestSenseResponse, McsCbw.dCBWDataTransferLength))
+ {
+ Scsi_Residue = 0;
+ }
+ else
+ {
+ Scsi_Status = SCSI_FAILED;
+ }
+ }
+ else
+ {
+ if(SUCCESS == MscSendData((PBYTE)&RequestSenseResponse,SCSI_REQ_SENSE_CMD_LEN))
+ {
+ Scsi_Residue = 0;
+ }
+ else
+ {
+ Scsi_Status = SCSI_FAILED;
+ }
+ }
+
+ // Clear the bUnitAttention flag after the response was properly sent via
+ // MscSendData().
+ if(bUnitAttention == TRUE)
+ {
+ bUnitAttention = FALSE;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID Scsi_Test_Unit_Ready(BYTE intfNum)
+{
+ if(SUCCESS != Check_CBW(intfNum,DIRECTION_OUT,0))
+ Scsi_Status = SCSI_FAILED;
+
+ Reset_RequestSenseResponse();
+}
+
+//----------------------------------------------------------------------------
+
+VOID Scsi_Unknown_Request(BYTE intfNum)
+{
+ Reset_RequestSenseResponse();
+
+ RequestSenseResponse.ResponseCode = RESCODE_CURRENT_ERROR;
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.AddSenseLen = 0xA0;
+ RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
+ RequestSenseResponse.ASC = ASC_INVALID_COMMAND_OP_CODE;
+ RequestSenseResponse.ASCQ = ASCQ_INVALID_COMMAND_OP_CODE;
+ Scsi_Residue = 0;
+ Scsi_Status = SCSI_FAILED;
+
+ if (McsCbw.dCBWDataTransferLength && (McsCbw.bmCBWFlags == DIRECTION_IN))
+ {
+ bMcsCommandSupported = FALSE;
+ usbStallInEndpoint(intfNum);
+ }
+ if (McsCbw.dCBWDataTransferLength && (McsCbw.bmCBWFlags == DIRECTION_OUT))
+ {
+ bMcsCommandSupported = FALSE;
+ usbStallOutEndpoint(intfNum);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+VOID Scsi_Report_Luns(BYTE intfNum)
+{
+ if(FAILURE == Check_CBW( intfNum, DIRECTION_IN, SCSI_REPORT_LUNS_CMD_LEN))
+ return;
+ if(SUCCESS != MscSendData( (PBYTE)&Report_Luns, SCSI_REPORT_LUNS_CMD_LEN))
+ Scsi_Status = SCSI_FAILED;
+}
+
+//----------------------------------------------------------------------------
+
+BYTE Scsi_Cmd_Parser(BYTE intfNum)
+{
+ BYTE ret = kUSBMSC_cmdBeingProcessed;
+ //Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = McsCbw.dCBWDataTransferLength;
+
+ // fails the commands during UNIT ATTENTION
+ if((bUnitAttention) &&(McsCbw.CBWCB[0] != SCSI_INQUIRY) && (McsCbw.CBWCB[0] !=SCSI_REQUEST_SENSE))
+ {
+ Scsi_Status = SCSI_FAILED;
+ return kUSB_generalError;
+ }
+
+ if(!McsCbw.bCBWCBLength)
+ return kUSB_generalError;
+
+ switch(McsCbw.CBWCB[0]) // SCSI Operation code
+ {
+ case SCSI_READ_10:
+ if(xBufferAddr == NULL) // Check for null address.
+ {
+ ret = kUSB_generalError;
+ SET_RequestsenseNotReady();
+ Scsi_Status = SCSI_FAILED;
+ usbStallInEndpoint(intfNum);
+ break;
+ }
+
+ if(sCtrlLun[McsCbw.bCBWLUN].bMediaPresent == kUSBMSC_MEDIA_NOT_PRESENT) // Check for media present. Do this for any command that accesses media.
+ {
+ ret = kUSB_generalError;
+ SET_RequestsenseMediaNotPresent();
+ usbStallInEndpoint(intfNum);
+ break;
+ }
+ Scsi_Read10(intfNum);
+ break;
+
+ case SCSI_WRITE_10:
+ if(xBufferAddr == NULL) // Check for null address.
+ {
+ ret = kUSB_generalError;
+ SET_RequestsenseNotReady();
+ Scsi_Status = SCSI_FAILED;
+ break;
+ }
+
+ if(sCtrlLun[McsCbw.bCBWLUN].bMediaPresent == kUSBMSC_MEDIA_NOT_PRESENT) // Check for media present. Do this for any command that accesses media.
+ {
+ ret = kUSB_generalError;
+ SET_RequestsenseMediaNotPresent();
+ usbStallOutEndpoint(intfNum);
+ break;
+ }
+
+ if(sCtrlLun[McsCbw.bCBWLUN].bWriteProtected) // Do this only for WRITE
+ {
+ ret = kUSB_generalError;
+ // Set REQUEST SENSE with "write protected"
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_WRITE_PROTECTED;
+ RequestSenseResponse.ASC =ASC_WRITE_PROTECTED;
+ RequestSenseResponse.ASCQ = ASCQ_WRITE_PROTECTED;
+ MscWriteControl.bWriteProcessing = FALSE;
+ // Send CSW with error status
+ Scsi_Residue = 1;
+ Scsi_Status = SCSI_FAILED;
+ usbStallOutEndpoint(intfNum);
+ break;
+ }
+
+ Scsi_Write10(intfNum);
+ break;
+
+ case START_STOP_UNIT:
+ case PREVENT_ALLW_MDM:
+ case SCSI_MODE_SELECT_10:
+ case SCSI_MODE_SELECT_6:
+ case SCSI_TEST_UNIT_READY:
+ if(sCtrlLun[McsCbw.bCBWLUN].bMediaPresent == kUSBMSC_MEDIA_NOT_PRESENT) // Check for media present. Do this for any command that accesses media.
+ {
+ ret = kUSB_generalError;
+ SET_RequestsenseMediaNotPresent();
+ break;
+ }
+ Scsi_Test_Unit_Ready(intfNum);
+ break;
+
+ case SCSI_INQUIRY:
+ Scsi_Inquiry(intfNum);
+ break;
+
+ case SCSI_MODE_SENSE_6:
+ Scsi_Mode_Sense6(intfNum);
+ break;
+
+ case SCSI_MODE_SENSE_10:
+ Scsi_Mode_Sense10(intfNum);
+ break;
+
+ case SCSI_READ_CAPACITY_10:
+ if(sCtrlLun[McsCbw.bCBWLUN].bMediaPresent == kUSBMSC_MEDIA_NOT_PRESENT) // Check for media present. Do this for any command that accesses media.
+ {
+ ret = kUSB_generalError;
+ SET_RequestsenseMediaNotPresent();
+ usbStallInEndpoint(intfNum);
+ break;
+ }
+ Scsi_Read_Capacity10(intfNum);
+ break;
+
+ case SCSI_REQUEST_SENSE:
+ Scsi_Request_Sense(intfNum);
+ break;
+
+ case SCSI_REPORT_LUNS:
+ if(sCtrlLun[McsCbw.bCBWLUN].bMediaPresent == kUSBMSC_MEDIA_NOT_PRESENT) // Check for media present. Do this for any command that accesses media.
+ {
+ ret = kUSB_generalError;
+ SET_RequestsenseMediaNotPresent();
+ if (McsCbw.bmCBWFlags == DIRECTION_IN)
+ {
+ usbStallInEndpoint(intfNum);
+ }
+ else
+ {
+ usbStallOutEndpoint(intfNum);
+ }
+ break;
+ }
+ Scsi_Report_Luns(intfNum);
+ break;
+ case SCSI_VERIFY:
+ /* Fix for SDOCM00078183 */
+ /* NOTE: we are assuming that BYTCHK=0 and PASSing the command. */
+ break;
+
+ default:
+ ret = kUSB_generalError;
+ Scsi_Unknown_Request(intfNum);
+ break;
+ }
+ return ret;
+}
+
+//-------------------------------------------------------------------------------------------------------
+/* This function is called only from ISR(only on Input endpoint interrupt to transfer data to host)
+ This function actually performs the data transfer to host Over USB */
+BOOL MSCToHostFromBuffer()
+{
+ // Check if there are any pending LBAs to process
+ BYTE * pEP1;
+ BYTE * pEP2;
+ BYTE * pCT1;
+ BYTE * pCT2;
+ BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt
+ BYTE edbIndex;
+ BYTE bCount;
+
+ MscReadControl.bIsIdle = FALSE;
+
+ // Check if there are any pending data to send
+ if (MscReadControl.dwBytesToSendLeft == 0)
+ {
+ //no more data to send - clear ready busy status
+ MscReadControl.bReadProcessing = FALSE;
+
+ //check if more LBA to send out pending...
+ if (MscReadControl.lbaCount > 0)
+ {
+ sRwbuf.lba = MscReadControl.lba; //update current lba
+ sRwbuf.lbCount = MscControl.lbaBufCapacity > MscReadControl.lbaCount ?
+ MscReadControl.lbaCount : MscControl.lbaBufCapacity; //update LBA count
+ sRwbuf.bufferAddr = xBufferAddr; //buffer for place data in
+ sRwbuf.operation = kUSBMSC_READ; //start data READ phase
+ sRwbuf.returnCode = kUSBMSC_RWSuccess;
+ sRwbuf.XorY = 0; //only one buffer is active
+ //buffer is prepared, let user's Application fill data.
+ USBMSC_handleBufferEvent();
+ }
+ return TRUE; //data sent out - wake up!
+ }
+
+ edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;
+
+ //check if the endpoint is stalled = do not send data.
+ if (tInputEndPointDescriptorBlock[edbIndex].bEPCNF & EPCNF_STALL)
+ {
+ return TRUE;
+ }
+
+ // send one chunk of 64 bytes
+ //check what is current buffer: X or Y
+ if (MscReadControl.bCurrentBufferXY == X_BUFFER) //X is current buffer
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].iep_X_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+
+ //second EP buffer
+ pEP2 = (BYTE*)stUsbHandle[MSC0_INTFNUM].iep_Y_Buffer;
+ pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+ else
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].iep_Y_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+
+ //second EP buffer
+ pEP2 = (BYTE*)stUsbHandle[MSC0_INTFNUM].iep_X_Buffer;
+ pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+
+ // how many byte we can send over one endpoint buffer
+ bCount = (MscReadControl.dwBytesToSendLeft > EP_MAX_PACKET_SIZE) ? EP_MAX_PACKET_SIZE : MscReadControl.dwBytesToSendLeft;
+
+ if(*pCT1 & EPBCNT_NAK)
+ {
+ USB_TX_memcpy(pEP1, MscReadControl.pUserBuffer, bCount); // copy data into IEPx X or Y buffer
+ *pCT1 = bCount; // Set counter for usb In-Transaction
+ MscReadControl.bCurrentBufferXY = (MscReadControl.bCurrentBufferXY+1)&0x01; //switch buffer
+ MscReadControl.dwBytesToSendLeft -= bCount;
+ MscReadControl.pUserBuffer += bCount; // move buffer pointer
+
+ //try to send data over second buffer
+ if ((MscReadControl.dwBytesToSendLeft > 0) && // do we have more data to send?
+ (*pCT2 & EPBCNT_NAK)) // if the second buffer is free?
+ {
+ // how many byte we can send over one endpoint buffer
+ bCount = (MscReadControl.dwBytesToSendLeft > EP_MAX_PACKET_SIZE) ? EP_MAX_PACKET_SIZE : MscReadControl.dwBytesToSendLeft;
+ // copy data into IEPx X or Y buffer
+ USB_TX_memcpy(pEP2, MscReadControl.pUserBuffer, bCount);
+ // Set counter for usb In-Transaction
+ *pCT2 = bCount;
+ //switch buffer
+ MscReadControl.bCurrentBufferXY = (MscReadControl.bCurrentBufferXY+1)&0x01;
+ MscReadControl.dwBytesToSendLeft -= bCount;
+ //move buffer pointer
+ MscReadControl.pUserBuffer += bCount;
+ }
+ } // if(*pCT1 & EPBCNT_NAK)
+ return bWakeUp;
+}
+
+//------------------------------------------------------------------------------------------------------
+
+//This function used to initialize the sending process.
+//Use this by functiosn for send CSW or send LBA
+//To use only by STACK itself, not by application
+//Returns: SUCCESS or FAILURE
+BYTE MscSendData(const BYTE* data, WORD size)
+{
+ BYTE edbIndex;
+ unsigned short bGIE;
+
+ edbIndex= stUsbHandle[MSC0_INTFNUM].edb_Index;
+
+ if (size == 0)
+ {
+ return FAILURE;
+ }
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ {
+ // data can not be read because of USB suspended
+ __bis_SR_register(bGIE); //restore interrupt status
+ return FAILURE;
+ }
+
+ if ((MscReadControl.dwBytesToSendLeft != 0) || // data was not sent out
+ (MscReadControl.bReadProcessing == TRUE)) //still processing previous data
+ {
+ // the USB still sends previous data, we have to wait
+ __bis_SR_register(bGIE); //restore interrupt status
+ return FAILURE;
+ }
+
+ //This function generate the USB interrupt. The data will be sent out from interrupt
+
+ MscReadControl.bReadProcessing = TRUE; //set reading busy status.
+ MscReadControl.dwBytesToSendLeft = size;
+ MscReadControl.pUserBuffer = (BYTE*)data;
+
+ //trigger Endpoint Interrupt - to start send operation
+ USBIEPIFG |= 1<<(edbIndex+1); //IEPIFGx;
+
+ __bis_SR_register(bGIE); //restore interrupt status
+
+ return SUCCESS;
+}
+
+// This function copies data from OUT endpoint into user's buffer
+// This function to call only from MSCFromHostToBuffer()
+// Arguments:
+// pEP - pointer to EP to copy from
+// pCT - pointer to EP control reg
+//
+VOID MscCopyUsbToBuff(BYTE* pEP, BYTE* pCT)
+{
+ BYTE nCount;
+ nCount = *pCT &(~EPBCNT_NAK);
+
+ //how many bytes we can receive to avoid overflow
+ nCount = (nCount > MscWriteControl.dwBytesToReceiveLeft) ? MscWriteControl.dwBytesToReceiveLeft : nCount;
+
+ USB_RX_memcpy(MscWriteControl.pUserBuffer, pEP, nCount); // copy data from OEPx X or Y buffer
+ MscWriteControl.dwBytesToReceiveLeft -= nCount;
+ MscWriteControl.pUserBuffer += nCount; // move buffer pointer
+ // to read rest of data next time from this place
+ MscWriteControl.wFreeBytesLeft -= nCount; //update counter
+
+ MscWriteControl.wCurrentByte += nCount;
+ if (MscWriteControl.wCurrentByte >= MscControl.lbaSize)
+ {
+ MscWriteControl.wCurrentByte = 0;
+ MscWriteControl.lbaCount++;
+ }
+
+ //switch current buffer
+ MscWriteControl.bCurrentBufferXY = (MscWriteControl.bCurrentBufferXY+1) &0x01;
+
+ //clear NAK, EP ready to receive data
+ *pCT = 0x00;
+}
+
+//------------------------------------------------------------------------------------------------------
+/* This function is called only from ISR(only on Output endpoint interrupt, to recv data from host)
+ This function actually recieves the data from host Over USB */
+BOOL MSCFromHostToBuffer()
+{
+ BYTE * pEP1;
+ BYTE nTmp1;
+ BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;
+
+ MscReadControl.bIsIdle = FALSE;
+
+ if (bMscCbwReceived == TRUE)
+ {
+ //previous CBW is not performed, so exit interrupt hendler
+ //and trigger it again later
+ return TRUE; //true for wake up!
+ }
+
+ if (!MscWriteControl.bWriteProcessing) //receiving CBW
+ {
+ //CBW will be received here....
+ //check what is current buffer: X or Y
+ if (MscWriteControl.bCurrentBufferXY == X_BUFFER) //X is current buffer
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_X_Buffer;
+ MscWriteControl.pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ MscWriteControl.pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+ else
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_Y_Buffer;
+ MscWriteControl.pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ MscWriteControl.pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+
+ // how many byte we can get from one endpoint buffer
+ nTmp1 = *MscWriteControl.pCT1;
+
+ if(nTmp1 & EPBCNT_NAK)
+ {
+ BYTE nCount;
+
+ //switch current buffer
+ MscWriteControl.bCurrentBufferXY = (MscWriteControl.bCurrentBufferXY+1) &0x01;
+
+ nTmp1 = nTmp1 &0x7f; // clear NAK bit
+ nCount = (nTmp1 > sizeof(McsCbw)) ? sizeof(McsCbw) : nTmp1;
+ USB_RX_memcpy(&McsCbw, pEP1, nCount); // copy data from OEPx X or Y buffer
+
+ //clear NAK, EP ready to receive data
+ *MscWriteControl.pCT1 = 0x00;
+
+ //set flag and check the CBW from the usbmsc_poll
+ bMscCbwReceived = TRUE;
+
+ // second 64b buffer will be not read out here because the CBW is <64 bytes
+ }
+
+ bWakeUp = TRUE; //wake up to perform CBW
+ return bWakeUp;
+ }
+
+ //if we are here - LBAs will be received
+
+ /*Check if there are any pending LBAs to process */
+ if (MscWriteControl.dwBytesToReceiveLeft > 0)
+ {
+ // read one chunk of 64 bytes
+
+ //check what is current buffer: X or Y
+ if (MscWriteControl.bCurrentBufferXY == X_BUFFER) //X is current buffer
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_X_Buffer;
+ MscWriteControl.pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+
+ //second EP buffer
+ MscWriteControl.pEP2 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_Y_Buffer;
+ MscWriteControl.pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+ else
+ {
+ //this is the active EP buffer
+ pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_Y_Buffer;
+ MscWriteControl.pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+
+ //second EP buffer
+ MscWriteControl.pEP2 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_X_Buffer;
+ MscWriteControl.pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+
+ // how many byte we can get from one endpoint buffer
+ nTmp1 = *MscWriteControl.pCT1;
+
+ if((nTmp1 & EPBCNT_NAK) &&
+ (MscWriteControl.wFreeBytesLeft >= 64))
+ {
+ //copy data from Endpoint
+ MscCopyUsbToBuff(pEP1, MscWriteControl.pCT1);
+
+ nTmp1 = *MscWriteControl.pCT2;
+
+ //try read data from second buffer
+ if ((MscWriteControl.dwBytesToReceiveLeft > 0) && // do we have more data to send?
+ (MscWriteControl.wFreeBytesLeft >= 64) &&
+ (nTmp1 & EPBCNT_NAK)) // if the second buffer has received data?
+ {
+ //copy data from Endpoint
+ MscCopyUsbToBuff(MscWriteControl.pEP2, MscWriteControl.pCT2);
+ //MscWriteControl.pCT1 = MscWriteControl.pCT2;
+ }
+
+ if ((MscWriteControl.wFreeBytesLeft == 0) || // user's buffer is full, give it to User
+ (MscWriteControl.dwBytesToReceiveLeft == 0)) //or no bytes to read left - give it to User
+ {
+ sRwbuf.operation = kUSBMSC_WRITE;
+ sRwbuf.lba = MscWriteControl.lba; //copy lba number
+ MscWriteControl.lba += MscWriteControl.lbaCount;
+ sRwbuf.lbCount = MscWriteControl.lbaCount; //copy lba count
+ MscWriteControl.wCurrentByte = 0;
+ MscWriteControl.lbaCount = 0;
+
+ //call event handler, we are ready with data
+ bWakeUp = USBMSC_handleBufferEvent();
+ } //if (wFreeBytesLeft == 0)
+ }
+ }// if (MscWriteControl.dwBytesToReceiveLeft > 0)
+ else
+ {
+ //perform error handling here, if required.
+ bWakeUp = TRUE;
+ }
+ return bWakeUp;
+}
+
+//--------------------------------------------------------------------------------------
+/*This function is called by application to indicate buffer processed and ready for stack to operate on */
+BYTE USBMSC_bufferProcessed()
+{
+ unsigned short bGIE;
+
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ // Disable interrupt
+ __disable_interrupt();
+
+ /* Fix for SDOCM00078384 */
+ /* Reset bWriteProcessing after last buffer is processed by the application */
+ if (sRwbuf.operation == kUSBMSC_WRITE && MscWriteControl.dwBytesToReceiveLeft == 0) // the Receive opereation (MSC_WRITE) is completed
+ {
+ MscWriteControl.pUserBuffer = NULL; // no more receiving pending
+ MscWriteControl.bWriteProcessing = FALSE; //ready to receive next CBW
+ }
+
+ if (sRwbuf.operation == kUSBMSC_WRITE && sRwbuf.returnCode == kUSBMSC_RWSuccess)
+ {
+ //initialize user buffer.
+ MscWriteControl.pUserBuffer = xBufferAddr;
+ MscWriteControl.wFreeBytesLeft = MscControl.wMscUserBufferSize;
+ sRwbuf.operation = NULL; //no operation pending...
+ //read out next portion of data if available.
+ MSCFromHostToBuffer();
+
+
+ }
+ else if (sRwbuf.operation == kUSBMSC_READ && sRwbuf.returnCode == kUSBMSC_RWSuccess)
+ {
+ WORD wCnt = sRwbuf.lbCount * MscControl.lbaSize;
+
+ //trigger sending LBA(s)
+ MscSendData(sRwbuf.bufferAddr, wCnt);
+
+ if (sRwbuf.lbCount >= MscReadControl.lbaCount)
+ {
+ //all bytes sent, reset structure
+ MscReadControl.lbaCount = 0;
+ }
+ else
+ {
+ //update read structure
+ MscReadControl.lbaCount -= sRwbuf.lbCount;
+ MscReadControl.lba += sRwbuf.lbCount;
+ }
+ sRwbuf.operation = NULL; //no operation pending...
+ }
+
+ switch(sRwbuf.returnCode)
+ {
+ case kUSBMSC_RWSuccess:
+ Scsi_Residue = 0;
+ Reset_RequestSenseResponse();
+ break;
+ // Set RequestSenseResponse if necessary? Maybe initialized values OK?
+
+ case kUSBMSC_RWNotReady:
+ Scsi_Status =SCSI_FAILED;
+ Scsi_Residue = 1;
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_NOT_READY;
+ RequestSenseResponse.ASC = ASC_NOT_READY;
+ RequestSenseResponse.ASCQ = ASCQ_NOT_READY;
+ break;
+
+ case kUSBMSC_RWIllegalReq:
+ Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = 0;
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
+ RequestSenseResponse.ASC = ASC_ILLEGAL_REQUEST;
+ RequestSenseResponse.ASCQ = ASCQ_ILLEGAL_REQUEST;
+ break;
+
+ case kUSBMSC_RWUnitAttn:
+ Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = 0;
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_UNITATTN;
+ RequestSenseResponse.ASC = ASC_UNITATTN_READY_NOTREADY;
+ RequestSenseResponse.ASCQ = ASCQ_UNITATTN_READY_NOTREADY;
+ break;
+
+ case kUSBMSC_RWLbaOutOfRange:
+ Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = 0;
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
+ RequestSenseResponse.ASC = ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+ RequestSenseResponse.ASCQ = ASCQ_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+ break;
+
+ case kUSBMSC_RWMedNotPresent:
+ Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = 0;
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_NOT_READY;
+ RequestSenseResponse.ASC =ASC_MEDIUM_NOT_PRESENT;
+ RequestSenseResponse.ASCQ = ASCQ_MEDIUM_NOT_PRESENT;
+ break;
+
+ case kUSBMSC_RWDevWriteFault:
+ Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = 0;
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_MEDIUM_ERROR;
+ RequestSenseResponse.ASC =ASC_WRITE_FAULT;
+ RequestSenseResponse.ASCQ = ASCQ_WRITE_FAULT;
+ break;
+
+ case kUSBMSC_RWUnrecoveredRead:
+ Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = 0;
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_MEDIUM_ERROR;
+ RequestSenseResponse.ASC = ASC_UNRECOVERED_READ;
+ RequestSenseResponse.ASCQ = ASCQ_UNRECOVERED_READ;
+ break;
+
+ case kUSBMSC_RWWriteProtected:
+ Scsi_Status = SCSI_FAILED;
+ Scsi_Residue = 0;
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_WRITE_PROTECTED;
+ RequestSenseResponse.ASC = ASC_WRITE_PROTECTED;
+ RequestSenseResponse.ASCQ = ASCQ_WRITE_PROTECTED;
+ break;
+ // case breakouts for all the codes
+ }
+
+ if(sRwbuf.returnCode != kUSBMSC_RWSuccess)
+ {
+ sRwbuf.operation = NULL; //no operation pending...
+ if (McsCbw.bmCBWFlags == DIRECTION_IN)
+ {
+ usbStallInEndpoint(MSC0_INTFNUM);
+ MscReadControl.bReadProcessing = FALSE; //ready to receive next CBW
+ MscReadControl.pUserBuffer = NULL; // no more receiving pending
+ MscReadControl.lbaCount = 0;
+ }
+ else
+ {
+ //we need to stall only if not all af data was transfered
+ if (MscWriteControl.dwBytesToReceiveLeft > 0)
+ {
+ usbStallOutEndpoint(MSC0_INTFNUM);
+ }
+ MscWriteControl.bWriteProcessing = FALSE; //ready to receive next CBW
+ MscWriteControl.pUserBuffer = NULL; // no more receiving pending
+ *MscWriteControl.pCT1 = 0x00; //clear NAK, EP ready to receive next data
+ *MscWriteControl.pCT2 = 0x00; //clear NAK, EP ready to receive next data
+ }
+ }
+
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSB_succeed;
+}
+
+//-------------------------------------------------------------------------------------------
+VOID Msc_ResetFlags()
+{
+ bMscCbwReceived = FALSE;
+}
+
+//-------------------------------------------------------------------------------------------
+VOID Msc_ResetStruct()
+{
+ memset(&sRwbuf,0,sizeof(USBMSC_RWbuf_Info));
+ memset(&McsCbw,0,sizeof(CBW));
+ memset(&McsCsw,0,sizeof(CSW));
+
+ MscReadControl.pUserBuffer = NULL;
+ MscReadControl.dwBytesToSendLeft = 0;
+ MscReadControl.bReadProcessing = FALSE;
+
+ MscWriteControl.bWriteProcessing = FALSE;
+ MscWriteControl.pUserBuffer = NULL;
+ MscWriteControl.dwBytesToReceiveLeft = 0; // holds how many bytes is still requested by WRITE operation (Host to MSP430)
+ // we do not reset the bCurrentBufferXY, becuase the buffer doesnt changed if he MSC reseted.
+ // The bCurrentBufferXY should be reseted in USB_Reset()
+
+ Reset_RequestSenseResponse();
+}
+
+//-------------------------------------------------------------------------------------------
+VOID MscResetData()
+{
+ Msc_ResetStruct();
+
+ memset(&MscWriteControl , 0, sizeof(MscWriteControl));
+ memset(&MscReadControl, 0, sizeof(MscReadControl));
+}
+
+//-------------------------------------------------------------------------------------------
+VOID MscResetCtrlLun()
+{
+ int i;
+ for(i =0; i < MSC_MAX_LUN_NUMBER; i++)
+ {
+ sCtrlLun[i].bMediaPresent = 0x80;
+ sCtrlLun[i].bWriteProtected = FALSE;
+ }
+}
+
+//-------------------------------------------------------------------------------------------
+/* This function can be called by application to get the current status of stack operation */
+BYTE USBMSC_getState()
+{
+ BYTE state;
+ if (sRwbuf.operation == 0 && MscReadControl.bIsIdle == TRUE)
+ state = kUSBMSC_idle;
+ else if(sRwbuf.operation == kUSBMSC_READ && sRwbuf.lbCount > 0)
+ state = kUSBMSC_readInProgress;
+ else if(sRwbuf.operation == kUSBMSC_WRITE && sRwbuf.lbCount > 0)
+ state = kUSBMSC_writeInProgress;
+ else if(sRwbuf.operation == 0 && MscReadControl.bIsIdle == FALSE)
+ state = kUSBMSC_cmdBeingProcessed;
+ return state;
+}
+
+//-------------------------------------------------------------------------------------------
+BYTE USBMSC_updateMediaInfo( BYTE lun, struct USBMSC_mediaInfoStr *info)
+{
+ BYTE state;
+
+ Scsi_Read_Capacity_10[lun].lLba[0] = (BYTE)(info->lastBlockLba >> 24);
+ Scsi_Read_Capacity_10[lun].lLba[1] = (BYTE)(info->lastBlockLba >> 16);
+ Scsi_Read_Capacity_10[lun].lLba[2] = (BYTE)(info->lastBlockLba >> 8);
+ Scsi_Read_Capacity_10[lun].lLba[3] = (BYTE)(info->lastBlockLba);
+
+ Scsi_Read_Capacity_10[lun].bLength[0] = (BYTE)(info->bytesPerBlock >> 24);
+ Scsi_Read_Capacity_10[lun].bLength[1] = (BYTE)(info->bytesPerBlock >> 16);
+ Scsi_Read_Capacity_10[lun].bLength[2] = (BYTE)(info->bytesPerBlock >> 8);
+ Scsi_Read_Capacity_10[lun].bLength[3] = (BYTE)(info->bytesPerBlock);
+
+ MscControl.lbaSize = (WORD)Scsi_Read_Capacity_10[lun].bLength[2] << 8 | Scsi_Read_Capacity_10[lun].bLength[3];
+ MscControl.lbaBufCapacity = MscControl.wMscUserBufferSize / MscControl.lbaSize;
+
+ // If the LUN was reported as not removable, then leave mediaPresent/mediaChanged as
+ // their initialized defaults.
+ if(USBMSC_config.LUN[lun].removable)
+ {
+ if(((sCtrlLun[lun].bMediaPresent== kUSBMSC_MEDIA_NOT_PRESENT)) && (info->mediaPresent == kUSBMSC_MEDIA_PRESENT)) // If media was inserted...
+ {
+ // Set Unit Attention flag. This flag is used in Scsi_Request_Sense().
+ bUnitAttention = TRUE;
+ Scsi_Status = SCSI_FAILED;
+ }
+
+ if((sCtrlLun[lun].bMediaPresent == kUSBMSC_MEDIA_PRESENT && ((info->mediaPresent == kUSBMSC_MEDIA_NOT_PRESENT))) || // If media was removed...
+ ((info->mediaPresent == kUSBMSC_MEDIA_PRESENT) && (info->mediaChanged))) // Or if media still present, but has changed...
+ {
+ // Set Unit Attention flag. This flag is used in Scsi_Request_Sense().
+ bUnitAttention = TRUE;
+ Scsi_Status = SCSI_FAILED;
+ state = USBMSC_getState();
+
+ if(state == kUSBMSC_readInProgress || state == kUSBMSC_writeInProgress)
+ {
+ if (McsCbw.bmCBWFlags == DIRECTION_IN)
+ {
+ usbStallInEndpoint(MSC0_INTFNUM);
+ }
+ else
+ {
+ usbStallOutEndpoint(MSC0_INTFNUM);
+ }
+
+ Msc_ResetStateMachine();
+ Msc_ResetFlags();
+ Msc_ResetStruct();
+ isMSCConfigured = TRUE;
+
+ Scsi_Send_CSW(MSC0_INTFNUM);
+ }
+ }
+ sCtrlLun[lun].bMediaPresent = info->mediaPresent;
+ }
+
+ sCtrlLun[lun].bWriteProtected = info->writeProtected;
+ return kUSB_succeed;
+}
+
+//-------------------------------------------------------------------------------------------
+BYTE USBMSC_registerBufInfo(BYTE *RWbuf_x, BYTE *RWbuf_y, WORD size)
+{
+ MscControl.wMscUserBufferSize = 0;
+ xBufferAddr = NULL;
+ yBufferAddr = NULL; //this version supports only X buffer.
+
+ //check if arguments are valid
+ if ((size < MscControl.lbaSize) ||
+ (RWbuf_x == NULL) ||
+ (RWbuf_y != NULL)) //this version supports only X buffer, so the y-buffer should be NULL
+ {
+ return kUSB_generalError;
+ }
+
+ MscControl.wMscUserBufferSize = size;
+ xBufferAddr = RWbuf_x;
+ return kUSB_succeed;
+}
+
+//-------------------------------------------------------------------------------------------
+VOID SET_RequestsenseNotReady()
+{
+ // Set REQUEST SENSE with "not ready"
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_NOT_READY;
+ RequestSenseResponse.ASC =ASC_NOT_READY;
+ RequestSenseResponse.ASCQ = ASCQ_NOT_READY;
+ // Send CSW with error status
+ Scsi_Status = SCSI_FAILED;
+}
+
+//-------------------------------------------------------------------------------------------
+VOID SET_RequestsenseMediaNotPresent()
+{
+ // Set REQUEST SENSE with "not ready"
+ Reset_RequestSenseResponse();
+ RequestSenseResponse.VALID = 1;
+ RequestSenseResponse.SenseKey = S_NOT_READY;
+ RequestSenseResponse.ASC =ASC_MEDIUM_NOT_PRESENT;
+ RequestSenseResponse.ASCQ = ASCQ_MEDIUM_NOT_PRESENT;
+ // Send CSW with error status
+ Scsi_Status = SCSI_FAILED;
+}
+
+//-------------------------------------------------------------------------------------------
+VOID usbClearOEPByteCount(BYTE intfNum)
+{
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0;
+}
+
+//-------------------------------------------------------------------------------------------
+VOID usbStallEndpoint(BYTE intfNum)
+{
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+ tOutputEndPointDescriptorBlock[edbIndex].bEPCNF |= EPCNF_STALL;
+ tInputEndPointDescriptorBlock[edbIndex].bEPCNF |= EPCNF_STALL;
+}
+
+//-------------------------------------------------------------------------------------------
+VOID usbStallInEndpoint(BYTE intfNum)
+{
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+ tInputEndPointDescriptorBlock[edbIndex].bEPCNF |= EPCNF_STALL;
+}
+
+//-------------------------------------------------------------------------------------------
+VOID usbStallOutEndpoint(BYTE intfNum)
+{
+ BYTE edbIndex;
+ edbIndex = stUsbHandle[intfNum].edb_Index;
+ tOutputEndPointDescriptorBlock[edbIndex].bEPCNF |= EPCNF_STALL;
+}
+
+//-------------------------------------------------------------------------------------------
+USBMSC_RWbuf_Info* USBMSC_fetchInfoStruct(VOID)
+{
+ return &sRwbuf;
+}
+#endif //_MSC_
+
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_MSC_API/UsbMscScsi.h b/USB_API/USB_MSC_API/UsbMscScsi.h
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * UsbMscScsi.h
+ *
+ * This file contains all the structure,function declarations used by stack
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+ | |
+ | Texas Instruments |
+ | |
+ | MSP430 USB-Example (MSC Driver) |
+ | |
+ +-----------------------------------------------------------------------------+
+ | Source: Msc_Scsi.h, File Version 1.02 |
+ | Description: This file contains all the structure,function declarations |
+ | used by stack |
+ | Author: Biju,MSP |
+ | |
+ | WHO WHEN WHAT |
+ | --- ---------- ------------------------------------------------ |
+ | MSP 2010/02/16 Created |
+ | Biju,MSP 2010/07/15 CV bug fix |
+ +----------------------------------------------------------------------------*/
+#ifndef _UMSC_SCSI_H_
+#define _UMSC_SCSI_H_
+
+#include <descriptors.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*Macros for CBW, CSW signatures */
+#define CBW_SIGNATURE 0x43425355u
+#define CSW_SIGNATURE 0x53425355u
+
+/*CBW, CSW length in bytes */
+#define CBW_LENGTH 31
+#define CSW_LENGTH 13
+
+/*SCSI Commands - Mandatory only implemented */
+#define SCSI_TEST_UNIT_READY 0x00
+#define SCSI_REQUEST_SENSE 0x03
+#define SCSI_INQUIRY 0x12
+#define SCSI_MODE_SENSE_6 0x1A
+#define SCSI_MODE_SENSE_10 0x5A
+#define SCSI_READ_CAPACITY_10 0x25
+#define SCSI_READ_10 0x28
+#define SCSI_WRITE_10 0x2A
+#define SCSI_READ_FORMAT_CAPACITIES 0x23
+#define SCSI_MODE_SELECT_6 0x15
+#define SCSI_MODE_SELECT_10 0x55
+#define PREVENT_ALLW_MDM 0x1E
+#define START_STOP_UNIT 0x1B
+#define SCSI_REPORT_LUNS 0xA0
+#define SCSI_VERIFY 0x2F
+
+/*SCSI Status codes. Used in CSW response */
+#define SCSI_PASSED 0
+#define SCSI_FAILED 1
+#define SCSI_PHASE_ERROR 2
+#define SCSI_READWRITE_FAIL 2
+
+#define kUSBMSC_RWSuccess 0
+#define kUSBMSC_RWNotReady 1
+#define kUSBMSC_RWIllegalReq 2
+#define kUSBMSC_RWUnitAttn 3
+#define kUSBMSC_RWLbaOutOfRange 4
+#define kUSBMSC_RWMedNotPresent 5
+#define kUSBMSC_RWDevWriteFault 6
+#define kUSBMSC_RWUnrecoveredRead 7
+#define kUSBMSC_RWWriteProtected 8
+
+
+ /* Macros to indicate READ or WRITE operation */
+#define kUSBMSC_READ 1
+#define kUSBMSC_WRITE 2
+
+#define kUSBMSC_MEDIA_PRESENT 0x81
+#define kUSBMSC_MEDIA_NOT_PRESENT 0x82
+
+#define kUSBMSC_WRITE_PROTECTED 0x00
+
+/* Defines for MSC SCSI State-Machine */
+#define MSC_READY 0x00
+#define MSC_COMMAND_TRANSPORT 0x01
+#define MSC_DATA_IN 0x02
+#define MSC_DATA_OUT 0x03
+#define MSC_STATUS_TRANSPORT 0x04
+#define MSC_DATA 0x05
+#define MSC_WAIT4RESET 0x06
+
+/*Lengths of SCSI commands(in bytes) */
+#define SCSI_SCSI_INQUIRY_CMD_LEN 36
+#define SCSI_READ_CAPACITY_CMD_LEN 8
+#define SCSI_MODE_SENSE_6_CMD_LEN 4
+#define SCSI_MODE_SENSE_10_CMD_LEN 8
+#define SCSI_REQ_SENSE_CMD_LEN 18
+#define SCSI_READ_FORMAT_CAPACITY_CMD_LEN 12
+#define SCSI_REPORT_LUNS_CMD_LEN 16
+/*----------------------------------------------------------------------------+
+| Type defines and structures |
++----------------------------------------------------------------------------*/
+/*CBW Structure */
+typedef struct _CBW
+{
+ DWORD dCBWSignature;
+ DWORD dCBWTag;
+ DWORD dCBWDataTransferLength;
+ BYTE bmCBWFlags;
+ BYTE bCBWLUN;
+ BYTE bCBWCBLength;
+ BYTE CBWCB[16];
+} CBW, *pCBW;
+
+/*CSW structure */
+typedef struct _CSW
+{
+ DWORD dCSWSignature;
+ DWORD dCSWTag;
+ DWORD dCSWDataResidue;
+ BYTE bCSWStatus;
+} CSW, *pCSW;
+
+/*Request Response union(Required for Request sense command) */
+typedef struct
+{
+ BYTE ResponseCode:7;
+ BYTE VALID:1;
+ BYTE Obsolete;
+ BYTE SenseKey:4;
+ BYTE Resv:1;
+ BYTE ILI:1;
+ BYTE EOM:1;
+ BYTE FILEMARK:1;
+ BYTE Information[4];
+ BYTE AddSenseLen;
+ BYTE CmdSpecificInfo[4];
+ BYTE ASC;
+ BYTE ASCQ;
+ BYTE FRUC;
+ BYTE SenseKeySpecific[3];
+ BYTE padding[14]; /* padding to cover case where host requests 24 bytes of sense data */
+
+} REQUEST_SENSE_RESPONSE;
+
+/*Read capacity union(Required for READ CAPACITY command)*/
+typedef struct
+{
+ DWORD Last_LBA;
+ BYTE Resv;
+ BYTE Size_LBA[3];
+} SCSI_READ_CAPACITY;
+
+/*Structure internal to stack for holding LBA,buffer addr etc information*/
+typedef struct
+{
+ // BYTE intfNum;
+ BYTE lun;
+ BYTE operation;
+ DWORD lba;
+ BYTE lbCount;
+ BYTE *bufferAddr;
+ BYTE returnCode;
+ BYTE XorY;
+}USBMSC_RWbuf_Info;
+
+/*Structure exposed(shared) to application. Populated by stack */
+struct LBAInfo
+{
+ BYTE intfNum;
+ BYTE lun;
+ DWORD dLBA;
+ int iLBA_Count;
+ BYTE operation;
+ BYTE *bufferAddr;
+ BYTE returnCode;
+ BYTE XorY;
+};
+
+/*Media info structure */
+struct USBMSC_mediaInfoStr
+{
+ DWORD lastBlockLba;
+ DWORD bytesPerBlock;
+ BYTE mediaPresent;
+ BYTE mediaChanged;
+ BYTE writeProtected;
+};
+
+/*Lun entry Structures */
+struct _LUN_entry_struct
+{
+ BYTE number;
+ BYTE PDT;
+ BYTE removable;
+ char t10VID[8];
+ char t10PID[16];
+ char t10rev[4];
+};
+
+struct config_struct
+{
+ struct _LUN_entry_struct LUN[MSC_MAX_LUN_NUMBER];
+};
+
+struct _Report_Luns
+{
+ BYTE LunListLength[4];
+ BYTE Reserved[4];
+ BYTE LunList1[8];
+};
+
+struct _Scsi_Read_Capacity
+{
+ BYTE lLba[4]; // Last logical block address
+ BYTE bLength[4]; // Block length, in this case 0x200 = 512 bytes for each Logical Block
+};
+
+//structure for controlling WRITE phase (HOST to MSP430)
+struct _MscWriteControl
+{
+ DWORD dwBytesToReceiveLeft; // holds how many bytes is still requested by WRITE operation:
+ // Host to MSP430.
+ WORD wFreeBytesLeft; // free bytes left in UserBuffer
+ DWORD lba; // holds the current LBA number. This is the first LBA in the UserBuffer
+ BYTE *pUserBuffer; // holds the current position of user's receiving buffer.
+ //If NULL- no receiving operation started
+ WORD wCurrentByte; // how many bytes in current LBA are received
+ BYTE lbaCount; // how many LBA we have received in current User Buffer
+ BYTE * pCT1; // holds current EPBCTxx register
+ BYTE * pCT2; // holds next EPBCTxx register
+ BYTE * pEP2; // holds addr of the next EP buffer
+ BYTE bCurrentBufferXY; // indicates which buffer is used by host to transmit data via OUT
+ BYTE bWriteProcessing; // indicated if the current state is DATA WRITE phase or CBW receiwing
+};
+
+//structure for controlling READ phase (MSP430 to HOST)
+struct _MscReadControl
+{
+ DWORD dwBytesToSendLeft;// holds how many bytes is still requested by WRITE operation (Host to MSP430)
+ BYTE *pUserBuffer; // holds the current position of user's receiving buffer.
+ //If NULL- no receiving operation started
+ DWORD lba; // holds the current LBA number. This is the first LBA in the UserBuffer.
+ BYTE * pCT1; // holds current EPBCTxx register
+ BYTE * pCT2; // holds next EPBCTxx register
+ BYTE * pEP2; // holds addr of the next EP buffer
+ BYTE lbaCount; // how many LBA we have to send to Host
+ BYTE bCurrentBufferXY; // indicates which buffer is used by host to transmit data via OUT
+ BYTE bReadProcessing; // indicated if the current state is DATA READ phase or CSW sending
+ // initiated by McsDataSend()
+ BYTE bIsIdle; //
+};
+
+//structure for common control of MSC stack
+struct _MscControl
+{
+ WORD wMscUserBufferSize;
+ WORD lbaSize; // limitid to WORD, but could be increased if required.
+ BYTE lbaBufCapacity; // how many LBAs (max) contains UserBuffer for read/write operation (>=1)
+};
+
+
+struct _CtrlLun
+{
+ BYTE bMediaPresent;
+ BYTE bWriteProtected;
+};
+extern struct _MscWriteControl MscWriteControl;
+extern struct _MscReadControl MscReadControl;
+extern struct _MscControl MscControl;
+
+/*----------------------------------------------------------------------------+
+| Extern Variables |
++----------------------------------------------------------------------------*/
+extern volatile DWORD Scsi_Residue;
+
+extern CBW cbw;
+extern CSW csw;
+extern REQUEST_SENSE_RESPONSE RequestSenseResponse;
+
+/*----------------------------------------------------------------------------+
+| Function Prototypes |
++----------------------------------------------------------------------------*/
+
+/*SCSI Wrapper functions */
+BYTE Scsi_Cmd_Parser(BYTE opcode);
+BYTE Scsi_Send_CSW(BYTE intfNum);
+
+/*Function to reset MSC SCSI state machine */
+VOID Msc_ResetStateMachine(VOID);
+VOID Msc_ResetFlags(VOID);
+VOID Msc_ResetStruct(VOID);
+VOID SET_RequestsenseNotReady(VOID);
+VOID SET_RequestsenseMediaNotPresent(VOID);
+VOID MscResetCtrlLun(VOID);
+
+USBMSC_RWbuf_Info* USBMSC_fetchInfoStruct(VOID);
+#ifdef __cplusplus
+}
+#endif
+#endif // _MSC_SCSI_H_
+
diff --git a/USB_API/USB_MSC_API/UsbMscStateMachine.c b/USB_API/USB_MSC_API/UsbMscStateMachine.c
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * UsbMscStateMachine.c
+ *
+ * This file contains the core function that handles the MSC SCSI state machine.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+ /*----------------------------------------------------------------------------+
+ | |
+ | Texas Instruments |
+ | |
+ | MSP430 USB-Example (MSC Driver) |
+ | |
+ +-----------------------------------------------------------------------------+
+ | Source: Msc_State_Machine.c, File Version 1.01 |
+ | Description: This file contains the core function that handles the MSC SCSI|
+ | state machine. |
+ | Author: Biju,MSP |
+ | |
+ | WHO WHEN WHAT |
+ | --- ---------- ------------------------------------------------ |
+ | MSP 2010/02/16 Created |
+ | Biju,MSP 2010/07/15 CV Bug fix |
+ | RSTO 2010/10/30 state machine rework |
+ +----------------------------------------------------------------------------*/
+/*File includes */
+#include "../USB_Common/device.h"
+#include "../USB_Common/types.h"
+#include "../USB_Common/defMSP430USB.h"
+#include "../USB_MSC_API/UsbMscScsi.h"
+#include "../USB_MSC_API/UsbMsc.h"
+#include "../USB_Common/usb.h"
+#include <descriptors.h>
+#include <string.h>
+
+#ifdef _MSC_
+
+/*Macros to indicate data direction */
+#define DIRECTION_IN 0x80
+#define DIRECTION_OUT 0x00
+
+/*Flags to monitor data send/recv.Will be set in ISR accordingly */
+extern BOOL bMscCbwReceived; //Flag to indicate whether any CBW recieved from host
+extern BOOL bMcsCommandSupported; //Flag to know if its a supported command
+extern BOOL bMscCbwFailed;
+
+/* Variable that holds the MSC SCSI state */
+static BOOL bMscSendCsw = FALSE;
+extern BOOL isMSCConfigured;
+
+/*Buffer pointers passed by application */
+extern BYTE *xBufferAddr;
+extern BYTE *yBufferAddr;
+extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
+
+BYTE Scsi_Verify_CBW();
+
+/*----------------------------------------------------------------------------+
+ | Functions |
++----------------------------------------------------------------------------*/
+VOID Msc_ResetStateMachine(VOID)
+{
+ bMscSendCsw = FALSE;
+ Scsi_Residue = 0;
+}
+
+//----------------------------------------------------------------------------
+/*This is the core function called by application to handle the MSC SCSI state
+ machine */
+BYTE USBMSC_poll()
+{
+ BYTE edbIndex;
+ BYTE ret;
+
+ edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;
+
+ //check if currently transmitting data..
+ if (MscReadControl.bReadProcessing == TRUE)
+ {
+ BYTE bGIE;
+ bGIE = (__get_SR_register() &GIE); //save interrupt status
+ // atomic operation - disable interrupts
+ __disable_interrupt(); // Disable global interrupts
+ if ((MscReadControl.dwBytesToSendLeft == 0) &&
+ (MscReadControl.lbaCount == 0))
+ {
+ //data is no more processing - clear flags..
+ MscReadControl.bReadProcessing = FALSE;
+ __bis_SR_register(bGIE); //restore interrupt status
+ }
+ else
+ {
+ if (!(tInputEndPointDescriptorBlock[edbIndex].bEPCNF & EPCNF_STALL)) //if it is not stalled - contiune communication
+ {
+ USBIEPIFG |= 1<<(edbIndex+1); //trigger IN interrupt to finish data tranmition
+ }
+ __bis_SR_register(bGIE); //restore interrupt status
+ return kUSBMSC_processBuffer;
+ }
+ }
+
+ if(isMSCConfigured == FALSE)
+ {
+ return kUSBMSC_okToSleep;
+ }
+
+ if (!bMscSendCsw)
+ {
+
+ ret = kUSBMSC_processBuffer;
+ if (bMscCbwReceived)
+ {
+ if (Scsi_Verify_CBW() == SUCCESS)
+ {
+ MscReadControl.bIsIdle = FALSE;
+ // Successful reception of CBW
+ // Parse the CBW opcode and invoke the right command handler function
+ Scsi_Cmd_Parser(MSC0_INTFNUM);
+ bMscSendCsw = TRUE;
+ }
+ bMscCbwReceived = FALSE; //CBW is performed!
+ }
+ else
+ {
+ if(!MscReadControl.bIsIdle)
+ {
+ return kUSBMSC_processBuffer;
+ }
+ else
+ {
+ return kUSBMSC_okToSleep;
+ }
+ }
+ //check if any of out pipes has pending data and trigger interrupt
+
+ if ((MscWriteControl.pCT1 != NULL) &&
+ ((*MscWriteControl.pCT1 & EPBCNT_NAK ) ||
+ (*MscWriteControl.pCT2 & EPBCNT_NAK )))
+ {
+ USBOEPIFG |= 1<<(edbIndex+1); //trigger OUT interrupt again
+ return kUSBMSC_processBuffer; //do not asleep, as data is coming in
+ //and follow up data perform will be required.
+ }
+ }
+
+ if (bMscSendCsw)
+ {
+ if (bMcsCommandSupported == TRUE)
+ {
+ // watiting till transport is finished!
+ if ((MscWriteControl.bWriteProcessing == FALSE) &&
+ (MscReadControl.bReadProcessing == FALSE) &&
+ (MscReadControl.lbaCount == 0))
+ {
+ // Send CSW
+ if(SUCCESS == Scsi_Send_CSW(MSC0_INTFNUM))
+ {
+ MscReadControl.bIsIdle = TRUE;
+ bMscSendCsw = FALSE;
+ ret = kUSBMSC_okToSleep;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+#endif // _MSC_
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_API/USB_MSC_API/UsbMscStateMachine.h b/USB_API/USB_MSC_API/UsbMscStateMachine.h
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * UsbMscStateMachine.h
+ *
+ * This file contains the core function that handles the MSC SCSI state machine.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+/*----------------------------------------------------------------------------+
+ | |
+ | Texas Instruments |
+ | |
+ | MSP430 USB-Example (MSC Driver) |
+ | |
+ +-----------------------------------------------------------------------------+
+ | Source: UsbMsc.h, File Version 1.01 |
+ | Description: This file contains API declarations for function to use by |
+ | User Application. |
+ | Author: Biju,MSP |
+ | |
+ | WHO WHEN WHAT |
+ | --- ---------- ------------------------------------------------ |
+ | RSTO 2010/10/29 Created |
+ +----------------------------------------------------------------------------*/
+#ifndef _USB_MSCSTATE_H_
+#define _USB_MSCSTATE_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ //this file is obsolete. To delete in next version.
+
+#ifdef __cplusplus
+}
+#endif
+#endif //_USB_MSCSTATE_H_
+
diff --git a/USB_config/MSP430_CDC.inf b/USB_config/MSP430_CDC.inf
--- /dev/null
@@ -0,0 +1,92 @@
+; Copyright (c) 2010 Texas Instruments
+; MSP430 Virtual COM Port Installation file for Win2000/XP/Vista/7
+;
+; Port drivers setup
+;
+; Supported operating systems:
+; Windows 32-bit and 64-bit
+[Version]
+
+Signature="$Windows NT$"
+CatalogFile=MSP430_CDC.cat
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%TI%
+DriverVer=09/06/2010, 1.02
+
+[Manufacturer]
+%TI%=DeviceList, NTamd64
+
+[DestinationDirs]
+FakeModemCopyFileSection=12
+DefaultDestDir=12
+
+[SourceDisksNames]
+
+[SourceDisksFiles]
+
+;You can modify next string and place your VID and PID
+[DeviceList]
+%DESCRIPTION0%=TIUSB, USB\Vid_2047&Pid_0300
+
+[DeviceList.NTamd64]
+%DESCRIPTION0%=TIUSB.NTamd64, USB\Vid_2047&Pid_0300
+
+ ;------------------------------------------------------------------------------
+; Windows 32-bit Sections
+;------------------------------------------------------------------------------
+
+[TIUSB.nt]
+include=mdmcpq.inf
+CopyFiles=FakeModemCopyFileSection
+AddReg=TIUSB.nt.AddReg
+
+[TIUSB.nt.AddReg]
+HKR,,NTMPDriver,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+HKR,,PortSubClass,1,01
+
+[TIUSB.nt.Services]
+AddService=usbser, 0x00000002, DriverService
+
+[TIUSB.nt.HW]
+include=mdmcpq.inf
+
+[DriverService]
+DisplayName=%DESCRIPTION%
+ServiceType=1
+StartType=3
+ErrorControl=1
+ServiceBinary=%12%\usbser.sys
+LoadOrderGroup=Base
+
+;------------------------------------------------------------------------------
+; Windows 64-bit Sections
+;------------------------------------------------------------------------------
+
+[TIUSB.NTamd64]
+include=mdmcpq.inf
+CopyFiles=FakeModemCopyFileSection
+AddReg=TIUSB.NTamd64.AddReg
+
+[TIUSB.NTamd64.AddReg]
+HKR,,NTMPDriver,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+HKR,,PortSubClass,1,01
+
+[TIUSB.NTamd64.Services]
+AddService=usbser, 0x00000002, DriverService
+
+[TIUSB.NTamd64.HW]
+include=mdmcpq.inf
+
+;------------------------------------------------------------------------------
+; String Definitions
+;------------------------------------------------------------------------------
+
+[Strings]
+TI="Texas Instruments"
+DESCRIPTION="MSP430-USB Example"
+DESCRIPTION0="Virtual UART0"
diff --git a/USB_config/UsbIsr.c b/USB_config/UsbIsr.c
--- /dev/null
+++ b/USB_config/UsbIsr.c
@@ -0,0 +1,386 @@
+// (c)2010 by Texas Instruments Incorporated, All Rights Reserved.
+/*-----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| This is an automatically generated script by MSP430 USB Descriptor Tool |
+| |
+| Descriptor Tool Version: 3.0.10 |
+| Date: 2011/10/13 11:03:28 |
+| |
+| UsbIsr.c |
+|-----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------+
+| Include files |
+|-----------------------------------------------------------------------------*/
+#include <USB_API/USB_Common/device.h>
+#include <USB_API/USB_Common/types.h> // Basic Type declarations
+#include <USB_API/USB_Common/defMSP430USB.h>
+#include "descriptors.h"
+#include <USB_API/USB_Common/usb.h> //USB-specific Data Structures
+#include <USB_API/USB_Common/UsbIsr.h>
+#include <string.h>
+#include <USB_API/USB_HID_API/UsbHidReportHandler.h>
+#include <USB_API/USB_CDC_API/UsbCdc.h>
+#include <USB_API/USB_HID_API/UsbHid.h>
+
+#include "../uart.h"
+
+/*----------------------------------------------------------------------------+
+| External Variables |
++----------------------------------------------------------------------------*/
+extern BYTE bFunctionSuspended;
+extern __no_init tEDB0 __data16 tEndPoint0DescriptorBlock;
+extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
+extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
+extern volatile BYTE bHostAsksUSBData;
+extern volatile BYTE bTransferInProgress;
+extern volatile BYTE bSecondUartTxDataCounter[];
+extern volatile PBYTE pbSecondUartTxData;
+extern BYTE bStatusAction;
+extern WORD wUsbEventMask;
+BOOL CdcToHostFromBuffer(BYTE);
+BOOL CdcToBufferFromHost(BYTE);
+BOOL CdcIsReceiveInProgress(BYTE);
+BOOL HidToHostFromBuffer(BYTE);
+BOOL HidToBufferFromHost(BYTE);
+BOOL HidIsReceiveInProgress(BYTE);
+/*----------------------------------------------------------------------------+
+| General Subroutines |
++----------------------------------------------------------------------------*/
+#pragma vector=USB_UBM_VECTOR
+__interrupt VOID iUsbInterruptHandler(VOID)
+{
+ BYTE bWakeUp = FALSE;
+ //Check if the setup interrupt is pending.
+ //We need to check it before other interrupts,
+ //to work around that the Setup Int has lower priority then Input Endpoint 0
+ if (USBIFG & SETUPIFG)
+ {
+ bWakeUp = SetupPacketInterruptHandler();
+ USBIFG &= ~SETUPIFG; // clear the interrupt bit
+ }
+ switch (__even_in_range(USBVECINT & 0x3f, USBVECINT_OUTPUT_ENDPOINT7))
+ {
+ case USBVECINT_NONE:
+ break;
+ case USBVECINT_PWR_DROP:
+ __no_operation();
+ break;
+ case USBVECINT_PLL_LOCK:
+ break;
+ case USBVECINT_PLL_SIGNAL:
+ break;
+ case USBVECINT_PLL_RANGE:
+ if (wUsbEventMask & kUSB_clockFaultEvent)
+ {
+ bWakeUp = USB_handleClockEvent();
+ }
+ break;
+ case USBVECINT_PWR_VBUSOn:
+ PWRVBUSonHandler();
+ if (wUsbEventMask & kUSB_VbusOnEvent)
+ {
+ bWakeUp = USB_handleVbusOnEvent();
+ }
+ break;
+ case USBVECINT_PWR_VBUSOff:
+ PWRVBUSoffHandler();
+ if (wUsbEventMask & kUSB_VbusOffEvent)
+ {
+ bWakeUp = USB_handleVbusOffEvent();
+ }
+ break;
+ case USBVECINT_USB_TIMESTAMP:
+ break;
+ case USBVECINT_INPUT_ENDPOINT0:
+ IEP0InterruptHandler();
+ break;
+ case USBVECINT_OUTPUT_ENDPOINT0:
+ OEP0InterruptHandler();
+ break;
+ case USBVECINT_RSTR:
+ USB_reset();
+ if (wUsbEventMask & kUSB_UsbResetEvent)
+ {
+ bWakeUp = USB_handleResetEvent();
+ }
+ break;
+ case USBVECINT_SUSR:
+ USB_suspend();
+ if (wUsbEventMask & kUSB_UsbSuspendEvent)
+ {
+ bWakeUp = USB_handleSuspendEvent();
+ }
+ break;
+ case USBVECINT_RESR:
+ USB_resume();
+ if (wUsbEventMask & kUSB_UsbResumeEvent)
+ {
+ bWakeUp = USB_handleResumeEvent();
+ }
+ //-- after resume we will wake up! Independ what event handler says.
+ bWakeUp = TRUE;
+ break;
+ case USBVECINT_SETUP_PACKET_RECEIVED:
+ // NAK both IEP and OEP enpoints
+ tEndPoint0DescriptorBlock.bIEPBCNT = EPBCNT_NAK;
+ tEndPoint0DescriptorBlock.bOEPBCNT = EPBCNT_NAK;
+ SetupPacketInterruptHandler();
+ break;
+ case USBVECINT_STPOW_PACKET_RECEIVED:
+ break;
+ case USBVECINT_INPUT_ENDPOINT1:
+ break;
+ case USBVECINT_INPUT_ENDPOINT2:
+ //send saved bytes from buffer...
+// bWakeUp = CdcToHostFromBuffer(CDC0_INTFNUM);
+
+ #ifdef UART0_INTFNUM
+ bWakeUp = UartToCdc(UART0_INTFNUM, CDC0_INTFNUM);
+ #else
+ //send saved bytes from buffer...
+ bWakeUp = CdcToHostFromBuffer(CDC0_INTFNUM);
+ #endif
+
+
+ break;
+ case USBVECINT_INPUT_ENDPOINT3:
+ break;
+ case USBVECINT_INPUT_ENDPOINT4:
+ //send saved bytes from buffer...
+// bWakeUp = CdcToHostFromBuffer(CDC1_INTFNUM);
+#if CDC_NUM_INTERFACES >= 2
+ #ifdef UART1_INTFNUM
+ bWakeUp = UartToCdc(UART1_INTFNUM, CDC1_INTFNUM);
+ #else
+ //send saved bytes from buffer...
+ bWakeUp = CdcToHostFromBuffer(CDC1_INTFNUM);
+ #endif
+#endif
+
+
+ break;
+ case USBVECINT_INPUT_ENDPOINT5:
+ break;
+ case USBVECINT_INPUT_ENDPOINT6:
+ break;
+ case USBVECINT_INPUT_ENDPOINT7:
+ break;
+ case USBVECINT_OUTPUT_ENDPOINT1:
+ break;
+ case USBVECINT_OUTPUT_ENDPOINT2:
+ //call callback function if no receive operation is underway
+/*
+ if (!CdcIsReceiveInProgress(CDC0_INTFNUM))
+ {
+ if (wUsbEventMask & kUSB_dataReceivedEvent)
+ {
+ bWakeUp = USBCDC_handleDataReceived(CDC0_INTFNUM);
+ }
+ }
+ else
+ {
+ //complete receive opereation - copy data to user buffer
+ bWakeUp = CdcToBufferFromHost(CDC0_INTFNUM);
+ }
+*/
+
+ #ifdef UART0_INTFNUM
+ bWakeUp = CdcToUart(CDC0_INTFNUM, UART0_INTFNUM);
+ #else
+ //call callback function if no receive operation is underway
+ if (!CdcIsReceiveInProgress(CDC0_INTFNUM))
+ {
+ if (wUsbEventMask & kUSB_dataReceivedEvent)
+ {
+ bWakeUp = USBCDC_handleDataReceived(CDC0_INTFNUM);
+ }
+ }
+ else
+ {
+ //complete receive opereation - copy data to user buffer
+ bWakeUp = CdcToBufferFromHost(CDC0_INTFNUM);
+ }
+ #endif
+
+
+ break;
+ case USBVECINT_OUTPUT_ENDPOINT3:
+ break;
+ case USBVECINT_OUTPUT_ENDPOINT4:
+ //call callback function if no receive operation is underway
+/*
+ if (!CdcIsReceiveInProgress(CDC1_INTFNUM))
+ {
+ if (wUsbEventMask & kUSB_dataReceivedEvent)
+ {
+ bWakeUp = USBCDC_handleDataReceived(CDC1_INTFNUM);
+ }
+ }
+ else
+ {
+ //complete receive opereation - copy data to user buffer
+ bWakeUp = CdcToBufferFromHost(CDC1_INTFNUM);
+ }
+*/
+
+#if CDC_NUM_INTERFACES >= 2
+ #ifdef UART1_INTFNUM
+ bWakeUp = CdcToUart(CDC1_INTFNUM, UART1_INTFNUM);
+ #else
+ //call callback function if no receive operation is underway
+ if (!CdcIsReceiveInProgress(CDC1_INTFNUM))
+ {
+ if (wUsbEventMask & kUSB_dataReceivedEvent)
+ {
+ bWakeUp = USBCDC_handleDataReceived(CDC1_INTFNUM);
+ }
+ }
+ else
+ {
+ //complete receive opereation - copy data to user buffer
+ bWakeUp = CdcToBufferFromHost(CDC1_INTFNUM);
+ }
+ #endif
+#endif
+
+ break;
+ case USBVECINT_OUTPUT_ENDPOINT5:
+ break;
+ case USBVECINT_OUTPUT_ENDPOINT6:
+ break;
+ case USBVECINT_OUTPUT_ENDPOINT7:
+ break;
+ default:
+ break;
+ }
+ if (bWakeUp)
+ {
+ __bic_SR_register_on_exit(LPM3_bits); // Exit LPM0-3
+ __no_operation(); // Required for debugger
+ }
+}
+
+/*----------------------------------------------------------------------------+
+| Interrupt Sub-routines |
++----------------------------------------------------------------------------*/
+BYTE SetupPacketInterruptHandler(VOID)
+{
+ BYTE bTemp;
+ BYTE bWakeUp = FALSE;
+ USBCTL |= FRSTE; // Function Reset Connection Enable - set enable after first setup packet was received
+ usbProcessNewSetupPacket:
+ // copy the MSB of bmRequestType to DIR bit of USBCTL
+ if((tSetupPacket.bmRequestType & USB_REQ_TYPE_INPUT) == USB_REQ_TYPE_INPUT)
+ {
+ USBCTL |= DIR;
+ }
+ else
+ {
+ USBCTL &= ~DIR;
+ }
+ bStatusAction = STATUS_ACTION_NOTHING;
+ // clear out return data buffer
+ for(bTemp=0; bTemp<USB_RETURN_DATA_LENGTH; bTemp++)
+ {
+ abUsbRequestReturnData[bTemp] = 0x00;
+ }
+ // decode and process the request
+ bWakeUp = usbDecodeAndProcessUsbRequest();
+ // check if there is another setup packet pending
+ // if it is, abandon current one by NAKing both data endpoint 0
+ if((USBIFG & STPOWIFG) != 0x00)
+ {
+ USBIFG &= ~(STPOWIFG | SETUPIFG);
+ goto usbProcessNewSetupPacket;
+ }
+ return bWakeUp;
+}
+
+//----------------------------------------------------------------------------
+VOID PWRVBUSoffHandler(VOID)
+{
+ volatile unsigned int i;
+ for (i =0; i < USB_MCLK_FREQ/1000*1/10; i++); // 1ms delay
+ if (!(USBPWRCTL & USBBGVBV))
+ {
+ USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
+ bEnumerationStatus = 0x00; // device is not enumerated
+ bFunctionSuspended = FALSE; // device is not suspended
+ USBCNF = 0; // disable USB module
+ USBPLLCTL &= ~UPLLEN; // disable PLL
+ USBPWRCTL &= ~(VBOFFIE + VBOFFIFG + SLDOEN); // disable interrupt VBUSoff
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+ }
+}
+
+//----------------------------------------------------------------------------
+VOID PWRVBUSonHandler(VOID)
+{
+ volatile unsigned int i;
+ for (i =0; i < USB_MCLK_FREQ/1000*1/10; i++); // waiting till voltage will be stable (1ms delay)
+ USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
+ USBPWRCTL |= VBOFFIE; // enable interrupt VBUSoff
+ USBPWRCTL &= ~ (VBONIFG + VBOFFIFG); // clean int flag (bouncing)
+ USBKEYPID = 0x9600; // access to configuration registers disabled
+}
+
+//----------------------------------------------------------------------------
+VOID IEP0InterruptHandler(VOID)
+{
+ USBCTL |= FRSTE; // Function Reset Connection Enable
+ tEndPoint0DescriptorBlock.bOEPBCNT = 0x00;
+ if(bStatusAction == STATUS_ACTION_DATA_IN)
+ {
+ usbSendNextPacketOnIEP0();
+ }
+ else
+ {
+ tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL; // no more data
+ }
+}
+
+//----------------------------------------------------------------------------
+VOID OEP0InterruptHandler(VOID)
+{
+ USBCTL |= FRSTE; // Function Reset Connection Enable
+ tEndPoint0DescriptorBlock.bIEPBCNT = 0x00;
+ if(bStatusAction == STATUS_ACTION_DATA_OUT)
+ {
+ usbReceiveNextPacketOnOEP0();
+ if(bStatusAction == STATUS_ACTION_NOTHING)
+ {
+# ifdef _CDC_
+ if(tSetupPacket.bRequest == USB_CDC_SET_LINE_CODING)
+ {
+ switch(tSetupPacket.wIndex)
+ {
+ case 0:
+ case 1:
+ Handler_SetLineCoding0();
+ break;
+ case 2:
+ case 3:
+ Handler_SetLineCoding1();
+ break;
+ case 4:
+ case 5:
+ Handler_SetLineCoding2();
+ break;
+ }
+ }
+# endif
+ }
+ }
+ else
+ {
+ tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL; // no more data
+ }
+}
+
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/
diff --git a/USB_config/descriptors.c b/USB_config/descriptors.c
--- /dev/null
+++ b/USB_config/descriptors.c
@@ -0,0 +1,368 @@
+// (c)2010 by Texas Instruments Incorporated, All Rights Reserved.
+/*-----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| This is an automatically generated script by MSP430 USB Descriptor Tool |
+| |
+| Descriptor Tool Version: 3.0.10 |
+| Date: 2011/10/25 21:16:05 |
+| |
+| Descriptor.c |
+|-----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------+
+| Include files |
+|-----------------------------------------------------------------------------*/
+#include <USB_API/USB_Common/device.h>
+#include <USB_API/USB_Common/types.h> // Basic Type declarations
+#include <USB_API/USB_Common/defMSP430USB.h>
+#include <USB_API/USB_Common/usb.h> // USB-specific Data Structures
+#include "descriptors.h"
+#include <USB_API/USB_CDC_API/UsbCdc.h>
+#include <USB_API/USB_HID_API/UsbHidReq.h>
+
+/*-----------------------------------------------------------------------------+
+| Device Descriptor |
+|-----------------------------------------------------------------------------*/
+BYTE const abromDeviceDescriptor[SIZEOF_DEVICE_DESCRIPTOR] = {
+ SIZEOF_DEVICE_DESCRIPTOR, // Length of this descriptor
+ DESC_TYPE_DEVICE, // Type code of this descriptor
+ 0x00, 0x02, // Release of USB spec
+ 0x02, // Device's base class code
+ 0x00, // Device's sub class code
+ 0x00, // Device's protocol type code
+ EP0_PACKET_SIZE, // End point 0's packet size
+ USB_VID&0xFF, USB_VID>>8, // Vendor ID for device, TI=0x0451
+ // You can order your own VID at www.usb.org
+ USB_PID&0xFF, USB_PID>>8, // Product ID for device,
+ // this ID is to only with this example
+ VER_FW_L, VER_FW_H, // Revision level of device
+ 1, // Index of manufacturer name string desc
+ 2, // Index of product name string desc
+ USB_STR_INDEX_SERNUM, // Index of serial number string desc
+ 1 // Number of configurations supported
+};
+
+/*-----------------------------------------------------------------------------+
+| Configuration Descriptor |
+|-----------------------------------------------------------------------------*/
+const struct abromConfigurationDescriptorGroup abromConfigurationDescriptorGroup=
+{
+ /* Generic part */
+ {
+ // CONFIGURATION DESCRIPTOR (9 bytes)
+ SIZEOF_CONFIG_DESCRIPTOR, // bLength
+ DESC_TYPE_CONFIG, // bDescriptorType
+ DESCRIPTOR_TOTAL_LENGTH, 0x00, // wTotalLength
+ USB_NUM_INTERFACES, // bNumInterfaces
+ USB_CONFIG_VALUE, // bConfigurationvalue
+ CONFIG_STRING_INDEX, // iConfiguration Description offset
+ USB_SUPPORT_SELF_POWERED | USB_SUPPORT_REM_WAKE, // bmAttributes, bus power, remote wakeup
+ USB_MAX_POWER // Max. Power Consumption
+ },
+
+ /******************************************************* start of CDC*************************************/
+
+ {
+ /* start CDC[0] */
+ {
+
+ //INTERFACE DESCRIPTOR (9 bytes)
+ 0x09, // bLength: Interface Descriptor size
+ DESC_TYPE_INTERFACE, // bDescriptorType: Interface
+ CDC0_COMM_INTERFACE, // bInterfaceNumber
+ 0x00, // bAlternateSetting: Alternate setting
+ 0x01, // bNumEndpoints: Three endpoints used
+ 0x02, // bInterfaceClass: Communication Interface Class
+ 0x02, // bInterfaceSubClass: Abstract Control Model
+ 0x01, // bInterfaceProtocol: Common AT commands
+ INTF_STRING_INDEX + 0, // iInterface:
+
+ //Header Functional Descriptor
+ 0x05, // bLength: Endpoint Descriptor size
+ 0x24, // bDescriptorType: CS_INTERFACE
+ 0x00, // bDescriptorSubtype: Header Func Desc
+ 0x10, // bcdCDC: spec release number
+ 0x01,
+
+ //Call Managment Functional Descriptor
+ 0x05, // bFunctionLength
+ 0x24, // bDescriptorType: CS_INTERFACE
+ 0x01, // bDescriptorSubtype: Call Management Func Desc
+ 0x00, // bmCapabilities: D0+D1
+ CDC0_DATA_INTERFACE, // bDataInterface: 0
+
+ //ACM Functional Descriptor
+ 0x04, // bFunctionLength
+ 0x24, // bDescriptorType: CS_INTERFACE
+ 0x02, // bDescriptorSubtype: Abstract Control Management desc
+ 0x02, // bmCapabilities
+
+ // Union Functional Descriptor
+ 0x05, // Size, in bytes
+ 0x24, // bDescriptorType: CS_INTERFACE
+ 0x06, // bDescriptorSubtype: Union Functional Desc
+ CDC0_COMM_INTERFACE, // bMasterInterface -- the controlling intf for the union
+ CDC0_DATA_INTERFACE, // bSlaveInterface -- the controlled intf for the union
+
+ //EndPoint Descriptor for Interrupt endpoint
+ SIZEOF_ENDPOINT_DESCRIPTOR, // bLength: Endpoint Descriptor size
+ DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint
+ CDC0_INTEP_ADDR, // bEndpointAddress: (IN2)
+ EP_DESC_ATTR_TYPE_INT, // bmAttributes: Interrupt
+ 0x40, 0x00, // wMaxPacketSize, 64 bytes
+ 0xFF, // bInterval
+
+ //DATA INTERFACE DESCRIPTOR (9 bytes)
+ 0x09, // bLength: Interface Descriptor size
+ DESC_TYPE_INTERFACE, // bDescriptorType: Interface
+ CDC0_DATA_INTERFACE, // bInterfaceNumber
+ 0x00, // bAlternateSetting: Alternate setting
+ 0x02, // bNumEndpoints: Three endpoints used
+ 0x0A, // bInterfaceClass: Data Interface Class
+ 0x00, // bInterfaceSubClass:
+ 0x00, // bInterfaceProtocol: No class specific protocol required
+ 0x00, // iInterface:
+
+ //EndPoint Descriptor for Output endpoint
+ SIZEOF_ENDPOINT_DESCRIPTOR, // bLength: Endpoint Descriptor size
+ DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint
+ CDC0_OUTEP_ADDR, // bEndpointAddress: (OUT3)
+ EP_DESC_ATTR_TYPE_BULK, // bmAttributes: Bulk
+ 0x40, 0x00, // wMaxPacketSize, 64 bytes
+ 0xFF, // bInterval: ignored for Bulk transfer
+
+ //EndPoint Descriptor for Input endpoint
+ SIZEOF_ENDPOINT_DESCRIPTOR, // bLength: Endpoint Descriptor size
+ DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint
+ CDC0_INEP_ADDR, // bEndpointAddress: (IN3)
+ EP_DESC_ATTR_TYPE_BULK, // bmAttributes: Bulk
+ 0x40, 0x00, // wMaxPacketSize, 64 bytes
+ 0xFF // bInterval: ignored for bulk transfer
+ }
+
+ /* end CDC[0]*/
+
+ }
+ /******************************************************* end of CDC**************************************/
+
+};
+/*-----------------------------------------------------------------------------+
+| String Descriptor |
+|-----------------------------------------------------------------------------*/
+BYTE const abromStringDescriptor[] = {
+
+ // String index0, language support
+ 4, // Length of language descriptor ID
+ 3, // LANGID tag
+ 0x09, 0x04, // 0x0409 for English
+
+ // String index1, Manufacturer
+ 36, // Length of this string descriptor
+ 3, // bDescriptorType
+ 'T',0x00,'e',0x00,'x',0x00,'a',0x00,'s',0x00,' ',0x00,
+ 'I',0x00,'n',0x00,'s',0x00,'t',0x00,'r',0x00,'u',0x00,
+ 'm',0x00,'e',0x00,'n',0x00,'t',0x00,'s',0x00,
+
+ // String index2, Product
+ 34, // Length of this string descriptor
+ 3, // bDescriptorType
+ 'M',0x00,'S',0x00,'P',0x00,' ',0x00,'B',0x00,'S',0x00,
+ 'L',0x00,' ',0x00,'U',0x00,'S',0x00,'B',0x00,' ',0x00,
+ 'T',0x00,'o',0x00,'o',0x00,'l',0x00,
+
+ // String index3, Serial Number
+ 4, // Length of this string descriptor
+ 3, // bDescriptorType
+ '0',0x00,
+
+ // String index4, Configuration String
+ 22, // Length of this string descriptor
+ 3, // bDescriptorType
+ 'M',0x00,'S',0x00,'P',0x00,'4',0x00,'3',0x00,'0',0x00,
+ ' ',0x00,'U',0x00,'S',0x00,'B',0x00,
+
+ // String index5, Interface String
+ 34, // Length of this string descriptor
+ 3, // bDescriptorType
+ 'M',0x00,'S',0x00,'P',0x00,' ',0x00,'B',0x00,'S',0x00,
+ 'L',0x00,' ',0x00,'U',0x00,'S',0x00,'B',0x00,' ',0x00,
+ 'T',0x00,'o',0x00,'o',0x00,'l',0x00
+};
+
+/**** Populating the endpoint information handle here ****/
+
+const struct tUsbHandle stUsbHandle[]=
+{
+ {
+ CDC0_INEP_ADDR,
+ CDC0_OUTEP_ADDR,
+ 1,
+ CDC_CLASS,
+ IEP1_X_BUFFER_ADDRESS,
+ IEP1_Y_BUFFER_ADDRESS,
+ OEP2_X_BUFFER_ADDRESS,
+ OEP2_Y_BUFFER_ADDRESS,
+ IEP2_X_BUFFER_ADDRESS,
+ IEP2_Y_BUFFER_ADDRESS
+ }
+};
+//-------------DEVICE REQUEST LIST---------------------------------------------
+
+const tDEVICE_REQUEST_COMPARE tUsbRequestList[] =
+{
+
+ //---- CDC 0 Class Requests -----//
+ // GET LINE CODING
+ USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
+ USB_CDC_GET_LINE_CODING,
+ 0x00,0x00, // always zero
+ CDC0_COMM_INTERFACE,0x00, // CDC interface is 0
+ 0x07,0x00, // Size of Structure (data length)
+ 0xff,&usbGetLineCoding0,
+
+ // SET LINE CODING
+ USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
+ USB_CDC_SET_LINE_CODING,
+ 0x00,0x00, // always zero
+ CDC0_COMM_INTERFACE,0x00, // CDC interface is 0
+ 0x07,0x00, // Size of Structure (data length)
+ 0xff,&usbSetLineCoding0,
+
+ // SET CONTROL LINE STATE
+ USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
+ USB_CDC_SET_CONTROL_LINE_STATE,
+ 0xff,0xff, // Contains data
+ CDC0_COMM_INTERFACE,0x00, // CDC interface is 0
+ 0x00,0x00, // No further data
+ 0xcf,&usbSetControlLineState0,
+
+ //---- USB Standard Requests -----//
+ // clear device feature
+ USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
+ USB_REQ_CLEAR_FEATURE,
+ FEATURE_REMOTE_WAKEUP,0x00, // feature selector
+ 0x00,0x00,
+ 0x00,0x00,
+ 0xff,&usbClearDeviceFeature,
+
+ // clear endpoint feature
+ USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT,
+ USB_REQ_CLEAR_FEATURE,
+ FEATURE_ENDPOINT_STALL,0x00,
+ 0xff,0x00,
+ 0x00,0x00,
+ 0xf7,&usbClearEndpointFeature,
+
+ // get configuration
+ USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
+ USB_REQ_GET_CONFIGURATION,
+ 0x00,0x00,
+ 0x00,0x00,
+ 0x01,0x00,
+ 0xff,&usbGetConfiguration,
+
+ // get device descriptor
+ USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
+ USB_REQ_GET_DESCRIPTOR,
+ 0xff,DESC_TYPE_DEVICE, // bValueL is index and bValueH is type
+ 0xff,0xff,
+ 0xff,0xff,
+ 0xd0,&usbGetDeviceDescriptor,
+
+ // get configuration descriptor
+ USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
+ USB_REQ_GET_DESCRIPTOR,
+ 0xff,DESC_TYPE_CONFIG, // bValueL is index and bValueH is type
+ 0xff,0xff,
+ 0xff,0xff,
+ 0xd0,&usbGetConfigurationDescriptor,
+
+ // get string descriptor
+ USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
+ USB_REQ_GET_DESCRIPTOR,
+ 0xff,DESC_TYPE_STRING, // bValueL is index and bValueH is type
+ 0xff,0xff,
+ 0xff,0xff,
+ 0xd0,&usbGetStringDescriptor,
+
+ // get interface
+ USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
+ USB_REQ_GET_INTERFACE,
+ 0x00,0x00,
+ 0xff,0xff,
+ 0x01,0x00,
+ 0xf3,&usbGetInterface,
+
+ // get device status
+ USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
+ USB_REQ_GET_STATUS,
+ 0x00,0x00,
+ 0x00,0x00,
+ 0x02,0x00,
+ 0xff,&usbGetDeviceStatus,
+ // get interface status
+ USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
+ USB_REQ_GET_STATUS,
+ 0x00,0x00,
+ 0xff,0x00,
+ 0x02,0x00,
+ 0xf7,&usbGetInterfaceStatus,
+ // get endpoint status
+ USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT,
+ USB_REQ_GET_STATUS,
+ 0x00,0x00,
+ 0xff,0x00,
+ 0x02,0x00,
+ 0xf7,&usbGetEndpointStatus,
+
+ // set address
+ USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
+ USB_REQ_SET_ADDRESS,
+ 0xff,0x00,
+ 0x00,0x00,
+ 0x00,0x00,
+ 0xdf,&usbSetAddress,
+
+ // set configuration
+ USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
+ USB_REQ_SET_CONFIGURATION,
+ 0xff,0x00,
+ 0x00,0x00,
+ 0x00,0x00,
+ 0xdf,&usbSetConfiguration,
+
+ // set device feature
+ USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
+ USB_REQ_SET_FEATURE,
+ 0xff,0x00, // feature selector
+ 0x00,0x00,
+ 0x00,0x00,
+ 0xdf,&usbSetDeviceFeature,
+
+ // set endpoint feature
+ USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT,
+ USB_REQ_SET_FEATURE,
+ 0xff,0x00, // feature selector
+ 0xff,0x00, // endpoint number <= 127
+ 0x00,0x00,
+ 0xd7,&usbSetEndpointFeature,
+
+ // set interface
+ USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
+ USB_REQ_SET_INTERFACE,
+ 0xff,0x00, // feature selector
+ 0xff,0x00, // interface number
+ 0x00,0x00,
+ 0xd7,&usbSetInterface,
+
+ // end of usb descriptor -- this one will be matched to any USB request
+ // since bCompareMask is 0x00.
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x00,&usbInvalidRequest // end of list
+};
+
+/*-----------------------------------------------------------------------------+
+| END OF Descriptor.c FILE |
+|-----------------------------------------------------------------------------*/
diff --git a/USB_config/descriptors.dat b/USB_config/descriptors.dat
new file mode 100644 (file)
index 0000000..da02a66
Binary files /dev/null and b/USB_config/descriptors.dat differ
index 0000000..da02a66
Binary files /dev/null and b/USB_config/descriptors.dat differ
diff --git a/USB_config/descriptors.h b/USB_config/descriptors.h
--- /dev/null
+++ b/USB_config/descriptors.h
@@ -0,0 +1,343 @@
+// (c)2010 by Texas Instruments Incorporated, All Rights Reserved.
+/*-----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| This is an automatically generated script by MSP430 USB Descriptor Tool |
+| |
+| Descriptor Tool Version: 3.0.10 |
+| Date: 2011/10/25 21:16:05 |
+| |
+| Descriptor.h |
+|-----------------------------------------------------------------------------*/
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*-----------------------------------------------------------------------------+
+| Include files |
+|-----------------------------------------------------------------------------*/
+#include <USB_API/USB_Common/types.h>
+
+//***********************************************************************************************
+// CDC or HID - Define both for composite support
+//***********************************************************************************************
+#define _CDC_ // Needed for CDC inteface
+//***********************************************************************************************
+// CONFIGURATION CONSTANTS
+//***********************************************************************************************
+// These constants configure the API stack and help define the USB descriptors.
+// Refer to Sec. 6 of the MSP430 USB CDC API Programmer's Guide for descriptions of these constants.
+
+// Configuration Constants that can change
+// #define that relates to Device Descriptor
+#define USB_VID 0x2047 // Vendor ID (VID)
+#define USB_PID 0x030B // Product ID (PID)
+/*----------------------------------------------------------------------------+
+| Firmware Version |
+| How to detect version number of the FW running on MSP430? |
+| on Windows Open ControlPanel->Systems->Hardware->DeviceManager->Ports-> |
+| Msp430->ApplicationUART->Details |
++----------------------------------------------------------------------------*/
+#define VER_FW_H 0x01 // Device release number, in binary-coded decimal
+#define VER_FW_L 0x00 // Device release number, in binary-coded decimal
+// If a serial number is to be reported, set this to the index within the string descriptor
+//of the dummy serial number string. It will then be automatically handled by the API.
+// If no serial number is to be reported, set this to 0.
+#define USB_STR_INDEX_SERNUM 3
+
+
+#define DESCRIPTOR_TOTAL_LENGTH 67 // wTotalLength, This is the sum of configuration descriptor length + CDC descriptor length + HID descriptor length
+#define USB_NUM_INTERFACES 2 // Number of implemented interfaces.
+
+#define CDC0_COMM_INTERFACE 0 // Comm interface number of CDC0
+#define CDC0_DATA_INTERFACE 1 // Data interface number of CDC0
+#define CDC0_INTEP_ADDR 0x81 // Interrupt Endpoint Address of CDC0
+#define CDC0_OUTEP_ADDR 0x02 // Output Endpoint Address of CDC0
+#define CDC0_INEP_ADDR 0x82 // Input Endpoint Address of CDC0
+
+#define CDC_NUM_INTERFACES 1 // Total Number of CDCs implemented. should set to 0 if there are no CDCs implemented.
+#define HID_NUM_INTERFACES 0 // Total Number of HIDs implemented. should set to 0 if there are no HIDs implemented.
+#define MSC_NUM_INTERFACES 0 // Total Number of MSCs implemented. should set to 0 if there are no MSCs implemented.
+// Interface numbers for the implemented CDSs and HIDs, This is to use in the Application(main.c) and in the interupt file(UsbIsr.c).
+#define CDC0_INTFNUM 0
+#define MSC_MAX_LUN_NUMBER 1 // Maximum number of LUNs supported
+
+#define USB_OUTEP_INT_EN BIT0 | BIT2
+#define USB_INEP_INT_EN BIT0 | BIT1 | BIT2
+// MCLK frequency of MCU, in Hz
+// For running higher frequencies the Vcore voltage adjustment may required.
+// Please refer to Data Sheet of the MSP430 device you use
+#define USB_MCLK_FREQ 20000000 // MCLK frequency of MCU, in Hz
+#define USB_PLL_XT 2 // Defines which XT is used by the PLL (1=XT1, 2=XT2)
+#define USB_XT_FREQ USBPLL_SETCLK_4_0 // Indicates the freq of the crystal on the oscillator indicated by USB_PLL_XT
+#define USB_DISABLE_XT_SUSPEND 1 // If non-zero, then USB_suspend() will disable the oscillator
+ // that is designated by USB_PLL_XT; if zero, USB_suspend won't
+ // affect the oscillator
+#define USB_DMA_CHAN 0x00 // Set to 0xFF if no DMA channel will be used 0..7 for selected DMA channel
+
+
+
+// Controls whether the remote wakeup feature is supported by this device.
+// A value of 0x20 indicates that is it supported (this value is the mask for
+// the bmAttributes field in the configuration descriptor).
+// A value of zero indicates remote wakeup is not supported.
+// Other values are undefined, as they will interfere with bmAttributes.
+#define USB_SUPPORT_REM_WAKE 0x00
+
+// Controls whether the application is self-powered to any degree. Should be
+// set to 0x40, unless the USB device is fully supplied by the bus.
+#define USB_SUPPORT_SELF_POWERED 0x80
+
+// Controls what the device reports to the host regarding how much power it will
+// consume from VBUS. Expressed in 2mA units; that is, the number of mA
+// communicated is twice the value of this field.
+#define USB_MAX_POWER 0x32
+//Configuration constants that can not change ( Fixed Values)
+#define CDC_CLASS 2
+#define HID_CLASS 3
+#define MSC_CLASS 4
+
+#define MAX_PACKET_SIZE 0x40 // Max size of the USB packets.
+
+//***********************************************************************************************
+// DESCRIPTOR CONSTANTS
+//***********************************************************************************************
+#define SIZEOF_DEVICE_DESCRIPTOR 0x12
+#define SIZEOF_REPORT_DESCRIPTOR 36
+#define USBHID_REPORT_LENGTH 64 // length of whole HID report (including Report ID)
+#define CONFIG_STRING_INDEX 4
+#define INTF_STRING_INDEX 5
+#define USB_CONFIG_VALUE 0x01
+//***********************************************************************************************
+// OUTWARD DECLARATIONS
+//***********************************************************************************************
+
+//Calculates the endpoint descriptor block number from given address
+#define EDB(addr) ((addr&0x07)-1)
+
+/* Structure for generic part of configuration descriptor */
+struct abromConfigurationDescriptorGenric
+{
+ BYTE sizeof_config_descriptor; // bLength
+ BYTE desc_type_config; // bDescriptorType: 2
+ BYTE sizeof_configuration_descriptor1; // wTotalLength
+ BYTE sizeof_configuration_descriptor2;
+ BYTE usb_num_configurations; // bNumInterfaces
+ BYTE bconfigurationvalue; // bConfigurationValue
+ BYTE config_string_index; // iConfiguration Description offset
+ BYTE mattributes; // bmAttributes, bus power, remote wakeup
+ BYTE usb_max_power; // Max. Power Consumption at 2mA unit
+};
+
+/************************************************CDC Descriptor**************************/
+struct abromConfigurationDescriptorCdc
+{
+// interface descriptor (9 bytes)
+ BYTE blength_intf; // blength: interface descriptor size
+ BYTE desc_type_interface; // bdescriptortype: interface
+ BYTE interface_number_cdc; // binterfacenumber
+ BYTE balternatesetting; // balternatesetting: alternate setting
+ BYTE bnumendpoints; // bnumendpoints: three endpoints used
+ BYTE binterfaceclass; // binterfaceclass: communication interface class
+ BYTE binterfacesubclass; // binterfacesubclass: abstract control model
+ BYTE binterfaceprotocol; // binterfaceprotocol: common at commands
+ BYTE intf_string_index; // interface:
+//header functional descriptor
+ BYTE blength_header; // blength: endpoint descriptor size
+ BYTE bdescriptortype_header; // bdescriptortype: cs_interface
+ BYTE bdescriptorsubtype_header; // bdescriptorsubtype: header func desc
+ BYTE bcdcdc1;
+ BYTE bcdcdc2; // bcdcdc: spec release number
+
+//call managment functional descriptor
+ BYTE bfunctionlength; // bfunctionlength
+ BYTE bdescriptortype_c; // bdescriptortype: cs_interface
+ BYTE bdescriptorsubtype_c; // bdescriptorsubtype: call management func desc
+ BYTE bmcapabilities; // bmcapabilities: d0+d1
+ BYTE intf_number_cdc; // bdatainterface: 0
+
+//acm functional descriptor
+ BYTE bfunctionlength_acm; // bfunctionlength
+ BYTE bdescriptortype_acm; // bdescriptortype: cs_interface
+ BYTE bdescriptorsubtype_acm; // bdescriptorsubtype: abstract control management desc
+ BYTE bmcapabilities_acm; // bmcapabilities
+
+// Union Functional Descriptor
+ BYTE bLength_ufd; // Size, in bytes
+ BYTE bdescriptortype_ufd; // bDescriptorType: CS_INTERFACE
+ BYTE bdescriptorsubtype_ufd; // bDescriptorSubtype: Union Functional Desc
+ BYTE bmasterinterface_ufd; // bMasterInterface -- the controlling intf for the union
+ BYTE bslaveinterface_ufd; // bSlaveInterface -- the controlled intf for the union
+
+//Interrupt end point related fields
+ BYTE sizeof_epintep_descriptor; // blength: endpoint descriptor size
+ BYTE desc_type_epintep; // bdescriptortype: endpoint
+ BYTE cdc_intep_addr; // bendpointaddress: (in2)
+ BYTE epintep_desc_attr_type_int; // bmattributes: interrupt
+ BYTE epintep_wmaxpacketsize1;
+ BYTE epintep_wmaxpacketsize; // wmaxpacketsize, 64 bytes
+ BYTE epintep_binterval; // binterval
+
+// Data interface descriptor (9 bytes)
+ BYTE blength_slaveintf; // blength: interface descriptor size
+ BYTE desc_type_slaveinterface; // bdescriptortype: interface
+ BYTE interface_number_slavecdc; // binterfacenumber
+ BYTE balternatesetting_slave; // balternatesetting: alternate setting
+ BYTE bnumendpoints_slave; // bnumendpoints: three endpoints used
+ BYTE binterfaceclass_slave; // binterfaceclass: data interface class
+ BYTE binterfacesubclass_slave; // binterfacesubclass: abstract control model
+ BYTE binterfaceprotocol_slave; // binterfaceprotocol: common at commands
+ BYTE intf_string_index_slave; // interface:
+
+// Bulk out end point related fields
+ BYTE sizeof_outep_descriptor; // blength: endpoint descriptor size
+ BYTE desc_type_outep; // bdescriptortype: endpoint
+ BYTE cdc_outep_addr; // bendpointaddress: (out3)
+ BYTE outep_desc_attr_type_bulk; // bmattributes: bulk
+ BYTE outep_wmaxpacketsize1;
+ BYTE outep_wmaxpacketsize2; // wmaxpacketsize, 64 bytes
+ BYTE outep_binterval; // binterval: ignored for bulk transfer
+
+// Bulk in related fields
+ BYTE sizeof_inep_descriptor; // blength: endpoint descriptor size
+ BYTE desc_type_inep; // bdescriptortype: endpoint
+ BYTE cdc_inep_addr; // bendpointaddress: (in3)
+ BYTE inep_desc_attr_type_bulk; // bmattributes: bulk
+ BYTE inep_wmaxpacketsize1;
+ BYTE inep_wmaxpacketsize2; // wmaxpacketsize, 64 bytes
+ BYTE inep_binterval; // binterval: ignored for bulk transfer
+} ;
+
+/**************************************HID descriptor structure *************************/
+struct abromConfigurationDescriptorHid
+{
+//INTERFACE DESCRIPTOR (9 bytes)
+ BYTE sizeof_interface_descriptor; // Desc Length
+ BYTE desc_type_interface; // DescriptorType
+ BYTE interface_number_hid; // Interface number
+ BYTE balternatesetting; // Any alternate settings if supported
+ BYTE bnumendpoints; // Number of end points required
+ BYTE binterfaceclass; // Class ID
+ BYTE binterfacesubclass; // Sub class ID
+ BYTE binterfaceprotocol; // Protocol
+ BYTE intf_string_index; // String Index
+
+//hid descriptor (9 bytes)
+ BYTE blength_hid_descriptor; // HID Desc length
+ BYTE hid_descriptor_type; // HID Desc Type
+ BYTE hidrevno1; // Rev no
+ BYTE hidrevno2; // Rev no - 2nd part
+ BYTE tcountry; // Country code
+ BYTE numhidclasses; // Number of HID classes to follow
+ BYTE report_descriptor_type; // Report desc type
+ BYTE tlength; // Total length of report descriptor
+ BYTE size_rep_desc;
+
+//input end point descriptor (7 bytes)
+ BYTE size_inp_endpoint_descriptor; // End point desc size
+ BYTE desc_type_inp_endpoint; // Desc type
+ BYTE hid_inep_addr; // Input end point address
+ BYTE ep_desc_attr_type_inp_int; // Type of end point
+ BYTE inp_wmaxpacketsize1; // Max packet size
+ BYTE inp_wmaxpacketsize2;
+ BYTE inp_binterval; // bInterval in ms
+
+ // Output end point descriptor; (7 bytes)
+ BYTE size_out_endpoint_descriptor; // Output endpoint desc size
+ BYTE desc_type_out_endpoint; // Desc type
+ BYTE hid_outep_addr; // Output end point address
+ BYTE ep_desc_attr_type_out_int; // End point type
+ BYTE out_wmaxpacketsize1; // Max packet size
+ BYTE out_wmaxpacketsize2;
+ BYTE out_binterval; // bInterval in ms
+};
+
+/**************************************MSC descriptor structure *************************/
+struct abromConfigurationDescriptorMsc
+{
+// INTERFACE DESCRIPTOR (9 bytes)
+ BYTE sizeof_interface_descriptor; // Desc Length
+ BYTE desc_type_interface; // DescriptorType
+ BYTE interface_number_hid; // Interface number
+ BYTE balternatesetting; // Any alternate settings if supported
+ BYTE bnumendpoints; // Number of end points required
+ BYTE binterfaceclass; // Class ID
+ BYTE binterfacesubclass; // Sub class ID
+ BYTE binterfaceprotocol; // Protocol
+ BYTE intf_string_index; // String Index
+
+// input end point descriptor (7 bytes)
+ BYTE size_inp_endpoint_descriptor; // End point desc size
+ BYTE desc_type_inp_endpoint; // Desc type
+ BYTE hid_inep_addr; // Input end point address
+ BYTE ep_desc_attr_type_inp_int; // Type of end point
+ BYTE inp_wmaxpacketsize1; // Max packet size
+ BYTE inp_wmaxpacketsize2;
+ BYTE inp_binterval; // bInterval in ms
+
+// Output end point descriptor; (7 bytes)
+ BYTE size_out_endpoint_descriptor; // Output endpoint desc size
+ BYTE desc_type_out_endpoint; // Desc type
+ BYTE hid_outep_addr; // Output end point address
+ BYTE ep_desc_attr_type_out_int; // End point type
+ BYTE out_wmaxpacketsize1; // Max packet size
+ BYTE out_wmaxpacketsize2;
+ BYTE out_binterval; // bInterval in ms
+};
+
+/* Global structure having Generic,CDC,HID, MSC structures */
+struct abromConfigurationDescriptorGroup
+{
+ /* Generic part of config descriptor */
+ const struct abromConfigurationDescriptorGenric abromConfigurationDescriptorGenric;
+#ifdef _MSC_
+ /* MSC descriptor structure */
+ const struct abromConfigurationDescriptorMsc stMsc[MSC_NUM_INTERFACES];
+#endif
+#ifdef _CDC_
+ /* CDC descriptor structure */
+ const struct abromConfigurationDescriptorCdc stCdc[CDC_NUM_INTERFACES];
+#endif
+#ifdef _HID_
+ /* HID descriptor structure */
+ const struct abromConfigurationDescriptorHid stHid[HID_NUM_INTERFACES];
+#endif
+};
+
+extern const struct abromConfigurationDescriptorGroup abromConfigurationDescriptorGroup;
+extern BYTE const abromDeviceDescriptor[SIZEOF_DEVICE_DESCRIPTOR];
+extern BYTE const abromStringDescriptor[];
+extern BYTE const abromReportDescriptor[SIZEOF_REPORT_DESCRIPTOR];
+
+/* Handle Structure - Will be populated in descriptors.c based on number of CDC,HID interfaces */
+struct tUsbHandle
+{
+ BYTE ep_In_Addr; // Input EP Addr
+ BYTE ep_Out_Addr; // Output EP Addr
+ BYTE edb_Index; // The EDB index
+ BYTE dev_Class; // Device Class- 2 for CDC, 3 for HID
+ WORD intepEP_X_Buffer; // Interupt X Buffer Addr
+ WORD intepEP_Y_Buffer; // Interupt Y Buffer Addr
+ WORD oep_X_Buffer; // Output X buffer Addr
+ WORD oep_Y_Buffer; // Output Y buffer Addr
+ WORD iep_X_Buffer; // Input X Buffer Addr
+ WORD iep_Y_Buffer; // Input Y Buffer Addr
+};
+
+extern const struct tUsbHandle stUsbHandle[CDC_NUM_INTERFACES + HID_NUM_INTERFACES + MSC_NUM_INTERFACES];
+extern const tDEVICE_REQUEST_COMPARE tUsbRequestList[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*------------------------ Nothing Below This Line --------------------------*/
+
diff --git a/baudrateselect.c b/baudrateselect.c
--- /dev/null
+++ b/baudrateselect.c
@@ -0,0 +1,155 @@
+/*
+ * baudrateselect.c
+ *
+ * Forwards baudrade change requests to individual peripheral modules.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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 <MSP430.h>
+#include "uart.h"
+#include "i2c.h"
+#include "main.h"
+
+extern enum active_peripherals active_peripheral;
+
+/* Configures the peripheral module selected by baudrate change */
+BYTE BaudrateSelect(ULONG lBaudrate)
+{
+ BYTE baudIndex;
+
+ switch(lBaudrate)
+ {
+ /* UART peripheral */
+ case 1200:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 2400:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 4800:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 4801:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 4802:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 9600:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 9601:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ /* reserved for future devices invoke sequence
+ case 9602: newInvoke(2); break;
+ case 9603: newInvoke(3); break;
+ case 9604: newInvoke(4); break;
+ case 9605: newInvoke(5); break;
+ case 9606: newInvoke(6); break;
+ case 9607: newInvoke(7); break;
+ case 9608: newInvoke(8); break;
+ case 9609: newInvoke(9); break;
+ case 9610: newInvoke(10); break;
+ case 9611: newInvoke(11); break;
+ case 9612: newInvoke(12); break;
+ case 9613: newInvoke(13); break;
+ case 9614: newInvoke(14); break;
+ case 9615: newInvoke(15); break;
+ case 9616: newInvoke(16); break;
+ case 9617: newInvoke(17); break;
+ case 9618: newInvoke(18); break;
+ */
+ case 19200:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 38400:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 57600:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 115200:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 230400:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 460800:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+ case 921600:
+ active_peripheral = UART;
+ baudIndex = InitUart(lBaudrate);
+ break;
+
+ /* I2C peripheral */
+ case 100000:
+ active_peripheral = I2C;
+ baudIndex = InitI2C(BSL_SLAVE_ADDR, lBaudrate);
+ break;
+ case 100001:
+ active_peripheral = I2C;
+ baudIndex = InitI2C(BSL_SLAVE_ADDR, lBaudrate);
+ break;
+ case 400000:
+ active_peripheral = I2C;
+ baudIndex = InitI2C(BSL_SLAVE_ADDR, lBaudrate);
+ break;
+ case 400001:
+ active_peripheral = I2C;
+ baudIndex = InitI2C(BSL_SLAVE_ADDR, lBaudrate);
+ break;
+
+ default:
+ baudIndex = 0;
+ break;
+
+ }
+
+ return baudIndex;
+}
diff --git a/baudrateselect.h b/baudrateselect.h
--- /dev/null
+++ b/baudrateselect.h
@@ -0,0 +1,45 @@
+/*
+ * baudrateselect.h
+ *
+ * Forwards baudrade change requests to individual peripheral modules.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+#ifndef BAUDRATESELECT_H_
+#define BAUDRATESELECT_H_
+
+/* Configures the peripheral module selected by baudrate change */
+BYTE BaudrateSelect(ULONG lBaudrate);
+
+#endif //BAUDRATESELECT_H_
\ No newline at end of file
diff --git a/initMCU.c b/initMCU.c
--- /dev/null
+++ b/initMCU.c
@@ -0,0 +1,240 @@
+/*
+ * initMCU.c
+ *
+ * Provides initialization functions.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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 <MSP430.h>
+#include "USB_API/USB_Common/types.h"
+#include "USB_API/USB_Common/device.h"
+#include "F5xx_F6xx_Core_Lib/HAL_UCS.h"
+#include "F5xx_F6xx_Core_Lib/HAL_PMM.h"
+
+#include "USB_config/descriptors.h"
+#include "USB_API/USB_Common/usb.h" // USB-specific functions
+#include "USB_API/USB_CDC_API/UsbCdc.h"
+
+#include "uart.h"
+#include "i2c.h"
+
+void Port_Mapping(void);
+
+//----------------------------------------------------------------------------
+VOID Init_Clock(VOID)
+{
+ #if defined (__MSP430F563x_F663x)
+ while(BAKCTL & LOCKIO) // Unlock XT1 pins for operation
+ BAKCTL &= ~(LOCKIO); // enable XT1 pins
+ // Workaround for USB7
+ UCSCTL6 &= ~XT1OFF;
+ #endif
+ if (USB_PLL_XT == 2)
+ {
+ #if defined (__MSP430F552x) || defined (__MSP430F550x)
+ P5SEL |= 0x0C; // enable XT2 pins for F5529
+ #elif defined (__MSP430F563x_F663x)
+ P7SEL |= 0x0C;
+ #endif
+ // Use the REFO oscillator to source the FLL and ACLK
+ UCSCTL3 = (UCSCTL3 & ~(SELREF_7)) | (SELREF__REFOCLK);
+ UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK);
+
+ // MCLK will be driven by the FLL (not by XT2), referenced to the REFO
+ Init_FLL(USB_MCLK_FREQ/1000, USB_MCLK_FREQ/32768); // Start the FLL, at the freq indicated by the config constant USB_MCLK_FREQ
+
+ //XT2_Start(XT2DRIVE_3); // Start the "USB crystal"
+ }
+ else
+ {
+ #if defined (__MSP430F552x) || defined (__MSP430F550x)
+ P5SEL |= 0x10; // enable XT1 pins
+ #endif
+ // Use the REFO oscillator to source the FLL and ACLK
+// UCSCTL3 = SELREF__REFOCLK;
+// UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK);
+
+ P5SEL |= 0x30; // enable XT1 pins for F5509
+ LFXT_Start(XT1DRIVE_3);
+ // Use the LFXT1 oscillator to source the FLL and ACLK
+ UCSCTL3 = SELA__XT1CLK;
+ UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__XT1CLK);
+
+
+ // MCLK will be driven by the FLL (not by XT2), referenced to the REFO
+ Init_FLL(USB_MCLK_FREQ/1000, USB_MCLK_FREQ/32768); // set FLL (DCOCLK)
+
+ //XT1_Start(XT1DRIVE_3); // Start the "USB crystal"
+ }
+}
+
+//----------------------------------------------------------------------------
+VOID Init_Ports(VOID)
+{
+ // Drive all I/O's as output-low, making sure there's no shoot-through current. There
+ // should be no floating I/Os, to prevent unnecessary current draw during USB suspend.
+ PAOUT = 0x0000;
+ PASEL = 0x0000;
+ PAREN = 0xF0FF;
+ PADIR = 0x0F00;
+
+ PBOUT = 0x0000;
+ PBSEL = 0x0000;
+ PBREN = 0xFFFF;
+
+ PCOUT = 0x0000;
+ PCSEL = 0x0000;
+ PCREN = 0xFFFF;
+
+ #ifndef __MSP430F550x
+ PDOUT = 0x0000; // If using a device other than:
+ PDSEL = 0x0000; // F5510, F5529, F5638, or F6638
+ PDREN = 0xF0FF;
+ PDDIR = 0xFFFF; // you may need to comment out these lines
+ #endif
+
+
+ #if defined (__MSP430F563x_F663x)
+ P9OUT = 0x00;
+ P9SEL = 0x00;
+ P9REN = 0xFF;
+ #endif
+
+ PJDIR = (0xFFFF - RESET_PIN - TEST_PIN);
+ PJOUT = 0x0000;
+
+ P1DIR |= 0x03; // for LEDs
+}
+
+
+
+//----------------------------------------------------------------------------
+VOID Init_StartUp(VOID)
+{
+ WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
+
+ __disable_interrupt(); // Disable global interrupts
+
+ Init_Ports(); // Init ports (do first ports because clocks do change ports)
+ SetVCore(3); // USB core requires the VCore set to 1.8 volt, independ of CPU clock frequency
+ Init_Clock();
+
+ __enable_interrupt(); // enable global interrupts
+
+ Port_Mapping();
+
+#ifdef UART_BASED
+ #ifdef UART0_INTFNUM
+ InitUart0(9600);
+ #endif
+
+ #ifdef UART1_INTFNUM
+ InitUart1(9600);
+ #endif
+#endif
+
+#ifdef I2C_BASED
+#ifdef UART0_INTFNUM
+ InitI2C(BSL_SLAVE_ADDR, 400000);
+ #endif
+#endif
+
+}
+
+//----------------------------------------------------------------------------
+VOID ConfigUSB(VOID)
+{
+ USB_init(); // Init USB
+
+ // Enable various USB event handling routines
+
+ USB_setEnabledEvents(kUSB_VbusOnEvent+kUSB_VbusOffEvent+kUSB_receiveCompletedEvent
+ +kUSB_dataReceivedEvent+kUSB_UsbSuspendEvent+kUSB_UsbResumeEvent+kUSB_UsbResetEvent);
+
+
+ // See if we're already attached physically to USB, and if so, connect to it
+ // Normally applications don't invoke the event handlers, but this is an exception.
+
+ if (USB_connectionInfo() & kUSB_vbusPresent)
+ {
+ if (USB_enable() == kUSB_succeed)
+ {
+ USB_reset();
+ USB_connect();
+ }
+ }
+
+}
+
+//----------------------------------------------------------------------------
+void Port_Mapping(void)
+{
+ // Disable Interrupts before altering Port Mapping registers
+ __disable_interrupt();
+ // Enable Write-access to modify port mapping registers
+ PMAPPWD = 0x02D52;
+
+ #ifdef PORT_MAP_RECFG
+ // Allow reconfiguration during runtime
+ PMAPCTL = PMAPRECFG;
+ #endif
+
+ #ifdef __MSP430F550x
+ //P4MAP0 = PM_UCA0RXD;
+ //P4MAP1 = PM_UCA0TXD;
+#ifdef UART_BASED
+ P4MAP4 = PM_UCA0TXD;
+ P4MAP5 = PM_UCA0RXD;
+#elif I2C_BASED
+ P4MAP4 = PM_UCB0SCL;
+ P4MAP5 = PM_UCB0SDA;
+#else
+#error Define a valid interface
+#endif
+ //P4MAP7 = PM_MCLK;
+ #endif
+ #ifdef __MSP430F563x_F663x
+ P2MAP0 = PM_UCA0TXD;
+ P2MAP1 = PM_UCA0RXD;
+ #endif
+
+ // Disable Write-Access to modify port mapping registers
+ PMAPPWD = 0;
+ #ifdef PORT_MAP_EINT
+ __enable_interrupt(); // Re-enable all interrupts
+ #endif
+}
+//----------------------------------------------------------------------------
+//End of file.
+//----------------------------------------------------------------------------
diff --git a/initMCU.h b/initMCU.h
--- /dev/null
+++ b/initMCU.h
@@ -0,0 +1,47 @@
+/*
+ * initMCU.h
+ *
+ * Provides initialization functions.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+#ifndef INITMCU_H_
+#define INITMCU_H_
+
+VOID Init_Clock(VOID);
+VOID Init_Ports(VOID);
+VOID Init_StartUp(VOID);
+VOID ConfigUSB(VOID);
+
+#endif /*INITMCU_H_*/
diff --git a/main.c b/main.c
--- /dev/null
+++ b/main.c
@@ -0,0 +1,313 @@
+/*
+ * main.c
+ *
+ * Main function of MSP430-BSL. Based on MSP430 USB-Example (CDC/HID Driver)
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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 <MSP430.h>
+#include "USB_API/USB_Common/device.h"
+#include "USB_API/USB_Common/types.h" // Basic Type declarations
+#include "USB_API/USB_Common/usb.h" // USB-specific functions
+#include "USB_config/descriptors.h"
+#include "USB_API/USB_CDC_API/UsbCdc.h"
+#include "usb/usbConstructs.h"
+
+#include "main.h"
+#include "initMCU.h"
+#include "timer.h"
+
+#include <intrinsics.h>
+#include <string.h>
+
+enum active_peripherals active_peripheral = I2C;
+
+#if (!defined (UART_BASED) && !defined(I2C_BASED))
+#error "Define a valid interface"
+#endif
+
+#include "i2c.h"
+#include "uart.h"
+
+#ifdef I2C_BASED
+#include "BSL_Comm.h"
+BYTE dataBuffer[300]; // buffer for data receiving
+volatile BYTE bDataSendCompleted_event[CDC_NUM_INTERFACES] = {FALSE};
+volatile BYTE bDataReceiveCompleted_event[CDC_NUM_INTERFACES] = {FALSE}; // data receive completed event
+unsigned char UART_FSM(BYTE* dataBuffer);
+#endif
+
+//------------------------------------------------------------------------------
+VOID BlinkLed(VOID)
+{
+ //static BYTE nCount = 0;
+
+ //if(nCount++ > 100)
+ //{
+ // nCount = 0;
+ TogglePin(1,0);// Toggle LED P1.0
+ //}
+}
+
+/*----------------------------------------------------------------------------+
+| Main Routine |
++----------------------------------------------------------------------------*/
+VOID main(VOID)
+{
+#ifdef I2C_BASED
+ BYTE ret;
+ WORD bytes_sent, bytes_received;
+ int16_t sendDataLength = 0;
+ unsigned int BSLCommandLength = 0;
+ int16_t requireSlaveAnswer = 1;
+#endif
+
+ Init_StartUp(); //initialize device
+ ConfigUSB(); //configure USB
+ Delay(3000000); // !!! Do not remove this delay !!!
+ Init_TimerA2();
+ TogglePin(1,0);
+ TogglePin(1,1);
+ __delay_cycles(5000000);
+ TogglePin(1,0);
+ TogglePin(1,1);
+ __delay_cycles(5000000);
+ TogglePin(1,0);
+ TogglePin(1,1);
+ __delay_cycles(5000000);
+ TogglePin(1,0);
+ TogglePin(1,1);
+ __delay_cycles(5000000);
+ __enable_interrupt(); // enable global interrupts
+#ifdef UART_BASED
+ while(1);
+#elif defined (I2C_BASED)
+ while(1)
+ {
+ if(active_peripheral == UART)
+ {
+ //Check the USB state and directly main loop accordingly
+ switch (USB_connectionState())
+ {
+ case ST_USB_DISCONNECTED:
+ // __bis_SR_register(LPM3_bits + GIE); //Enter LPM3 w/ interrupts enabled
+ _NOP(); //For Debugger
+ break;
+
+ case ST_USB_CONNECTED_NO_ENUM:
+ break;
+
+ case ST_ENUM_ACTIVE:
+ //__bis_SR_register(LPM0_bits + GIE); //Enter LPM0 (can't do LPM3 when active)
+ //_NOP(); //For Debugger
+
+ ret = USBCDC_intfStatus(CDC0_INTFNUM, &bytes_sent, &bytes_received);
+ if (ret & kUSBCDC_dataWaiting)
+ {
+ //_NOP(); // Send data received from USB to UART
+ USBCDC_receiveData(dataBuffer, 1, CDC0_INTFNUM);
+ while(UCA0STAT & UCBUSY);
+ UCA0TXBUF = dataBuffer[0];
+ }
+
+// if(UCA0IFG & UCRXIFG)
+// {
+// _NOP(); // Send data received from UART to USB
+// bDataSendCompleted_event[0] = FALSE;
+// ret = USBCDC_sendData((BYTE*)&UCA0RXBUF, 1, CDC0_INTFNUM);
+// while (bDataSendCompleted_event == FALSE){};
+// UCA0IFG &= ~UCRXIFG;
+// }
+
+ break;
+
+ case ST_ENUM_SUSPENDED:
+ // P1OUT &= ~BIT0; //When suspended, turn off LED
+ // __bis_SR_register(LPM3_bits + GIE); //Enter LPM3 w/ interrupts
+ _NOP();
+ break;
+
+ case ST_ENUM_IN_PROGRESS:
+ break;
+
+ case ST_NOENUM_SUSPENDED:
+ // P1OUT &= ~BIT0;
+ //__bis_SR_register(LPM3_bits + GIE);
+ _NOP();
+ break;
+
+ case ST_ERROR:
+ _NOP();
+ break;
+
+ default:;
+ }
+ }
+ else if(active_peripheral == I2C)
+ {
+ //Check the USB state and directly main loop accordingly
+ switch (USB_connectionState())
+ {
+ case ST_USB_DISCONNECTED:
+ // __bis_SR_register(LPM3_bits + GIE); //Enter LPM3 w/ interrupts enabled
+ _NOP(); //For Debugger
+ break;
+
+ case ST_USB_CONNECTED_NO_ENUM:
+ break;
+
+ case ST_ENUM_ACTIVE:
+ //__bis_SR_register(LPM0_bits + GIE); //Enter LPM0 (can't do LPM3 when active)
+ //_NOP(); //For Debugger
+
+ ret = USBCDC_intfStatus(CDC0_INTFNUM, &bytes_sent, &bytes_received);
+ if (ret & kUSBCDC_dataWaiting)
+ {
+ BSLCommandLength = UART_FSM(dataBuffer);
+ }
+ if (BSLCommandLength > 0)
+ {
+ // Special command to just get data
+ if (BSLCommandLength == 0x01)
+ {
+ // If response is OK, request response from Slave
+ sendDataLength = i2cReceiveMessage(dataBuffer);
+ if ((requireSlaveAnswer < 0) || (sendDataLength < 0))
+ {
+ // If there was an error, report to PC
+ sendDataLength = 1;
+ dataBuffer[0] = 0x55; // Temporary error code
+ }
+ }
+ else
+ {
+ requireSlaveAnswer = i2cSendMessage(dataBuffer, BSLCommandLength);
+ i2cStopSending();
+ __delay_cycles(10000);
+
+ if (requireSlaveAnswer == 0x00)
+ {
+ sendDataLength = 0; // Don't send response to PC
+ }
+ else if(requireSlaveAnswer > 0)
+ {
+ // If response is OK, request response from Slave
+ sendDataLength = i2cReceiveMessage(dataBuffer);
+ }
+
+ if ((requireSlaveAnswer < 0) || (sendDataLength < 0))
+ {
+ // If there was an error, report to PC
+ sendDataLength = 1;
+ dataBuffer[0] = 0x55; // Temporary error code
+ }
+ BSLCommandLength = 0;
+ }
+ }
+
+ if (sendDataLength > 0)
+ {
+ //send data back to PC
+ bDataSendCompleted_event[0] = FALSE;
+ ret = USBCDC_sendData((BYTE*)&dataBuffer, sendDataLength, CDC0_INTFNUM);
+ while (bDataSendCompleted_event == FALSE){};
+/*
+ do
+ {
+ ret = USBCDC_intfStatus(CDC0_INTERFACE_NUMBER, &bytes_sent, &bytes_received);
+ }
+ while (ret & kUSBCDC_waitingForSend);
+*/
+ sendDataLength = 0;
+ __no_operation();
+ }
+
+ break;
+
+ case ST_ENUM_SUSPENDED:
+ // P1OUT &= ~BIT0; //When suspended, turn off LED
+ // __bis_SR_register(LPM3_bits + GIE); //Enter LPM3 w/ interrupts
+ _NOP();
+ break;
+
+ case ST_ENUM_IN_PROGRESS:
+ break;
+
+ case ST_NOENUM_SUSPENDED:
+ // P1OUT &= ~BIT0;
+ //__bis_SR_register(LPM3_bits + GIE);
+ _NOP();
+ break;
+
+ case ST_ERROR:
+ _NOP();
+ break;
+
+ default:;
+ }
+ }
+ }
+#endif
+
+} //main()
+
+//------------------------------------------------------------------------------
+#pragma vector = UNMI_VECTOR
+__interrupt VOID UNMI_ISR(VOID)
+{
+ switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG))
+ {
+ case SYSUNIV_NONE:
+ __no_operation();
+ break;
+ case SYSUNIV_NMIIFG:
+ __no_operation();
+ break;
+ case SYSUNIV_OFIFG:
+ UCSCTL7 &= ~(DCOFFG+0+0+0); // Clear OSC flaut Flags fault flags
+ SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
+ break;
+ case SYSUNIV_ACCVIFG:
+ __no_operation();
+ break;
+ case SYSUNIV_BUSIFG:
+ SYSBERRIV = 0; // clear bus error flag
+ USB_disable(); // Disable
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//End of file.
+//------------------------------------------------------------------------------
diff --git a/main.h b/main.h
--- /dev/null
+++ b/main.h
@@ -0,0 +1,79 @@
+/*
+ * main.h
+ *
+ * Main function of MSP430-BSL. Based on MSP430 USB-Example (CDC/HID Driver)
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+#include "USB_API/USB_Common/device.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+Call all needed Init_...() functions.
+ Needed Init_...() functions depends on build settings.
+*/
+
+enum active_peripherals{UART, I2C};
+
+// Macro definition
+#define SetPinOut(px,py) P##px##DIR |= (1<<py)
+#define SetPinIn(px,py) P##px##DIR &= ~(1<<py)
+#define SetPin(px,py) P##px##OUT |= (1<<py)
+#define ClearPin(px, py) P##px##OUT &= ~(1<<py)
+#define TogglePin(px, py) P##px##OUT ^= (1<<py)
+
+#define SelectPin(px,py) P##px##SEL |= (1<<py)
+#define ResetPin(px,py) P##px##SEL &= ~(1<<py)
+
+#define Delay(time) \
+{ \
+ ULONG count = time; \
+ while(--count); \
+}
+
+VOID BlinkLed(VOID);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _MAIN_H_ */
+/*------------------------ Nothing Below This Line --------------------------*/
+
diff --git a/timer.c b/timer.c
--- /dev/null
+++ b/timer.c
@@ -0,0 +1,75 @@
+/*
+ * timer.c
+ *
+ * Generates period for checking UART buffer and Task Queue.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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 <MSP430.h>
+#include "USB_API/USB_Common/types.h"
+#include "main.h"
+
+#include "descriptors.h"
+#include "uart.h"
+
+//----------------------------------------------------------------------------
+// TimerA2 Init
+VOID Init_TimerA2(VOID)
+{
+ TA2CCTL0 = CCIE; // CCR0 interrupt enabled
+ TA2CTL = TASSEL_1 + TACLR; // ACLK, clear TAR
+
+ TA2CTL &= ~MC_1; // Turn off Timer
+ TA2CCR0 = 33; // Set Timer Period = 1 ms
+ TA2CTL |= MC_1; // Start Timer
+}
+
+//-----------------------------------------------------------------------------
+// Timer1 A0 interrupt service routine
+#pragma vector=TIMER2_A0_VECTOR
+__interrupt void TIMER2_A0_ISR(void)
+{
+ #ifdef UART0_INTFNUM
+ UartToCdc(UART0_INTFNUM, CDC0_INTFNUM);
+ #endif
+ #ifdef UART1_INTFNUM
+ UartToCdc(UART1_INTFNUM, CDC1_INTFNUM);
+ #endif
+
+ //BlinkLed();
+}
+
+//==============================================================================
+// End of file timer.c
+//==============================================================================
diff --git a/timer.h b/timer.h
--- /dev/null
+++ b/timer.h
@@ -0,0 +1,45 @@
+/*
+ * timer.h
+ *
+ * Generates period for checking UART buffer and Task Queue.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+#ifndef TIMER_H_
+#define TIMER_H_
+
+// Initialize TimerA2
+VOID Init_TimerA2(VOID);
+
+#endif //TIMER_H_
\ No newline at end of file
diff --git a/uart.c b/uart.c
--- /dev/null
+++ b/uart.c
@@ -0,0 +1,993 @@
+/*
+ * uart.c
+ *
+ * Implementation of UART Bridge.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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 <MSP430.h>
+#include <descriptors.h>
+
+#include "USB_API/USB_Common/types.h"
+#include "main.h"
+#include "USB_API/USB_Common/types.h"
+#include "USB_API/USB_Common/defMSP430USB.h"
+#include "USB_API/USB_Common/usb.h" // USB-specific Data Structures
+#include "USB_API/USB_CDC_API/UsbCdc.h"
+#include "uart.h"
+
+#include <string.h>
+//function pointers
+extern VOID *(*USB_RX_memcpy)(VOID * dest, const VOID * source, size_t count);
+extern VOID *(*USB_TX_memcpy)(VOID * dest, const VOID * source, size_t count);
+
+//------------------------------------------------------------------------------
+// Global Variables
+//------------------------------------------------------------------------------
+extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
+extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
+
+//------------------------------------------------------------------------------
+
+// List of standard baudrates
+const struct _BaudrateList{
+ BYTE ucaBR0, ucaBR1, ucaMCTL;
+}BaudrateList[] = { // CLK 20MHz
+ {0x00, 0x00, 0x00},
+ {0x1A, 0x41, UCBRS_5}, // 1.2 kb/s
+ {0x8D, 0x20, UCBRS_3}, // 2.4 kb/s
+ {0x46, 0x10, UCBRS_5}, // 4.8 kb/s
+ {0x82, 0x00, 0x30 + UCOS16}, // 9.6 kb/s
+ {0x41, 0x00, (UCBRF_2+UCOS16)}, // 19.2 kb/s
+ {0x20, 0x00, (UCBRF_9+UCOS16)}, // 38.4 kb/s
+ {0x15, 0x00, (UCBRF_11+UCOS16)}, // 57.6 kb/s
+ {0x0A, 0x00, (UCBRF_14+UCOS16)}, // 115.2 kbit/s
+ {0x05, 0x00, (UCBRF_7+UCOS16)}, // 230.4 kbit/s
+ {0x02, 0x00, (UCBRS_6+UCBRF_10+UCOS16)}, // 460.8 kbit/s
+ {0x15, 0x00, (UCBRS_6)} // 921.6 kbit/s
+};
+
+// Baudrate indexes
+enum baud{ BAUD_ERROR, BAUD_1200, BAUD_2400, BAUD_4800, BAUD_9600, BAUD_19200,
+ BAUD_38400, BAUD_57600, BAUD_115200, BAUD_230400, BAUD_460800, BAUD_921600};
+
+// Macro gets number of UART channels
+#ifdef UART0_INTFNUM
+ #ifdef UART1_INTFNUM
+ #define UART_NUM_INTERFACES 2
+ #else
+ #define UART_NUM_INTERFACES 1
+ #endif
+#else
+ #ifdef UART1_INTFNUM
+ #define UART_NUM_INTERFACES 1
+ #endif
+#endif
+
+// Rx/Tx Buffers
+#if ( UART_NUM_INTERFACES )
+static struct _UartBridge
+{
+ // indicates which buffer is used by host to receive/transmit data
+ BYTE inpCurrentBufferXY;
+ BYTE outpCurrentBufferXY;
+
+ BYTE txInProgress;
+ UINT rxBufferOffset;
+
+ BYTE txBuffer[TX_BUFFER_SIZE];
+ BYTE rxBuffer[RX_BUFFER_SIZE];
+}UartBridge[UART_NUM_INTERFACES];
+#endif
+
+//Local functions prototypes
+VOID SetupDmaForUart0(VOID);
+VOID SetupDmaForUart1(VOID);
+
+BYTE InitUart(ULONG lBaudrate)
+{
+ BYTE baudIndex;
+
+ #ifdef __MSP430F550x
+ //SelectPin(3,3); // Assign P3.3 to UCA0TXD and..
+ //SelectPin(3,4); // P3.4 to UCA0RXD
+
+ SelectPin(4,4); // Assign P4.4 to UCA0TXD and..
+ //SetPinOut(4,4);
+ SelectPin(4,5); // P4.5 to UCA0RXD
+ //SetPinOut(4,5);
+
+ PJDIR |= (RESET_PIN | TEST_PIN);
+
+#ifdef JTAG_RELEASE
+ PJDIR = BIT2+BIT1;
+ PJOUT = BIT2+BIT1;
+#endif
+
+
+ //Simple port mapping
+ __disable_interrupt(); // Disable Interrupts before altering Port Mapping registers
+ PMAPKEYID = PMAPKEY;
+ P4MAP4 = PM_UCA0TXD;
+ P4MAP5 = PM_UCA0RXD;
+ PMAPKEYID = 0;
+ __enable_interrupt();
+
+ #endif
+ #ifdef __MSP430F563x_F663x
+ SelectPin(2,0); // Assign P2.0 to UCA0TXD and..
+ SelectPin(2,1); // P2.1 to UCA0RXD
+ #endif
+
+
+ // configure USCI_A0 UART
+ UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
+ UCA0CTL1 |= UCSSEL__SMCLK; // SMCLK
+ UCA0CTL0 = UCPEN+UCPAR;
+
+ switch(lBaudrate)
+ {
+ #if (RX_BUFFER_SIZE > (1200*SYS_DELAY/1000/8))
+ case 1200: baudIndex = BAUD_1200; break;
+ #endif
+ #if (RX_BUFFER_SIZE > (2400*SYS_DELAY/1000/8))
+ case 2400: baudIndex = BAUD_2400; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (4800*SYS_DELAY/1000/8))
+ case 4800: baudIndex = BAUD_4800; break;
+ #endif
+ case 4801:
+ __disable_interrupt();
+ USB_disable();
+ Delay(100000);
+ ((void(*)(void))0x1000)(); // Call #0x1000, enter BSL
+ break;
+
+ case 4802:
+ P1OUT |= BIT0;
+ // JTAG 20 work around
+ // start, all high
+ PJOUT = RESET_PIN+TEST_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ //Step 1
+ //RESET LOW
+ //TEST LOW
+ PJOUT = 0;
+ Delay(INVOKE_DELAY);
+
+ //Step 2
+ //RESET LOW
+ //TEST HIGH
+ PJOUT = TEST_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 3
+ //RESET LOW
+ //TEST LOW
+ PJOUT = 0;
+ Delay(INVOKE_DELAY);
+
+ //Step 4
+ //RESET LOW
+ //TEST HIGH
+ PJOUT = TEST_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 5
+ //RESET LOW
+ //TEST LOW
+ PJOUT = 0;
+ Delay(INVOKE_DELAY);
+
+ //Step 6
+ //RESET HIGH
+ //TEST LOW
+ PJOUT = RESET_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ baudIndex = BAUD_9600;
+ break;
+ #if(RX_BUFFER_SIZE > (9600*SYS_DELAY/1000/8))
+ case 9600: baudIndex = BAUD_9600; break;
+ #endif
+ case 9601:
+ P1OUT |= BIT1;
+ // invoke BSL, classic
+ //Start: all high
+ PJOUT = RESET_PIN+TEST_PIN+TCK_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ //Step 1
+ //RESET LOW
+ //TEST LOW
+ //TCK HIGHT
+ PJOUT = TCK_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 2
+ //RESET LOW
+ //TEST HIGH
+ //TCK LOW
+ PJOUT = TEST_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 3
+ //RESET LOW
+ //TEST LOW
+ //TCK HIGH
+ PJOUT = TCK_PIN;
+ Delay(20);
+
+ //Step 4
+ //RESET LOW
+ //TEST HIGH
+ //TCK LOW
+ PJOUT = TEST_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 5
+ //RESET HIGH
+ //TEST HIGH
+ //TCK LOW
+ PJOUT = TEST_PIN + RESET_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 6
+ //RESET HIGH
+ //TEST LOW
+ //TCK HIGH
+ PJOUT = TCK_PIN + RESET_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ baudIndex = BAUD_9600;
+ break;
+ /* reserved for future devices invoke sequence
+ case 9602: newInvoke(2); break;
+ case 9603: newInvoke(3); break;
+ case 9604: newInvoke(4); break;
+ case 9605: newInvoke(5); break;
+ case 9606: newInvoke(6); break;
+ case 9607: newInvoke(7); break;
+ case 9608: newInvoke(8); break;
+ case 9609: newInvoke(9); break;
+ case 9610: newInvoke(10); break;
+ case 9611: newInvoke(11); break;
+ case 9612: newInvoke(12); break;
+ case 9613: newInvoke(13); break;
+ case 9614: newInvoke(14); break;
+ case 9615: newInvoke(15); break;
+ case 9616: newInvoke(16); break;
+ case 9617: newInvoke(17); break;
+ case 9618: newInvoke(18); break;
+ */
+ #if(RX_BUFFER_SIZE > (19200*SYS_DELAY/1000/8))
+ case 19200: baudIndex = BAUD_19200; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (38400*SYS_DELAY/1000/8))
+ case 38400: baudIndex = BAUD_38400; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (57600*SYS_DELAY/1000/8))
+ case 57600: baudIndex = BAUD_57600; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (115200*SYS_DELAY/1000/8))
+ case 115200:baudIndex = BAUD_115200; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (230400*SYS_DELAY/1000/8))
+ case 230400:baudIndex = BAUD_230400; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (460800*SYS_DELAY/1000/8))
+ case 460800:baudIndex = BAUD_460800; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (921600*SYS_DELAY/1000/8))
+ case 921600:baudIndex = BAUD_921600; break;
+ #endif
+ default: baudIndex = BAUD_ERROR; break;
+ }
+
+ if(baudIndex != BAUD_ERROR)
+ {
+ UCA0BR0 = BaudrateList[baudIndex].ucaBR0;
+ UCA0BR1 = BaudrateList[baudIndex].ucaBR1;
+ UCA0MCTL = BaudrateList[baudIndex].ucaMCTL;
+ }
+
+ //UCA0STAT |= 0x80; // Enable internal loopback
+
+ UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
+ //UCA0IE |= UCRXIE;// + UCTXIE; // Enable USCI_A0 Rx/Tx interrupt
+
+ // SetupDmaForUart0();
+
+ UCA0IE |= UCRXIE;
+
+ return baudIndex;
+}
+
+#pragma vector=USCI_A0_VECTOR
+__interrupt void USCI_A0_ISR(void)
+{
+ extern volatile BYTE bDataSendCompleted_event[];
+ switch(__even_in_range(UCA0IV,4))
+ {
+ case 0:break; // Vector 0 - no interrupt
+ case 2: // Vector 2 - RXIFG
+ _NOP(); // Send data received from UART to USB
+ bDataSendCompleted_event[0] = FALSE;
+ USBCDC_sendData((BYTE*)&UCA0RXBUF, 1, CDC0_INTFNUM);
+ while (bDataSendCompleted_event == FALSE){};
+ UCA0IFG &= ~UCRXIFG;
+ break;
+ case 4: // Vector 4 - TXIFG
+ __no_operation(); // used for debugging
+ break;
+ default: break;
+ }
+}
+
+#ifdef UART0_INTFNUM
+//------------------------------------------------------------------------------
+BYTE InitUart0(ULONG lBaudrate)
+{
+ BYTE baudIndex;
+
+ #ifdef __MSP430F550x
+ //SelectPin(3,3); // Assign P3.3 to UCA0TXD and..
+ //SelectPin(3,4); // P3.4 to UCA0RXD
+
+ SelectPin(4,4); // Assign P4.4 to UCA0TXD and..
+ //SetPinOut(4,4);
+ SelectPin(4,5); // P4.5 to UCA0RXD
+ //SetPinOut(4,5);
+
+#ifdef JTAG_RELEASE
+ PJDIR = BIT2+BIT1;
+ PJOUT = BIT2+BIT1;
+#endif
+
+
+ //Simple port mapping
+ __disable_interrupt(); // Disable Interrupts before altering Port Mapping registers
+ PMAPKEYID = PMAPKEY;
+ P4MAP4 = PM_UCA0TXD;
+ P4MAP5 = PM_UCA0RXD;
+ PMAPKEYID = 0;
+ __enable_interrupt();
+
+ #endif
+ #ifdef __MSP430F563x_F663x
+ SelectPin(2,0); // Assign P2.0 to UCA0TXD and..
+ SelectPin(2,1); // P2.1 to UCA0RXD
+ #endif
+
+
+ // configure USCI_A0 UART
+ UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
+ UCA0CTL1 |= UCSSEL__SMCLK; // SMCLK
+ UCA0CTL0 = UCPEN+UCPAR;
+
+ switch(lBaudrate)
+ {
+ #if (RX_BUFFER_SIZE > (1200*SYS_DELAY/1000/8))
+ case 1200: baudIndex = BAUD_1200; break;
+ #endif
+ #if (RX_BUFFER_SIZE > (2400*SYS_DELAY/1000/8))
+ case 2400: baudIndex = BAUD_2400; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (4800*SYS_DELAY/1000/8))
+ case 4800: baudIndex = BAUD_4800; break;
+ #endif
+ case 4801:
+ __disable_interrupt();
+ USB_disable();
+ Delay(100000);
+ ((void(*)(void))0x1000)(); // Call #0x1000, enter BSL
+ break;
+
+ case 4802:
+ P1OUT |= BIT0;
+ // JTAG 20 work around
+ // start, all high
+ PJOUT = RESET_PIN+TEST_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ //Step 1
+ //RESET LOW
+ //TEST LOW
+ PJOUT = 0;
+ Delay(INVOKE_DELAY);
+
+ //Step 2
+ //RESET LOW
+ //TEST HIGH
+ PJOUT = TEST_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 3
+ //RESET LOW
+ //TEST LOW
+ PJOUT = 0;
+ Delay(INVOKE_DELAY);
+
+ //Step 4
+ //RESET LOW
+ //TEST HIGH
+ PJOUT = TEST_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 5
+ //RESET LOW
+ //TEST LOW
+ PJOUT = 0;
+ Delay(INVOKE_DELAY);
+
+ //Step 6
+ //RESET HIGH
+ //TEST LOW
+ PJOUT = RESET_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ baudIndex = BAUD_9600;
+ break;
+ #if(RX_BUFFER_SIZE > (9600*SYS_DELAY/1000/8))
+ case 9600: baudIndex = BAUD_9600; break;
+ #endif
+ case 9601:
+ P1OUT |= BIT1;
+ // invoke BSL, classic
+ //Start: all high
+ PJOUT = RESET_PIN+TEST_PIN+TCK_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ //Step 1
+ //RESET LOW
+ //TEST LOW
+ //TCK HIGHT
+ PJOUT = TCK_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 2
+ //RESET LOW
+ //TEST HIGH
+ //TCK LOW
+ PJOUT = TEST_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 3
+ //RESET LOW
+ //TEST LOW
+ //TCK HIGH
+ PJOUT = TCK_PIN;
+ Delay(20);
+
+ //Step 4
+ //RESET LOW
+ //TEST HIGH
+ //TCK LOW
+ PJOUT = TEST_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 5
+ //RESET HIGH
+ //TEST HIGH
+ //TCK LOW
+ PJOUT = TEST_PIN + RESET_PIN;
+ Delay(INVOKE_DELAY);
+
+ //Step 6
+ //RESET HIGH
+ //TEST LOW
+ //TCK HIGH
+ PJOUT = TCK_PIN + RESET_PIN;
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+ Delay(INVOKE_DELAY);
+
+ baudIndex = BAUD_9600;
+ break;
+ /* reserved for future devices invoke sequence
+ case 9602: newInvoke(2); break;
+ case 9603: newInvoke(3); break;
+ case 9604: newInvoke(4); break;
+ case 9605: newInvoke(5); break;
+ case 9606: newInvoke(6); break;
+ case 9607: newInvoke(7); break;
+ case 9608: newInvoke(8); break;
+ case 9609: newInvoke(9); break;
+ case 9610: newInvoke(10); break;
+ case 9611: newInvoke(11); break;
+ case 9612: newInvoke(12); break;
+ case 9613: newInvoke(13); break;
+ case 9614: newInvoke(14); break;
+ case 9615: newInvoke(15); break;
+ case 9616: newInvoke(16); break;
+ case 9617: newInvoke(17); break;
+ case 9618: newInvoke(18); break;
+ */
+ #if(RX_BUFFER_SIZE > (19200*SYS_DELAY/1000/8))
+ case 19200: baudIndex = BAUD_19200; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (38400*SYS_DELAY/1000/8))
+ case 38400: baudIndex = BAUD_38400; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (57600*SYS_DELAY/1000/8))
+ case 57600: baudIndex = BAUD_57600; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (115200*SYS_DELAY/1000/8))
+ case 115200:baudIndex = BAUD_115200; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (230400*SYS_DELAY/1000/8))
+ case 230400:baudIndex = BAUD_230400; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (460800*SYS_DELAY/1000/8))
+ case 460800:baudIndex = BAUD_460800; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (921600*SYS_DELAY/1000/8))
+ case 921600:baudIndex = BAUD_921600; break;
+ #endif
+ default: baudIndex = BAUD_ERROR; break;
+ }
+
+ if(baudIndex != BAUD_ERROR)
+ {
+ UCA0BR0 = BaudrateList[baudIndex].ucaBR0;
+ UCA0BR1 = BaudrateList[baudIndex].ucaBR1;
+ UCA0MCTL = BaudrateList[baudIndex].ucaMCTL;
+ }
+
+ //UCA0STAT |= 0x80; // Enable internal loopback
+
+ UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
+ //UCA0IE |= UCRXIE;// + UCTXIE; // Enable USCI_A0 Rx/Tx interrupt
+
+ SetupDmaForUart0();
+
+ return baudIndex;
+}
+
+void newInvoke( BYTE invokeParam )
+{
+// TBD for new devices
+}
+
+//------------------------------------------------------------------------------
+#pragma vector=USCI_A0_VECTOR
+__interrupt void USCI_A0_ISR(void)
+{
+ switch(__even_in_range(UCA0IV,4))
+ {
+ case 0:break; // Vector 0 - no interrupt
+ case 2:break; // Vector 2 - RXIFG
+ case 4: // Vector 4 - TXIFG
+ __no_operation(); // used for debugging
+ break;
+ default: break;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+VOID SetupDmaForUart0(VOID)
+{
+ // configure DMA2
+ DMACTL4 |= ROUNDROBIN;// + DMARMWDIS + ENNMI;
+
+ DMACTL1 |= DMA2TSEL__USCIA0RX; // triger on USCIA0 receive
+ __data16_write_addr((unsigned short) &DMA2SA,(unsigned long) &UCA0RXBUF);
+ // Source block address
+ __data16_write_addr((unsigned short) &DMA2DA,// Destination single address
+ (unsigned long) UartBridge[UART0_INTFNUM].rxBuffer);
+ DMA2SZ = RX_BUFFER_SIZE; // Block size
+ DMA2CTL = DMADT_4 + DMADSTINCR_3 + DMALEVEL +
+ DMASBDB + DMAEN + DMAIE; // Rpt, inc dst, enable
+
+ // configure DMA1
+ DMACTL0 |= DMA1TSEL__USCIA0TX; // triger on USCIA0 transmit
+ __data16_write_addr((unsigned short) &DMA1SA,// Source block address
+ (unsigned long) UartBridge[UART0_INTFNUM].txBuffer);
+ __data16_write_addr((unsigned short) &DMA1DA,(unsigned long) &UCA0TXBUF);
+ // Destination single address
+ DMA1CTL = DMADT_0 + DMASRCINCR_3 + DMALEVEL +
+ DMASBDB + DMAIE; // inc src, int
+}
+#endif
+
+#ifdef UART1_INTFNUM
+//------------------------------------------------------------------------------
+BYTE InitUart1(ULONG lBaudrate)
+{
+ BYTE baudIndex;
+
+ #ifdef __MSP430F550x
+ SelectPin(4,4); // Assign P4.4 to UCA0TXD and..
+ SelectPin(4,5); // P4.5 to UCA0RXD
+ #endif
+ #ifdef __MSP430F563x_F663x
+ SelectPin(8,2); // Assign P8.2 to UCA1TXD and..
+ SelectPin(8,3); // P8.3 to UCA1RXD
+ #endif
+
+ // configure USCI_A1 UART
+ UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
+ UCA1CTL1 = UCSSEL__SMCLK; // SMCLK
+
+ switch(lBaudrate)
+ {
+ #if (RX_BUFFER_SIZE > (1200*SYS_DELAY/1000/8))
+ case 1200: baudIndex = BAUD_1200; break;
+ #endif
+ #if (RX_BUFFER_SIZE > (2400*SYS_DELAY/1000/8))
+ case 2400: baudIndex = BAUD_2400; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (4800*SYS_DELAY/1000/8))
+ case 4800: baudIndex = BAUD_4800; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (9600*SYS_DELAY/1000/8))
+ case 9600: baudIndex = BAUD_9600; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (19200*SYS_DELAY/1000/8))
+ case 19200: baudIndex = BAUD_19200; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (38400*SYS_DELAY/1000/8))
+ case 38400: baudIndex = BAUD_38400; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (57600*SYS_DELAY/1000/8))
+ case 57600: baudIndex = BAUD_57600; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (115200*SYS_DELAY/1000/8))
+ case 115200:baudIndex = BAUD_115200; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (230400*SYS_DELAY/1000/8))
+ case 230400:baudIndex = BAUD_230400; break;
+ #endif
+ #if(RX_BUFFER_SIZE > (460800*SYS_DELAY/1000/8))
+ case 460800:baudIndex = BAUD_460800; break;
+ #endif
+ //#if(RX_BUFFER_SIZE > (921600*SYS_DELAY/1000/8))
+ //case 921600:baudIndex = BAUD_921600; break;
+ //#endif
+ default: baudIndex = BAUD_ERROR; break;
+ }
+
+ if(baudIndex != BAUD_ERROR)
+ {
+ UCA1BR0 = BaudrateList[baudIndex].ucaBR0;
+ UCA1BR1 = BaudrateList[baudIndex].ucaBR1;
+ UCA1MCTL = BaudrateList[baudIndex].ucaMCTL;
+ }
+
+ //UCA1STAT |= 0x80; // Enable internal loopback
+
+ UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
+ //UCA1IE |= UCRXIE + UCTXIE; // Enable USCI_A1 Rx/Tx interrupt
+
+ SetupDmaForUart1();
+
+ return baudIndex;
+}
+
+/*
+//------------------------------------------------------------------------------
+#pragma vector=USCI_A1_VECTOR
+__interrupt void USCI_A1_ISR(void)
+{
+ //BYTE tmp = 0x00;
+ switch(__even_in_range(UCA1IV,4))
+ {
+ case 0:break; // Vector 0 - no interrupt
+ case 2: // Vector 2 - RXIFG
+ __no_operation(); // used for debugging
+ break;
+ case 4: // Vector 4 - TXIFG
+ __no_operation(); // used for debugging
+ break;
+ default: break;
+ }
+}
+*/
+
+//------------------------------------------------------------------------------
+VOID SetupDmaForUart1(VOID)
+{
+ // configure DMA4
+ DMACTL4 |= ROUNDROBIN;// + DMARMWDIS + ENNMI;
+
+ DMACTL2 |= DMA4TSEL__USCIA1RX; // triger on USCIA1 receive
+ __data16_write_addr((unsigned short) &DMA4SA,(unsigned long) &UCA1RXBUF);
+ // Source block address
+ __data16_write_addr((unsigned short) &DMA4DA,// Destination single address
+ (unsigned long) UartBridge[UART1_INTFNUM].rxBuffer);
+ DMA4SZ = RX_BUFFER_SIZE; // Block size
+ DMA4CTL = DMADT_4 + DMADSTINCR_3 + DMALEVEL +
+ DMASBDB + DMAEN + DMAIE; // Rpt, inc dst, enable
+
+ // configure DMA5
+ DMACTL2 |= DMA5TSEL__USCIA1TX; // triger on USCIA1 transmit
+ __data16_write_addr((unsigned short) &DMA5SA,// Source block address
+ (unsigned long) UartBridge[UART1_INTFNUM].txBuffer);
+ __data16_write_addr((unsigned short) &DMA5DA,(unsigned long) &UCA1TXBUF);
+ // Destination single address
+ DMA5CTL = DMADT_0 + DMASRCINCR_3 + DMALEVEL +
+ DMASBDB + DMAIE; // inc src, int
+}
+#endif
+
+//------------------------------------------------------------------------------
+// DMA Interrupt Service Routine
+//------------------------------------------------------------------------------
+#pragma vector=DMA_VECTOR
+__interrupt void DMA_ISR(void)
+{
+ switch(__even_in_range(DMAIV,16))
+ {
+ case 0: break;
+ case 2: break; // DMA0IFG = DMA Channel 0
+ case 4: // DMA1IFG = DMA Channel 1
+ #ifdef UART0_INTFNUM
+ UartBridge[UART0_INTFNUM].txInProgress = FALSE;
+ CdcToUart(CDC0_INTFNUM, UART0_INTFNUM);
+ #endif
+ break;
+ case 6: // DMA2IFG = DMA Channel 2
+ #ifdef UART0_INTFNUM
+ UartToCdc(UART0_INTFNUM, CDC0_INTFNUM);
+ #endif
+ break;
+ case 8: // DMA3IFG = DMA Channel 3
+// #ifdef UART0_INTFNUM
+// UartBridge[UART0_INTFNUM].txInProgress = FALSE;
+// CdcToUart(CDC0_INTFNUM, UART0_INTFNUM);
+// #endif
+ break;
+ case 10: // DMA4IFG = DMA Channel 4
+ #ifdef UART1_INTFNUM
+ UartToCdc(UART1_INTFNUM, CDC1_INTFNUM);
+ #endif
+ break;
+ case 12: // DMA5IFG = DMA Channel 5
+ #ifdef UART1_INTFNUM
+ UartBridge[UART1_INTFNUM].txInProgress = FALSE;
+ CdcToUart(CDC1_INTFNUM, UART1_INTFNUM);
+ #endif
+ break;
+ case 14: break; // DMA6IFG = DMA Channel 6
+ case 16: break; // DMA7IFG = DMA Channel 7
+ default: break;
+ }
+}
+
+#if ( UART_NUM_INTERFACES )
+//------------------------------------------------------------------------------
+// Transfers data from the UART buffer to USB_CDC
+//------------------------------------------------------------------------------
+BYTE UartToCdc(BYTE uartNum, BYTE cdcNum)
+{
+ BYTE nTmp;
+ UINT nCount, size;
+ PBYTE pPacket;
+ PBYTE pEP1, pEP2;
+ PBYTE pCT1, pCT2;
+ BYTE edbIndex = stUsbHandle[cdcNum].edb_Index;
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ return FALSE;
+
+ if (UartBridge[uartNum].inpCurrentBufferXY == X_BUFFER) //get current buffer
+ { // X_BUFFER is the active EP buffer
+ pEP1 = (PBYTE)stUsbHandle[cdcNum].iep_X_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ // second EP buffer
+ pEP2 = (PBYTE)stUsbHandle[cdcNum].iep_Y_Buffer;
+ pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+ else
+ {
+ // Y_BUFFER is the active EP buffer
+ pEP1 = (PBYTE)stUsbHandle[cdcNum].iep_Y_Buffer;
+ pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ // second EP buffer
+ pEP2 = (PBYTE)stUsbHandle[cdcNum].iep_X_Buffer;
+ pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+
+ // get DMA counter
+ #ifdef UART0_INTFNUM
+ if(uartNum == UART0_INTFNUM)
+ nCount = RX_BUFFER_SIZE - DMA2SZ;
+ #endif
+
+ #ifdef UART1_INTFNUM
+ if(uartNum == UART1_INTFNUM)
+ nCount = RX_BUFFER_SIZE - DMA4SZ;
+ #endif
+
+ if(UartBridge[uartNum].rxBufferOffset >= RX_BUFFER_SIZE)
+ UartBridge[uartNum].rxBufferOffset = 0;
+
+ if(UartBridge[uartNum].rxBufferOffset > nCount)
+ nCount = RX_BUFFER_SIZE;
+
+ nTmp = *pCT1;
+ if(nTmp & EPBCNT_NAK)
+ {
+ size = nCount - UartBridge[uartNum].rxBufferOffset;
+ if(size)
+ {
+ TogglePin(1,1); // LED2 = RX blink
+ // get packet pointer
+ pPacket = UartBridge[uartNum].rxBuffer + UartBridge[uartNum].rxBufferOffset;
+
+ if(size > (MAX_PACKET_SIZE-1)) // check packet size
+ size = (MAX_PACKET_SIZE-1);
+ UartBridge[uartNum].rxBufferOffset += size; // update offset
+
+
+ USB_RX_memcpy(pEP1, pPacket, size); // copy data into EP X or Y buffer
+ *pCT1 = (BYTE)size;
+
+ // switch current buffer
+ UartBridge[uartNum].inpCurrentBufferXY = (UartBridge[uartNum].inpCurrentBufferXY+1) &0x01;
+ }
+ }
+
+ nTmp = *pCT2;
+ if(nTmp & EPBCNT_NAK)
+ {
+ size = nCount - UartBridge[uartNum].rxBufferOffset;
+ if(size)
+ {
+ // get packet pointer
+ pPacket = UartBridge[uartNum].rxBuffer + UartBridge[uartNum].rxBufferOffset;
+
+ if(size > (MAX_PACKET_SIZE-1)) // check packet size
+ size = (MAX_PACKET_SIZE-1);
+ UartBridge[uartNum].rxBufferOffset += size; // update offset
+
+
+ USB_RX_memcpy(pEP2, pPacket, size); // copy data into EP X or Y buffer
+ *pCT2 = (BYTE)size;
+
+ //switch current buffer
+ UartBridge[uartNum].inpCurrentBufferXY = (UartBridge[uartNum].inpCurrentBufferXY+1) &0x01;
+ }
+ }
+
+
+ return FALSE;
+}
+
+//------------------------------------------------------------------------------
+// Transfers data from the USB_CDC buffer to UART
+//------------------------------------------------------------------------------
+BYTE CdcToUart(BYTE cdcNum, BYTE uartNum)
+{
+ BYTE nCount;
+ PBYTE pEP, pCT;
+ BYTE edbIndex = stUsbHandle[cdcNum].edb_Index;
+
+
+ // Is transmit in progress?
+ if(UartBridge[uartNum].txInProgress)
+ return FALSE;
+
+ // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
+ if ((bFunctionSuspended) ||
+ (bEnumerationStatus != ENUMERATION_COMPLETE))
+ return FALSE;
+
+ // No data to transfer...
+ if (!((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX |
+ tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY) & EPBCNT_NAK))
+ return FALSE;
+
+ if (UartBridge[uartNum].outpCurrentBufferXY == X_BUFFER)//get current buffer
+ {
+ //this is the active EP buffer
+ pEP = (PBYTE)stUsbHandle[cdcNum].oep_X_Buffer;
+ // how many byte we can get from endpoint buffer
+ pCT = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
+ }
+ else
+ {
+ //this is the active EP buffer
+ pEP = (PBYTE)stUsbHandle[cdcNum].oep_Y_Buffer;
+ // how many byte we can get from endpoint buffer
+ pCT = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
+ }
+
+ nCount = *pCT;
+ if(nCount & EPBCNT_NAK)
+ {
+ nCount &= ~EPBCNT_NAK; // clear NAK bit
+ if(nCount)
+ {
+ // copy data from EP X or Y buffer
+ USB_TX_memcpy(UartBridge[uartNum].txBuffer, pEP, nCount);
+
+ // configure DMA
+
+ #ifdef UART0_INTFNUM
+ if(uartNum == UART0_INTFNUM)
+ {
+ DMA1SZ = nCount; // set size
+ DMA1CTL |= DMAEN; // enable
+ }
+ #endif
+
+ #ifdef UART1_INTFNUM
+ if(uartNum == UART1_INTFNUM)
+ {
+ DMA5SZ = nCount; // set size
+ DMA5CTL |= DMAEN; // enable
+ }
+ #endif
+
+ // set tx status
+ UartBridge[uartNum].txInProgress = TRUE;
+ }
+ else
+ UartBridge[uartNum].txInProgress = FALSE;
+
+ //clear NAK, EP ready to receive data
+ *pCT = 0x00;
+
+ //switch current buffer
+ UartBridge[uartNum].outpCurrentBufferXY = (UartBridge[uartNum].outpCurrentBufferXY+1) &0x01;
+ }
+
+ TogglePin(1,0); // LED1 = TX blink
+
+ return FALSE;
+}
+#endif
+
+//==============================================================================
+// End of file uart.c
+//==============================================================================
diff --git a/uart.h b/uart.h
--- /dev/null
+++ b/uart.h
@@ -0,0 +1,104 @@
+/*
+ * uart.h
+ *
+ * Implementation of UART Bridge.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated 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
+ * OWNER 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.
+ *
+ */
+
+#ifndef UART_H_
+#define UART_H_
+
+#include "USB_config/descriptors.h"
+
+#ifdef UART_BASED
+
+// Enable/disable UART Bridge
+// Comment definition for disabling the channel
+#define UART0_INTFNUM 0
+#if CDC_NUM_INTERFACES >= 2
+#define UART1_INTFNUM 1
+#endif
+
+#endif // #define UART_BASED
+
+#if defined (__MSP430F6638__)
+#define CLR_DTR0 P2OUT |= 0x04
+#define SET_DTR0 P2OUT &= ~0x04
+#define CLR_RTS0 P2OUT |= 0x08
+#define SET_RTS0 P2OUT &= ~0x08
+#define CLR_DTR1 P8OUT |= 0x01
+#define SET_DTR1 P8OUT &= ~0x01
+#define CLR_RTS1 P8OUT |= 0x02
+#define SET_RTS1 P8OUT &= ~0x02
+#endif
+
+#if defined (__MSP430F5509__)
+#define SET_DTR0 P4OUT |= 0x08
+#define CLR_DTR0 P4OUT &= ~0x08
+#define CLR_RTS0 {P4OUT |= 0x04 ;P2OUT &= ~0x01;}
+#define SET_RTS0 {P4OUT &= ~0x04;P2OUT |= 0x01;}
+#endif
+
+#define RESET_HIGH {PJOUT |= BIT1;}
+#define RESET_LOW {PJOUT &= ~BIT1;}
+#define TEST_HIGH {PJOUT |= BIT2;}
+#define TEST_LOW {PJOUT &= ~BIT2;}
+#define RESET_PIN BIT1
+#define TEST_PIN BIT2
+#define TCK_PIN BIT3
+
+// Maximal host system delay
+#define MAX_SYS_DELAY 20 // ms
+
+// Size of Rx/Tx UART Buffers
+// Value should be big enough to cover max system delay
+#define RX_BUFFER_SIZE 1280 // max_baud * SYS_DELAY ms/1000/ 8bit
+#define TX_BUFFER_SIZE MAX_PACKET_SIZE // Don't modyfy this value!!!
+
+// Initialize UART
+BYTE InitUart(ULONG lBaudrate);
+BYTE InitUart0(ULONG lBaudrate);
+BYTE InitUart1(ULONG lBaudrate);
+
+// Transfers data from the UART buffer to USB_CDC.
+BYTE UartToCdc(BYTE uartNum, BYTE cdcNum);
+
+// Transfers data from the USB_CDC buffer to UART.
+BYTE CdcToUart(BYTE cdcNum, BYTE uartNum);
+
+void newInvoke( BYTE invokeParam );
+//#define INVOKE_DELAY 30000
+#define INVOKE_DELAY 1000
+
+#endif //UART_H_
diff --git a/usb/usbConstructs.c b/usb/usbConstructs.c
--- /dev/null
+++ b/usb/usbConstructs.c
@@ -0,0 +1,253 @@
+#include "USB_API/USB_Common/device.h"
+#include "USB_API/USB_Common/types.h" // Basic Type declarations
+
+#include "USB_config/descriptors.h"
+#include "USB_API/USB_Common/usb.h" // USB-specific functions
+
+#ifdef _CDC_
+ #include "USB_API/USB_CDC_API/UsbCdc.h"
+#endif
+#ifdef _HID_
+ #include "USB_API/USB_HID_API/UsbHid.h"
+#endif
+
+#include <intrinsics.h>
+#include "usbConstructs.h"
+
+
+/**************************************************************************************************
+These are example, user-editable construct functions for calling the API.
+
+In cases where fast development is the priority, it's usually best to use these sending
+construct functions, rather than calling USBCDC_sendData() or USBHID_sendData()
+directly. This is because they put boundaries on the "background execution" of sends,
+simplfying the application.
+
+xxxsendDataWaitTilDone() essentially eliminates background processing altogether, always
+polling after the call to send and not allowing execution to resume until it's done. This
+allows simpler coding at the expense of wasted MCU cycles, and MCU execution being "locked"
+to the host (also called "synchronous" operation).
+
+xxxsendDataInBackground() takes advantage of background processing ("asynchronous" operation)
+by allowing sending to happen during application execution; while at the same time ensuring
+that the sending always definitely occurs. It provides most of the simplicity of
+xxxsendDataWaitTilDone() while minimizing wasted cycles. It's probably the best choice
+for most applications.
+
+A true, asynchronous implementation would be the most cycle-efficient, but is the most
+difficult to code; and can't be "contained" in an example function as these other approaches
+are. Such an implementation might be advantageous in RTOS-based implementations or those
+requiring the highest levels of efficiency.
+
+These functions take into account all the pertinent return codes, toward ensuring fully
+robust operation. The send functions implement a timeout feature, using a loose "number of
+retries" approach. This was done in order to avoid using additional hardware resources. A
+more sophisticated approach, which the developer might want to implement, would be to use a
+hardware timer.
+
+Please see the MSP430 CDC/HID/MSC USB API Programmer's Guide for a full description of these
+functions, how they work, and how to use them.
+**************************************************************************************************/
+
+
+
+#ifdef _HID_
+/* This construct implements post-call polling to ensure the sending completes before the function
+ returns. It provides the simplest coding, at the expense of wasted cycles and potentially
+ allowing MCU execution to become "locked" to the host, a disadvantage if the host (or bus) is
+ slow. The function also checks all valid return codes, and returns non-zero if an error occurred.
+ It assumes no previous send operation is underway; also assumes size is non-zero. */
+BYTE hidSendDataWaitTilDone(BYTE* dataBuf, WORD size, BYTE intfNum, ULONG ulTimeout)
+{
+ ULONG sendCounter = 0;
+ WORD bytesSent, bytesReceived;
+
+ switch(USBHID_sendData(dataBuf,size,intfNum)) {
+ case kUSBHID_sendStarted:
+ break;
+ case kUSBHID_busNotAvailable:
+ return 2;
+ case kUSBHID_intfBusyError:
+ return 3;
+ case kUSBHID_generalError:
+ return 4;
+ default:;
+ }
+
+ /* If execution reaches this point, then the operation successfully started. Now wait til it's finished. */
+ while(1) {
+ BYTE ret = USBHID_intfStatus(intfNum,&bytesSent,&bytesReceived);
+ if(ret & kUSBHID_busNotAvailable) /* This may happen at any time */
+ return 2;
+ if(ret & kUSBHID_waitingForSend)
+ {
+ if(ulTimeout && (sendCounter++ >= ulTimeout)) /* Incr counter & try again */
+ return 1 ; /* Timed out */
+ }
+ else
+ return 0; /* If neither busNotAvailable nor waitingForSend, it succeeded */
+ }
+}
+
+
+/* This construct implements pre-call polling to ensure the sending completes before the function
+returns. It provides simple coding while also taking advantage of the efficiencies of background
+processing. If a previous send operation is underway, this function does waste cycles polling,
+like xxxsendDataWaitTilDone(); however it's less likely to do so since much of the sending
+presumably took place in the background since the last call to xxxsendDataInBackground().
+The function also checks all valid return codes, and returns non-zero if an error occurred.
+It assumes no previous send operation is underway; also assumes size is non-zero.
+This call assumes a previous send operation might be underway; also assumes size is non-zero.
+Returns zero if send completed; non-zero if it failed, with 1 = timeout and 2 = bus is gone. */
+BYTE hidSendDataInBackground(BYTE* dataBuf, WORD size, BYTE intfNum, ULONG ulTimeout)
+{
+ ULONG sendCounter = 0;
+ WORD bytesSent, bytesReceived;
+
+ while(USBHID_intfStatus(intfNum,&bytesSent,&bytesReceived) & kUSBHID_waitingForSend) {
+ if(ulTimeout && ((sendCounter++)>ulTimeout)) /* A send operation is underway; incr counter & try again */
+ return 1; /* Timed out */
+ }
+
+ /* The interface is now clear. Call sendData(). */
+ switch(USBHID_sendData(dataBuf,size,intfNum)) {
+ case kUSBHID_sendStarted:
+ return 0;
+ case kUSBHID_busNotAvailable:
+ return 2;
+ default:
+ return 4;
+ }
+}
+
+
+
+/* This call only retrieves data that is already waiting in the USB buffer -- that is, data that has
+already been received by the MCU. It assumes a previous, open receive operation (began by a direct
+call to USBxxx_receiveData()) is NOT underway on this interface; and no receive operation remains
+open after this call returns. It doesn't check for kUSBxxx_busNotAvailable, because it doesn't
+matter if it's not. size is the maximum that is allowed to be received before exiting; i.e., it
+is the size allotted to dataBuf. Returns the number of bytes received. */
+WORD hidReceiveDataInBuffer(BYTE* dataBuf, WORD size, BYTE intfNum)
+{
+ WORD bytesInBuf,rxCount;
+ BYTE* currentPos=dataBuf;
+
+ while(bytesInBuf = USBHID_bytesInUSBBuffer(intfNum))
+ {
+ if((WORD)(currentPos-dataBuf+bytesInBuf) <= size) {
+ rxCount = bytesInBuf;
+ }
+ else {
+ rxCount = size;
+ }
+
+ USBHID_receiveData(currentPos,rxCount,intfNum);
+ currentPos += bytesInBuf;
+ }
+ return (currentPos-dataBuf);
+}
+#endif
+
+/*********************************************************************************************
+Please see the MSP430 USB CDC API Programmer's Guide Sec. 9 for a full description of these
+functions, how they work, and how to use them.
+**********************************************************************************************/
+
+#ifdef _CDC_
+/* This construct implements post-call polling to ensure the sending completes before the function
+returns. It provides the simplest coding, at the expense of wasted cycles and potentially
+allowing MCU execution to become "locked" to the host, a disadvantage if the host (or bus) is
+slow. The function also checks all valid return codes, and returns non-zero if an error occurred.
+It assumes no previous send operation is underway; also assumes size is non-zero. */
+BYTE cdcSendDataWaitTilDone(BYTE* dataBuf, WORD size, BYTE intfNum, ULONG ulTimeout)
+{
+ ULONG sendCounter = 0;
+ WORD bytesSent, bytesReceived;
+
+ switch(USBCDC_sendData(dataBuf,size,intfNum))
+ {
+ case kUSBCDC_sendStarted:
+ break;
+ case kUSBCDC_busNotAvailable:
+ return 2;
+ case kUSBCDC_intfBusyError:
+ return 3;
+ case kUSBCDC_generalError:
+ return 4;
+ default:;
+ }
+
+ /* If execution reaches this point, then the operation successfully started. Now wait til it's finished. */
+ while(1) {
+ BYTE ret = USBCDC_intfStatus(intfNum,&bytesSent,&bytesReceived);
+ if(ret & kUSBCDC_busNotAvailable) /* This may happen at any time */
+ return 2;
+ if(ret & kUSBCDC_waitingForSend) {
+ if(ulTimeout && (sendCounter++ >= ulTimeout)) /* Incr counter & try again */
+ return 1 ; /* Timed out */
+ }
+ else
+ return 0; /* If neither busNotAvailable nor waitingForSend, it succeeded */
+ }
+}
+
+
+
+/* This construct implements pre-call polling to ensure the sending completes before the function
+returns. It provides simple coding while also taking advantage of the efficiencies of background
+processing. If a previous send operation is underway, this function does waste cycles polling,
+like xxxsendDataWaitTilDone(); however it's less likely to do so since much of the sending
+presumably took place in the background since the last call to xxxsendDataInBackground().
+The function also checks all valid return codes, and returns non-zero if an error occurred.
+It assumes no previous send operation is underway; also assumes size is non-zero.
+This call assumes a previous send operation might be underway; also assumes size is non-zero.
+Returns zero if send completed; non-zero if it failed, with 1 = timeout and 2 = bus is gone. */
+BYTE cdcSendDataInBackground(BYTE* dataBuf, WORD size, BYTE intfNum, ULONG ulTimeout)
+{
+ ULONG sendCounter = 0;
+ WORD bytesSent, bytesReceived;
+
+ while(USBCDC_intfStatus(intfNum,&bytesSent,&bytesReceived) & kUSBCDC_waitingForSend) {
+ if(ulTimeout && ((sendCounter++)>ulTimeout)) /* A send operation is underway; incr counter & try again */
+ return 1; /* Timed out */
+ }
+
+ /* The interface is now clear. Call sendData(). */
+ switch(USBCDC_sendData(dataBuf,size,intfNum)) {
+ case kUSBCDC_sendStarted:
+ return 0;
+ case kUSBCDC_busNotAvailable:
+ return 2;
+ default:
+ return 4;
+ }
+}
+
+
+
+/* This call only retrieves data that is already waiting in the USB buffer -- that is, data that has
+already been received by the MCU. It assumes a previous, open receive operation (began by a direct
+call to USBxxx_receiveData()) is NOT underway on this interface; and no receive operation remains
+open after this call returns. It doesn't check for kUSBxxx_busNotAvailable, because it doesn't
+matter if it's not. size is the maximum that is allowed to be received before exiting; i.e., it
+is the size allotted to dataBuf. Returns the number of bytes received. */
+WORD cdcReceiveDataInBuffer(BYTE* dataBuf, WORD size, BYTE intfNum)
+{
+ WORD bytesInBuf,rxCount;
+ BYTE* currentPos=dataBuf;
+
+ while(bytesInBuf = USBCDC_bytesInUSBBuffer(intfNum)) {
+ if((WORD)(currentPos-dataBuf+bytesInBuf) <= size) {
+ rxCount = bytesInBuf;
+ }
+ else {
+ rxCount = size;
+ }
+
+ USBCDC_receiveData(currentPos,rxCount,intfNum);
+ currentPos += bytesInBuf;
+ }
+ return (currentPos-dataBuf);
+}
+#endif
diff --git a/usb/usbConstructs.h b/usb/usbConstructs.h
--- /dev/null
+++ b/usb/usbConstructs.h
@@ -0,0 +1,7 @@
+BYTE hidSendDataWaitTilDone(BYTE* dataBuf, WORD size, BYTE intfNum, ULONG ulTimeout);
+BYTE hidSendDataInBackground(BYTE* dataBuf, WORD size, BYTE intfNum, ULONG ulTimeout);
+WORD hidReceiveDataInBuffer(BYTE*,WORD,BYTE);
+
+BYTE cdcSendDataWaitTilDone(BYTE* dataBuf, WORD size, BYTE intfNum, ULONG ulTimeout);
+BYTE cdcSendDataInBackground(BYTE* dataBuf, WORD size, BYTE intfNum, ULONG ulTimeout);
+WORD cdcReceiveDataInBuffer(BYTE*,WORD,BYTE);
diff --git a/usb/usbEventHandling.c b/usb/usbEventHandling.c
--- /dev/null
+++ b/usb/usbEventHandling.c
@@ -0,0 +1,242 @@
+// (c)2009 by Texas Instruments Incorporated, All Rights Reserved.
+/*----------------------------------------------------------------------------+
+| |
+| Texas Instruments |
+| |
+| MSP430 USB-Example (CDC/HID Driver) |
+| |
++-----------------------------------------------------------------------------+
+| Source: usbEventHandling.c, File Version 1.00 2009/12/03 |
+| Author: RSTO |
+| |
+| Description: |
+| Event-handling placeholder functions. |
+| All functios are called in interrupt context. |
+| |
++----------------------------------------------------------------------------*/
+
+#include "USB_API/USB_Common/device.h"
+#include "USB_API/USB_Common/types.h"
+#include "USB_API/USB_Common/defMSP430USB.h"
+#include "USB_config/descriptors.h"
+#include "USB_API/USB_Common/usb.h"
+#include "F5xx_F6xx_Core_Lib/HAL_UCS.h"
+
+#ifdef _CDC_
+#include "USB_API/USB_CDC_API/UsbCdc.h"
+#endif
+
+#ifdef _HID_
+#include "USB_API/USB_HID_API/UsbHid.h"
+#endif
+
+#ifdef _MSC_
+#include "USB_API/USB_MSC_API/UsbMsc.h"
+#endif
+
+#include "main.h"
+
+// These variables are only example, they are not needed for stack
+
+#if CDC_NUM_INTERFACES == 1
+volatile BYTE bDataReceived_event[CDC_NUM_INTERFACES] = {FALSE};
+#endif
+#if CDC_NUM_INTERFACES == 2
+volatile BYTE bDataReceived_event[CDC_NUM_INTERFACES] = {FALSE, FALSE};
+#endif
+#if CDC_NUM_INTERFACES == 3
+volatile BYTE bDataReceived_event[CDC_NUM_INTERFACES] = {FALSE, FALSE, FALSE};
+#endif
+//volatile BYTE bDataReceived_event0 = FALSE;
+//volatile BYTE bDataReceived_event1 = FALSE;
+//volatile BYTE bDataReceived_event2 = FALSE;
+
+/*
+If this function gets executed, it's a sign that the output of the USB PLL has failed.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleClockEvent()
+{
+ //TO DO: You can place your code here
+
+ return TRUE; //return TRUE to wake the main loop (in the case the CPU slept before interrupt)
+}
+
+/*
+If this function gets executed, it indicates that a valid voltage has just been applied to the VBUS pin.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleVbusOnEvent()
+{
+ //TO DO: You can place your code here
+
+ //We switch on USB and connect to the BUS
+ if (USB_enable() == kUSB_succeed)
+ {
+ USB_reset();
+ USB_connect(); // generate rising edge on DP -> the host enumerates our device as full speed device
+ }
+ return TRUE; //return TRUE to wake the main loop (in the case the CPU slept before interrupt)
+}
+
+/*
+If this function gets executed, it indicates that a valid voltage has just been removed from the VBUS pin.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleVbusOffEvent()
+{
+ //TO DO: You can place your code here
+
+ XT2_Stop();
+
+ return TRUE; //return TRUE to wake the main loop (in the case the CPU slept before interrupt)
+}
+
+/*
+If this function gets executed, it indicates that the USB host has issued a USB reset event to the device.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleResetEvent()
+{
+ //TO DO: You can place your code here
+
+ return TRUE; //return TRUE to wake the main loop (in the case the CPU slept before interrupt)
+}
+
+/*
+If this function gets executed, it indicates that the USB host has chosen to suspend this device after a period of active operation.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleSuspendEvent()
+{
+ //TO DO: You can place your code here
+
+ return TRUE; //return TRUE to wake the main loop (in the case the CPU slept before interrupt)
+}
+
+/*
+If this function gets executed, it indicates that the USB host has chosen to resume this device after a period of suspended operation.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleResumeEvent()
+{
+ //TO DO: You can place your code here
+
+ return TRUE; //return TRUE to wake the main loop (in the case the CPU slept before interrupt)
+}
+
+/*
+If this function gets executed, it indicates that the USB host has enumerated this device :
+after host assigned the address to the device.
+returns TRUE to keep CPU awake
+*/
+BYTE USB_handleEnumCompleteEvent()
+{
+ //TO DO: You can place your code here
+
+ return TRUE; //return TRUE to wake the main loop (in the case the CPU slept before interrupt)
+}
+
+
+#ifdef _CDC_
+
+/*
+This event indicates that data has been received for interface intfNum, but no data receive operation is underway.
+returns TRUE to keep CPU awake
+*/
+BYTE USBCDC_handleDataReceived(BYTE intfNum)
+{
+
+ if(!USBCDC_bytesInUSBBuffer(intfNum))
+ return TRUE;
+
+ if(!bDataReceived_event[intfNum])
+ {
+ bDataReceived_event[intfNum] = TRUE;
+
+ //TO DO: You can place your code here
+ }
+
+ // data received event
+
+ return TRUE; //return FALSE to go asleep after interrupt (in the case the CPU slept before interrupt)
+}
+
+/*
+This event indicates that a send operation on interface intfNum has just been completed.
+returns TRUE to keep CPU awake
+*/
+BYTE USBCDC_handleSendCompleted(BYTE intfNum)
+{
+ extern volatile BYTE bDataSendCompleted_event[]; // data send completed event
+ //TO DO: You can place your code here
+
+ bDataSendCompleted_event[intfNum] = TRUE;
+
+ return FALSE; //return FALSE to go asleep after interrupt (in the case the CPU slept before interrupt)
+}
+
+/*
+This event indicates that a receive operation on interface intfNum has just been completed.
+*/
+BYTE USBCDC_handleReceiveCompleted(BYTE intfNum)
+{
+ //TO DO: You can place your code here
+ extern volatile BYTE bDataReceiveCompleted_event[];
+
+ bDataReceiveCompleted_event[intfNum] = TRUE;
+
+ return FALSE; //return FALSE to go asleep after interrupt (in the case the CPU slept before interrupt)
+}
+
+#endif // _CDC_
+
+#ifdef _HID_
+/*
+This event indicates that data has been received for interface intfNum, but no data receive operation is underway.
+returns TRUE to keep CPU awake
+*/
+BYTE USBHID_handleDataReceived(BYTE intfNum)
+{
+ //TO DO: You can place your code here
+
+ return FALSE; //return FALSE to go asleep after interrupt (in the case the CPU slept before interrupt)
+}
+
+/*
+This event indicates that a send operation on interface intfNum has just been completed.
+returns TRUE to keep CPU awake
+*/
+BYTE USBHID_handleSendCompleted(BYTE intfNum)
+{
+ //TO DO: You can place your code here
+
+ return FALSE; //return FALSE to go asleep after interrupt (in the case the CPU slept before interrupt)
+}
+
+/*
+This event indicates that a receive operation on interface intfNum has just been completed.
+*/
+BYTE USBHID_handleReceiveCompleted(BYTE intfNum)
+{
+ //TO DO: You can place your code here
+
+ return FALSE; //return FALSE to go asleep after interrupt (in the case the CPU slept before interrupt)
+}
+
+#endif // _HID_
+
+#ifdef _MSC_
+BYTE USBMSC_handleBufferEvent(VOID)
+{
+
+ return FALSE; //return FALSE to go asleep after interrupt (in the case the CPU slept before interrupt)
+
+}
+#endif // _MSC_
+
+
+/*----------------------------------------------------------------------------+
+| End of source file |
++----------------------------------------------------------------------------*/
+/*------------------------ Nothing Below This Line --------------------------*/