예제 #1
0
static void i2cs_send(char c)
{
  I2C_WAIT();
  while( TW_STATUS != TW_ST_SLA_ACK && TW_STATUS != TW_ST_DATA_ACK ) {
    I2C_ACK();
  }
  I2C_SEND(c);
}
예제 #2
0
파일: i2cm.c 프로젝트: ohayak/tars_code
// Send a n-byte data frame to an address
void i2cm_send(uint8_t slave_addr, uint8_t n, const uint8_t* data)
{
  int i;
  I2C_START();

  // Slave address + Write bit (0)
  I2C_SEND(slave_addr<<1);

  // Data
  for( i=0; i<n; i++ )
  {
    I2C_SEND(data[i]);
  }

  // Stop and wait
  I2C_STOP();
  wait_4cyc(100);
}
예제 #3
0
파일: i2cm.c 프로젝트: ohayak/tars_code
// Receive one data byte from an address, -1 on error
int i2cm_rcv_single(uint8_t slave_addr)
{
  I2C_START();

  // Slave address + Read bit (1)
  I2C_SEND((slave_addr<<1)+1);

  // No ACK, no data
  if( TW_STATUS != TW_MR_SLA_ACK )
  {
    I2C_STOP();
    wait_4cyc(100);
    return -1;
  }

  // First byte: is there something to transmit?
  I2C_ACK();
  return TWDR;
}
예제 #4
0
/* @brief Receive data from an I2C slave.
 *
 * Parameters for the '>' command:
 *  - I2C slave address (u8)
 *  - data size (u8) or 0
 *
 * If the data size is 0, the value is read from the first data byte and is the
 * number of bytes to read after this first one. This is used to read protocol
 * replies from the slave.
 */
static void cmd_i2c_recv(void)
{
  const uint8_t addr = init_cmd_i2c();
  if( addr == 0 ) {
    return; // reply sent by init_cmd_i2c()
  }

  uint8_t size = recv_u8();
  // poll the slave
  do I2CM_START(); while( TW_STATUS != TW_START );
  // slave address + Read bit (1)
  I2C_SEND((addr<<1)+1);
#ifndef DISABLE_STRICT_CHECKS
  if( TW_STATUS != TW_MR_SLA_ACK && TW_STATUS != TW_MR_SLA_NACK ) {
    I2CM_STOP();
    goto slave_i2c_error;
  }
#endif
  if( size == 0 ) {
    // read the size in the first byte
    I2C_ACK();
    size = TWDR;
    reply_success(size+1);
    send_u8(size);
  } else {
    reply_success(size);
  }
  while( size-- != 1 ) {
    I2C_ACK();
    const uint8_t c = TWDR;
    send_u8(c);
  }
  I2C_NACK();
  send_u8( TWDR );
  I2CM_STOP();

  return;
#ifndef DISABLE_STRICT_CHECKS
slave_i2c_error:
  reply_error(STATUS_I2C_ERROR);
  return;
#endif
}
예제 #5
0
파일: i2cm.c 프로젝트: ohayak/tars_code
// Receive a frame from an address
// Slave must respect the i2c_ryder protocol : first byte tells if there are
// data to transmit or not
// Return number of read bytes
uint8_t i2cm_rcv(uint8_t slave_addr, uint8_t n, uint8_t* data)
{
  int i;

  I2C_START();

  // Slave address + Read bit (1)
  I2C_SEND((slave_addr<<1)+1);

  // No ACK, no data
  if( TW_STATUS != TW_MR_SLA_ACK )
  {
    I2C_STOP();
    wait_4cyc(100);
    return 0;
  }

  // First byte: is there something to transmit?
  I2C_ACK();
  if( TWDR == 0 )
  {
    I2C_NACK();
    I2C_STOP();
    wait_4cyc(100);
    return 0;
  }

  // Read all data
  for( i=0; i<n; i++ )
  {
    I2C_ACK();
    data[i] = TWDR;
  }

  I2C_NACK();
		
  I2C_STOP();
  wait_4cyc(100);

  return 1;
}
예제 #6
0
/** @brief Send data to an I2C slave.
 *
 * Parameters:
 *  - I2C slave address (u8)
 *  - data size (u16)
 *  - data to send
 *
 * If the data size is 0 an empty frame is sent.
 * This can be used to synchronize the slave.
 *
 * @warning Since UART data is not bufferised, if slave is too long to UART
 * buffer overflows and the server will wait forever its input data.
 */
static void cmd_i2c_send(void)
{
  const uint8_t addr = init_cmd_i2c();
  if( addr == 0 ) {
    return; // reply sent by init_cmd_i2c()
  }

  // write frame
  uint16_t size = recv_u16();
  // poll the slave
  do I2CM_START(); while( TW_STATUS != TW_START );
  // slave address + Write bit (0)
  I2C_SEND(addr<<1);
#ifndef DISABLE_STRICT_CHECKS
  uint8_t tw_status_copy = TW_STATUS;
  if( tw_status_copy == TW_MT_SLA_NACK ) {
    goto i2c_stop_slave_i2c_error;
  }
  if( tw_status_copy != TW_MT_SLA_ACK ) {
    goto slave_i2c_error;
  }
#endif

  if( size != 0 ) {
#ifndef DISABLE_STRICT_CHECKS
    tw_status_copy = TW_STATUS;
    if( tw_status_copy == TW_MT_SLA_NACK ) {
      goto i2c_stop_slave_i2c_error;
    }
    if( tw_status_copy != TW_MT_SLA_ACK ) {
      goto slave_i2c_error;
    }
#endif
    // transfer data
    while( size-- != 1 ) {
      const uint8_t c = recv_u8();
      I2C_SEND(c);
#ifndef DISABLE_STRICT_CHECKS
      tw_status_copy = TW_STATUS;
      if( tw_status_copy != TW_MT_DATA_ACK ) {
        goto i2c_stop_slave_i2c_error;
      }
#endif
    }
    const uint8_t c_last = recv_u8();
    I2C_SEND_LAST(c_last);
#ifndef DISABLE_STRICT_CHECKS
    tw_status_copy = TW_STATUS;
    if( tw_status_copy != TW_MT_DATA_ACK && tw_status_copy != TW_MT_DATA_NACK ) {
      goto i2c_stop_slave_i2c_error;
    }
#endif
  }

  I2CM_STOP();

  reply_success(0);
  return;
#ifndef DISABLE_STRICT_CHECKS
i2c_stop_slave_i2c_error:
  I2CM_STOP();
slave_i2c_error:
  reply_error(STATUS_I2C_ERROR);
  return;
#endif
}