Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages | Examples

temperature.c

Example of I2C.
/*
 * Copyright (C) 2003 BLADOX, s.r.o.  All rights reserved.
 *
 * This file is part of an example program for Turbo. This example
 * program may be used, distributed and modified without limitation.
 *
 */

#include <config.h>
#include <turbo/turbo.h>

#include <avr/sfr_defs.h>
#include <avr/io.h>

u8 PROGMEM t_Foo_en[] = "Temperature";
u8 PROGMEM t_Deg[] = " deg.C";
u8 PROGMEM t_Error[] = "Sensor ERROR";

#define TEMP_SENSOR_ID 0x09
#define TEMP_SENSOR_ADDRESS 0x00
#define MY_SLAVE_ADDRESS 0x7F

void i2c_init ()
{
  outb (TWBR, 0x10);            // set TWI bit rate register to 16
  outb (TWCR, 0x04);            // enable TWI
  outb (TWSR, 0x00);            // TWI prescaler = 0
  outb (TWAR, (MY_SLAVE_ADDRESS) << 1); // set address
}

void init_temp ()
{
  i2c_init ();
}

// TWI send START condition
u8 i2c_send_start ()
{
  u8 status;

  dbsp ("Start: ");
  outb (TWCR, 0xA4);            // send START, clear TWINT
  while ((inb (TWCR) & 0x80) == 0);     //Wait for finishing of START
  status = (inb (TWSR) & 0xF8); // return STATUS of TWI
  dbch (status);
  dbc ('\n');
  return status;
}

// TWI send SLAVE ADDRESS with nWRITE bit = 0
u8 i2c_send_sla_w ()
{
  u8 status;

  dbsp ("Ssw:");
  outb (TWDR, (((TEMP_SENSOR_ID) << 4) | ((TEMP_SENSOR_ADDRESS) << 1) | 0x00)); // send slave addres and nWRITE bit = 0
  outb (TWCR, 0x84);            // clear TWINT
  while ((inb (TWCR) & 0x80) == 0);     //Wait for finishing of SLA+W transmit
  status = (inb (TWSR) & 0xF8); // return STATUS of TWI
  dbch (status);
  dbc ('\n');
  return status;
}

// TWI send SLAVE ADDRESS with nWRITE bit = 1
u8 i2c_send_sla_r ()
{
  u8 status;

  dbsp ("Ssr: ");
  outb (TWDR, (((TEMP_SENSOR_ID) << 4) | ((TEMP_SENSOR_ADDRESS) << 1) | 0x01)); // send slave addres and nWRITE bit = 1
  outb (TWCR, 0x84);            // clear TWINT
  while ((inb (TWCR) & 0x80) == 0);     //Wait for finishing of SLA+W transmit
  status = (inb (TWSR) & 0xF8); // return STATUS of TWI
  dbch (status);
  dbc ('\n');
  return status;
}

// TWI send DATA
u8 i2c_send_data (u8 value)
{
  u8 status;

  dbsp ("Ssd: ");
  outb (TWDR, value);           // send DATA
  outb (TWCR, 0x84);            // clear TWINT
  while ((inb (TWCR) & 0x80) == 0);     //Wait for finishing of DATA transmit
  status = (inb (TWSR) & 0xF8); // return STATUS of TWI
  dbch (status);
  dbc ('\n');
  return status;
}

// TWI receive DATA
u8 i2c_receive_data (u8 * value, u8 lastFlag)
{
  u8 status;

  dbsp ("Srd: ");
  if (lastFlag == 0)
  {
//      sbi(TWCR,TWEA); //set ACK after receiving data
    outb (TWCR, 0x84 | (1 << TWEA));    // clear TWINT answer with ACK
  }
  else
  {
//      cbi(TWCR,TWEA); //clear ACK after receiving data
    outb (TWCR, 0x84);          // clear TWINT answer with NACK
  }
  while ((inb (TWCR) & 0x80) == 0);     //Wait for finishing of DATA transmit
  *value = inb (TWDR);          // read DATA
  status = (inb (TWSR) & 0xF8); // return STATUS of TWI
  dbch (status);
  dbc ('\n');
  return status;
}

// TWI send STOP condition
u8 i2c_send_stop ()
{
  u8 status;

  dbsp ("Stop: ");
  outb (TWCR, 0x94);            // send STOP, clear TWINT
  status = (inb (TWSR) & 0xF8); // return STATUS of TWI
  dbch (status);
  dbc ('\n');
  return status;
}

