OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [drivers/] [i2c_master_slave/] [i2c_master_slave.c] - Diff between revs 486 and 545

Only display areas with differences | Details | Blame | View Log

Rev 486 Rev 545
/*************************************************************
/*************************************************************
* I2C functions for the Herveille i2c controller            *
* I2C functions for the Herveille i2c controller            *
*                                                           *
*                                                           *
* Provides functions to read from and write to the I2C bus. *
* Provides functions to read from and write to the I2C bus. *
* Master and slave mode are both supported                  *
* Master and slave mode are both supported                  *
*                                                           *
*                                                           *
* Julius Baxter, julius@opencores.org                       *
* Julius Baxter, julius@opencores.org                       *
*                                                           *
*                                                           *
************************************************************/
************************************************************/
 
 
#include "board.h"
#include "board.h"
#include "cpu-utils.h"
#include "cpu-utils.h"
#include "i2c_master_slave.h"
#include "i2c_master_slave.h"
 
 
 
 
// Ensure board.h defines I2C_MASTER_SLAVE_NUM_CORES and 
// Ensure board.h defines I2C_MASTER_SLAVE_NUM_CORES and 
// I2C_MASTER_SLAVE_BASE_ADDRESSES_CSV which should be the base address values
// I2C_MASTER_SLAVE_BASE_ADDRESSES_CSV which should be the base address values
// separated with commas
// separated with commas
#ifdef I2C_MASTER_SLAVE_NUM_CORES
#ifdef I2C_MASTER_SLAVE_NUM_CORES
 
 
const int I2C_MASTER_SLAVE_BASE_ADR[I2C_MASTER_SLAVE_NUM_CORES] = {
const int I2C_MASTER_SLAVE_BASE_ADR[I2C_MASTER_SLAVE_NUM_CORES] = {
        I2C_MASTER_SLAVE_BASE_ADDRESSES_CSV };
        I2C_MASTER_SLAVE_BASE_ADDRESSES_CSV };
