2013-05-11 07:20 AM
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 concernwith 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 singlewrite
Imay 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_tCPAL_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) John2013-05-15 11:09 AM
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