cancel
Showing results for 
Search instead for 
Did you mean: 

CPAL Spin Waits in Interupt

johnsotack9
Associate II
Posted on May 11, 2013 at 16:20

I noticed the CPAL

uses spin type

waits including at least one in an interrupt (see code below). Thes

e are u

sed

v

ia the MACRO

__CPAL_I2C_TIMEOUT

. I have some concern

with the one in the interrupt handl

er below because it appears to spin for 302 us = 20,536 cyles. The wait is on the B

TF flag which there is an interrupt for

(see table from STMf

4XX

reference manual.

Is there are reason

a spin wait

is done o

n the BTF rather than using the interrupt? I may want to optimize my code to recover the cyles. Were I to take a guess is would be that BTF is usu

ally not used in DMA transfers and is t

h

i

s not specially turned on in this case

.

For my cause it looks li

ke the wait occurs in the last two transmi

tted bytes

.

If sw

itching from DMA to interrupt mode saves 20

,

536

cycles on a single

write

I

may be

better off using

interrupt

mode.

Does ST have any opi

nion of th

e

relat

ive

efficiency

of Interrupt vs DMA in CPAL?

From cpal_i2c.c:

uint32_t

CPAL_I2C_DMA_TX_IRQHandler

(CPAL_InitTypeDef* pDevInitStruct)

{

/* Reinitialize Timeout Value to default (no timeout initiated) */

pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_DEFAULT;

CPAL_LOG(''\n\r\n\rLOG <CPAL_I2C_DMA_TX_IRQHandler> : I2C Device TX DMA '');

/*------------- If TC interrupt ------------*/

if((__CPAL_I2C_HAL_GET_DMATX_TCIT(pDevInitStruct->CPAL_Dev)) != 0)

{

CPAL_LOG(''\n\rLOG : I2C Device TX Complete'');

/* Update remaining number of data */

pDevInitStruct->pCPAL_TransferTx->wNumData = 0;

/* Call DMA TX TC UserCallback */

CPAL_I2C_DMATXTC_UserCallback(pDevInitStruct);

/* If DMA Normal mode */

if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_DMATX_CIRCULAR) == 0)

{

/* If Master Mode selected */

if (pDevInitStruct->CPAL_Mode == CPAL_MODE_MASTER)

{

#ifdef CPAL_I2C_MASTER_MODE

/* Disable DMA Request */

__CPAL_I2C_HAL_DISABLE_DMAREQ(pDevInitStruct->CPAL_Dev);

/* Wait until BTF flag is set */

__CPAL_I2C_TIMEOUT(__CPAL_I2C_HAL_GET_BTF(pDevInitStruct->CPAL_Dev), CPAL_I2C_TIMEOUT_BTF);

/* No Stop Condition Generation option bit not selected */

if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NOSTOP) == 0)

John

1 REPLY 1
jdsotack
Associate II
Posted on May 15, 2013 at 20:09

I think the solution may be to check the BTF flag and enable the interrupt if it is not sent.  The processing which follows can then be done in a separate method that is called from the current ISR if the flag is already set or the BTF related ISR if it is not.

In general CPAL looks nice.  However, it may need to do less spinning.  I have a protocol running right now that can require a 50us response.  This is nearly 10000 cycles and is not a problem unless the processes wait spins.

John