#else
#else
 
 
const int I2C_MASTER_SLAVE_BASE_ADR[1] = {-1};
const int I2C_MASTER_SLAVE_BASE_ADR[1] = {-1};
 
 
#endif
#endif
 
 
inline unsigned char i2c_master_slave_read_reg(int core, unsigned char addr)
inline unsigned char i2c_master_slave_read_reg(int core, unsigned char addr)
{
{
        return REG8((I2C_MASTER_SLAVE_BASE_ADR[core] + addr));
        return REG8((I2C_MASTER_SLAVE_BASE_ADR[core] + addr));
}
}
 
 
inline void i2c_master_slave_write_reg(int core, unsigned char addr,
inline void i2c_master_slave_write_reg(int core, unsigned char addr,
                                       unsigned char data)
                                       unsigned char data)
{
{
        REG8((I2C_MASTER_SLAVE_BASE_ADR[core] + addr)) = data;
        REG8((I2C_MASTER_SLAVE_BASE_ADR[core] + addr)) = data;
}
}
 
 
int i2c_master_slave_wait_for_busy(int core)
int i2c_master_slave_wait_for_busy(int core)
{
{
        while (1) {
        while (1) {
                // Check for busy flag in i2c status reg
                // Check for busy flag in i2c status reg
                if (!
                if (!
                    (i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_SR) &
                    (i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_SR) &
                     I2C_MASTER_SLAVE_SR_BUSY))
                     I2C_MASTER_SLAVE_SR_BUSY))
                        return 0;
                        return 0;
        }
        }
}
}
 
 
int i2c_master_slave_wait_for_transfer(int core)
int i2c_master_slave_wait_for_transfer(int core)
{
{
        volatile unsigned char status;
        volatile unsigned char status;
        // Wait for ongoing transmission to finish
        // Wait for ongoing transmission to finish
        while (1) {
        while (1) {
                status = i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_SR);
                status = i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_SR);
                // If arbitration lost
                // If arbitration lost
                if ((status & I2C_MASTER_SLAVE_SR_ARB_LOST) ==
                if ((status & I2C_MASTER_SLAVE_SR_ARB_LOST) ==
                    I2C_MASTER_SLAVE_SR_ARB_LOST)
                    I2C_MASTER_SLAVE_SR_ARB_LOST)
                        return 2;
                        return 2;
                // If TIP bit = o , stop waiting
                // If TIP bit = o , stop waiting
                else if (!(status & I2C_MASTER_SLAVE_SR_TRANSFER_IN_PRG))
                else if (!(status & I2C_MASTER_SLAVE_SR_TRANSFER_IN_PRG))
                        return 0;
                        return 0;
        }
        }
}
}
 
 
/***********************************************************
/***********************************************************
* i2c_master_slave_init_core                               *
* i2c_master_slave_init_core                               *
*                                                          *
*                                                          *
* Setup i2c core:                                          *
* Setup i2c core:                                          *
* Write prescaler register with parmeter passed, enable    *
* Write prescaler register with parmeter passed, enable    *
* core in control register, optionally enable interrupts   *
* core in control register, optionally enable interrupts   *
************************************************************/
************************************************************/
int i2c_master_slave_init_core(int core, unsigned short prescaler,
int i2c_master_slave_init_core(int core, unsigned short prescaler,
                               int interrupt_enable)
                               int interrupt_enable)
{
{
 
 
        // Setup I2C prescaler,
        // Setup I2C prescaler,
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_PRERlo,
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_PRERlo,
                                   prescaler & 0xff);
                                   prescaler & 0xff);
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_PRERhi,
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_PRERhi,
                                   (prescaler >> 8) & 0xff);
                                   (prescaler >> 8) & 0xff);
 
 
        // Enable I2C controller and optionally interrupts
        // Enable I2C controller and optionally interrupts
        if (interrupt_enable)
        if (interrupt_enable)
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
                                           I2C_MASTER_SLAVE_CTR_CORE_ENABLE |
                                           I2C_MASTER_SLAVE_CTR_CORE_ENABLE |
                                           I2C_MASTER_SLAVE_CTR_INTR_ENABLE);
                                           I2C_MASTER_SLAVE_CTR_INTR_ENABLE);
        else
        else
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
                                           I2C_MASTER_SLAVE_CTR_CORE_ENABLE);
                                           I2C_MASTER_SLAVE_CTR_CORE_ENABLE);
 
 
        return 0;
        return 0;
 
 
}
}
 
 
/***********************************************************
/***********************************************************
* i2c_master_slave_deact_core                              *
* i2c_master_slave_deact_core                              *
*                                                          *
*                                                          *
* Deactivate i2c core:                                     *
* Deactivate i2c core:                                     *
* Clear core enable and interrupt enable bits              *
* Clear core enable and interrupt enable bits              *
************************************************************/
************************************************************/
int i2c_master_slave_deact_core(int core)
int i2c_master_slave_deact_core(int core)
{
{
 
 
 
 
  i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
  i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
                             i2c_master_slave_read_reg(core,
                             i2c_master_slave_read_reg(core,
                                                       I2C_MASTER_SLAVE_CTR) &
                                                       I2C_MASTER_SLAVE_CTR) &
                             ~(I2C_MASTER_SLAVE_CTR_CORE_ENABLE |
                             ~(I2C_MASTER_SLAVE_CTR_CORE_ENABLE |
                               I2C_MASTER_SLAVE_CTR_INTR_ENABLE));
                               I2C_MASTER_SLAVE_CTR_INTR_ENABLE));
 
 
 
 
        return 0;
        return 0;
 
 
}
}
 
 
/***********************************************************
/***********************************************************
* i2c_master_slave_init_as_slave                           *
* i2c_master_slave_init_as_slave                           *
*                                                          *
*                                                          *
* Setup i2c core to service slave accesses                 *
* Setup i2c core to service slave accesses                 *
* OR in slave enable bit to control register               *
* OR in slave enable bit to control register               *
* Set slave address                                        *
* Set slave address                                        *
************************************************************/
************************************************************/
int i2c_master_slave_init_as_slave(int core, char addr)
int i2c_master_slave_init_as_slave(int core, char addr)
{
{
 
 
        // Set slave enable bit
        // Set slave enable bit
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
                                   i2c_master_slave_read_reg(core,
                                   i2c_master_slave_read_reg(core,
                                                             I2C_MASTER_SLAVE_CTR)
                                                             I2C_MASTER_SLAVE_CTR)
                                   | I2C_MASTER_SLAVE_CTR_SLAVE_ENABLE);
                                   | I2C_MASTER_SLAVE_CTR_SLAVE_ENABLE);
        // Set slave address
        // Set slave address
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_SLADR, addr);
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_SLADR, addr);
 
 
        return 0;
        return 0;
 
 
}
}
 
 
/***********************************************************
/***********************************************************
* i2c_master_slave_deact_as_slave                          *
* i2c_master_slave_deact_as_slave                          *
*                                                          *
*                                                          *
* Disable slave mode for this I2C core                     *
* Disable slave mode for this I2C core                     *
* Deassert slave eanble bit in control register            *
* Deassert slave eanble bit in control register            *
************************************************************/
************************************************************/
int i2c_master_slave_deact_as_slave(int core)
int i2c_master_slave_deact_as_slave(int core)
{
{
        // Clear slave enable bit
        // Clear slave enable bit
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
                                   i2c_master_slave_read_reg(core,
                                   i2c_master_slave_read_reg(core,
                                                             I2C_MASTER_SLAVE_CTR)
                                                             I2C_MASTER_SLAVE_CTR)
                                   & ~I2C_MASTER_SLAVE_CTR_SLAVE_ENABLE);
                                   & ~I2C_MASTER_SLAVE_CTR_SLAVE_ENABLE);
 
 
        return 0;
        return 0;
}
}
 
 
/***********************************************************
/***********************************************************
* i2c_master_slave_master_start                            *
* i2c_master_slave_master_start                            *
*                                                          *
*                                                          *
* Get the i2c bus.                                         *
* Get the i2c bus.                                         *
************************************************************/
************************************************************/
int i2c_master_slave_master_start(int core, unsigned char addr, int read)
int i2c_master_slave_master_start(int core, unsigned char addr, int read)
{
{
 
 
        i2c_master_slave_wait_for_busy(core);
        i2c_master_slave_wait_for_busy(core);
 
 
        // Set address in transfer register
        // Set address in transfer register
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_TXR,
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_TXR,
                                   (addr << 1) | read);
                                   (addr << 1) | read);
 
 
        // Start and write the address
        // Start and write the address
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                                   I2C_MASTER_SLAVE_CR_START |
                                   I2C_MASTER_SLAVE_CR_START |
                                   I2C_MASTER_SLAVE_CR_WRITE);
                                   I2C_MASTER_SLAVE_CR_WRITE);
 
 
        i2c_master_slave_wait_for_transfer(core);
        i2c_master_slave_wait_for_transfer(core);
 
 
        return 0;
        return 0;
}
}
 
 
/***********************************************************
/***********************************************************
* i2c_master_slave_master_write                            *
* i2c_master_slave_master_write                            *
*                                                          *
*                                                          *
* Send 1 byte of data                                      *
* Send 1 byte of data                                      *
************************************************************/
************************************************************/
int i2c_master_slave_master_write(int core, unsigned char data,
int i2c_master_slave_master_write(int core, unsigned char data,
                                  int check_prev_ack, int stop)
                                  int check_prev_ack, int stop)
{
{
        if (i2c_master_slave_wait_for_transfer(core))
        if (i2c_master_slave_wait_for_transfer(core))
                return 1;
                return 1;
 
 
        // present data
        // present data
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_TXR, data);
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_TXR, data);
 
 
        if (!stop)
        if (!stop)
                // set command (write)
                // set command (write)
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                                           I2C_MASTER_SLAVE_CR_WRITE);
                                           I2C_MASTER_SLAVE_CR_WRITE);
        else
        else
                // set command (write) and stop
                // set command (write) and stop
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                                           I2C_MASTER_SLAVE_CR_WRITE |
                                           I2C_MASTER_SLAVE_CR_WRITE |
                                           I2C_MASTER_SLAVE_CR_STOP);
                                           I2C_MASTER_SLAVE_CR_STOP);
 
 
        return i2c_master_slave_wait_for_transfer(core);
        return i2c_master_slave_wait_for_transfer(core);
 
 
}
}
 
 
/***********************************************************
/***********************************************************
* i2c_master_slave_master_stop                             *
* i2c_master_slave_master_stop                             *
*                                                          *
*                                                          *
* Send stop condition                                      *
* Send stop condition                                      *
************************************************************/
************************************************************/
int i2c_master_slave_master_stop(int core)
int i2c_master_slave_master_stop(int core)
{
{
        unsigned char status;
        unsigned char status;
        unsigned char ready = 0;
        unsigned char ready = 0;
 
 
        // Make I2C controller wait at end of finished byte
        // Make I2C controller wait at end of finished byte
        if (i2c_master_slave_wait_for_transfer(core))
        if (i2c_master_slave_wait_for_transfer(core))
                return 1;
                return 1;
 
 
        // Send stop condition
        // Send stop condition
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                                   I2C_MASTER_SLAVE_CR_STOP);
                                   I2C_MASTER_SLAVE_CR_STOP);
 
 
        return 0;
        return 0;
}
}
 
 
/***********************************************************
/***********************************************************
* i2c_master_slave_master_read                             *
* i2c_master_slave_master_read                             *
*                                                          *
*                                                          *
* Read 1 byte of data                                      *
* Read 1 byte of data                                      *
************************************************************/
************************************************************/
int i2c_master_slave_master_read(int core, int check_prev_ack,
int i2c_master_slave_master_read(int core, int check_prev_ack,
                                 int stop, char *data)
                                 int stop, char *data)
{
{
 
 
        // Make I2C controller wait at end of finished byte
        // Make I2C controller wait at end of finished byte
        if (i2c_master_slave_wait_for_transfer(core))
        if (i2c_master_slave_wait_for_transfer(core))
                return 1;
                return 1;
 
 
        if (stop)
        if (stop)
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                                           I2C_MASTER_SLAVE_CR_READ |
                                           I2C_MASTER_SLAVE_CR_READ |
 
                                           // Final read, so send a NAK to slave
 
                                           I2C_MASTER_SLAVE_CR_ACK |
                                           I2C_MASTER_SLAVE_CR_STOP);
                                           I2C_MASTER_SLAVE_CR_STOP);
        else
        else
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                                           I2C_MASTER_SLAVE_CR_READ);
                                           I2C_MASTER_SLAVE_CR_READ);
 
 
        if (i2c_master_slave_wait_for_transfer(core))
        if (i2c_master_slave_wait_for_transfer(core))
                return 1;
                return 1;
 
 
        *data = i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_RXR);
        *data = i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_RXR);
 
 
        return i2c_master_slave_wait_for_transfer(core);
        return i2c_master_slave_wait_for_transfer(core);
}
}
 
 
/***********************************************************
/***********************************************************
* i2c_master_slave_ack_interrupt                           *
* i2c_master_slave_ack_interrupt                           *
*                                                          *
*                                                          *
* Acknowledge interrupt has been serviced                  *
* Acknowledge interrupt has been serviced                  *
************************************************************/
************************************************************/
int i2c_master_slave_ack_interrupt(int core)
int i2c_master_slave_ack_interrupt(int core)
{
{
 
 
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
                                   I2C_MASTER_SLAVE_CR_IACK);
                                   I2C_MASTER_SLAVE_CR_IACK);
 
 
        return 0;
        return 0;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.