コード例 #1
0
ファイル: pmap.c プロジェクト: barkatz/CellularBeeper
void PMAP_initPorts(uint16_t baseAddress,
                    PMAP_initPortsParam *param)
{
    //Store current interrupt state, then disable all interrupts
    uint16_t globalInterruptState = __get_SR_register() & GIE;
    __disable_interrupt();

    //Get write-access to port mapping registers:
    HWREG16(baseAddress + OFS_PMAPKEYID) = PMAPPW;

    //Enable/Disable reconfiguration during runtime
    HWREG8(baseAddress + OFS_PMAPCTL) &= ~PMAPRECFG;
    HWREG8(baseAddress + OFS_PMAPCTL) |= param->portMapReconfigure;

    //Configure Port Mapping:
    uint16_t i;
    for(i = 0; i < param->numberOfPorts * 8; i++)
    {
        param->PxMAPy[i] = param->portMapping[i];
    }

    //Disable write-access to port mapping registers:
    HWREG8(baseAddress + OFS_PMAPKEYID) = 0;

    //Restore previous interrupt state
    __bis_SR_register(globalInterruptState);
}
コード例 #2
0
ファイル: usci_b_i2c.c プロジェクト: Greeeg/gpsLogger
void USCI_B_I2C_masterReceiveSingleStart(uint16_t baseAddress)
{
    //local variable to store GIE status
    uint16_t gieStatus;

    //Store current SR register
    gieStatus = __get_SR_register() & GIE;

    //Disable global interrupt
    __disable_interrupt();

    //Set USCI in Receive mode
    HWREG8(baseAddress + OFS_UCBxCTL1) &= ~UCTR;

    //Send start condition.
    HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTT;

    //Poll for Start bit to complete
    while(HWREG8(baseAddress + OFS_UCBxCTL1) & UCTXSTT)
    {
        ;
    }

    //Send stop condition.
    HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;

    //Reinstate SR register
    __bis_SR_register(gieStatus);
}
コード例 #3
0
ファイル: ads1292.c プロジェクト: ShimmerResearch/shimmer3
void ADS1292_regWrite(uint8_t startaddress, uint8_t size, uint8_t *wdata) {
   uint16_t gie = __get_SR_register() & GIE; //Store current GIE state

   __disable_interrupt();                    //Make this operation atomic

   __delay_cycles(144);                      //Wait 6us (assuming 24MHz MCLK), required to allow t_sdecode to be 4 T_clk
                                             //needed to ensure previous byte was not sent within this time period

   // Clock the actual data transfer and send the bytes. Note that we
   // intentionally do not read out the receive buffer during frame transmission
   // in order to optimize transfer speed, however we need to take care of the
   // resulting overrun condition.
   while (!(UCA0IFG & UCTXIFG)) ;            //Wait while not ready for TX
   UCA0TXBUF = startaddress | WREG;
   __delay_cycles(180);                      //Wait 7.5us (assuming 24MHz MCLK), required to allow t_sdecode to be 4 T_clk
   while (!(UCA0IFG & UCTXIFG));             //Wait while not ready for TX
   UCA0TXBUF = size-1;
   while(size--) {
      __delay_cycles(180);                   //Wait 7.5us (assuming 24MHz MCLK), required to allow t_sdecode to be 4 T_clk
      while (!(UCA0IFG & UCTXIFG));          //Wait while not ready for TX
      UCA0TXBUF = *wdata++;
   }

   while ((UCA0STAT & UCBUSY));              //Wait for all TX/RX to finish

   UCA0RXBUF;                                //Dummy read to empty RX buffer
                                             //and clear any overrun conditions
   __bis_SR_register(gie);                   //Restore original GIE state
}
コード例 #4
0
ファイル: flash.c プロジェクト: Hsinmo/fatool-fw-v1
//*****************************************************************************
//
//! Erase a single bank of the flash memory.
//!
//! \param baseAddress is the base address of the Flash module.
//! \param Flash_ptr is a pointer into the bank to be erased
//!
//! \returns NONE
//
//*****************************************************************************
void Flash_bankErase (unsigned int baseAddress, unsigned char *Flash_ptr)
{
    //5xx Workaround: Disable global interrupt while erasing.
    //local variable to store GIE status
    unsigned int gieStatus;

    //Store current SR register
    gieStatus = __get_SR_register() & GIE;
    //Disable global interrupt
    __disable_interrupt();
  
    //Clear Lock bit
    HWREG(baseAddress + OFS_FCTL3) = FWKEY;
    
    while (HWREGB(baseAddress + OFS_FCTL3) & BUSY) ;

    //Set MERAS bit
    HWREG(baseAddress + OFS_FCTL1) = FWKEY + MERAS;

    //Dummy write to erase Flash seg
    *Flash_ptr = 0;

    //test busy
    while (HWREGB(baseAddress + OFS_FCTL3) & BUSY) ;

    //Clear WRT bit
    HWREG(baseAddress + OFS_FCTL1) = FWKEY;

    //Set LOCK bit
    HWREG(baseAddress + OFS_FCTL3) = FWKEY + LOCK;

    //Reinstate SR register
    __bis_SR_register(gieStatus);
}
コード例 #5
0
ファイル: flash.c プロジェクト: phooky/Snap-Pad
//*****************************************************************************
//
//! \brief Erase a single segment of the flash memory.
//!
//! \param baseAddress is the base address of the FLASH module.
//! \param flash_ptr is the pointer into the flash segment to be erased
//!
//! \return None
//
//*****************************************************************************
void FLASH_segmentErase(uint32_t baseAddress, uint8_t *flash_ptr)
{
        //5xx Workaround: Disable global interrupt while erasing.
        //local variable to store GIE status
        uint16_t gieStatus;

        //Store current SR register
        gieStatus = __get_SR_register() & GIE;
        //Disable global interrupt
        __disable_interrupt();

        //Clear Lock bit
        HWREG16(baseAddress + OFS_FCTL3) = FWKEY;

        //Set Erase bit
        HWREG16(baseAddress + OFS_FCTL1) = FWKEY + ERASE;

        //Dummy write to erase Flash seg
        *flash_ptr = 0;

        //test busy
        while (HWREG8(baseAddress + OFS_FCTL3) & BUSY) ;

        //Clear ERASE bit
        HWREG16(baseAddress + OFS_FCTL1) = FWKEY;

        //Set LOCK bit
        HWREG16(baseAddress + OFS_FCTL3) = FWKEY + LOCK;

        //Reinstate SR register
        __bis_SR_register(gieStatus);
}
コード例 #6
0
ファイル: ads1292.c プロジェクト: ShimmerResearch/shimmer3
void ADS1292_resetRegs(void) {
   uint16_t gie = __get_SR_register() & GIE; //Store current GIE state

   __disable_interrupt();                    //Make this operation atomic

   __delay_cycles(144);                      //Wait 6us (assuming 24MHz MCLK), required to allow t_sdecode to be 4 T_clk
                                             //needed to ensure previous byte was not sent within this time period

   // Clock the actual data transfer and send the bytes. Note that we
   // intentionally not read out the receive buffer during frame transmission
   // in order to optimize transfer speed, however we need to take care of the
   // resulting overrun condition.
   while (!(UCA0IFG & UCTXIFG)) ;            //Wait while not ready for TX
   UCA0TXBUF = RESET;
   while ( (UCA0STAT & UCBUSY) );            //Wait for all TX/RX to finish

   UCA0RXBUF;                                //Dummy read to empty RX buffer
                                             //and clear any overrun conditions

   __bis_SR_register(gie);                   //Restore original GIE state

   //takes 9f_MOD cycles (assume f_MOD is 128kHz as f_CLK is fixed to 512kHz)
   //so 70.3125us
   //must avoid sending other commands during this time
   //Every other function waits 6us before sending a command
   //so wait 65us here
   __delay_cycles(1560);                     //wait 65us (assuming 24MHz MCLK)
}
コード例 #7
0
ファイル: pmap.c プロジェクト: liuzheng712/MSP430-Keyboard
//*****************************************************************************
//
//! \brief This function configures the MSP430 Port Mapper
//!
//! THis function port maps a set of pins to a new set.
//!
//! \param baseAddress is the base address of the PMAP control module.
//! \param portMapping is the pointer to init Data
//! \param PxMAPy is the pointer start of first PMAP to initialize
//! \param numberOfPorts is the number of Ports to initialize
//! \param portMapReconfigure is used to enable/disable reconfiguration
//!        Valid values are:
//!        - \b PMAP_ENABLE_RECONFIGURATION
//!        - \b PMAP_DISABLE_RECONFIGURATION [Default]
//!
//! Modified bits of \b PMAPKETID register and bits of \b PMAPCTL register.
//!
//! \return None
//
//*****************************************************************************
void PMAP_configurePorts( uint32_t baseAddress,
                          const uint8_t *portMapping,
                          uint8_t *PxMAPy,
                          uint8_t numberOfPorts,
                          uint8_t portMapReconfigure
                          )
{
        assert((portMapReconfigure == PMAP_ENABLE_RECONFIGURATION) ||
               (portMapReconfigure == PMAP_DISABLE_RECONFIGURATION)
               );

        //Store current interrupt state, then disable all interrupts
        uint16_t globalInterruptState = __get_SR_register() & GIE;
        __disable_interrupt();

        //Get write-access to port mapping registers:
        HWREG16(baseAddress + OFS_PMAPKEYID) = PMAPPW;

        //Enable/Disable reconfiguration during runtime
        HWREG8(baseAddress + OFS_PMAPCTL) &= ~PMAPRECFG;
        HWREG8(baseAddress + OFS_PMAPCTL) |= portMapReconfigure;

        //Configure Port Mapping:
        uint16_t i;
        for (i = 0; i < numberOfPorts * 8; i++)
                PxMAPy[i] = portMapping[i];

        //Disable write-access to port mapping registers:
        HWREG8(baseAddress + OFS_PMAPKEYID) = 0;

        //Restore previous interrupt state
        __bis_SR_register(globalInterruptState);
}
コード例 #8
0
inline uint16_t GetTA1(void) {
   register uint16_t t0, t1;
   uint8_t ie;
   if(ie=(__get_SR_register()&0x0008))   //interrupts enabled?
      __disable_interrupt();
   t1 =TA1R;
   do {t0=t1; t1=TA1R;} while(t0!=t1);
   if(ie)
      __enable_interrupt();
   return t1;
}
コード例 #9
0
/*
 * Write bytes to specified device - optional start and stop
 * First byte has to be preloaded for start to complete
 */
