📄 i2c_h8s_edosk2674.c
字号:
//==========================================================================
//
// devs/wallclock/h8s/edosk2674/include/i2c_h8s_edosk2674.c
//
// EDOSK2674 I2C interface
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2003 Gary Thomas
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): Uwe Kindler
// Contributors:Uwe Kindler
// Date: 2003-11-26
// Purpose: EDOSK2674 I2C interface - the I2C interface is only required
// for interfacing the Dallas DS1672 RTC. Therefore we make it
// part of the EDOSK2674 RTC drivers
//####DESCRIPTIONEND####
//==========================================================================
//===========================================================================
// INCLUDES
//===========================================================================
#include <cyg/io/ds1672.h> // ds1672 I2C interface and register definitions
#include <cyg/hal/var_arch.h> // h8s2674 port io
#include <cyg/hal/hal_io.h> // generic H8S register access
#include <cyg/hal/plf_intr.h> // HAL_DELAY_US()
//===========================================================================
// DEFINES
//===========================================================================
#define P3DDR_SDA_READ (0x3A) // read from sda register
#define P3DDR_SDA_WRITE (0x3A | CYGARC_P3_I2C_SDA)// write to sda register
//===========================================================================
// READ SDA FROM I2C BUS
// DESCRIPTTION:
// Reads pin state of SDA pin on port 3
//
// RETURNS:
// Pin state of SDA pin on port 3
//===========================================================================
cyg_uint8 i2c_sda_rd(void)
{
cyg_uint8 tmp;
HAL_WRITE_UINT8(CYGARC_P3DDR, P3DDR_SDA_READ); // set P32 as input
HAL_READ_UINT8(CYGARC_PORT3, tmp); // read port 3 pin states
return (tmp & CYGARC_P3_I2C_SDA) >> 2; // return pin state
}
//===========================================================================
// WRITE TO I2C SDA LINE
// DESCRIPTTION:
// Sets pin state of SDA pin on port 3
//
// ARGUMENTS:
// 'sdaval' Is 0 or 1
//===========================================================================
void i2c_sda_wr(cyg_uint8 sdaval)
{
cyg_uint8 tmp;
HAL_WRITE_UINT8(CYGARC_P3DDR, P3DDR_SDA_WRITE); // set P32 as output
HAL_READ_UINT8(CYGARC_P3DR, tmp); // read P3DR value
if (sdaval > 0)
{
tmp |= CYGARC_P3_I2C_SDA;
}
else
{
tmp &= ~CYGARC_P3_I2C_SDA;
}
HAL_WRITE_UINT8(CYGARC_P3DR, tmp); // write P3DR value
}
//===========================================================================
// WRITE TO I2C SCL LINE
// DESCRIPTTION:
// Sets pin state of SCL pin on port 3
//
// ARGUMENTS:
// 'sclval' Is 0 or 1
//===========================================================================
void i2c_scl_wr(cyg_uint8 sclval)
{
cyg_uint8 tmp;
HAL_READ_UINT8(CYGARC_P3DR, tmp); // read P3DR value
if (sclval > 0)
{
tmp |= CYGARC_P3_I2C_SCL;
}
else
{
tmp &= ~CYGARC_P3_I2C_SCL;
}
HAL_WRITE_UINT8(CYGARC_P3DR, tmp); // write P3DR value
}
//===========================================================================
// CREATE I2C BUS START CONDITION
// DESCRIPTTION:
// A change in the state of the data line from high to low, while clock
// line is high defines a start condition
//===========================================================================
void i2c_start(void)
{
i2c_sda_wr(1);
i2c_scl_wr(1);
i2c_sda_wr(0);
}
//===========================================================================
// CREATE I2C BUS STOP CONDITION
// DESCRIPTION:
// A change in the state of the data line from low to high, while clock
// line is high defines a stop condition
//===========================================================================
void i2c_stop(void)
{
i2c_sda_wr(0);
HAL_DELAY_US(4);
i2c_scl_wr(0);
HAL_DELAY_US(4);
i2c_sda_wr(1);
}
//===========================================================================
// READ BYTE FROM I2C BUS
// DESCRIPTTION:
// Read one single byte from I2C bus
//
// ARGUMENTS:
// 'ackn' Select if acknowledge should be sent (I2C_ACK or I2C_NACK)
//
// RETURNS:
// Byte read from I2C bus
//===========================================================================
cyg_uint8 i2c_byte_rd(cyg_uint8 ackn)
{
cyg_uint8 i;
cyg_uint8 data;
cyg_uint8 sda;
data = 0;
i2c_sda_wr(1); // let go of SDA line
//
// now read one byte from sda - read msbfirst
//
for (i = 0; i < 8; i++)
{
i2c_scl_wr(0);
HAL_DELAY_US(2);
//
// set SCL high and read data
//
i2c_scl_wr(1);
HAL_DELAY_US(2);
sda = i2c_sda_rd();
data <<= 1;
data |= sda;
i2c_scl_wr(1);
//
// data is read - pull SCL down again
//
i2c_scl_wr(0);
}
//
// hold sda low for acknowledge
//
i2c_sda_wr(ackn);
i2c_scl_wr(0);
HAL_DELAY_US(4);
i2c_scl_wr(1);
HAL_DELAY_US(4);
if (I2C_NACK == ackn)
{
i2c_sda_wr(1); // next cycle is reset
}
i2c_scl_wr(0);
HAL_DELAY_US(4);
//
// release sda line
//
i2c_sda_wr(1);
return data;
}
//===========================================================================
// WRITE BYTE TO I2C BUS
// DESCRIPTTION:
// Writes one single byte to I2C bus
//
// ARGUMENTS:
// 'data' Data byte to be written to I2C bus
//===========================================================================
void i2c_byte_wr(cyg_uint8 data)
{
cyg_uint8 i;
i2c_scl_wr(0);
for (i = 0; i < 8; i++)
{
//
// send the msbits first
//
if (data & 0x80)
{
i2c_sda_wr(1);
}
else
{
i2c_sda_wr(0);
}
i2c_scl_wr(0);
HAL_DELAY_US(4);
i2c_scl_wr(1);
HAL_DELAY_US(4);
i2c_scl_wr(0);
HAL_DELAY_US(4);
data <<= 1;
}
//
// Release the sda line
//
i2c_sda_wr(1);
HAL_DELAY_US(4);
i2c_scl_wr(0);
HAL_DELAY_US(4);
i2c_scl_wr(1);
HAL_DELAY_US(4);
i2c_scl_wr(0);
HAL_DELAY_US(4);
}
//--------------------------------------------------------------------------
// End of i2c_h8s_edosk2674.h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -