Ejemplo n.º 1
0
/**
 * End the transmission and transmit the tx buffer's contents over the bus
 * it returns false if succesful
 */
bool DWire::endTransmission( bool sendStop ) 
{
    // return, if there is nothing to transmit
    if (!*pTxBufferIndex) 
    {
        return true;
    }

    // Wait until any ongoing (incoming) transmissions are finished
    timeout = 0xFFFF;
    while ( MAP_I2C_masterIsStopSent( module ) == EUSCI_B_I2C_SENDING_STOP
            && timeout)
        timeout--;

    if (!timeout) 
    {
        /* If we can't start the transmission, then reset everything */
        _resetBus( );
        return true;
    }

    this->sendStop = sendStop;
    gotNAK = false;

    // Clear the interrupt flags and enable
    MAP_I2C_clearInterruptFlag( module,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT );

    MAP_I2C_enableInterrupt( module,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT );

    // Set the master into transmit mode
    MAP_I2C_setMode( module, EUSCI_B_I2C_TRANSMIT_MODE );

    // Send the start condition and initial byte
    (*pTxBufferSize) = *pTxBufferIndex;

    // Send the first byte, triggering the TX interrupt
    MAP_I2C_masterSendMultiByteStartWithTimeout( module, pTxBuffer[0],
    TIMEOUTLIMIT );

    // make sure the transmitter buffer has been flushed
    timeout = TIMEOUTLIMIT;
    while (*pTxBufferIndex && timeout)
        timeout--;

    if (!timeout) 
    {
        _resetBus( );
        return true;
    }

    if (gotNAK) 
    {
        _I2CDelay( );
        MAP_I2C_masterReceiveMultiByteStop( module );
    }
    return gotNAK;
}
Ejemplo n.º 2
0
/**
 * Begin a transmission as a master
 */
void DWire::beginTransmission(uint_fast8_t slaveAddress) {
	// Starting a transmission as a master to the slave at slaveAddress
	if (busRole != BUS_ROLE_MASTER)
		return;

	// Wait in case a previous message is still being sent
	while ( MAP_I2C_masterIsStopSent(module) == EUSCI_B_I2C_SENDING_STOP)
		;

	if (slaveAddress != this->slaveAddress)
		_setSlaveAddress(slaveAddress);
}
Ejemplo n.º 3
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;
        }
    }
}
int main(void)
{
    volatile uint32_t ii;

    /* Disabling the Watchdog */
    MAP_WDT_A_holdTimer();

    /* Select Port 1 for I2C - Set Pin 6, 7 to input Primary Module Function,
     *   (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
     */
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
            GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
    sendStopCondition = false;
    sendToSlaveAddress2 = false;

    /* Initializing I2C Master to SMCLK at 400kbs with no autostop */
    MAP_I2C_initMaster(EUSCI_B0_MODULE, &i2cConfig);

    /* Specify slave address. For start we will do our first slave address */
    MAP_I2C_setSlaveAddress(EUSCI_B0_MODULE, SLAVE_ADDRESS_1);

    /* Set Master in receive mode */
    MAP_I2C_setMode(EUSCI_B0_MODULE, EUSCI_B_I2C_TRANSMIT_MODE);

    /* Enable I2C Module to start operations */
    MAP_I2C_enableModule(EUSCI_B0_MODULE);

    /* Enable and clear the interrupt flag */
    MAP_I2C_clearInterruptFlag(EUSCI_B0_MODULE,
            EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);

    //Enable master Receive interrupt
    MAP_I2C_enableInterrupt(EUSCI_B0_MODULE,
            EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
    MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
    
    while (1)
    {

        /* Load Byte Counter */
        TXByteCtr = 4;

        /* Making sure the last transaction has been completely sent out */
        while (MAP_I2C_masterIsStopSent(EUSCI_B0_MODULE) == EUSCI_B_I2C_SENDING_STOP);

        /* Sending the initial start condition for appropriate
         *   slave addresses */
        if(sendToSlaveAddress2)
        {
            MAP_I2C_setSlaveAddress(EUSCI_B0_MODULE, SLAVE_ADDRESS_2);
        }
        else
        {
            MAP_I2C_setSlaveAddress(EUSCI_B0_MODULE, SLAVE_ADDRESS_1);
        }

        MAP_I2C_masterSendMultiByteStart(EUSCI_B0_MODULE, TXData++);

        while(sendStopCondition == false)
        {
            /* Go to sleep while data is being transmitted */
            MAP_Interrupt_enableSleepOnIsrExit();
            MAP_PCM_gotoLPM0InterruptSafe();
        }

        sendStopCondition = false;
    }
}