2017-06-10 09:35 AM
Hi everybody, I am trying to implement callback function for I2C peripheral.
This is the code without dma implementation:
void ADXL345_GetXyzRAW(uint8_t *buffer){
uint8_t firstRegAddress = ADXL345_DATAX0;HAL_I2C_Master_Transmit(ADXL345_I2C,
(uint8_t)(ADXL345_ADDRESS<<1), &firstRegAddress, 1, ADXL345_I2C_TIMEOUT_TRANSFER);HAL_I2C_Master_Receive(ADXL345_I2C,
(uint8_t)(ADXL345_ADDRESS<<1), buffer, 6, ADXL345_I2C_TIMEOUT_TRANSFER);}
As you can see, the code works properly but it demands cpu cycles. So my objective is to use dma controller for automatizing the process. The problem rise when the task
ADXL345_GetXyzRAW
demand me two i2c functions (transmit and receive).It is a problem because my idea is execute
ADXL345_GetXyzRAW function once and then still doing another task. It doens't allow me wait for ending of I2C transmit for then executing i2c receive (time is gold for my device). I need both of theses task executing one by one with out wait for the first for then execute the second in a polling mode.
My idea is
call the function
i2c receive dmainside
HAL_I2C_MasterTxCpltCallback(), but i dont know if I am doing a bad practice or a violation for access memory.
#hal #stm32 #dma #callback #i2c2017-06-10 01:15 PM
I have always read that you should set/check a flag in your interrupt handler, in order to get out of the handler as quickly as possible, rather than doing things like serial i/o inside it.
2017-06-11 03:46 AM
I think that I will access to the function
ADXL345_GetXyzRAW two times, first one for transmit and second one for receive, I will control the operation with a couple of flags, for fragmenting the operation. However I don't feel this solution as a correct and optimized solution for doing the task. If someone has another sight for solving my problem, it will be very welcome.
Thank you very much.
2017-10-16 09:48 AM
Cunalata.Jefferson
Can you share your code if you found a way to use DMA ?2017-10-16 09:57 AM
Dear Alexander,
I am sorry but I could not solve the problem. I had to implement a flag and interrupt mode.
2018-03-14 04:07 AM
Hello,
Based on I2C protocol specification itself, you need to provide 2 functions to fullfill this goal.
But using DMA functions, it is fairly easy to only use one function provided by ST to do that.
This depends on your I2C slave ADXL device. Looking into the datasheet it has a register address (we call this an i2c memory slave device), so you can use this HAL function :
HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA
(
I2C_HandleTypeDef *hi2c,
uint16_t DevAddress,
uint16_t MemAddress,
uint16_t MemAddSize,
uint8_t *pData,
uint16_t Size
)
and you have to register to the low level DMA transfer complet event.
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
{}Basically, with one function and one IRQ interrupt you are done.
Hope this could help.
Regards,
Youssouf