// TEMPERATURE SENSOR TRANSMIT function
u8 temp_tx_data (u8 * data, u8 len)
{
  u8 status;
  u8 i;

  status = i2c_send_start ();   //send START
  if (status != 0x08)
    goto I2C_SEND_DATA_ERROR;   //finish with error code
  status = i2c_send_sla_w ();   //send SLA+W
  if (status != 0x18)
    goto I2C_SEND_DATA_ERROR;   //finish with error code
  for (i = 0; i < len; i++)
  {
    status = i2c_send_data (data[i]);   //send DATA
    if (status != 0x28)
      goto I2C_SEND_DATA_ERROR; //finish with error code
  }
  status = i2c_send_stop ();    //send START
  return 0;
I2C_SEND_DATA_ERROR:
  return status;
}

// TEMPERATURE SENSOR RECEIVE function
u8 temp_rx_data (u8 * data, u8 len)
{
  u8 status;
  u8 i;

  status = i2c_send_start ();   //send START
  if (status != 0x08)
    goto I2C_SEND_DATA_ERROR;   //finish with error code
  status = i2c_send_sla_r ();   //send SLA+R
  if (status != 0x40)
    goto I2C_SEND_DATA_ERROR;   //finish with error code
  for (i = 0; i < len; i++)
  {
    if (i != (len - 1))
    {                           //not last byte te read, generate ACK
      status = i2c_receive_data ((u8 *) & (data[i]), 0);        //receive not last DATA
      if (status != 0x50)
        goto I2C_SEND_DATA_ERROR;       //finish with error code
    }
    else
    {                           //last byte te read, generate NACK
      status = i2c_receive_data (&(data[i]), 1);        //receive last DATA
      if (status != 0x58)
        goto I2C_SEND_DATA_ERROR;       //finish with error code
    }
  }
  status = i2c_send_stop ();    //send START
  return 0;
I2C_SEND_DATA_ERROR:
  return status;
}

// TEMPERATURE SENSOR WRITE config. reg.
u8 temp_write_conf_reg ()
{
  u8 buf[2];
  u8 status;

  buf[0] = 0x01;                //pointer reg. = config. reg.
  buf[1] = 0x78;                //config. reg. = 12bit,6conv,low,comp,active
  status = temp_tx_data (buf, 2);
  return status;
}

// TEMPERATURE SENSOR SELECT temp. reg.
u8 temp_select_temp_reg ()
{
  u8 buf[2];
  u8 status;

  buf[0] = 0x00;                //pointer reg. = temp. reg.
  buf[1] = 0x00;                //dump
  status = temp_tx_data (buf, 2);
  return status;
}

// TEMPERATURE SENSOR READ temp. reg.
u8 temp_read_temp_reg (u16 * temp)
{
  u8 buf[2];
  u8 status;

  status = temp_rx_data ((u8 *) buf, 2);
  *temp = (buf[0] << 8) | (buf[1]);
  return status;
}

void action_menu (void *data)
{
  u8 *buf = buf_B ();
  u8 *r = buf;
  u16 tempValue;
  u8 i;
  u8 tl;
  u16 tempLow = 0;
  u8 s;

  s = temp_write_conf_reg ();
  s |= temp_select_temp_reg ();
  s |= temp_read_temp_reg (&tempValue);

  if (s == 0)
  {
    dbsp ("TEMP: ");
    dbih (tempValue);
    dbc ('\n');

    if ((tempValue & 0x8000) != 0)
    {
      r = sprintc (r, '-');
      tempValue = ~tempValue;
      tempValue &= 0x7FF0;
      tempValue += 0x0010;
    }
    else
      r = sprintc (r, '+');

    r = sprinti (r, tempValue >> 8);
    r = sprintc (r, '.');
    tl = tempValue & 0xF0;

#define T_STEP 625

    tempLow = 0;
    for (i = 7; i > 3; i--)
      tempLow += ((tl >> i) & 0x01) * (1 << (i - 4)) * T_STEP;

    if (tempLow < 1000)
      r = sprintc (r, '0');
    r = sprinti (r, tempLow);
    r = sprints (r, t_Deg);
  }
  else
    r = sprints (r, t_Error);

  r = sprintc (r, '\0');

  display_text_raw (buf, Q_DISPLAY_TEXT_USER_CLEAR);
}

void turbo_handler (u8 action, void *data)
{
  switch (action)
  {
    case ACTION_INSERT_MENU:
      insert_menu (t_Foo_en);
      init_temp ();
      break;
    case ACTION_MENU_SELECTION:
      stk_thread (action_menu, data);
      break;
    default:
      break;
  }
}


Copyright © 2004-2006 BLADOX
Turbo version 1.2