Ejemplo n.º 1
0
void TwoWire::onService(void)
{
  if ( sercom->isSlaveWIRE() )
  {
    if(sercom->isStopDetectedWIRE() || 
        (sercom->isAddressMatch() && sercom->isRestartDetectedWIRE() && !sercom->isMasterReadOperationWIRE())) //Stop or Restart detected
    {
      sercom->prepareAckBitWIRE();
      sercom->prepareCommandBitsWire(0x03);

      //Calling onReceiveCallback, if exists
      if(onReceiveCallback)
      {
        onReceiveCallback(available());
      }
      
      rxBuffer.clear();
    }
    else if(sercom->isAddressMatch())  //Address Match
    {
      sercom->prepareAckBitWIRE();
      sercom->prepareCommandBitsWire(0x03);

      if(sercom->isMasterReadOperationWIRE()) //Is a request ?
      {
        // wait for data ready flag,
        // before calling request callback
        while(!sercom->isDataReadyWIRE());

        //Calling onRequestCallback, if exists
        if(onRequestCallback)
        {
          onRequestCallback();
        }
      }
    }
    else if(sercom->isDataReadyWIRE()) //Received data
    {
      if (rxBuffer.isFull()) {
        sercom->prepareNackBitWIRE(); 
      } else {
        //Store data
        rxBuffer.store_char(sercom->readDataWIRE());

        sercom->prepareAckBitWIRE(); 
      }

      sercom->prepareCommandBitsWire(0x03);
    }
  }
}
Ejemplo n.º 2
0
void TwoWire::onService(void) 
{
	if (I2C_GetITStatus(twi, I2C_IT_ADDR) == SET)
	{
		I2C_ITConfig(twi, I2C_IT_RXI | I2C_IT_TXI | I2C_IT_STOPI, ENABLE);
		srvBufferLength = 0;
		srvBufferIndex = 0;
		if (twi->ISR & (1 << 16)) {
			status = SLAVE_SEND;
			if (onRequestCallback)
				onRequestCallback();
		} else {
			status = SLAVE_RECV;
		}

		I2C_ClearITPendingBit(twi, I2C_IT_ADDR);
	}
	if (I2C_GetITStatus(twi, I2C_IT_TXIS) == SET)
	{
		uint8_t c = 'x';
		if (srvBufferIndex < srvBufferLength)
			c = srvBuffer[srvBufferIndex++];
		I2C_SendData(twi, c);
	}
	if (I2C_GetITStatus(twi, I2C_IT_RXNE) == SET)
	{
		if (srvBufferLength < BUFFER_LENGTH)
			srvBuffer[srvBufferLength++] = I2C_ReceiveData(twi);
	}
	if (I2C_GetITStatus(twi, I2C_IT_STOPF) == SET)
	{
		if (status == SLAVE_RECV && onReceiveCallback) {
			// Copy data into rxBuffer
			// (allows to receive another packet while the
			// user program reads actual data)
			for (uint8_t i = 0; i < srvBufferLength; ++i)
				rxBuffer[i] = srvBuffer[i];
			rxBufferIndex = 0;
			rxBufferLength = srvBufferLength;
			// Alert calling program
			onReceiveCallback( rxBufferLength);
		}
		I2C_ITConfig(twi, I2C_IT_ADDRI, ENABLE);
		I2C_ITConfig(twi, I2C_IT_RXI | I2C_IT_TXI | I2C_IT_STOPI, DISABLE);
		I2C_ClearITPendingBit(twi, I2C_IT_STOPF);
	}
}
Ejemplo n.º 3
0
void TwoWire::onService(void)
{
  if ( sercom->isSlaveWIRE() )
  {
    //Received data
    if(sercom->isDataReadyWIRE())
    {
      //Store data
      rxBuffer.store_char(sercom->readDataWIRE());

      //Stop or Restart detected
      if(sercom->isStopDetectedWIRE() || sercom->isRestartDetectedWIRE())
      {
        //Calling onReceiveCallback, if exists
        if(onReceiveCallback)
        {
          onReceiveCallback(available());
        }
      }
    }

    //Address Match
    if(sercom->isAddressMatch())
    {
      //Is a request ?
      if(sercom->isMasterReadOperationWIRE())
      {
        //Calling onRequestCallback, if exists
        if(onRequestCallback)
        {
          onRequestCallback();
        }
      }
    }
  }
}
Ejemplo n.º 4
0
void TwoWire::onService(void) {
	// Retrieve interrupt status
	uint32_t sr = TWI_GetStatus(twi);

	if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) {
		TWI_DisableIt(twi, TWI_IDR_SVACC);
		TWI_EnableIt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK
				| TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP);

		srvBufferLength = 0;
		srvBufferIndex = 0;

		// Detect if we should go into RECV or SEND status
		// SVREAD==1 means *master* reading -> SLAVE_SEND
		if (!TWI_STATUS_SVREAD(sr)) {
			status = SLAVE_RECV;
		} else {
			status = SLAVE_SEND;

			// Alert calling program to generate a response ASAP
			if (onRequestCallback)
				onRequestCallback();
			else
				// create a default 1-byte response
				write((uint8_t) 0);
		}
	}

	if (status != SLAVE_IDLE) {
		if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) {
			if (status == SLAVE_RECV && onReceiveCallback) {
				// Copy data into rxBuffer
				// (allows to receive another packet while the
				// user program reads actual data)
				for (uint8_t i = 0; i < srvBufferLength; ++i)
					rxBuffer[i] = srvBuffer[i];
				rxBufferIndex = 0;
				rxBufferLength = srvBufferLength;

				// Alert calling program
				onReceiveCallback( rxBufferLength);
			}

			// Transfer completed
			TWI_EnableIt(twi, TWI_SR_SVACC);
			TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
					| TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
			status = SLAVE_IDLE;
		}
	}

	if (status == SLAVE_RECV) {
		if (TWI_STATUS_RXRDY(sr)) {
			if (srvBufferLength < BUFFER_LENGTH)
				srvBuffer[srvBufferLength++] = TWI_ReadByte(twi);
		}
	}

	if (status == SLAVE_SEND) {
		if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) {
			uint8_t c = 'x';
			if (srvBufferIndex < srvBufferLength)
				c = srvBuffer[srvBufferIndex++];
			TWI_WriteByte(twi, c);
		}
	}
}
void TwoWire::onService(void)
{
    //interrupt handler
    uint8_t  i2cData  = 0x00;
    bool     wasArbLost = I2C_HAL_GetStatusFlag(instance, kI2CArbitrationLost);
    bool     addressed = I2C_HAL_GetStatusFlag(instance, kI2CAddressAsSlave);
    bool     stopIntEnabled = false;

    bool     startDetected = I2C_HAL_GetStartFlag(instance);
    bool     startIntEnabled = I2C_HAL_GetStartStopIntCmd(instance);
    bool     stopDetected = I2C_HAL_GetStopFlag(instance);
    stopIntEnabled = startIntEnabled;

    /* Get current slave transfer direction */
    i2c_direction_t direction = I2C_HAL_GetDirMode(instance);

    /*--------------- Handle START, STOP or REPEAT START ------------------*/
    if (stopIntEnabled && (startDetected || stopDetected))
    {
        if(startDetected)
            I2C_HAL_ClearStartFlag(instance);
        if(stopDetected)
            I2C_HAL_ClearStopFlag(instance);
        I2C_HAL_ClearInt(instance);
        if(slaveBufferLength)
        {
            if(onReceiveCallback)
            {
                receiving_slave = true;
                onReceiveCallback(slaveBufferLength);
                receiving_slave = false;
            }
            slaveBufferIndex = 0;
            slaveBufferLength = 0;
        }
        return;
    }

    /* Clear I2C IRQ.*/
    I2C_HAL_ClearInt(instance);

    if (wasArbLost)
    {
        I2C_HAL_ClearArbitrationLost(instance);
        if (!addressed)
        {
            master_state = MASTER_STATE_ARB_LOST;
            return;
        }
    }

    if(I2C_HAL_IsMaster(instance))
    {
        if (direction == kI2CSend)
        {
            //check for NAK
            /* Check whether we got an ACK or NAK from the former byte we sent */
            if (I2C_HAL_GetStatusFlag(instance, kI2CReceivedNak))
            {
                master_state = MASTER_STATE_TX_NAK;
            }
            else if(transmitting_master)
            {
                /* Continue send if still have data. TxSize/txBuff index need
                 * increment first because one byte is already sent in order
                 * to trigger interrupt */
                 if (txBufferIndex < txBufferLength)
                 {
                     /* Transmit next byte and update buffer index */
                     I2C_HAL_WriteByte(instance, txBuffer[txBufferIndex++]);
                 }
                 else
                 {
                     /* Finish send data, send STOP, disable interrupt */
                     master_state = MASTER_STATE_COMPLETE;
                 }
             }
             else
             {
                 master_state = MASTER_STATE_READ_READY; //address sent for a read
             }
        }
        else
        {
            switch (--rxBufferQuantity)
            {
                case 0x0U:
                    /* Finish receive data, send STOP, disable interrupt */
                    master_state = MASTER_STATE_COMPLETE;
                    if(master_send_stop)
                        I2C_HAL_SendStop(instance);
                    else
                        I2C_HAL_SendStart(instance);
                    break;
                case 0x1U:
                    /* For the byte before last, we need to set NAK */
                    I2C_HAL_SendNak(instance);
                    break;
                default :
                    I2C_HAL_SendAck(instance);
                    break;
            }

            rxBuffer[rxBufferLength++] = I2C_HAL_ReadByte(instance);
        }
        return;
    }

    /*--------------- Handle Address ------------------*/
    /* Addressed only happens when receiving address. */
    if (addressed) /* Slave is addressed. */
    {
        /* Master read from Slave. Slave transmit.*/
        if (I2C_HAL_GetStatusFlag(instance, kI2CSlaveTransmit))
        {
            /* Switch to TX mode*/
            I2C_HAL_SetDirMode(instance, kI2CSend);

            transmitting_slave = true;
            slaveBufferIndex = 0;
            slaveBufferLength = 0;

            if (onRequestCallback)
                onRequestCallback(); //this needs to load the transmit buffer
            else
                // create a default 1-byte response
                write((uint8_t) 0);

        }
        else /* Master write to Slave. Slave receive.*/
        {
            /* Switch to RX mode.*/
            I2C_HAL_SetDirMode(instance, kI2CReceive);
            I2C_HAL_SendAck(instance);

            /* Read dummy character.*/
            I2C_HAL_ReadByte(instance);

            slaveBufferIndex = 0;
            slaveBufferLength = 0;
        }
    }
    /*--------------- Handle Transfer ------------------*/
    else
    {
        /* Handle transmit */
        if (direction == kI2CSend)
        {
            if (I2C_HAL_GetStatusFlag(instance, kI2CReceivedNak))
            {
                /* Switch to RX mode.*/
                I2C_HAL_SetDirMode(instance, kI2CReceive);
                /* Read dummy character to release bus */
                I2C_HAL_ReadByte(instance);

                transmitting_slave = false;
                slaveBufferIndex = 0;
                slaveBufferLength = 0;
            }
            else /* ACK from receiver.*/
            {
                transmitting_slave = true;
            }
        }
        /* Handle receive */
        else
        {
            /* Get byte from data register */
            I2C_HAL_SendAck(instance);
            i2cData = I2C_HAL_ReadByte(instance);
            if(slaveBufferLength < BUFFER_LENGTH)
                slaveBuffer[slaveBufferLength++] = i2cData;
        }
    }

    if (transmitting_slave)
    {
        /* Send byte to data register */
        if (slaveBufferIndex < slaveBufferLength)
        {
            I2C_HAL_WriteByte(instance, slaveBuffer[slaveBufferIndex++]);
            if (slaveBufferIndex >= slaveBufferLength)
            {
                slaveBufferIndex = 0;
                slaveBufferLength = 0;
                transmitting_slave = false;
            }
        }
        else
            transmitting_slave = false;
    }
}
Ejemplo n.º 6
0
void TwoWire::I2C_SlaveTRx(uint32_t u32Status)
{
    if(u32Status == 0x60)                       /* Own SLA+W has been receive; ACK has been return */
    {
    	 status = SLAVE_RECV;
        srvBufferLength = 0;
        I2C_SET_CONTROL_REG(i2c, I2C_SI_AA);
    }
    else if(u32Status == 0x80 || u32Status==0x10)                 /* Previously address with own SLA address
                                                   Data has been received; ACK has been returned*/
    {
        srvBuffer[srvBufferLength] = (unsigned char) I2C_GET_DATA(i2c);
        srvBufferLength++;

        I2C_SET_CONTROL_REG(i2c, I2C_SI_AA);
    }
    else if(u32Status == 0xA8)                  /* Own SLA+R has been receive; ACK has been return */
    {				    		        
     
				// Alert calling program to generate a response ASAP
				if (onRequestCallback && status != SLAVE_SEND)
				{
					srvBufferLength = 0;
					srvBufferIndex = 0;	
					onRequestCallback();
				}			
  			status = SLAVE_SEND;  							
				if (srvBufferIndex < srvBufferLength)
				{						
						//Serial.print("==============>");
						//Serial.println((char)srvBuffer[srvBufferIndex]);
						I2C_SET_DATA(i2c, srvBuffer[srvBufferIndex++]);						
						I2C_SET_CONTROL_REG(i2c, I2C_SI_AA);						
				}
				
				if (srvBufferIndex == srvBufferLength)
						status = SLAVE_IDLE;
		}else if(u32Status == 0xB8)	{
				if (srvBufferIndex < srvBufferLength){				
						//Serial.print("==============>");
						//Serial.println((char)srvBuffer[srvBufferIndex]);		
						I2C_SET_DATA(i2c, srvBuffer[srvBufferIndex++]);						
						I2C_SET_CONTROL_REG(i2c, I2C_SI_AA);						
				}
				
				if (srvBufferIndex == srvBufferLength)
						status = SLAVE_IDLE;			
		}
    else if(u32Status == 0xC0)                 /* Data byte or last data in I2CDAT has been transmitted
                                                   Not ACK has been received */
    {
        I2C_SET_CONTROL_REG(i2c, I2C_SI_AA);
    }
    else if(u32Status == 0x88)                 /* Previously addressed with own SLA address; NOT ACK has
                                                   been returned */
    {
        srvBufferLength = 0;
        I2C_SET_CONTROL_REG(i2c, I2C_SI_AA);
    }
    else if(u32Status == 0xA0)                 /* A STOP or repeated START has been received while still
                                                   addressed as Slave/Receiver*/
    {
        srvBufferIndex = 0;
        I2C_SET_CONTROL_REG(i2c, I2C_SI_AA);
 
 
 			if (status != SLAVE_IDLE)
 			{
 				for (uint8_t i = 0; i < srvBufferLength; ++i)
					rxBuffer[i] = srvBuffer[i];
				rxBufferIndex = 0;
				rxBufferLength = srvBufferLength;				             
				onReceiveCallback( rxBufferLength); // Alert calling program
				status = SLAVE_IDLE;
			}
    }
}
Ejemplo n.º 7
0
void TwoWire::onService(void)
{
  if ( sercom->isSlaveWIRE() )
  {
    if(sercom->isStopDetectedWIRE() || 
        (sercom->isAddressMatch() && sercom->isRestartDetectedWIRE() && !sercom->isMasterReadOperationWIRE())) //Stop or Restart detected
    {
      sercom->prepareAckBitWIRE();
      sercom->prepareCommandBitsWire(0x03);

      //Calling onReceiveCallback, if exists
      if(onReceiveCallback)
      {
        onReceiveCallback(available());
      }
      
      rxBuffer.clear();
    }
    else if(sercom->isAddressMatch())  //Address Match
    {
      sercom->prepareAckBitWIRE();
      sercom->prepareCommandBitsWire(0x03);

      if(sercom->isMasterReadOperationWIRE()) //Is a request ?
      {
        txBuffer.clear();

        transmissionBegun = true;

        //Calling onRequestCallback, if exists
        if(onRequestCallback)
        {
          onRequestCallback();
        }
      }
    }
    else if(sercom->isDataReadyWIRE())
    {
      if (sercom->isMasterReadOperationWIRE())
      {
        uint8_t c = 0xff;

        if( txBuffer.available() ) {
          c = txBuffer.read_char();
        }

        transmissionBegun = sercom->sendDataSlaveWIRE(c);
      } else { //Received data
        if (rxBuffer.isFull()) {
          sercom->prepareNackBitWIRE(); 
        } else {
          //Store data
          rxBuffer.store_char(sercom->readDataWIRE());

          sercom->prepareAckBitWIRE(); 
        }

        sercom->prepareCommandBitsWire(0x03);
      }
    }
  }
}