static int msp430_i2c_write(struct pl_i2c *i2c, uint8_t i2c_addr,
			    const uint8_t *data, uint8_t count, uint8_t flags)
{
	int result = -1;
	unsigned int gie = __get_SR_register() & GIE; //Store current GIE state

	__disable_interrupt();              	// Make this operation atomic

	if (count == 0)							// no data but may want to stop
		goto no_data;

	if (!(flags & PL_I2C_NO_START))
	{
		UCxnI2CSA  = i2c_addr;        		// set Slave Address

		UCxnIFG = 0;						// clear all interrupt flags
		UCxnCTL1 |= UCTR;                   // UCTR=1 => Transmit Mode (R/W bit = 0)
		UCxnCTL1 |= UCTXSTT;				// Transmit start

		UCxnTXBUF = *data++;				// preload first byte
		count--;

		while (UCxnCTL1 & UCTXSTT);			// wait for START to complete
		if (UCxnIFG & UCNACKIFG)			// bail if NACK'd
			goto error;
	}

	while (count--)
	{
		while ((UCxnIFG & UCTXIFG) == 0) {	// Wait for ok to send next byte
			if (UCxnIFG & UCNACKIFG)		// see if last byte was NACK'd
				goto error;
		}
		UCxnTXBUF = *data++;				// send the next byte
	}

	while ((UCxnIFG & UCTXIFG) == 0);		// Wait for last byte to clear

no_data:
	result = 0;

	// suppress stop if requested
	if (!(flags & PL_I2C_NO_STOP))
	{
error:
		UCxnCTL1 |= UCTXSTP;				// Transmit Stop
		while (UCxnCTL1 & UCTXSTP);      	// Ensure stop condition got sent
	}

	__bis_SR_register(gie);             	// Restore original GIE state

	return result;
}
コード例 #10
0
/*
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;
}
コード例 #11
0
ファイル: cc430_ucs.c プロジェクト: KennyRIM/OpenTag
void Init_FLL(u16 fsystem, u16 ratio) {

    // save actual state of FLL loop control
    // Have at least a divider of 2
    u16 srRegisterState = __get_SR_register() & SCG0;
    u16 d               = ratio;
    u16 dco_div_bits    = FLLD__2;
    //u16 mode            = 0;

    if (fsystem > 16000){
    	d >>= 1;
        //mode = 1;
    }
コード例 #12
0
/*
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;
}
コード例 #13
0
ファイル: flashctl.c プロジェクト: Eilliar/MSP430
void FlashCtl_unlockInfo(void)
{
    //Disable global interrupts while doing RMW operation on LOCKSEG bit
    uint16_t gieStatus;                         //Local variable to store GIE status
    gieStatus = __get_SR_register() & GIE;      //Store current SR register
    __disable_interrupt();                      //Disable global interrupt

    //Clear the LOCKSEG bit in FCTL3.
    //Since LOCKSEG toggles when you write a 1 (and writing 0 has no effect),
    //read the register, mask the lower byte, and write it back.
    HWREG16(FLASH_BASE +
            OFS_FCTL3) = FWKEY + (HWREG16(FLASH_BASE + OFS_FCTL3) & 0xFF);

    //Reinstate SR register to restore global interrupt enable status
    __bis_SR_register(gieStatus);
}
コード例 #14
0
ファイル: flash.c プロジェクト: jacksitlab/WSUartBridge
//*****************************************************************************
//
//! \brief Unlocks the information flash memory segment A
//!
//! This function must be called before an erase or write operation on the
//! information flash segment is performed by any of the other API functions.
//!
//! \param baseAddress is the base address of the FLASH module.
//!
//! \return None
//
//*****************************************************************************
void FLASH_unlockInfoA (uint32_t baseAddress)
{
    //Disable global interrupts while doing RMW operation on LOCKA bit
    uint16_t gieStatus;
    gieStatus = __get_SR_register() & GIE;          //Store current SR register
    __disable_interrupt();                          //Disable global interrupt

    //Clear the LOCKA bit in FCTL3.
    //Since LOCKA toggles when you write a 1 (and writing 0 has no effect),
    //read the register, mask the lower byte, and write it back.
    HWREG16(baseAddress + OFS_FCTL3) = FWKEY 
        + (HWREG16(baseAddress + OFS_FCTL3) & 0xFF);

    //Reinstate SR register to restore global interrupt enable status
    __bis_SR_register(gieStatus);
}
コード例 #15
0
ファイル: flash.c プロジェクト: 14Ohm/Energia
//*****************************************************************************
//
//! \brief Locks the information flash memory segment A
//!
//! This function is typically called after an erase or write operation on the
//! information flash segment is performed by any of the other API functions in
//! order to re-lock the information flash segment.
//!
//!
//! \return None
//
//*****************************************************************************
void FLASH_lockInfoA (void)
{
    //Disable global interrupts while doing RMW operation on LOCKA bit
    uint16_t gieStatus;
    gieStatus = __get_SR_register() & GIE;          //Store current SR register
    __disable_interrupt();                          //Disable global interrupt

    //Set the LOCKA bit in FCTL3.
    //Since LOCKA toggles when you write a 1 (and writing 0 has no effect),
    //read the register, XOR with LOCKA mask, mask the lower byte
    //and write it back.
    HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY
        + ((HWREG16(FLASH_BASE + OFS_FCTL3) ^ LOCKA) & 0xFF);

    //Reinstate SR register to restore global interrupt enable status
    __bis_SR_register(gieStatus);
}
コード例 #16
0
/*
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;
}
コード例 #17
0
ファイル: HAL_SDCard.c プロジェクト: Norskan/Playground
/***************************************************************************//**
 * @brief   Read a frame of bytes via SPI
 * @param   pBuffer Place to store the received bytes
 * @param   size Indicator of how many bytes to receive
 * @return  None
 ******************************************************************************/
