2020-05-25 04:36 AM
Hi,
I am trying to emulate a EEPROM with my STM32F103 as a I2C slave.
I'm using STM32CubeIDE 1.0.2.
The chip that will request data doesn't write data to the EEPROM, so I can use only an array to save the data in the code. And it cant have any code in the main, I'll implement another code there.
Here is the code:
#include "main.h"
#include "dma.h"
#include "i2c.h"
#define RX_BUFFER_SIZE 1
#define TX_BUFFER_SIZE 16
uint8_t aRxBuffer[RX_BUFFER_SIZE] = { 0xFF };
uint8_t aTxBuffer[256] = {
0x05,0xAA,0x03,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x39,0x00,
0x4B,0x07,0x00,0x00,0x14,0x60,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
0x28,0x00,0x01,0x00,0x01,0x02,0x1E,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x00,0x10,0x00,0x00,0x12,
0x2C,0x01,0x66,0x00,0x01,0x00,0x40,0x13,0x2C,0x01,0x22,0x00,0x01,0x00,0x00,0x10,
0x02,0x00,0x64,0x00,0x01,0x00,0x00,0x11,0x10,0x00,0x20,0x00,0x01,0x00,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBB
};
void SystemClock_Config(void);
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
{
HAL_I2C_EnableListen_IT(&hi2c2); // slave is ready again
}
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
if (TransferDirection == I2C_DIRECTION_TRANSMIT)
{;
if (HAL_I2C_Slave_Seq_Receive_IT(&hi2c2, &aRxBuffer[0], RX_BUFFER_SIZE, I2C_NEXT_FRAME) != HAL_OK)
{
/* Transfer error in reception process */
Error_Handler();
}
}
else
{
if (HAL_I2C_Slave_Seq_Transmit_IT(&hi2c2, &aTxBuffer[aRxBuffer[0]], 16, I2C_LAST_FRAME) != HAL_OK)
{
/* Transfer error in transmission process */
Error_Handler();
}
}
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
{
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C2_Init();
while (1)
{
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
And I setup the I2C channel like this:
I used a logic analyser to see what is happening in the I2C line:
The chip (master) makes a write request to set the address of the memory it would like to read and the slave acknowledge it and it recives the data correctly (I saw in the debugger).
Then the chip request the data from the MCU and here is the problem, the MCU is supposed to sent the first 16 bytes from aTxBuffer but instead it send only the first one and and apparently the chip makes another read request that the logic analyser sees as data.
HAL_I2C_ErrorCallback is called right after HAL_I2C_AddrCallback is called with an OVR error.
Thanks! =)