/******************************************************************************* * eUSCIB1 ISR. The repeated start and transmit/receive operations happen * within this ISR. ******************************************************************************/ void euscib1_isr(void) { uint_fast16_t status; status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE); MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status); static bool inAlert = false; if (status & EUSCI_B_I2C_STOP_INTERRUPT) { #ifdef EVDEBUG eventArr[eventIx++] = STOP; #endif if (inAlert) { inAlert = false; I2C_AlertDone(); } else i2c_l2_buf.stop(); return; } if (status & EUSCI_B_I2C_NAK_INTERRUPT) { #ifdef EVDEBUG eventArr[eventIx++] = NAK; #endif i2c_l2_buf.nak(); return; } /* RXIFG */ if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0) { #ifdef EVDEBUG eventArr[eventIx++] = RECEIVE; #endif i2c_l2_buf.put(MAP_I2C_slaveGetData(EUSCI_B0_BASE)); } /* TXIFG */ if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0) { #ifdef EVDEBUG eventArr[eventIx++] = TRANSMIT; #endif MAP_I2C_slavePutData(EUSCI_B0_BASE, i2c_l2_buf.get()); } if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT1) { // SMbus alert response. Put my address as a reply #ifdef EVDEBUG eventArr[eventIx++] = TRANSMIT_SMBUS_ADDR; #endif inAlert = true; MAP_I2C_slavePutData(EUSCI_B0_BASE, SLAVE_ADDRESS << 1); } #ifdef EVDEBUG if (eventIx == 50) eventIx = 0; #endif }
/****************************************************************************** * The USCI_B0 data ISR RX vector is used to move received data from the I2C * master to the MSP432 memory. ******************************************************************************/ void euscib0_isr(void) { uint_fast16_t status; status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_MODULE); MAP_I2C_clearInterruptFlag(EUSCI_B0_MODULE, status); /* RXIFG for Slave Address 1*/ if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0) { MAP_I2C_slavePutData(EUSCI_B0_MODULE, TXData[xferIndex++]); /* Resetting the index if we are at the end. Also resetting the GPIO * if we are on the last byte */ if (xferIndex == NUM_OF_RX_BYTES) { MAP_I2C_disableInterrupt(EUSCI_B0_MODULE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0); MAP_GPIO_setAsInputPin(GPIO_PORT_P1, GPIO_PIN0); MAP_Interrupt_disableSleepOnIsrExit(); xferIndex = 0; /* IMPORTANT: Clearing out the TX Buffer for the next transfer. * This is required to compensate for the shift/buffer settings * of the I2C module */ MAP_I2C_slavePutData(EUSCI_B0_MODULE, 0); } } }
/** * Handle a request ISL as a slave */ void DWire::_handleRequestSlave( void ) { // Check whether a user interrupt has been set if ( !user_onRequest ) return; // If no message has been set, then call the user interrupt to set if (!(*pTxBufferIndex)) { user_onRequest( ); *pTxBufferSize = *pTxBufferIndex - 1; *pTxBufferIndex = 0; } // If we've transmitted the entire message, then reset the tx buffer if (*pTxBufferIndex > *pTxBufferSize) { *pTxBufferIndex = 0; *pTxBufferSize = 0; } else { // Transmit a byte MAP_I2C_slavePutData( module, pTxBuffer[*pTxBufferIndex] ); (*pTxBufferIndex)++; } }
/** * The main (global) interrupt handler */ void IRQHandler(IRQParam param) { uint_fast16_t status; status = MAP_I2C_getEnabledInterruptStatus(param.module); MAP_I2C_clearInterruptFlag(param.module, status); /* RXIFG */ // Triggered when data has been received if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0) { // If the rxBufferSize > 0, then we're a master performing a request if (*param.rxBufferSize > 0) { param.rxBuffer[*param.rxBufferIndex] = MAP_I2C_masterReceiveMultiByteNext(param.module); (*param.rxBufferIndex)++; if (*param.rxBufferIndex == *param.rxBufferSize) { DWire * instance = getInstance(param.module); if (instance) { instance->_finishRequest(); } } // Otherwise we're a slave receiving data } else { param.rxBuffer[*param.rxBufferIndex] = MAP_I2C_slaveGetData( param.module); (*param.rxBufferIndex)++; } } // As master: triggered when a byte has been transmitted // As slave: triggered on request */ if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0) { DWire * instance = getInstance(param.module); if (instance) { // If the module is setup as a master, then we're transmitting data if (instance->isMaster()) { // If we've transmitted the last byte from the buffer, then send a stop if (!(*param.txBufferIndex)) { if (instance->_isSendStop(false)) MAP_I2C_masterSendMultiByteStop(param.module); instance->_isSendStop(true); } else { // If we still have data left in the buffer, then transmit that MAP_I2C_masterSendMultiByteNext(param.module, param.txBuffer[(*param.txBufferSize) - (*param.txBufferIndex)]); (*param.txBufferIndex)--; } // Otherwise we're a slave and a master is requesting data } else { instance->_handleRequestSlave(); } } } // Handle a NAK if (status & EUSCI_B_I2C_NAK_INTERRUPT) { //MAP_I2C_masterSendStart(param.module); DWire * instance = getInstance(param.module); //*param.txBufferIndex = 0; if (instance) if (*param.rxBufferSize > 0) { } instance->_finishRequest(true); } /* STPIFG * Called when a STOP is received */ if (status & EUSCI_B_I2C_STOP_INTERRUPT) { DWire * instance = getInstance(param.module); if (instance) { if (*param.txBufferIndex != 0 && !instance->isMaster()) { MAP_I2C_slavePutData(instance->module, 0); *param.rxBufferIndex = 0; *param.rxBufferSize = 0; } else if (*param.rxBufferIndex != 0) { instance->_handleReceive(param.rxBuffer); } } } }