mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Update the Microsemi I2C code to be event driver, rather than polling for Tx complete.
This commit is contained in:
parent
1f2a287b7f
commit
b84c870b54
|
@ -7,6 +7,8 @@
|
||||||
* SVN $Revision: 2152 $
|
* SVN $Revision: 2152 $
|
||||||
* SVN $Date: 2010-02-11 14:44:11 +0000 (Thu, 11 Feb 2010) $
|
* SVN $Date: 2010-02-11 14:44:11 +0000 (Thu, 11 Feb 2010) $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "../../CMSIS/mss_assert.h"
|
#include "../../CMSIS/mss_assert.h"
|
||||||
|
|
||||||
|
@ -145,6 +147,14 @@ void MSS_I2C_init
|
||||||
this_i2c->hw_reg_bit->CTRL_CR1 = (clock_speed >> 1) & 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_bit->CTRL_CR0 = clock_speed & 0x01;
|
||||||
this_i2c->hw_reg->ADDR = this_i2c->ser_address;
|
this_i2c->hw_reg->ADDR = this_i2c->ser_address;
|
||||||
|
|
||||||
|
/* The interrupt can cause a context switch, so ensure its priority is
|
||||||
|
between configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
NVIC_SetPriority( this_i2c->irqn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
|
vSemaphoreCreateBinary( ( this_i2c->xI2CCompleteSemaphore ) );
|
||||||
|
xSemaphoreTake( ( this_i2c->xI2CCompleteSemaphore ), 0 );
|
||||||
|
configASSERT( ( this_i2c->xI2CCompleteSemaphore ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
|
@ -196,6 +206,7 @@ void MSS_I2C_write
|
||||||
uint32_t primask;
|
uint32_t primask;
|
||||||
|
|
||||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||||
|
configASSERT( ( this_i2c->xI2CCompleteSemaphore ) );
|
||||||
|
|
||||||
primask = disable_interrupts();
|
primask = disable_interrupts();
|
||||||
|
|
||||||
|
@ -431,11 +442,28 @@ mss_i2c_status_t MSS_I2C_wait_complete
|
||||||
{
|
{
|
||||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||||
|
|
||||||
|
#ifdef USE_OLD_I2C_POLLING_CODE
|
||||||
while ( this_i2c->status == MSS_I2C_IN_PROGRESS )
|
while ( this_i2c->status == MSS_I2C_IN_PROGRESS )
|
||||||
{
|
{
|
||||||
/* Wait for transaction to compltete.*/
|
/* Wait for transaction to compltete.*/
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
configASSERT( ( this_i2c->xI2CCompleteSemaphore ) );
|
||||||
|
if( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED )
|
||||||
|
{
|
||||||
|
while ( this_i2c->status == MSS_I2C_IN_PROGRESS )
|
||||||
|
{
|
||||||
|
/* Wait for transaction to compltete.*/
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xSemaphoreTake( this_i2c->xI2CCompleteSemaphore, portMAX_DELAY );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return this_i2c->status;
|
return this_i2c->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,12 +479,14 @@ mss_i2c_status_t MSS_I2C_wait_complete
|
||||||
static void mss_i2c_isr
|
static void mss_i2c_isr
|
||||||
(
|
(
|
||||||
mss_i2c_instance_t * this_i2c
|
mss_i2c_instance_t * this_i2c
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
volatile uint8_t status;
|
volatile uint8_t status;
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
uint8_t hold_bus;
|
uint8_t hold_bus;
|
||||||
uint8_t clear_irq = 1;
|
uint8_t clear_irq = 1;
|
||||||
|
long lHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
configASSERT( ( this_i2c->xI2CCompleteSemaphore ) );
|
||||||
|
|
||||||
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );
|
||||||
|
|
||||||
|
@ -539,6 +569,7 @@ static void mss_i2c_isr
|
||||||
clear_irq = 0;
|
clear_irq = 0;
|
||||||
}
|
}
|
||||||
this_i2c->status = MSS_I2C_SUCCESS;
|
this_i2c->status = MSS_I2C_SUCCESS;
|
||||||
|
xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -577,6 +608,7 @@ static void mss_i2c_isr
|
||||||
clear_irq = 0;
|
clear_irq = 0;
|
||||||
}
|
}
|
||||||
this_i2c->status = MSS_I2C_SUCCESS;
|
this_i2c->status = MSS_I2C_SUCCESS;
|
||||||
|
xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -600,6 +632,7 @@ static void mss_i2c_isr
|
||||||
case ST_SLAR_NACK: /* SLA+R tx'ed; let's release the bus (send a stop condition) */
|
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->hw_reg_bit->CTRL_STO = 0x01;
|
||||||
this_i2c->status = MSS_I2C_FAILED;
|
this_i2c->status = MSS_I2C_FAILED;
|
||||||
|
xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ST_RX_DATA_ACK: /* Data byte received, ACK returned */
|
case ST_RX_DATA_ACK: /* Data byte received, ACK returned */
|
||||||
|
@ -630,6 +663,7 @@ static void mss_i2c_isr
|
||||||
}
|
}
|
||||||
|
|
||||||
this_i2c->status = MSS_I2C_SUCCESS;
|
this_i2c->status = MSS_I2C_SUCCESS;
|
||||||
|
// xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/******************** SLAVE RECEIVER **************************/
|
/******************** SLAVE RECEIVER **************************/
|
||||||
|
@ -696,6 +730,7 @@ static void mss_i2c_isr
|
||||||
}
|
}
|
||||||
/* Mark any previous master write transaction as complete. */
|
/* Mark any previous master write transaction as complete. */
|
||||||
this_i2c->status = MSS_I2C_SUCCESS;
|
this_i2c->status = MSS_I2C_SUCCESS;
|
||||||
|
// xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */
|
case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */
|
||||||
|
@ -747,6 +782,8 @@ static void mss_i2c_isr
|
||||||
/* Read the status register to ensure the last I2C registers write took place
|
/* 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. */
|
* in a system built around a bus making use of posted writes. */
|
||||||
status = this_i2c->hw_reg->STATUS;
|
status = this_i2c->hw_reg->STATUS;
|
||||||
|
|
||||||
|
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
|
|
|
@ -194,6 +194,11 @@
|
||||||
|
|
||||||
#include "../../CMSIS/a2fxxxm3.h"
|
#include "../../CMSIS/a2fxxxm3.h"
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -325,6 +330,9 @@ typedef struct mss_i2c_instance
|
||||||
uint_fast8_t slave_mem_offset_length;
|
uint_fast8_t slave_mem_offset_length;
|
||||||
mss_i2c_slave_wr_handler_t slave_write_handler;
|
mss_i2c_slave_wr_handler_t slave_write_handler;
|
||||||
|
|
||||||
|
/* Used to get access to and wait for completion of an I2C transaction. */
|
||||||
|
xSemaphoreHandle xI2CCompleteSemaphore;
|
||||||
|
|
||||||
} mss_i2c_instance_t;
|
} mss_i2c_instance_t;
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*//**
|
/*-------------------------------------------------------------------------*//**
|
||||||
|
|
Loading…
Reference in a new issue