void SDCard_readFrame (uint8_t *pBuffer, uint16_t size)
{
    uint16_t gie = __get_SR_register() & GIE;               //Store current GIE state

    __disable_interrupt();                                  //Make this operation atomic

    UCB1IFG &= ~UCRXIFG;                                    //Ensure RXIFG is clear

    //Clock the actual data transfer and receive the bytes
    while (size--){
        while (!(UCB1IFG & UCTXIFG)) ;                      //Wait while not ready for TX
        UCB1TXBUF = 0xff;                                   //Write dummy byte
        while (!(UCB1IFG & UCRXIFG)) ;                      //Wait for RX buffer (full)
        *pBuffer++ = UCB1RXBUF;
    }

    __bis_SR_register(gie);                                 //Restore original GIE state
}
コード例 #18
0
ファイル: board.c プロジェクト: zlalanne/msp430-webcontrol
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;
  }
コード例 #19
0
ファイル: hal_UCS.c プロジェクト: Rossano/RTOSDemo
/**
  * Initializes FLL of the UCS and wait till settled
  *
  * \param fsystem  required system frequency (MCLK) in kHz
  * \param ratio    ratio between MCLK and FLLREFCLK
  */
void Init_FLL_Settle(uint16_t fsystem, uint16_t ratio)
{
  volatile uint16_t x = ratio * 32;       
  // save actual state of FLL loop control
  uint16_t globalInterruptState = __get_SR_register() & SCG0;
  								
  __bic_SR_register(SCG0);      // Enable FLL loop control

  Init_FLL(fsystem, ratio);
  
  while(x--)
  {
   __delay_cycles(30); 
  }
  
  __bis_SR_register(globalInterruptState);	// restore previous state

}
コード例 #20
0
ファイル: HAL_SDCard.c プロジェクト: Norskan/Playground
/***************************************************************************//**
 * @brief   Send a frame of bytes via SPI
 * @param   pBuffer Place that holds the bytes to send
 * @param   size Indicator of how many bytes to send
 * @return  None
 ******************************************************************************/
