mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Add I2S driver to the StmartFusion demo.
This commit is contained in:
parent
7915c348c3
commit
8e3e51e3a2
798
Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/I2C/i2c.c
Normal file
798
Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/I2C/i2c.c
Normal file
|
@ -0,0 +1,798 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2007-2008 Actel Corporation. All rights reserved.
|
||||
*
|
||||
* SmartFusion microcontroller subsystem I2C bare metal software driver
|
||||
* implementation.
|
||||
*
|
||||
* SVN $Revision: 2152 $
|
||||
* SVN $Date: 2010-02-11 14:44:11 +0000 (Thu, 11 Feb 2010) $
|
||||
*/
|
||||
#include "i2c.h"
|
||||
#include "../../CMSIS/mss_assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* I2C transaction direction.
|
||||
*/
|
||||
#define WRITE_DIR 0
|
||||
#define READ_DIR 1
|
||||
|
||||
/* -- TRANSACTIONS TYPES -- */
|
||||
#define NO_TRANSACTION 0
|
||||
#define MASTER_WRITE_TRANSACTION 1
|
||||
#define MASTER_READ_TRANSACTION 2
|
||||
#define MASTER_RANDOM_READ_TRANSACTION 3
|
||||
#define WRITE_SLAVE_TRANSACTION 4
|
||||
#define READ_SLAVE_TRANSACTION 5
|
||||
#define RANDOM_READ_SLAVE_TRANSACTION 6
|
||||
|
||||
|
||||
/* -- SMBUS H/W STATES -- */
|
||||
/* -- MASTER STATES -- */
|
||||
#define ST_START 0x08 /* start condition sent */
|
||||
#define ST_RESTART 0x10 /* repeated start */
|
||||
#define ST_SLAW_ACK 0x18 /* SLA+W sent, ack received */
|
||||
#define ST_SLAW_NACK 0x20 /* SLA+W sent, nack received */
|
||||
#define ST_TX_DATA_ACK 0x28 /* Data sent, ACK'ed */
|
||||
#define ST_TX_DATA_NACK 0x30 /* Data sent, NACK'ed */
|
||||
#define ST_LOST_ARB 0x38 /* Master lost arbitration */
|
||||
#define ST_SLAR_ACK 0x40 /* SLA+R sent, ACK'ed */
|
||||
#define ST_SLAR_NACK 0x48 /* SLA+R sent, NACK'ed */
|
||||
#define ST_RX_DATA_ACK 0x50 /* Data received, ACK sent */
|
||||
#define ST_RX_DATA_NACK 0x58 /* Data received, NACK sent */
|
||||
|
||||
/* -- SLAVE STATES -- */
|
||||
#define ST_SLAVE_SLAW 0x60 /* SLA+W received */
|
||||
#define ST_SLAVE_SLAR_ACK 0xA8 /* SLA+R received, ACK returned */
|
||||
#define ST_SLV_LA 0x68 /* Slave lost arbitration */
|
||||
#define ST_GCA 0x70 /* GCA received */
|
||||
#define ST_GCA_LA 0x78 /* GCA lost arbitration */
|
||||
#define ST_RDATA 0x80 /* Data received */
|
||||
#define ST_SLA_NACK 0x88 /* Slave addressed, NACK returned */
|
||||
#define ST_GCA_ACK 0x90 /* Previously addresses with GCA, data ACKed */
|
||||
#define ST_GCA_NACK 0x98 /* GCA addressed, NACK returned */
|
||||
#define ST_RSTOP 0xA0 /* Stop received */
|
||||
#define ST_REPEAT 0xA0 /* Repeated start received */
|
||||
#define ST_SLAR_ACKS 0xA8 /* Slave read received, ACKed */
|
||||
#define ST_SLARW_LA 0xB0 /* Arbitration lost */
|
||||
#define ST_RACK 0xB8 /* Byte sent, ACK received */
|
||||
#define ST_SLAVE_RNACK 0xC0 /* Byte sent, NACK received */
|
||||
#define ST_FINAL 0xC8 /* Final byte sent, ACK received */
|
||||
#define ST_BERR 0x00 /* Error on the bus */
|
||||
#define ST_SLV_RST 0xD8 /* Slave reset state */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
static uint32_t disable_interrupts( void );
|
||||
static void restore_interrupts( uint32_t primask );
|
||||
static void mss_i2c_isr( mss_i2c_instance_t * this_i2c );
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
mss_i2c_instance_t g_mss_i2c0;
|
||||
mss_i2c_instance_t g_mss_i2c1;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_init()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_I2C_init
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t ser_address,
|
||||
mss_i2c_clock_divider_t ser_clock_speed
|
||||
)
|
||||
{
|
||||
uint_fast16_t clock_speed = ser_clock_speed;
|
||||
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
if ( this_i2c == &g_mss_i2c0 )
|
||||
{
|
||||
this_i2c->irqn = I2C0_IRQn;
|
||||
this_i2c->hw_reg = I2C0;
|
||||
this_i2c->hw_reg_bit = I2C0_BITBAND;
|
||||
|
||||
/* reset I2C0 */
|
||||
SYSREG->SOFT_RST_CR |= SYSREG_I2C0_SOFTRESET_MASK;
|
||||
/* Clear any previously pended I2C0 interrupt */
|
||||
NVIC_ClearPendingIRQ( I2C0_IRQn );
|
||||
/* Take I2C0 out of reset. */
|
||||
SYSREG->SOFT_RST_CR &= ~SYSREG_I2C0_SOFTRESET_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
this_i2c->irqn = I2C1_IRQn;
|
||||
this_i2c->hw_reg = I2C1;
|
||||
this_i2c->hw_reg_bit = I2C1_BITBAND;
|
||||
|
||||
/* reset I2C1 */
|
||||
SYSREG->SOFT_RST_CR |= SYSREG_I2C1_SOFTRESET_MASK;
|
||||
/* Clear any previously pended I2C1 interrupt */
|
||||
NVIC_ClearPendingIRQ( I2C1_IRQn );
|
||||
/* Take I2C1 out of reset. */
|
||||
SYSREG->SOFT_RST_CR &= ~SYSREG_I2C1_SOFTRESET_MASK;
|
||||
}
|
||||
|
||||
this_i2c->transaction = NO_TRANSACTION;
|
||||
|
||||
this_i2c->ser_address = ser_address;
|
||||
|
||||
this_i2c->tx_buffer = 0;
|
||||
this_i2c->tx_size = 0;
|
||||
this_i2c->tx_idx = 0;
|
||||
|
||||
this_i2c->rx_buffer = 0;
|
||||
this_i2c->rx_size = 0;
|
||||
this_i2c->rx_idx = 0;
|
||||
|
||||
this_i2c->status = MSS_I2C_SUCCESS;
|
||||
|
||||
this_i2c->random_read_addr = 0;
|
||||
|
||||
this_i2c->slave_write_handler = 0;
|
||||
this_i2c->slave_mem_offset_length = 0;
|
||||
|
||||
this_i2c->hw_reg_bit->CTRL_ENS1 = 0x01; /* set enable bit */
|
||||
this_i2c->hw_reg_bit->CTRL_CR2 = (clock_speed >> 2) & 0x01;
|
||||
this_i2c->hw_reg_bit->CTRL_CR1 = (clock_speed >> 1) & 0x01;
|
||||
this_i2c->hw_reg_bit->CTRL_CR0 = clock_speed & 0x01;
|
||||
this_i2c->hw_reg->ADDR = this_i2c->ser_address;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_set_slave_mem_offset_length()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_I2C_set_slave_mem_offset_length
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t offset_length
|
||||
)
|
||||
{
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
this_i2c->slave_mem_offset_length = offset_length;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_register_write_handler()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_I2C_register_write_handler
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
mss_i2c_slave_wr_handler_t handler
|
||||
)
|
||||
{
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
this_i2c->slave_write_handler = handler;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_write()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_I2C_write
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t serial_addr,
|
||||
const uint8_t * write_buffer,
|
||||
uint16_t write_size,
|
||||
uint8_t options
|
||||
)
|
||||
{
|
||||
volatile uint8_t stat_ctrl;
|
||||
uint8_t serial_interrupt;
|
||||
|
||||
uint32_t primask;
|
||||
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
primask = disable_interrupts();
|
||||
|
||||
this_i2c->transaction = MASTER_WRITE_TRANSACTION;
|
||||
|
||||
this_i2c->target_addr = serial_addr;
|
||||
this_i2c->dir = WRITE_DIR;
|
||||
this_i2c->tx_buffer = write_buffer;
|
||||
this_i2c->tx_size = write_size;
|
||||
this_i2c->tx_idx = 0;
|
||||
|
||||
this_i2c->status = MSS_I2C_IN_PROGRESS;
|
||||
this_i2c->options = options;
|
||||
|
||||
/* Clear interrupts if required (depends on repeated starts).*/
|
||||
serial_interrupt = this_i2c->hw_reg_bit->CTRL_SI;
|
||||
this_i2c->hw_reg_bit->CTRL_STA = 0x01;
|
||||
|
||||
if ( serial_interrupt != 0 )
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_SI = 0x00;
|
||||
NVIC_ClearPendingIRQ( this_i2c->irqn );
|
||||
}
|
||||
|
||||
stat_ctrl = this_i2c->hw_reg->STATUS;
|
||||
|
||||
NVIC_EnableIRQ( this_i2c->irqn );
|
||||
|
||||
restore_interrupts( primask );
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_read()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_I2C_read
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t serial_addr,
|
||||
uint8_t * read_buffer,
|
||||
uint16_t read_size,
|
||||
uint8_t options
|
||||
)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
if ( read_size > 0 )
|
||||
{
|
||||
volatile uint8_t stat_ctrl;
|
||||
uint8_t serial_interrupt;
|
||||
|
||||
primask = disable_interrupts();
|
||||
|
||||
this_i2c->transaction = MASTER_READ_TRANSACTION;
|
||||
|
||||
this_i2c->target_addr = serial_addr;
|
||||
this_i2c->dir = READ_DIR;
|
||||
this_i2c->rx_buffer = read_buffer;
|
||||
this_i2c->rx_size = read_size;
|
||||
this_i2c->rx_idx = 0;
|
||||
|
||||
this_i2c->status = MSS_I2C_IN_PROGRESS;
|
||||
|
||||
this_i2c->options = options;
|
||||
|
||||
/* Clear interrupts if required (depends on repeated starts).*/
|
||||
serial_interrupt = this_i2c->hw_reg_bit->CTRL_SI;
|
||||
this_i2c->hw_reg_bit->CTRL_STA = 0x01;
|
||||
|
||||
if ( serial_interrupt != 0 )
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_SI = 0x00;
|
||||
NVIC_ClearPendingIRQ( this_i2c->irqn );
|
||||
}
|
||||
|
||||
stat_ctrl = this_i2c->hw_reg->STATUS;
|
||||
|
||||
NVIC_EnableIRQ( this_i2c->irqn );
|
||||
|
||||
restore_interrupts( primask );
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_write_read()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_I2C_write_read
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t serial_addr,
|
||||
const uint8_t * addr_offset,
|
||||
uint16_t offset_size,
|
||||
uint8_t * read_buffer,
|
||||
uint16_t read_size,
|
||||
uint8_t options
|
||||
)
|
||||
{
|
||||
volatile uint8_t stat_ctrl;
|
||||
uint8_t serial_interrupt;
|
||||
uint32_t primask;
|
||||
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
primask = disable_interrupts();
|
||||
|
||||
this_i2c->transaction = MASTER_RANDOM_READ_TRANSACTION;
|
||||
this_i2c->target_addr = serial_addr;
|
||||
this_i2c->dir = WRITE_DIR;
|
||||
this_i2c->tx_buffer = addr_offset;
|
||||
this_i2c->tx_size = offset_size;
|
||||
this_i2c->tx_idx = 0;
|
||||
|
||||
this_i2c->rx_buffer = read_buffer;
|
||||
this_i2c->rx_size = read_size;
|
||||
this_i2c->rx_idx = 0;
|
||||
|
||||
this_i2c->status = MSS_I2C_IN_PROGRESS;
|
||||
this_i2c->options = options;
|
||||
|
||||
/* Clear interrupts if required (depends on repeated starts).*/
|
||||
serial_interrupt = this_i2c->hw_reg_bit->CTRL_SI;
|
||||
this_i2c->hw_reg_bit->CTRL_STA = 0x01;
|
||||
|
||||
if ( serial_interrupt != 0 )
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_SI = 0x00;
|
||||
NVIC_ClearPendingIRQ( this_i2c->irqn );
|
||||
}
|
||||
|
||||
stat_ctrl = this_i2c->hw_reg->STATUS;
|
||||
|
||||
NVIC_EnableIRQ( this_i2c->irqn );
|
||||
|
||||
restore_interrupts( primask );
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_set_slave_rx_buffer()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_I2C_set_slave_rx_buffer
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t * rx_buffer,
|
||||
uint16_t rx_size
|
||||
)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
primask = disable_interrupts();
|
||||
|
||||
this_i2c->rx_buffer = rx_buffer;
|
||||
this_i2c->rx_size = rx_size;
|
||||
this_i2c->rx_idx = 0;
|
||||
|
||||
restore_interrupts( primask );
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_get_status()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
mss_i2c_status_t MSS_I2C_get_status
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c
|
||||
)
|
||||
{
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
return this_i2c->status;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_set_slave_tx_buffer()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_I2C_set_slave_tx_buffer
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t * tx_buffer,
|
||||
uint16_t tx_size
|
||||
)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
primask = disable_interrupts();
|
||||
|
||||
this_i2c->tx_buffer = tx_buffer;
|
||||
this_i2c->tx_size = tx_size;
|
||||
this_i2c->tx_idx = 0;
|
||||
|
||||
restore_interrupts( primask );
|
||||
|
||||
/* Set the assert acknowledge bit. */
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x01;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_enable_slave_rx()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_I2C_enable_slave_rx
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c
|
||||
)
|
||||
{
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
/* Set the assert acknowledge bit. */
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x01;
|
||||
/* accept GC addressing. */
|
||||
this_i2c->hw_reg_bit->ADDR_GC = 0x01;
|
||||
|
||||
NVIC_EnableIRQ( this_i2c->irqn );
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS_I2C_wait_complete()
|
||||
* See "mss_i2c.h" for details of how to use this function.
|
||||
*/
|
||||
mss_i2c_status_t MSS_I2C_wait_complete
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c
|
||||
)
|
||||
{
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
while ( this_i2c->status == MSS_I2C_IN_PROGRESS )
|
||||
{
|
||||
/* Wait for transaction to compltete.*/
|
||||
;
|
||||
}
|
||||
return this_i2c->status;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MSS I2C interrupt service routine.
|
||||
*------------------------------------------------------------------------------
|
||||
* Parameters:
|
||||
*
|
||||
* mss_i2c_instance_t * this_i2c:
|
||||
* Pointer to the mss_i2c_instance_t data structure holding all data related to
|
||||
* the MSS I2C instance that generated the interrupt.
|
||||
*/
|
||||
static void mss_i2c_isr
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c
|
||||
)
|
||||
{
|
||||
volatile uint8_t status;
|
||||
uint8_t data;
|
||||
uint8_t hold_bus;
|
||||
uint8_t clear_irq = 1;
|
||||
|
||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||
|
||||
status = this_i2c->hw_reg->STATUS;
|
||||
|
||||
switch( status )
|
||||
{
|
||||
/************** MASTER TRANSMITTER / RECEIVER *******************/
|
||||
|
||||
case ST_START: /* start has been xmt'd */
|
||||
case ST_RESTART: /* repeated start has been xmt'd */
|
||||
this_i2c->hw_reg_bit->CTRL_STA = 0x0;
|
||||
this_i2c->hw_reg->DATA = this_i2c->target_addr;
|
||||
this_i2c->hw_reg_bit->DATA_DIR = this_i2c->dir;
|
||||
|
||||
this_i2c->tx_idx = 0;
|
||||
this_i2c->rx_idx = 0;
|
||||
break;
|
||||
|
||||
case ST_LOST_ARB:
|
||||
/* Set start bit. Let's keep trying! Don't give up! */
|
||||
this_i2c->hw_reg_bit->CTRL_STA = 0x01;
|
||||
break;
|
||||
|
||||
/******************* MASTER TRANSMITTER *************************/
|
||||
case ST_SLAW_ACK:
|
||||
/* call address has been xmt'd with ACK, time to send data byte and increment index. */
|
||||
if ( this_i2c->tx_idx < this_i2c->tx_size )
|
||||
{
|
||||
/* load data byte */
|
||||
this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_DisableIRQ( this_i2c->irqn );
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_SLAW_NACK:
|
||||
#if 0
|
||||
/* SLA+W has been transmitted; not ACK has been received - let's stop. */
|
||||
this_i2c->hw_reg_bit->CTRL_STO = 0x01;
|
||||
this_i2c->status = MSS_I2C_FAILED;
|
||||
#endif
|
||||
/* call address has been xmt'd with ACK, time to send data byte and increment index. */
|
||||
if ( this_i2c->tx_idx < this_i2c->tx_size )
|
||||
{
|
||||
/* load data byte */
|
||||
this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_DisableIRQ( this_i2c->irqn );
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_TX_DATA_ACK:
|
||||
/* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */
|
||||
if (this_i2c->tx_idx < this_i2c->tx_size)
|
||||
{
|
||||
this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
|
||||
}
|
||||
else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION )
|
||||
{
|
||||
/* We are finished sending the address offset part of a random read transaction.
|
||||
* It is is time to send a restart in order to change direction. */
|
||||
this_i2c->dir = READ_DIR;
|
||||
this_i2c->hw_reg_bit->CTRL_STA = 0x01;
|
||||
}
|
||||
else /* done sending. let's stop */
|
||||
{
|
||||
hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS;
|
||||
if ( hold_bus == 0 )
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_DisableIRQ( this_i2c->irqn );
|
||||
clear_irq = 0;
|
||||
}
|
||||
this_i2c->status = MSS_I2C_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_TX_DATA_NACK:
|
||||
#if 0
|
||||
/* data byte SENT, ACK to be received
|
||||
* In fact, this means we've received a NACK (This may not be
|
||||
* obvious, but if we've rec'd an ACK then we would be in state
|
||||
* 0x28!) hence, let's send a stop bit
|
||||
*/
|
||||
this_i2c->hw_reg_bit->CTRL_STO = 0x01;
|
||||
this_i2c->status = MSS_I2C_FAILED;
|
||||
#endif
|
||||
/* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */
|
||||
if (this_i2c->tx_idx < this_i2c->tx_size)
|
||||
{
|
||||
this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
|
||||
}
|
||||
else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION )
|
||||
{
|
||||
/* We are finished sending the address offset part of a random read transaction.
|
||||
* It is is time to send a restart in order to change direction. */
|
||||
this_i2c->dir = READ_DIR;
|
||||
this_i2c->hw_reg_bit->CTRL_STA = 0x01;
|
||||
}
|
||||
else /* done sending. let's stop */
|
||||
{
|
||||
hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS;
|
||||
if ( hold_bus == 0 )
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_DisableIRQ( this_i2c->irqn );
|
||||
clear_irq = 0;
|
||||
}
|
||||
this_i2c->status = MSS_I2C_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
/********************* MASTER (or slave?) RECEIVER *************************/
|
||||
|
||||
/* STATUS codes 08H, 10H, 38H are all covered in MTX mode */
|
||||
case ST_SLAR_ACK: /* SLA+R tx'ed. */
|
||||
/* Let's make sure we ACK the first data byte received (set AA bit in CTRL) unless
|
||||
* the next byte is the last byte of the read transaction.
|
||||
*/
|
||||
if( this_i2c->rx_size > 1 )
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x00;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_SLAR_NACK: /* SLA+R tx'ed; let's release the bus (send a stop condition) */
|
||||
this_i2c->hw_reg_bit->CTRL_STO = 0x01;
|
||||
this_i2c->status = MSS_I2C_FAILED;
|
||||
break;
|
||||
|
||||
case ST_RX_DATA_ACK: /* Data byte received, ACK returned */
|
||||
/* First, get the data */
|
||||
this_i2c->rx_buffer[this_i2c->rx_idx++] = this_i2c->hw_reg->DATA;
|
||||
|
||||
if( this_i2c->rx_idx >= this_i2c->rx_size - 1)
|
||||
{
|
||||
/* If we're at the second last byte, let's set AA to 0 so
|
||||
* we return a NACK at the last byte. */
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x00;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_RX_DATA_NACK: /* Data byte received, NACK returned */
|
||||
/* Get the data, then send a stop condition */
|
||||
this_i2c->rx_buffer[this_i2c->rx_idx++] = this_i2c->hw_reg->DATA;
|
||||
|
||||
hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS;
|
||||
if ( hold_bus == 0 )
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_DisableIRQ( this_i2c->irqn );
|
||||
clear_irq = 0;
|
||||
}
|
||||
|
||||
this_i2c->status = MSS_I2C_SUCCESS;
|
||||
break;
|
||||
|
||||
/******************** SLAVE RECEIVER **************************/
|
||||
case ST_GCA_NACK: /* NACK after, GCA addressing */
|
||||
case ST_SLA_NACK: /* Get Data, but also re-enable AA (assert ack) bit for future transmissions */
|
||||
if ( this_i2c->rx_buffer != 0 )
|
||||
{
|
||||
this_i2c->rx_buffer[this_i2c->rx_idx] = this_i2c->hw_reg->DATA;
|
||||
}
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x01;
|
||||
break;
|
||||
|
||||
case ST_SLAVE_SLAW: /* SLA+W received, ACK returned */
|
||||
this_i2c->transaction = WRITE_SLAVE_TRANSACTION;
|
||||
this_i2c->rx_idx = 0;
|
||||
this_i2c->random_read_addr = 0;
|
||||
#ifndef INCLUDE_SLA_IN_RX_PAYLOAD
|
||||
/* Only break from this case if the slave address must NOT be included at the
|
||||
* beginning of the received write data. */
|
||||
break;
|
||||
#endif
|
||||
case ST_GCA_ACK: /* DATA received; ACK sent after GCA */
|
||||
case ST_RDATA: /* DATA received; must clear DATA register */
|
||||
if (this_i2c->rx_idx >= this_i2c->rx_size - 2)
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x00; /* send a NACK when done (next reception) */
|
||||
}
|
||||
data = this_i2c->hw_reg->DATA;
|
||||
this_i2c->rx_buffer[this_i2c->rx_idx++] = data;
|
||||
this_i2c->random_read_addr = (this_i2c->random_read_addr << 8) + data;
|
||||
|
||||
break;
|
||||
|
||||
case ST_RSTOP:
|
||||
/* STOP or repeated START occured. */
|
||||
/* We cannot be sure if the transaction has actually completed as
|
||||
* this hardware state reports that either a STOP or repeated START
|
||||
* condition has occured. We assume that this is a repeated START
|
||||
* if the transaction was a write from the master to this point.*/
|
||||
if ( this_i2c->transaction == WRITE_SLAVE_TRANSACTION )
|
||||
{
|
||||
if ( this_i2c->rx_idx == this_i2c->slave_mem_offset_length )
|
||||
{
|
||||
this_i2c->transaction = RANDOM_READ_SLAVE_TRANSACTION;
|
||||
this_i2c->tx_idx = this_i2c->random_read_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call the slave's write transaction handler if it exists. */
|
||||
if ( this_i2c->slave_write_handler != 0 )
|
||||
{
|
||||
mss_i2c_slave_handler_ret_t h_ret;
|
||||
h_ret = this_i2c->slave_write_handler( this_i2c->rx_buffer, (uint16_t)this_i2c->rx_idx );
|
||||
if ( MSS_I2C_REENABLE_SLAVE_RX == h_ret )
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Mark any previous master write transaction as complete. */
|
||||
this_i2c->status = MSS_I2C_SUCCESS;
|
||||
break;
|
||||
|
||||
case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */
|
||||
case ST_SLV_LA: /* Arbitr. lost (SLA rec'd) */
|
||||
case ST_GCA: /* General call address received, ACK returned */
|
||||
case ST_GCA_LA: /* Arbitr. lost (GCA rec'd) */
|
||||
/* do nothing */
|
||||
break;
|
||||
|
||||
/****************** SLAVE TRANSMITTER **************************/
|
||||
case ST_SLAVE_SLAR_ACK: /* SLA+R received, ACK returned */
|
||||
case ST_SLARW_LA: /* Arbitration lost, and: */
|
||||
case ST_RACK: /* Data tx'ed, ACK received */
|
||||
if ( status == ST_SLAVE_SLAR_ACK )
|
||||
{
|
||||
this_i2c->transaction = READ_SLAVE_TRANSACTION;
|
||||
this_i2c->random_read_addr = 0;
|
||||
}
|
||||
/* Load the data, and determine if it is the last one */
|
||||
this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
|
||||
if (this_i2c->tx_idx >= this_i2c->tx_size - 1) /* last byte? */
|
||||
{
|
||||
this_i2c->hw_reg_bit->CTRL_AA = 0x00;
|
||||
/* Next read transaction will result in slave's transmit buffer
|
||||
* being sent from the first byte. */
|
||||
this_i2c->tx_idx = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_SLAVE_RNACK: /* Data byte has been transmitted; not-ACK has been received. */
|
||||
/* We assume that the transaction will be stopped by the master.
|
||||
* Reset tx_idx so that a subsequent read will result in the slave's
|
||||
* transmit buffer being sent from the first byte. */
|
||||
this_i2c->tx_idx = 0;
|
||||
break;
|
||||
|
||||
case ST_FINAL: /* Last Data byte tx'ed, ACK recieved */
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
if ( clear_irq )
|
||||
{
|
||||
/* clear interrupt. */
|
||||
this_i2c->hw_reg_bit->CTRL_SI = 0x00;
|
||||
}
|
||||
|
||||
/* Read the status register to ensure the last I2C registers write took place
|
||||
* in a system built around a bus making use of posted writes. */
|
||||
status = this_i2c->hw_reg->STATUS;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
uint32_t disable_interrupts( void )
|
||||
{
|
||||
uint32_t primask;
|
||||
primask = __get_PRIMASK();
|
||||
return primask;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void restore_interrupts( uint32_t primask )
|
||||
{
|
||||
__set_PRIMASK( primask );
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void I2C0_IRQHandler( void )
|
||||
#else
|
||||
void I2C0_IRQHandler( void )
|
||||
#endif
|
||||
{
|
||||
mss_i2c_isr( &g_mss_i2c0 );
|
||||
NVIC_ClearPendingIRQ( I2C0_IRQn );
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void I2C1_IRQHandler( void )
|
||||
#else
|
||||
void I2C1_IRQHandler( void )
|
||||
#endif
|
||||
{
|
||||
mss_i2c_isr( &g_mss_i2c1 );
|
||||
NVIC_ClearPendingIRQ( I2C1_IRQn );
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
775
Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/I2C/i2c.h
Normal file
775
Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/I2C/i2c.h
Normal file
|
@ -0,0 +1,775 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2007-2008 Actel Corporation. All rights reserved.
|
||||
*
|
||||
* SmartFusion microcontroller subsystem I2C bare metal software driver public
|
||||
* API.
|
||||
*
|
||||
* SVN $Revision: 2150 $
|
||||
* SVN $Date: 2010-02-11 14:39:24 +0000 (Thu, 11 Feb 2010) $
|
||||
*/
|
||||
/*=========================================================================*//**
|
||||
@mainpage SmartFusion MSS I2C Bare Metal Driver.
|
||||
|
||||
@section intro_sec Introduction
|
||||
The SmartFusion™ microcontroller subsystem (MSS) includes two I2C peripherals
|
||||
for serial communication. This driver provides a set of functions for
|
||||
controlling the MSS I2Cs as part of a bare metal system where no operating
|
||||
system is available. These drivers can be adapted for use as part of an
|
||||
operating system, but the implementation of the adaptation layer between this
|
||||
driver and the operating system's driver model is outside the scope of this
|
||||
driver.
|
||||
|
||||
@section hw_dependencies Hardware Flow Dependencies
|
||||
The configuration of all features of the MSS I2Cs is covered by this driver
|
||||
with the exception of the SmartFusion IOMUX configuration. SmartFusion allows
|
||||
multiple non-concurrent uses of some external pins through IOMUX configuration.
|
||||
This feature allows optimization of external pin usage by assigning external
|
||||
pins for use by either the microcontroller subsystem or the FPGA fabric. The
|
||||
MSS I2Cs serial signals are routed through IOMUXes to the SmartFusion device
|
||||
external pins. These IOMUXes are automatically configured correctly by the MSS
|
||||
configurator tool in the hardware flow when the MSS I2Cs are enabled in that
|
||||
tool. You must ensure that the MSS I2Cs are enabled by the MSS configurator
|
||||
tool in the hardware flow; otherwise the serial inputs and outputs will not be
|
||||
connected to the chip's external pins. For more information on IOMUX, refer to
|
||||
the IOMUX section of the SmartFusion Datasheet.
|
||||
The base address, register addresses and interrupt number assignment for the
|
||||
MSS I2C blocks are defined as constants in the SmartFusion CMSIS-PAL. You must
|
||||
ensure that the SmartFusion CMSIS-PAL is either included in the software tool
|
||||
chain used to build your project or is included in your project.
|
||||
|
||||
@section theory_op Theory of Operation
|
||||
The MSS I2C driver functions are grouped into the following categories:
|
||||
• Initialization and configuration functions
|
||||
• Interrupt control
|
||||
• I2C master operations – functions to handle write, read and write-read transactions
|
||||
• I2C slave operations – functions to handle write, read and write-read transactions
|
||||
|
||||
Initialization and Configuration
|
||||
The MSS I2C driver is initialized through a call to the MSS_I2C_init()
|
||||
function. This function takes the MSS I2C's configuration as parameters. The
|
||||
MSS_I2C_init() function must be called before any other MSS I2C driver
|
||||
functions can be called. The first parameter of the MSS_I2C_init() function
|
||||
is a pointer to one of two global data structures used by the driver to
|
||||
store state information for each MSS I2C. A pointer to these data structures
|
||||
is also used as first parameter to any of the driver functions to identify
|
||||
which MSS I2C will be used by the called function. The names of these two
|
||||
data structures are g_mss_i2c0 and g_mss_i2c1. Therefore any call to an MSS
|
||||
I2C driver function should be of the form MSS_I2C_function_name( &g_mss_i2c0, ... )
|
||||
or MSS_I2C_function_name( &g_mss_i2c1, ... ).
|
||||
The MSS_I2C_init() function call for each MSS I2C also takes the I2C serial
|
||||
address assigned to the MSS I2C and the serial clock divider to be used to
|
||||
generate its I2C clock as configuration parameters.
|
||||
|
||||
Interrupt Control
|
||||
The MSS I2C driver is interrupt driven and it enables and disables the
|
||||
generation of interrupts by MSS I2C at various times when it is operating.
|
||||
The driver automatically handles MSS I2C interrupts internally, including
|
||||
enabling disabling and clearing MSS I2C interrupts in the Cortex-M3
|
||||
interrupt controller when required.
|
||||
The function MSS_I2C_register_write_handler() is used to register a write
|
||||
handler function with the MSS I2C driver that it will call on completion of
|
||||
an I2C write transaction by the MSS I2C slave. It is your responsibility to
|
||||
create and register the implementation of this handler function that will
|
||||
process or trigger the processing of the received data.
|
||||
Transaction Types
|
||||
The MSS I2C driver is designed to handle three types of I2C transaction:
|
||||
• Write transactions
|
||||
• Read transactions
|
||||
• Write-read transactions
|
||||
|
||||
Write transaction
|
||||
The master I2C device initiates a write transaction by sending a START bit
|
||||
as soon as the bus becomes free. The START bit is followed by the 7-bit
|
||||
serial address of the target slave device followed by the read/write bit
|
||||
indicating the direction of the transaction. The slave acknowledges receipt
|
||||
of it’s address with an acknowledge bit. The master sends data one byte at
|
||||
a time to the slave, which must acknowledge receipt of each byte for the
|
||||
next byte to be sent. The master sends a STOP bit to complete the transaction.
|
||||
The slave can abort the transaction by replying with a non-acknowledge bit
|
||||
instead of an acknowledge.
|
||||
The application programmer can choose not to send a STOP bit at the end of
|
||||
the transaction causing the next transaction to begin with a repeated START bit.
|
||||
|
||||
Read transaction
|
||||
The master I2C device initiates a read transaction by sending a START bit
|
||||
as soon as the bus becomes free. The START bit is followed by the 7-bit
|
||||
serial address of the target slave device followed by the read/write bit
|
||||
indicating the direction of the transaction. The slave acknowledges receipt
|
||||
of it’s slave address with an acknowledge bit. The slave sends data one byte
|
||||
at a time to the master, which must acknowledge receipt of each byte for the
|
||||
next byte to be sent. The master sends a non-acknowledge bit following the
|
||||
last byte it wishes to read followed by a STOP bit.
|
||||
The application programmer can choose not to send a STOP bit at the end of
|
||||
the transaction causing the next transaction to begin with a repeated START bit.
|
||||
|
||||
Write-read transaction
|
||||
The write-read transaction is a combination of a write transaction
|
||||
immediately followed by a read transaction. There is no STOP bit between
|
||||
the write and read phases of a write-read transaction. A repeated START
|
||||
bit is sent between the write and read phases.
|
||||
The write-read transaction is typically used to send a command or offset
|
||||
in the write transaction specifying the logical data to be transferred
|
||||
during the read phase.
|
||||
The application programmer can choose not to send a STOP bit at the end of
|
||||
the transaction causing the next transaction to begin with a repeated START bit.
|
||||
|
||||
Master Operations
|
||||
The application can use the MSS_I2C_write(), MSS_I2C_read() and MSS_I2C_write_read()
|
||||
functions to initiate an I2C bus transaction. The application can then wait
|
||||
for the transaction to complete using the MSS_I2C_wait_complete() function
|
||||
or poll the status of the I2C transaction using the MSS_I2C_get_status()
|
||||
function until it returns a value different from MSS_I2C_IN_PROGRESS.
|
||||
|
||||
Slave Operations
|
||||
The configuration of the MSS I2C driver to operate as an I2C slave requires
|
||||
the use of the following functions:
|
||||
• MSS_I2C_set_slave_tx_buffer()
|
||||
• MSS_I2C_set_slave_rx_buffer()
|
||||
• MSS_I2C_set_slave_mem_offset_length()
|
||||
• MSS_I2C_register_write_handler()
|
||||
• MSS_I2C_enable_slave_rx()
|
||||
Use of all functions is not required if the slave I2C does not need to support
|
||||
all types of I2C read transactions. The subsequent sections list the functions
|
||||
that must be used to support each transaction type.
|
||||
|
||||
Responding to read transactions
|
||||
The following functions are used to configure the MSS I2C driver to respond
|
||||
to I2C read transactions:
|
||||
• MSS_I2C_set_slave_tx_buffer()
|
||||
• MSS_I2C_enable_slave_rx()
|
||||
The function MSS_I2C_set_slave_tx_buffer() specifies the data buffer that
|
||||
will be transmitted when the I2C slave is the target of an I2C read
|
||||
transaction. It is then up to the application to manage the content of that
|
||||
buffer to control the data that will be transmitted to the I2C master as a
|
||||
result of the read transaction.
|
||||
The function MSS_I2C_enable_slave_rx() enables the MSS I2C hardware instance
|
||||
to respond to I2C transactions. It must be called after the MSS I2C driver
|
||||
has been configured to respond to the required transaction types.
|
||||
|
||||
Responding to write transactions
|
||||
The following functions are used to configure the MSS I2C driver to respond
|
||||
to I2C write transactions:
|
||||
• MSS_I2C_set_slave_rx_buffer()
|
||||
• MSS_I2C_register_write_handler()
|
||||
• MSS_I2C_enable_slave_rx()
|
||||
The function MSS_I2C_set_slave_rx_buffer() specifies the data buffer that
|
||||
will be used to store the data received by the I2C slave when it is the
|
||||
target an I2C write transaction.
|
||||
The function MSS_I2C_register_write_handler() specifies the handler function
|
||||
that must be called on completion of the I2C write transaction. It is this
|
||||
handler function that will process or trigger the processing of the received
|
||||
data.
|
||||
The function MSS_I2C_enable_slave_rx() enables the MSS I2C hardware instance
|
||||
to respond to I2C transactions. It must be called after the MSS I2C driver
|
||||
has been configured to respond to the required transaction types.
|
||||
|
||||
Responding to write-read transactions
|
||||
The following functions are used to configure the MSS I2C driver to respond
|
||||
to write-read transactions:
|
||||
• MSS_I2C_set_slave_tx_buffer()
|
||||
• MSS_I2C_set_slave_rx_buffer()
|
||||
• MSS_I2C_set_slave_mem_offset_length()
|
||||
• MSS_I2C_enable_slave_rx()
|
||||
The function MSS_I2C_set_slave_mem_offset_length() specifies the number of
|
||||
bytes expected by the I2C slave during the write phase of the write-read
|
||||
transaction.
|
||||
The function MSS_I2C_set_slave_tx_buffer() specifies the data that will be
|
||||
transmitted to the I2C master during the read phase of the write-read
|
||||
transaction. The value received by the I2C slave during the write phase of
|
||||
the transaction will be used as an index into the transmit buffer specified
|
||||
by this function to decide which part of the transmit buffer will be
|
||||
transmitted to the I2C master as part of the read phase of the write-read
|
||||
transaction.
|
||||
The function MSS_I2C_set_slave_rx_buffer() specifies the data buffer that
|
||||
will be used to store the data received by the I2C slave during the write
|
||||
phase of the write-read transaction. This buffer must be at least large
|
||||
enough to accommodate the number of bytes specified through the
|
||||
MSS_I2C_set_slave_mem_offset_length() function.
|
||||
The function MSS_I2C_enable_slave_rx() enables the MSS I2C hardware
|
||||
instance to respond to I2C transactions. It must be called after the MSS
|
||||
I2C driver has been configured to respond to the required transaction types.
|
||||
*//*=========================================================================*/
|
||||
#ifndef I2C_H_
|
||||
#define I2C_H_
|
||||
|
||||
#include "../../CMSIS/a2fxxxm3.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The mss_i2c_clock_divider_t type is used to specify the divider to be applied
|
||||
to the MSS I2C BCLK signal in order to generate the I2C clock.
|
||||
*/
|
||||
typedef enum mss_i2c_clock_divider {
|
||||
MSS_I2C_PCLK_DIV_256 = 0,
|
||||
MSS_I2C_PCLK_DIV_224,
|
||||
MSS_I2C_PCLK_DIV_192,
|
||||
MSS_I2C_PCLK_DIV_160,
|
||||
MSS_I2C_PCLK_DIV_960,
|
||||
MSS_I2C_PCLK_DIV_120,
|
||||
MSS_I2C_PCLK_DIV_60,
|
||||
MSS_I2C_BCLK_DIV_8
|
||||
} mss_i2c_clock_divider_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_I2C_RELEASE_BUS constant is used to specify the options parameter to
|
||||
functions MSS_I2C_read(), MSS_I2C_write() and MSS_I2C_write_read() to indicate
|
||||
that a STOP bit must be generated at the end of the I2C transaction to release
|
||||
the bus.
|
||||
*/
|
||||
#define MSS_I2C_RELEASE_BUS 0x00
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_I2C_HOLD_BUS constant is used to specify the options parameter to
|
||||
functions MSS_I2C_read(), MSS_I2C_write() and MSS_I2C_write_read() to indicate
|
||||
that a STOP bit must not be generated at the end of the I2C transaction in
|
||||
order to retain the bus ownership. This will cause the next transaction to
|
||||
begin with a repeated START bit and no STOP bit between the transactions.
|
||||
*/
|
||||
#define MSS_I2C_HOLD_BUS 0x01
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The mss_i2c_status_t type is used to report the status of I2C transactions.
|
||||
*/
|
||||
typedef enum mss_i2c_status
|
||||
{
|
||||
MSS_I2C_SUCCESS = 0,
|
||||
MSS_I2C_IN_PROGRESS,
|
||||
MSS_I2C_FAILED
|
||||
} mss_i2c_status_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The mss_i2c_slave_handler_ret_t type is used by slave write handler functions
|
||||
to indicate whether the received data buffer should be released or not.
|
||||
*/
|
||||
typedef enum mss_i2c_slave_handler_ret {
|
||||
MSS_I2C_REENABLE_SLAVE_RX = 0,
|
||||
MSS_I2C_PAUSE_SLAVE_RX = 1
|
||||
} mss_i2c_slave_handler_ret_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Slave write handler functions prototype.
|
||||
------------------------------------------------------------------------------
|
||||
This defines the function prototype that must be followed by MSS I2C slave
|
||||
write handler functions. These functions are registered with the MSS I2C driver
|
||||
through the MSS_I2C_register_write_handler() function.
|
||||
|
||||
Declaring and Implementing Slave Write Handler Functions:
|
||||
Slave write handler functions should follow the following prototype:
|
||||
mss_i2c_slave_handler_ret_t write_handler( uint8_t * data, uint16_t size );
|
||||
|
||||
The data parameter is a pointer to a buffer (received data buffer) holding
|
||||
the data written to the MSS I2C slave.
|
||||
The size parameter is the number of bytes held in the received data buffer.
|
||||
Handler functions must return one of the following values:
|
||||
• MSS_I2C_REENABLE_SLAVE_RX
|
||||
• MSS_I2C_PAUSE_SLAVE_RX.
|
||||
If the handler function returns MSS_I2C_REENABLE_SLAVE_RX, the driver will
|
||||
release the received data buffer and allow further I2C write transactions to
|
||||
the MSS I2C slave to take place.
|
||||
If the handler function returns MSS_I2C_PAUSE_SLAVE_RX, the MSS I2C slave
|
||||
will respond to subsequent write requests with a non-acknowledge bit (NACK),
|
||||
until the received data buffer content has been processed by some other part
|
||||
of the software application.
|
||||
A call to MSS_I2C_enable_slave_rx() is required at some point after
|
||||
returning MSS_I2C_PAUSE_SLAVE_RX in order to release the received data
|
||||
buffer so it can be used to store data received by subsequent I2C write
|
||||
transactions.
|
||||
*/
|
||||
typedef mss_i2c_slave_handler_ret_t (*mss_i2c_slave_wr_handler_t)( uint8_t *, uint16_t );
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
mss_i2c_instance_t
|
||||
------------------------------------------------------------------------------
|
||||
There is one instance of this structure for each of the microcontroller
|
||||
subsystem's I2Cs. Instances of this structure are used to identify a specific
|
||||
I2C. A pointer to an instance of the mss_i2c_instance_t structure is passed as
|
||||
the first parameter to MSS I2C driver functions to identify which I2C should
|
||||
perform the requested operation.
|
||||
*/
|
||||
typedef struct mss_i2c_instance
|
||||
{
|
||||
uint_fast8_t ser_address;
|
||||
/* Transmit related info:*/
|
||||
uint_fast8_t target_addr;
|
||||
|
||||
/* Current transaction type (WRITE, READ, RANDOM_READ)*/
|
||||
uint8_t transaction;
|
||||
|
||||
uint_fast16_t random_read_addr;
|
||||
|
||||
uint8_t options;
|
||||
|
||||
/* I2C hardware instance identification */
|
||||
IRQn_Type irqn;
|
||||
I2C_TypeDef * hw_reg;
|
||||
I2C_BitBand_TypeDef * hw_reg_bit;
|
||||
|
||||
/* TX INFO: */
|
||||
const uint8_t * tx_buffer;
|
||||
uint_fast16_t tx_size;
|
||||
uint_fast16_t tx_idx;
|
||||
uint_fast8_t dir;
|
||||
|
||||
/* RX INFO: */
|
||||
uint8_t * rx_buffer;
|
||||
uint_fast16_t rx_size;
|
||||
uint_fast16_t rx_idx;
|
||||
|
||||
/* status variable: */
|
||||
volatile mss_i2c_status_t status;
|
||||
|
||||
/* Slave data: */
|
||||
uint_fast8_t slave_mem_offset_length;
|
||||
mss_i2c_slave_wr_handler_t slave_write_handler;
|
||||
|
||||
} mss_i2c_instance_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
This instance of mss_i2c_instance_t holds all data related to the operations
|
||||
performed by MSS I2C 0. A pointer to g_mss_i2c0 is passed as the first
|
||||
parameter to MSS I2C driver functions to indicate that MSS I2C 0 should
|
||||
perform the requested operation.
|
||||
*/
|
||||
extern mss_i2c_instance_t g_mss_i2c0;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
This instance of mss_i2c_instance_t holds all data related to the operations
|
||||
performed by MSS I2C 1. A pointer to g_mss_i2c1 is passed as the first
|
||||
parameter to MSS I2C driver functions to indicate that MSS I2C 1 should
|
||||
perform the requested operation.
|
||||
*/
|
||||
extern mss_i2c_instance_t g_mss_i2c1;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
MSS I2C initialisation routine.
|
||||
------------------------------------------------------------------------------
|
||||
The MSS_I2C_init() function initializes and configures hardware and data
|
||||
structures of one of the SmartFusion MSS I2Cs.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block to be initialized. There are two such
|
||||
data structures, g_mss_i2c0 and g_mss_i2c1, associated with MSS I2C 0 and
|
||||
MSS I2C 1 respectively. This parameter must point to either the g_mss_i2c0
|
||||
or g_mss_i2c1 global data structure defined within the I2C driver.
|
||||
|
||||
@param ser_address:
|
||||
This parameter sets the I2C serial address being initialized. It is the I2C
|
||||
bus address to which the MSS I2C instance will respond. Any 8 bit address is
|
||||
allowed.
|
||||
|
||||
@param ser_clock_speed:
|
||||
This parameter sets the I2C serial clock frequency. It selects the divider
|
||||
that will be used to generate the serial clock from the APB clock. It can be
|
||||
one of the following:
|
||||
• MSS_I2C_PCLK_DIV_256
|
||||
• MSS_I2C_PCLK_DIV_224
|
||||
• MSS_I2C_PCLK_DIV_192
|
||||
• MSS_I2C_PCLK_DIV_160
|
||||
• MSS_I2C_PCLK_DIV_960
|
||||
• MSS_I2C_PCLK_DIV_120
|
||||
• MSS_I2C_PCLK_DIV_60
|
||||
• MSS_I2C_BCLK_DIV_8
|
||||
*/
|
||||
void MSS_I2C_init
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t ser_address,
|
||||
mss_i2c_clock_divider_t ser_clock_speed
|
||||
);
|
||||
|
||||
/*******************************************************************************
|
||||
*******************************************************************************
|
||||
*
|
||||
* Master specific functions
|
||||
*
|
||||
* The following functions are only used within an I2C master's implementation.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
I2C master write function.
|
||||
------------------------------------------------------------------------------
|
||||
This function initiates an I2C master write transaction. This function returns
|
||||
immediately after initiating the transaction. The content of the write buffer
|
||||
passed as parameter should not be modified until the write transaction
|
||||
completes. It also means that the memory allocated for the write buffer should
|
||||
not be freed or go out of scope before the write completes. You can check for
|
||||
the write transaction completion using the MSS_I2C_status() function.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
|
||||
@param serial_addr:
|
||||
This parameter specifies the serial address of the target I2C device.
|
||||
|
||||
@param write_buffer:
|
||||
This parameter is a pointer to a buffer holding the data to be written to
|
||||
the target I2C device.
|
||||
Care must be taken not to release the memory used by this buffer before the
|
||||
write transaction completes. For example, it is not appropriate to return
|
||||
from a function allocating this buffer as an array variable before the write
|
||||
transaction completes as this would result in the buffer's memory being
|
||||
de-allocated from the stack when the function returns. This memory could
|
||||
then be subsequently reused and modified causing unexpected data to be
|
||||
written to the target I2C device.
|
||||
|
||||
@param write_size:
|
||||
Number of bytes held in the write_buffer to be written to the target I2C
|
||||
device.
|
||||
|
||||
@param options:
|
||||
The options parameter is used to indicate if the I2C bus should be released
|
||||
on completion of the write transaction. Using the MSS_I2C_RELEASE_BUS
|
||||
constant for the options parameter causes a STOP bit to be generated at the
|
||||
end of the write transaction causing the bus to be released for other I2C
|
||||
devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter
|
||||
prevents a STOP bit from being generated at the end of the write
|
||||
transaction, preventing other I2C devices from initiating a bus transaction.
|
||||
*/
|
||||
void MSS_I2C_write
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t serial_addr,
|
||||
const uint8_t * write_buffer,
|
||||
uint16_t write_size,
|
||||
uint8_t options
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
I2C master read.
|
||||
------------------------------------------------------------------------------
|
||||
This function initiates an I2C master read transaction. This function returns
|
||||
immediately after initiating the transaction.
|
||||
The content of the read buffer passed as parameter should not be modified
|
||||
until the read transaction completes. It also means that the memory allocated
|
||||
for the read buffer should not be freed or go out of scope before the read
|
||||
completes. You can check for the read transaction completion using the
|
||||
MSS_I2C_status() function.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
|
||||
@param serial_addr:
|
||||
This parameter specifies the serial address of the target I2C device.
|
||||
|
||||
@param read_buffer
|
||||
Pointer to a buffer where the data received from the target device will be
|
||||
stored.
|
||||
Care must be taken not to release the memory used by this buffer before the
|
||||
read transaction completes. For example, it is not appropriate to return
|
||||
from a function allocating this buffer as an array variable before the read
|
||||
transaction completes as this would result in the buffer's memory being
|
||||
de-allocated from the stack when the function returns. This memory could
|
||||
then be subsequently reallocated resulting in the read transaction
|
||||
corrupting the newly allocated memory.
|
||||
|
||||
@param read_size:
|
||||
This parameter is the number of bytes to read from the target device. This
|
||||
size must not exceed the size of the read_buffer buffer.
|
||||
|
||||
@param options:
|
||||
The options parameter is used to indicate if the I2C bus should be released
|
||||
on completion of the read transaction. Using the MSS_I2C_RELEASE_BUS
|
||||
constant for the options parameter causes a STOP bit to be generated at the
|
||||
end of the read transaction causing the bus to be released for other I2C
|
||||
devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter
|
||||
prevents a STOP bit from being generated at the end of the read transaction,
|
||||
preventing other I2C devices from initiating a bus transaction.
|
||||
*/
|
||||
void MSS_I2C_read
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t serial_addr,
|
||||
uint8_t * read_buffer,
|
||||
uint16_t read_size,
|
||||
uint8_t options
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
I2C master write-read
|
||||
------------------------------------------------------------------------------
|
||||
This function initiates an I2C write-read transaction where data is first
|
||||
written to the target device before issuing a restart condition and changing
|
||||
the direction of the I2C transaction in order to read from the target device.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
|
||||
@param serial_addr:
|
||||
This parameter specifies the serial address of the target I2C device.
|
||||
|
||||
@param addr_offset:
|
||||
This parameter is a pointer to the buffer containing the data that will be
|
||||
sent to the slave during the write phase of the write-read transaction. This
|
||||
data is typically used to specify an address offset specifying to the I2C
|
||||
slave device what data it must return during the read phase of the
|
||||
write-read transaction.
|
||||
|
||||
@param offset_size:
|
||||
This parameter specifies the number of offset bytes to be written during the
|
||||
write phase of the write-read transaction. This is typically the size of the
|
||||
buffer pointed to by the addr_offset parameter.
|
||||
|
||||
@param read_buffer:
|
||||
This parameter is a pointer to the buffer where the data read from the I2C
|
||||
slave will be stored.
|
||||
|
||||
@param read_size:
|
||||
This parameter specifies the number of bytes to read from the target I2C
|
||||
slave device. This size must not exceed the size of the buffer pointed to by
|
||||
the read_buffer parameter.
|
||||
|
||||
@param options:
|
||||
The options parameter is used to indicate if the I2C bus should be released
|
||||
on completion of the write-read transaction. Using the MSS_I2C_RELEASE_BUS
|
||||
constant for the options parameter causes a STOP bit to be generated at the
|
||||
end of the write-read transaction causing the bus to be released for other
|
||||
I2C devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter
|
||||
prevents a STOP bit from being generated at the end of the write-read
|
||||
transaction, preventing other I2C devices from initiating a bus transaction.
|
||||
*/
|
||||
void MSS_I2C_write_read
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t serial_addr,
|
||||
const uint8_t * addr_offset,
|
||||
uint16_t offset_size,
|
||||
uint8_t * read_buffer,
|
||||
uint16_t read_size,
|
||||
uint8_t options
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
I2C status
|
||||
------------------------------------------------------------------------------
|
||||
This function indicates the current state of a MSS I2C instance.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
------------------------------------------------------------------------------
|
||||
@return
|
||||
The return value indicates the current state of a MSS I2C instance or the
|
||||
outcome of the previous transaction if no transaction is in progress.
|
||||
Possible return values are:
|
||||
SUCCESS
|
||||
The last I2C transaction has completed successfully.
|
||||
IN_PROGRESS
|
||||
There is an I2C transaction in progress.
|
||||
FAILED
|
||||
The last I2C transaction failed.
|
||||
|
||||
*/
|
||||
mss_i2c_status_t MSS_I2C_get_status
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Wait for I2C transaction completion.
|
||||
------------------------------------------------------------------------------
|
||||
This function waits for the current I2C transaction to complete. The return
|
||||
value indicates whether the last I2C transaction was successful, or is still
|
||||
in progress, or failed.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
------------------------------------------------------------------------------
|
||||
@return
|
||||
The return value indicates the outcome of the last I2C transaction. It can
|
||||
be one of the following:
|
||||
MSS_I2C_SUCCESS
|
||||
The last I2C transaction has completed successfully.
|
||||
MSS_I2C_IN_PROGRESS
|
||||
The current I2C transaction is still in progress.
|
||||
MSS_I2C_FAILED
|
||||
The last I2C transaction failed.
|
||||
*/
|
||||
mss_i2c_status_t MSS_I2C_wait_complete
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c
|
||||
);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*******************************************************************************
|
||||
*
|
||||
* Slave specific functions
|
||||
*
|
||||
* The following functions are only used within the implementation of an I2C
|
||||
* slave device.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
I2C slave transmit buffer configuration.
|
||||
------------------------------------------------------------------------------
|
||||
This function specifies the memory buffer holding the data that will be sent
|
||||
to the I2C master when this MSS I2C instance is the target of an I2C read or
|
||||
write-read transaction.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
|
||||
@param tx_buffer:
|
||||
This parameter is a pointer to the memory buffer holding the data to be
|
||||
returned to the I2C master when this MSS I2C instance is the target of an
|
||||
I2C read or write-read transaction.
|
||||
|
||||
@param tx_size:
|
||||
Size of the transmit buffer pointed to by the tx_buffer parameter.
|
||||
*/
|
||||
void MSS_I2C_set_slave_tx_buffer
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t * tx_buffer,
|
||||
uint16_t tx_size
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
I2C slave receive buffer configuration.
|
||||
------------------------------------------------------------------------------
|
||||
This function specifies the memory buffer that will be used by the MSS I2C
|
||||
instance to receive data when it is a slave. This buffer is the memory where
|
||||
data will be stored when the MSS I2C is the target of an I2C master write
|
||||
transaction (i.e. when it is the slave).
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
|
||||
@param rx_buffer:
|
||||
This parameter is a pointer to the memory buffer allocated by the caller
|
||||
software to be used as a slave receive buffer.
|
||||
|
||||
@param rx_size:
|
||||
Size of the slave receive buffer. This is the amount of memory that is
|
||||
allocated to the buffer pointed to by rx_buffer.
|
||||
Note: This buffer size will indirectly specify the maximum I2C write
|
||||
transaction length this MSS I2C instance can be the target of. This
|
||||
is because this MSS I2C instance will respond to further received
|
||||
bytes with a non-acknowledge bit (NACK) as soon as its receive
|
||||
buffer is full. This will cause the write transaction to fail.
|
||||
*/
|
||||
void MSS_I2C_set_slave_rx_buffer
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t * rx_buffer,
|
||||
uint16_t rx_size
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
I2C slave memory offset length configuration.
|
||||
------------------------------------------------------------------------------
|
||||
This function is used as part of the configuration of a MSS I2C instance for
|
||||
operation as a slave supporting write-read transactions. It specifies the
|
||||
number of bytes expected as part of the write phase of a write-read
|
||||
transaction. The bytes received during the write phase of a write-read
|
||||
transaction will be interpreted as an offset into the slave’s transmit buffer.
|
||||
This allows random access into the I2C slave transmit buffer from a remote
|
||||
I2C master.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
|
||||
@param offset_length:
|
||||
The offset_length parameter configures the number of bytes to be interpreted
|
||||
by the MSS I2C slave as a memory offset value during the write phase of
|
||||
write-read transactions.
|
||||
*/
|
||||
void MSS_I2C_set_slave_mem_offset_length
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
uint8_t offset_length
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
I2C write handler registration.
|
||||
------------------------------------------------------------------------------
|
||||
Register the function that will be called to process the data written to this
|
||||
MSS I2C instance when it is the slave in an I2C write transaction.
|
||||
Note: The write handler is not called as a result of a write-read transaction.
|
||||
The write data of a write read transaction is interpreted as an offset
|
||||
into the slave’s transmit buffer and handled by the driver.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
|
||||
@param handler:
|
||||
Pointer to the function that will process the I2C write request.
|
||||
*/
|
||||
void MSS_I2C_register_write_handler
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c,
|
||||
mss_i2c_slave_wr_handler_t handler
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
I2C slave receive enable.
|
||||
------------------------------------------------------------------------------
|
||||
Enables the MSS I2C instance identified through the this_i2c parameter to
|
||||
receive data when it is the target of an I2C write or write-read transaction.
|
||||
------------------------------------------------------------------------------
|
||||
@param this_i2c:
|
||||
The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
|
||||
identifying the MSS I2C hardware block that will perform the requested
|
||||
function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,
|
||||
associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must
|
||||
point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined
|
||||
within the I2C driver.
|
||||
*/
|
||||
void MSS_I2C_enable_slave_rx
|
||||
(
|
||||
mss_i2c_instance_t * this_i2c
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*MSS_I2C_H_*/
|
Loading…
Reference in a new issue