コード例 #1
0
ファイル: DWire.cpp プロジェクト: DelfiSpace/DWire
/**
 * 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)++;
    }
}
コード例 #2
0
ファイル: Wire.cpp プロジェクト: TravisRo/chipKIT-core
// behind the scenes function that is called when data is requested
void TwoWire::onRequestService(void)
{
  // don't bother if user hasn't registered a callback
  if(!user_onRequest){
    return;
  }
  // alert user program
  user_onRequest();
}
コード例 #3
0
ファイル: Wire.cpp プロジェクト: Azz1/RPI_EPI
// behind the scenes function that is called when data is requested
void WireClass::onRequestService(void){
    // don't bother if user hasn't registered a callback
    if(!user_onRequest){
        return;
    }
    // reset tx buffer iterator vars
    // !!! this will kill any pending pre-master sendTo() activity
    txBufferIndex = 0;
    txBufferLength = 0;
    // alert user program
    user_onRequest();
}
コード例 #4
0
ファイル: Wire.cpp プロジェクト: JuergenGe/Energia
void TwoWire::I2CIntHandler(void) {
    //clear data interrupt
    HWREG(SLAVE_BASE + I2C_O_SICR) = I2C_SICR_DATAIC;
    uint8_t startDetected = 0;
    uint8_t stopDetected = 0;

    if(HWREG(SLAVE_BASE + I2C_O_SRIS) & I2C_SLAVE_INT_START) {
        startDetected = 1;
        //clear raw start interrupt
        HWREG(SLAVE_BASE + I2C_O_SICR) = I2C_SICR_STARTIC;
    }
    else if(HWREG(SLAVE_BASE + I2C_O_SRIS) & I2C_SLAVE_INT_STOP) {
        stopDetected = 1;
        HWREG(SLAVE_BASE + I2C_O_SICR) = I2C_SICR_STOPIC;
    }

    switch(I2CSlaveStatus(SLAVE_BASE) & (I2C_SCSR_TREQ | I2C_SCSR_RREQ)) {

    case(I2C_SLAVE_ACT_RREQ)://data received
        if(I2CSlaveStatus(SLAVE_BASE) & I2C_SCSR_FBR)
            currentState = SLAVE_RX;
        if(!RX_BUFFER_FULL) {
            rxBuffer[rxWriteIndex] = I2CSlaveDataGet(SLAVE_BASE);
            rxWriteIndex = (rxWriteIndex + 1) % BUFFER_LENGTH;
        }

        break;

    case(I2C_SLAVE_ACT_TREQ)://data requested

        if(startDetected) {
            uint8_t oldWriteIndex = txWriteIndex;
            user_onRequest();

            //
            // send data if onRequest() wrote data that has
            // yet to be sent
            //
            if(oldWriteIndex != txWriteIndex) {
                I2CSlaveDataPut(SLAVE_BASE, txBuffer[txReadIndex]);
                txReadIndex = (txReadIndex + 1) % BUFFER_LENGTH;
            }

        }

        else if(!TX_BUFFER_EMPTY) {
            I2CSlaveDataPut(SLAVE_BASE, txBuffer[txReadIndex]);
            txReadIndex = (txReadIndex + 1) % BUFFER_LENGTH;
        }

        else
            I2CSlaveDataPut(SLAVE_BASE, 0);

        break;

    default:
        break;
    }

    if(stopDetected && currentState == SLAVE_RX) {
        int avail = available();
        user_onReceive(avail);
        currentState = IDLE;
    }

}
コード例 #5
0
ファイル: WireKinetis.cpp プロジェクト: PaulStoffregen/Wire
void TwoWire::isr(void)
{
	uint8_t status, c1, data;
	static uint8_t receiving=0;

	status = port().S;
	//serial_print(".");
	if (status & I2C_S_ARBL) {
		// Arbitration Lost
		port().S = I2C_S_ARBL;
		//serial_print("a");
		if (receiving && rxBufferLength > 0) {
			// TODO: does this detect the STOP condition in slave receive mode?


		}
		if (!(status & I2C_S_IAAS)) return;
	}
	if (status & I2C_S_IAAS) {
		//serial_print("\n");
		// Addressed As A Slave
		if (status & I2C_S_SRW) {
			//serial_print("T");
			// Begin Slave Transmit
			receiving = 0;
			txBufferLength = 0;
			if (user_onRequest != NULL) {
				user_onRequest();
			}
			if (txBufferLength == 0) {
				// is this correct, transmitting a single zero
				// when we should send nothing?  Arduino's AVR
				// implementation does this, but is it ok?
				txBufferLength = 1;
				txBuffer[0] = 0;
			}
			port().C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX;
			port().D = txBuffer[0];
			txBufferIndex = 1;
		} else {
			// Begin Slave Receive
			//serial_print("R");
			receiving = 1;
			rxBufferLength = 0;
			port().C1 = I2C_C1_IICEN | I2C_C1_IICIE;
			data = port().D;
		}
		port().S = I2C_S_IICIF;
		return;
	}
	#if defined(WIRE_HAS_STOP_INTERRUPT)
	c1 = port().FLT;
	if ((c1 & I2C_FLT_STOPF) && (c1 & I2C_FLT_STOPIE)) {
		port().FLT = c1 & ~I2C_FLT_STOPIE;
		if (user_onReceive != NULL) {
			rxBufferIndex = 0;
			user_onReceive(rxBufferLength);
		}
	}
	#endif
	c1 = port().C1;
	if (c1 & I2C_C1_TX) {
		// Continue Slave Transmit
		//serial_print("t");
		if ((status & I2C_S_RXAK) == 0) {
			//serial_print(".");
			// Master ACK'd previous byte
			if (txBufferIndex < txBufferLength) {
				port().D = txBuffer[txBufferIndex++];
			} else {
				port().D = 0;
			}
			port().C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_TX;
		} else {
			//serial_print("*");
			// Master did not ACK previous byte
			port().C1 = I2C_C1_IICEN | I2C_C1_IICIE;
			data = port().D;
		}
	} else {
		// Continue Slave Receive
		irqcount = 0;
		#ifdef WIRE_HAS_STOP_INTERRUPT
		port().FLT |= I2C_FLT_STOPIE;
		#else
		#if defined(WIRE_IMPLEMENT_WIRE) && !defined(WIRE_IMPLEMENT_WIRE1)
		attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr0, RISING);
		#elif !defined(WIRE_IMPLEMENT_WIRE) && defined(WIRE_IMPLEMENT_WIRE1)
		attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr1, RISING);
		#elif defined(WIRE_IMPLEMENT_WIRE) && defined(WIRE_IMPLEMENT_WIRE1)
		if (this == &Wire) {
			attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr0, RISING);
		} else if (this == &Wire1) {
			attachInterrupt(hardware.sda_pin[sda_pin_index], sda_rising_isr1, RISING);
		}
		#endif
		#endif // WIRE_HAS_STOP_INTERRUPT
		//digitalWriteFast(4, HIGH);
		data = port().D;
		//serial_phex(data);
		if (rxBufferLength < BUFFER_LENGTH && receiving) {
			rxBuffer[rxBufferLength++] = data;
		}
		//digitalWriteFast(4, LOW);
	}
	port().S = I2C_S_IICIF;
}