URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2/sw/drivers/i2c_host_slave
- from Rev 393 to Rev 403
- ↔ Reverse comparison
Rev 393 → Rev 403
/i2c_master_slave.c
4,7 → 4,7
* Provides functions to read from and write to the I2C bus. * |
* Master and slave mode are both supported * |
* * |
* Julius Baxter, julius.baxter@orsoc.se * |
* Julius Baxter, julius@opencores.org * |
* * |
************************************************************/ |
|
12,195 → 12,245
#include "cpu-utils.h" |
#include "i2c_master_slave.h" |
|
|
inline unsigned char i2c_master_slave_read_i2c_reg(int core, unsigned char addr) |
inline unsigned char i2c_master_slave_read_reg(int core, unsigned char addr) |
{ |
return REG8((i2c_base_adr[core] + addr)); |
return REG8((i2c_base_adr[core] + addr)); |
} |
inline void i2c_master_slave_write_i2c_reg(int core, unsigned char addr, unsigned char data) |
|
inline void i2c_master_slave_write_reg(int core, unsigned char addr, |
unsigned char data) |
{ |
REG8((i2c_base_adr[core] + addr)) = data; |
REG8((i2c_base_adr[core] + addr)) = data; |
} |
|
int i2c_master_slave_wait_for_busy(int core) |
{ |
while(1) { |
// Check for busy flag in i2c status reg |
if(!(i2c_master_slave_read_i2c_reg(core, SR) & SR_BUSY)) |
return 0; |
} |
while (1) { |
// Check for busy flag in i2c status reg |
if (! |
(i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_SR) & |
I2C_MASTER_SLAVE_SR_BUSY)) |
return 0; |
} |
} |
|
|
int i2c_master_slave_wait_for_transfer(int core) |
{ |
volatile unsigned char status; |
// Wait for ongoing transmission to finish |
while(1) { |
status = i2c_master_slave_read_i2c_reg(core, SR); |
// If arbitration lost |
if( (status & SR_ARB_LOST) == SR_ARB_LOST) |
return 2; |
// If TIP bit = o , stop waiting |
else if(!(status & SR_TRANSFER_IN_PRG)) |
return 0; |
} |
volatile unsigned char status; |
// Wait for ongoing transmission to finish |
while (1) { |
status = i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_SR); |
// If arbitration lost |
if ((status & I2C_MASTER_SLAVE_SR_ARB_LOST) == |
I2C_MASTER_SLAVE_SR_ARB_LOST) |
return 2; |
// If TIP bit = o , stop waiting |
else if (!(status & I2C_MASTER_SLAVE_SR_TRANSFER_IN_PRG)) |
return 0; |
} |
} |
|
/*********************************************************** |
* initI2C * |
* i2c_master_slave_init_core * |
* * |
* Setup i2c core: * |
* Write prescaler register with parmeter passed, enable * |
* core in control register, optionally enable interrupts * |
************************************************************/ |
int i2c_master_slave_initI2C (int core, unsigned short prescaler, int interrupt_enable) |
int i2c_master_slave_init_core(int core, unsigned short prescaler, |
int interrupt_enable) |
{ |
|
// Setup I2C prescaler, |
i2c_master_slave_write_i2c_reg(core, PRERlo, prescaler&0xff); |
i2c_master_slave_write_i2c_reg(core, PRERhi, (prescaler>>8)&0xff); |
// Setup I2C prescaler, |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_PRERlo, |
prescaler & 0xff); |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_PRERhi, |
(prescaler >> 8) & 0xff); |
|
// Enable I2C controller and optionally interrupts |
if (interrupt_enable) |
i2c_master_slave_write_i2c_reg(core, CTR, CTR_CORE_ENABLE | CTR_INTR_ENABLE ); |
else |
i2c_master_slave_write_i2c_reg(core, CTR, CTR_CORE_ENABLE ); |
// Enable I2C controller and optionally interrupts |
if (interrupt_enable) |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR, |
I2C_MASTER_SLAVE_CTR_CORE_ENABLE | |
I2C_MASTER_SLAVE_CTR_INTR_ENABLE); |
else |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR, |
I2C_MASTER_SLAVE_CTR_CORE_ENABLE); |
|
return 0; |
return 0; |
|
} |
|
/*********************************************************** |
* initI2CSlave * |
* i2c_master_slave_deact_core * |
* * |
* Setup i2c core to allow slave accesses: * |
* Deactivate i2c core: * |
* Clear core enable and interrupt enable bits * |
************************************************************/ |
int i2c_master_slave_deact_core(int core) |
{ |
|
|
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR, |
i2c_master_slave_read_reg(core, |
I2C_MASTER_SLAVE_CTR) & |
~(I2C_MASTER_SLAVE_CTR_CORE_ENABLE | |
I2C_MASTER_SLAVE_CTR_INTR_ENABLE)); |
|
|
return 0; |
|
} |
|
/*********************************************************** |
* i2c_master_slave_init_as_slave * |
* * |
* Setup i2c core to service slave accesses * |
* OR in slave enable bit to control register * |
* Set slave address * |
************************************************************/ |
int i2c_master_slave_initI2CSlave (int core, char addr) |
int i2c_master_slave_init_as_slave(int core, char addr) |
{ |
|
// Set slave enable bit |
i2c_master_slave_write_i2c_reg(core, CTR, i2c_master_slave_read_i2c_reg(core, CTR) | CTR_SLAVE_ENABLE); |
// Set slave address |
i2c_master_slave_write_i2c_reg(core, SLADR, addr ); |
|
return 0; |
|
// Set slave enable bit |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR, |
i2c_master_slave_read_reg(core, |
I2C_MASTER_SLAVE_CTR) |
| I2C_MASTER_SLAVE_CTR_SLAVE_ENABLE); |
// Set slave address |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_SLADR, addr); |
|
return 0; |
|
} |
|
/*********************************************************** |
* deactI2CSlave * |
* i2c_master_slave_deact_as_slave * |
* * |
* Disable slave mode for this I2C core * |
* Deassert slave eanble bit in control register * |
************************************************************/ |
int i2c_master_slave_deactI2CSlave (int core) |
int i2c_master_slave_deact_as_slave(int core) |
{ |
// Slave slave enable bit |
i2c_master_slave_write_i2c_reg(core, CTR, i2c_master_slave_read_i2c_reg(core, CTR) & ~CTR_SLAVE_ENABLE); |
|
return 0; |
// Clear slave enable bit |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR, |
i2c_master_slave_read_reg(core, |
I2C_MASTER_SLAVE_CTR) |
& ~I2C_MASTER_SLAVE_CTR_SLAVE_ENABLE); |
|
return 0; |
} |
|
|
/*********************************************************** |
* masterStart * |
* i2c_master_slave_master_start * |
* * |
* Get the i2c bus. * |
************************************************************/ |
int i2c_master_slave_masterStart(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); |
|
// Set address in transfer register |
i2c_master_slave_write_i2c_reg(core, TXR, (addr<<1)|read); |
i2c_master_slave_wait_for_busy(core); |
|
// Start and write the address |
i2c_master_slave_write_i2c_reg(core, CR, CR_START | CR_WRITE); |
|
i2c_master_slave_wait_for_transfer(core); |
|
return 0; |
// Set address in transfer register |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_TXR, |
(addr << 1) | read); |
|
// Start and write the address |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR, |
I2C_MASTER_SLAVE_CR_START | |
I2C_MASTER_SLAVE_CR_WRITE); |
|
i2c_master_slave_wait_for_transfer(core); |
|
return 0; |
} |
|
/*********************************************************** |
* masterWrite * |
* i2c_master_slave_master_write * |
* * |
* Send 1 byte of data * |
************************************************************/ |
int i2c_master_slave_masterWrite(int core, unsigned char data, |
int check_prev_ack, int stop) |
int i2c_master_slave_master_write(int core, unsigned char data, |
int check_prev_ack, int stop) |
{ |
if (i2c_master_slave_wait_for_transfer(core)) |
return 1; |
|
i2c_master_slave_write_i2c_reg(core, TXR, data); // present data |
if (i2c_master_slave_wait_for_transfer(core)) |
return 1; |
|
// present data |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_TXR, data); |
|
if (!stop) |
i2c_master_slave_write_i2c_reg(core, CR, CR_WRITE); // set command (write) |
else |
i2c_master_slave_write_i2c_reg(core, CR, CR_WRITE | CR_STOP); // set command (write) |
|
return 0; |
if (!stop) |
// set command (write) |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR, |
I2C_MASTER_SLAVE_CR_WRITE); |
else |
// set command (write) and stop |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR, |
I2C_MASTER_SLAVE_CR_WRITE | |
I2C_MASTER_SLAVE_CR_STOP); |
|
return 0; |
} |
|
/*********************************************************** |
* masterStop * |
* i2c_master_slave_master_stop * |
* * |
* Send stop condition * |
************************************************************/ |
int i2c_master_slave_masterStop(int core) { |
unsigned char status; |
unsigned char ready=0; |
int i2c_master_slave_master_stop(int core) |
{ |
unsigned char status; |
unsigned char ready = 0; |
|
// Make I2C controller wait at end of finished byte |
if (i2c_master_slave_wait_for_transfer(core)) |
return 1; |
|
// Send stop condition |
i2c_master_slave_write_i2c_reg(core, CR, CR_STOP); |
// Make I2C controller wait at end of finished byte |
if (i2c_master_slave_wait_for_transfer(core)) |
return 1; |
|
return 0; |
// Send stop condition |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR, |
I2C_MASTER_SLAVE_CR_STOP); |
|
return 0; |
} |
|
/*********************************************************** |
* masterRead * |
* i2c_master_slave_master_read * |
* * |
* Read 1 byte of data * |
************************************************************/ |
int i2c_master_slave_masterRead(int core, int check_prev_ack, |
int stop, char* data) { |
|
// Make I2C controller wait at end of finished byte |
if (i2c_master_slave_wait_for_transfer(core)) |
return 1; |
|
if (stop) |
i2c_master_slave_write_i2c_reg(core, CR, CR_READ | CR_STOP); |
else |
i2c_master_slave_write_i2c_reg(core, CR, CR_READ); |
int i2c_master_slave_master_read(int core, int check_prev_ack, |
int stop, char *data) |
{ |
|
if (i2c_master_slave_wait_for_transfer(core)) |
return 1; |
// Make I2C controller wait at end of finished byte |
if (i2c_master_slave_wait_for_transfer(core)) |
return 1; |
|
*data = i2c_master_slave_read_i2c_reg(core, RXR); |
if (stop) |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR, |
I2C_MASTER_SLAVE_CR_READ | |
I2C_MASTER_SLAVE_CR_STOP); |
else |
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR, |
I2C_MASTER_SLAVE_CR_READ); |
|
return 0; |
if (i2c_master_slave_wait_for_transfer(core)) |
return 1; |
|
*data = i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_RXR); |
|
return 0; |
} |
|
|
/*********************************************************** |
* ackInterrupt * |
* i2c_master_slave_ack_interrupt * |
* * |
* Acknowledge interrupt has been serviced * |
************************************************************/ |
int i2c_master_slave_ackInterrupt(int core) |
int i2c_master_slave_ack_interrupt(int core) |
{ |
|
i2c_master_slave_write_i2c_reg(core, CR, CR_IACK); |
|
return 0; |
|
i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR, |
I2C_MASTER_SLAVE_CR_IACK); |
|
return 0; |
} |
/include/i2c_master_slave.h
13,48 → 13,46
extern const int i2c_base_adr[4]; |
//Memory mapping adresses |
|
#define PRERlo 0x0 // Clock prescaler register |
#define PRERhi 0x1 // Clock prescaler register |
#define CTR 0x2 // Control register |
#define TXR 0x3 // Transmit register |
#define RXR 0x3 // Recive register |
#define CR 0x4 // Controll register |
#define SR 0x4 // Status register |
#define SLADR 0x7 // Slave address register |
#define I2C_MASTER_SLAVE_PRERlo 0x0 // Clock prescaler register |
#define I2C_MASTER_SLAVE_PRERhi 0x1 // Clock prescaler register |
#define I2C_MASTER_SLAVE_CTR 0x2 // Control register |
#define I2C_MASTER_SLAVE_TXR 0x3 // Transmit register |
#define I2C_MASTER_SLAVE_RXR 0x3 // Recive register |
#define I2C_MASTER_SLAVE_CR 0x4 // Control register |
#define I2C_MASTER_SLAVE_SR 0x4 // Status register |
#define I2C_MASTER_SLAVE_SLADR 0x7 // Slave address register |
|
#define I2C_MASTER_SLAVE_CTR_CORE_ENABLE 0x80 |
#define I2C_MASTER_SLAVE_CTR_INTR_ENABLE 0x40 |
#define I2C_MASTER_SLAVE_CTR_SLAVE_ENABLE 0x20 |
|
#define CTR_CORE_ENABLE 0x80 |
#define CTR_INTR_ENABLE 0x40 |
#define CTR_SLAVE_ENABLE 0x20 |
#define I2C_MASTER_SLAVE_CR_START 0x80 |
#define I2C_MASTER_SLAVE_CR_STOP 0x40 |
#define I2C_MASTER_SLAVE_CR_READ 0x20 |
#define I2C_MASTER_SLAVE_CR_WRITE 0x10 |
#define I2C_MASTER_SLAVE_CR_ACK 0x08 |
#define I2C_MASTER_SLAVE_CR_SL_CONT 0x02 |
#define I2C_MASTER_SLAVE_CR_IACK 0x01 |
|
#define CR_START 0x80 |
#define CR_STOP 0x40 |
#define CR_READ 0x20 |
#define CR_WRITE 0x10 |
#define CR_ACK 0x08 |
#define CR_SL_CONT 0x02 |
#define CR_IACK 0x01 |
#define I2C_MASTER_SLAVE_SR_RXACK 0x80 |
#define I2C_MASTER_SLAVE_SR_BUSY 0x40 |
#define I2C_MASTER_SLAVE_SR_ARB_LOST 0x20 |
#define I2C_MASTER_SLAVE_SR_SLAVE_MODE 0x10 |
#define I2C_MASTER_SLAVE_SR_SLAVE_DATA_AVAIL 0x08 |
#define I2C_MASTER_SLAVE_SR_SLAVE_DATA_REQ 0x04 |
#define I2C_MASTER_SLAVE_SR_TRANSFER_IN_PRG 0x02 |
#define I2C_MASTER_SLAVE_SR_IRQ_FLAG 0x01 |
|
#define SR_RXACK 0x80 |
#define SR_BUSY 0x40 |
#define SR_ARB_LOST 0x20 |
#define SR_SLAVE_MODE 0x10 |
#define SR_SLAVE_DATA_AVAIL 0x08 |
#define SR_SLAVE_DATA_REQ 0x04 |
#define SR_TRANSFER_IN_PRG 0x02 |
#define SR_IRQ_FLAG 0x01 |
|
|
int i2c_master_slave_initI2C(int core, unsigned short prescaler, |
int interrupt_enable); |
|
int i2c_master_slave_initI2CSlave (int core, char addr); |
int i2c_master_slave_deactI2CSlave (int core); |
int i2c_master_slave_masterStart(int core, unsigned char addr, int read); |
int i2c_master_slave_masterWrite(int core, unsigned char data, |
int check_prev_ack, int stop); |
int i2c_master_slave_masterStop(int core); |
int i2c_master_slave_masterRead(int core, int check_prev_ack, int stop, |
char* data); |
int i2c_master_slave_ackInterrupt(int core); |
int i2c_master_slave_init_core(int core, unsigned short prescaler, |
int interrupt_enable); |
int i2c_master_slave_deact_core(int core); |
int i2c_master_slave_init_as_slave(int core, char addr); |
int i2c_master_slave_deact_as_slave(int core); |
int i2c_master_slave_master_start(int core, unsigned char addr, int read); |
int i2c_master_slave_master_write(int core, unsigned char data, |
int check_prev_ack, int stop); |
int i2c_master_slave_master_stop(int core); |
int i2c_master_slave_master_read(int core, int check_prev_ack, int stop, |
char *data); |
int i2c_master_slave_ack_interrupt(int core); |
#endif |