void SDCard_sendFrame (uint8_t *pBuffer, uint16_t size)
{
    uint16_t gie = __get_SR_register() & GIE;               //Store current GIE state

    __disable_interrupt();                                  //Make this operation atomic

    //Clock the actual data transfer and send the bytes. Note that we
    //intentionally not read out the receive buffer during frame transmission
    //in order to optimize transfer speed, however we need to take care of the
    //resulting overrun condition.
    while (size--){
        while (!(UCB1IFG & UCTXIFG)) ;                      //Wait while not ready for TX
        UCB1TXBUF = *pBuffer++;                             //Write byte
    }
    while (UCB1STAT & UCBUSY) ;                             //Wait for all TX/RX to finish

    UCB1RXBUF;                                              //Dummy read to empty RX buffer
                                                            //and clear any overrun conditions

    __bis_SR_register(gie);                                 //Restore original GIE state
}
コード例 #21
0
ファイル: main.c プロジェクト: TECHNOTICSROBOTICS/mspdev
VOID Init_StartUp(VOID)
{
   unsigned short bGIE;
   bGIE  = (__get_SR_register() &GIE);  //save interrupt status

   __disable_interrupt();               // Disable global interrupts
    
#   ifdef __MSP430F6638    
        // only for F663x devices!
        while (BAKCTL & LOCKBAK)            // check if bit for backup subsystem is cleared
        {
            BAKCTL &= ~LOCKBAK;             // clear lock backup bit for backup subsystem 
        }
#   endif
    
    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();

    __bis_SR_register(bGIE); //restore interrupt status
}
コード例 #22
0
/*
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;
}
コード例 #23
0
ファイル: usci_b_i2c.c プロジェクト: Greeeg/gpsLogger
bool USCI_B_I2C_masterReceiveSingleStartWithTimeout(uint16_t baseAddress,
                                                    uint32_t timeout)
{
    //local variable to store GIE status
    uint16_t gieStatus;

    //Store current SR register
    gieStatus = __get_SR_register() & GIE;

    //Disable global interrupt
    __disable_interrupt();

    //Set USCI in Receive mode
    HWREG8(baseAddress + OFS_UCBxCTL1) &= ~UCTR;

    //Send start condition.
    HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTT;

    //Poll for Start bit to complete
    while((!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXSTT)) && --timeout)
    {
        ;
    }

    //Check if transfer timed out
    if(timeout == 0)
    {
        return (STATUS_FAIL);
    }

    //Send stop condition.
    HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;

    //Reinstate SR register
    __bis_SR_register(gieStatus);

    return (STATUS_SUCCESS);
}
コード例 #24
0
ファイル: main.c プロジェクト: TECHNOTICSROBOTICS/mspdev
VOID Init_StartUp(VOID)
{
   unsigned short bGIE;
   bGIE  = (__get_SR_register() &GIE);  //save interrupt status

   __disable_interrupt();               // Disable global interrupts
    
#   ifdef __MSP430F6638    
        // only for F663x devices!
        while (BAKCTL & LOCKBAK)            // check if bit for backup subsystem is cleared
        {
            BAKCTL &= ~LOCKBAK;             // clear lock backup bit for backup subsystem 
        }
#   endif
    
    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();

# if 0  // Use for FET boards
    // Configure P1.6 as a button input
    P1DIR &= ~BIT6; // Input
    P1OUT |= BIT6;  
    P1REN |= BIT6;  // Together with P1OUT, creates a pullup
    P1IFG &= ~BIT6; // Clear the flag
    P1IE |= BIT6;   // Enable interrupts

# else  // Use for F5529 EXP board
    P1DIR &= ~BIT7; // Input
    P1OUT |= BIT7;  
    P1REN |= BIT7;  // Together with P1OUT, creates a pullup
    P1IFG &= ~BIT7; // Clear the flag
    P1IE |= BIT7;   // Enable interrupts
# endif
    
    __bis_SR_register(bGIE); //restore interrupt status
}
コード例 #25
0
ファイル: usb.c プロジェクト: TECHNOTICSROBOTICS/mspdev
//----------------------------------------------------------------------------
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;
}
コード例 #26
0
/*
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;
}
コード例 #27
0
/*
 * Read bytes from specified device - optional start and stop
 * There is an issue with receiving a single byte. We must
 * issue the stop before we even get the byte. Suspect emptying the
 * rx data buffer triggers the next read operation.
 */
