Пример #1
0
/**
 * Request data from a SLAVE as a MASTER
 */
uint8_t DWire::requestFrom(uint_fast8_t slaveAddress, uint_fast8_t numBytes) {
	// No point of doing anything else if there we're not a MASTER
	if (busRole != BUS_ROLE_MASTER)
		return 0;

	if (*pTxBufferIndex > 0) {
		endTransmission(false);
	}

	while (!sendStop)
		;

	// Re-initialise the rx buffer
	*pRxBufferSize = numBytes;
	*pRxBufferIndex = 0;

	// Configure the correct slave
	MAP_I2C_setSlaveAddress(module, slaveAddress);
	this->slaveAddress = slaveAddress;

	MAP_I2C_disableInterrupt(module, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

	// Set the master into receive mode
	MAP_I2C_setMode(module, EUSCI_B_I2C_RECEIVE_MODE);

	// Send the START
	MAP_I2C_masterReceiveStart(module);

	// Send a stop early if we're only requesting one byte
	// to prevent timing issues
	if (numBytes == 1) {
		MAP_I2C_masterReceiveMultiByteStop(module);
	}

	// Initialize the flag showing the status of the request
	requestDone = false;
	gotNAK = false;

	// Wait until the request is done
	while (!requestDone)
		;

	MAP_I2C_setMode(module, EUSCI_B_I2C_TRANSMIT_MODE);

	MAP_I2C_enableInterrupt(module, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
	MAP_I2C_clearInterruptFlag(module, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

	// Reset the buffer
	(*pRxBufferIndex) = 0;
	(*pRxBufferSize) = 0;

	if (gotNAK) {
		return 0;
	} else {
		return rxReadLength;
	}
}
Пример #2
0
/**
 * Request data from a SLAVE as a MASTER
 */
uint8_t DWire::requestFrom( uint_fast8_t slaveAddress, uint_fast8_t numBytes ) 
{
    // No point of doing anything else if there we're not a MASTER
    if (busRole != BUS_ROLE_MASTER)
        return 0;

    // still something to send? Flush the TX buffer but do not send a STOP
    if (*pTxBufferIndex > 0) 
    {
    	// this is a repeated start: no point in trying to receive if we fail finishing the transmission
        if (endTransmission( false ))
        {
        	return 0;
        }
    } 
    else 
    {
        // Wait until any request is finished
        timeout = TIMEOUTLIMIT;
        while ( MAP_I2C_masterIsStopSent( module ) == EUSCI_B_I2C_SENDING_STOP
                && timeout)
            timeout--;
    }

    if (!timeout) 
    {
        /* If we get a timeout, then reset everything */
        _resetBus( );
        return 0;
    }

    // Re-initialise the rx buffer
    // and make sure we never request 1 byte only
    // this is an anomalous behaviour of the MSP432 related to the double
    // buffering of I2C. This is a workaround.
    if (numBytes == 1) 
    {
        *pRxBufferSize = 2;
    } else 
    {
        *pRxBufferSize = numBytes;
    }
    *pRxBufferIndex = 0;

    // Configure the correct slave
    MAP_I2C_setSlaveAddress( module, slaveAddress );
    this->slaveAddress = slaveAddress;

    MAP_I2C_clearInterruptFlag( module,
    EUSCI_B_I2C_RECEIVE_INTERRUPT0 | EUSCI_B_I2C_NAK_INTERRUPT );
    MAP_I2C_enableInterrupt( module,
    EUSCI_B_I2C_RECEIVE_INTERRUPT0 | EUSCI_B_I2C_NAK_INTERRUPT );

    // Set the master into receive mode
    MAP_I2C_setMode( module, EUSCI_B_I2C_RECEIVE_MODE );

    // Initialize the flag showing the status of the request
    requestDone = false;
    gotNAK = false;

    // Send the START
    MAP_I2C_masterReceiveStart( module );

    // Wait until the request is done
    timeout = TIMEOUTLIMIT;
    while (!requestDone && timeout)
        timeout--;

    if (!timeout)
    {
        /* If we get a timeout, then reset everything */
        _resetBus( );
        return 0;
    }

    if (gotNAK) 
    {
        _I2CDelay( );
        MAP_I2C_masterReceiveMultiByteStop( module );
        return 0;
    } 
    else 
    {
        if (numBytes == 1)
        {
            return --(*pRxBufferSize);
        }
        else
        {
            return *pRxBufferSize;
        }
    }
}