static int msp430_i2c_read(struct pl_i2c *i2c, uint8_t i2c_addr, uint8_t *data,
			   uint8_t count, uint8_t flags)
{
	int result = -1;
	int remaining = count;
	int send_stop;
	int stop_sent = 0;
	unsigned int gie = __get_SR_register() & GIE; // store current GIE state

	__disable_interrupt();              	// Make this operation atomic

	send_stop = (!(flags & PL_I2C_NO_STOP) && (count == 1));

	if (count == 0)
		goto no_data;

	if (!(flags & PL_I2C_NO_START))
	{
		UCxnI2CSA  = i2c_addr;         		// set Slave Address

		UCxnIFG = 0;						// clear interrupt flags
		UCxnCTL1 &= ~UCTR;                  // UCTR=0 => Receive Mode (R/W bit = 1)
		UCxnCTL1 |= UCTXSTT;				// Transmit start

		while (UCxnCTL1 & UCTXSTT);			// wait for START to complete
		if (UCxnIFG & UCNACKIFG)			// bail if NACK'd
			goto error;

		// special case handling of single byte read in case timing critical
		if (send_stop) {
			UCxnCTL1 |= UCTXSTP;			// generate stop
			while (UCxnCTL1 & UCTXSTP);     // Ensure stop condition got sent

			while ((UCxnIFG & UCRXIFG) == 0);	// Wait for data ready
			*data++ = UCxnRXBUF;				// read the byte (allows collection of next)
			remaining--;
			stop_sent = 1;
		}
	}

	while (remaining)
	{
		remaining--;
		if (remaining == 0 && !(flags & PL_I2C_NO_STOP)) {
			UCxnCTL1 |= UCTXSTP;			// generate stop
			while(UCxnCTL1 & UCTXSTP);      // Ensure stop condition got sent
			stop_sent = 1;
		}
		while ((UCxnIFG & UCRXIFG) == 0);	// Wait for data ready
		*data++ = UCxnRXBUF;				// read the byte (allows collection of next)
	}

no_data:
	result = 0;

	// suppress stop if requested or not already sent
	if (!(flags & PL_I2C_NO_STOP) && !stop_sent)
	{
error:
		UCxnCTL1 |= UCTXSTP;				// Transmit Stop
		while(UCxnCTL1 & UCTXSTP);          // Ensure stop condition got sent
	}
	__bis_SR_register(gie);             	// Restore original GIE state

	return result;
}
コード例 #28
0
/*This is the core function called by application to handle the MSC SCSI state
 * machine */
BYTE USBMSC_poll ()
{
    BYTE edbIndex;

    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
        _DINT_FET();                      //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 (MscState.isMSCConfigured == FALSE){
        return (kUSBMSC_okToSleep);
    }

    if (!MscState.bMscSendCsw){
        if (MscState.bMscCbwReceived){
            if (Scsi_Verify_CBW() == SUCCESS){
                //Successful reception of CBW
                //Parse the CBW opcode and invoke the right command handler function
                Scsi_Cmd_Parser(MSC0_INTFNUM);
                MscState.bMscSendCsw = TRUE;
            }
            MscState.bMscCbwReceived = FALSE;       //CBW is performed!
        } 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_okToSleep);             //do not asleep, as data is coming in
            //and follow up data perform will be required.
        }
    }

    if (MscState.bMscSendCsw){
        if (MscState.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)){
                    MscState.bMscSendCsw = FALSE;
                    return (kUSBMSC_okToSleep);
                }
            }		
            else {
            	MSCFromHostToBuffer();
            }
        }
    }

    return (kUSBMSC_processBuffer);                 //When MscState.bMcsCommandSupported = FALSE, bReadProcessing became true, and
                                                    //bWriteProcessing = true.
}
コード例 #29
0
/*
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;
}
コード例 #30
0
/*
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;
}