2024-12-06 11:16 AM - edited 2024-12-10 06:30 AM
I can write and read byte, float or text on the eeprom. And I was thinking that is Ok with the processes of wiriting and reading. But when I tried that with the group of data, it appeared that something is wrong. It means that when I first write goup of data, fx seven bytes and then I try read them, it appears that only about half of them are correct. Fx:
bytes written:
Test byte to write into EEPROM: spi_buf = 0xA0
Test byte to write into EEPROM: spi_buf = 0xA1
Test byte to write into EEPROM: spi_buf = 0xA2
Test byte to write into EEPROM: spi_buf = 0xA3
Test byte to write into EEPROM: spi_buf = 0xA4
Test byte to write into EEPROM: spi_buf = 0xA5
Test byte to write into EEPROM: spi_buf = 0xA6
Bytes read:
Test byte read: 0xA0
Test byte read: 0xAF
Test byte read: 0xA2
Test byte read: 0x0
Test byte read: 0xA4
Test byte read: 0xA4
Test byte read: 0xA6
The same concerns other type of data.
=============================================
The code written under stm32CubeIDE, board F103C8T6.
SPI configuration:
Full-Duplex Master
NSS Signal Type
Data Size - 8 Bits
First Bit - MSB First
Prescaler(for baud rate) - 64 (Baud Rate = 1.125 Mbits/s)
CPOL - LOW
CPHA - 1 Edge
// EEPROM SPI 25LC020A is 8 bit adressing (as read in datasheet).
Changing clock frequency or inserting delays for CS or transmitting functions did not help.
Does anyone know how to fix this ????
void EEPROM_Write_Byte(uint16_t address, uint8_t data)
{
EEPROM_Write_Enable();
uint8_t cmd[3];
cmd[0] = 0x02; // command Write
cmd[1] = (address >> & 0xFF;
cmd[2] = address & 0xFF;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
HAL_SPI_Transmit(&hspi1, cmd, 3, HAL_MAX_DELAY);
HAL_SPI_Transmit(&hspi1, &data, 1, HAL_MAX_DELAY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
HAL_Delay(10);
EEPROM_Wait_For_Ready();
}
uint8_t EEPROM_Read_Byte(uint16_t address)
{
uint8_t data;
uint8_t cmd[3];
cmd[0] = 0x03; // command Read
cmd[1] = (address >> & 0xFF;
cmd[2] = address & 0xFF;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
HAL_SPI_Transmit(&hspi1, cmd, 3, HAL_MAX_DELAY);
HAL_SPI_Receive(&hspi1, &data, 1, HAL_MAX_DELAY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
return data;
}
void EEPROM_Write_Enable(void)
{
uint8_t cmd = 0x06; // command Write Enable
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
HAL_Delay(5);
}
void EEPROM_Write_Float(uint16_t address, float data)
{
EEPROM_Write_Enable();
uint8_t cmd[3];
cmd[0] = 0x02; // command Write
cmd[1] = (address >> & 0xFF;
cmd[2] = address & 0xFF;
uint8_t* dataBytes = (uint8_t*)&data;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
HAL_SPI_Transmit(&hspi1, cmd, 3, HAL_MAX_DELAY); // sending command and adress
HAL_SPI_Transmit(&hspi1, dataBytes, sizeof(float), HAL_MAX_DELAY); // data send
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
HAL_Delay(10);
}
float EEPROM_Read_Float(uint16_t address)
{
float data;
uint8_t cmd[3];
uint8_t* dataBytes = (uint8_t*)&data;
cmd[0] = 0x03; // command Read
cmd[1] = (address >> & 0xFF;
cmd[2] = address & 0xFF;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
HAL_SPI_Transmit(&hspi1, cmd, 3, HAL_MAX_DELAY); // sending command and adress
HAL_SPI_Receive(&hspi1, dataBytes, sizeof(float), HAL_MAX_DELAY); // data read
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
return data;
}
void saveFloats() {
for (uint16_t i = 0; i < 7; i++) {
uint16_t address = i * sizeof(float);
float value = (i + 1) * 3.14f; // value to save
EEPROM_Write_Float(address, value);
EEPROM_Wait_For_Ready();
HAL_Delay(100);
printf("%2d: Adress: %3d, float to save: %6.3f\n", i, address, value);
}
printf("\n");
}
void readFloats() {
uint16_t address;
float readValue;
for (uint16_t i = 0; i < 7; i++) {
address = i * sizeof(float);
readValue = EEPROM_Read_Float(address);
EEPROM_Wait_For_Ready();
HAL_Delay(100);
printf("%2d: Adress: %3d, read float: %6.3f\n", i, address, readValue);
}
printf("\n");
}
void save_read_float()
{
for (uint16_t i = 0; i < 7; i++)
{
uint16_t address = i * sizeof(float);
float value = (i + 1) * 3.14159f; // value to save
EEPROM_Write_Float(address, value);
HAL_Delay(10);
printf("%2d: Adres: %3d, float to save: %6.3f\n",i, address, value);
float readValue = EEPROM_Read_Float(address);
printf("%2d: Adres: %3d, read float directly after 10ms: %6.3f\n",i, address, readValue);
} printf("\n\n");
}
int main()
{
save_read_float();
saveFloats();
HAL_Delay(1000);
readFloats();
return 0;
}
2024-12-06 11:25 AM
>>As it is seen some error. Why?
The addressing isn't working?
You're driving the CS high too early, perhaps use TransmitReceive rather the Transmit which returns as soon as the TXE is cleared and you stuff the data in.
Look at the signals with a scope or logic analyzer, to understand / confirm what's happening.
Perhaps read the data sheet, isn't the 25LC020A a 2Kbit device (256 Byte) with 8-bit addressing, not 16-bit?
2024-12-06 11:40 AM - edited 2024-12-07 01:23 PM
Accordin datasheet EEPROM SPI 25LC020A is 8 bit addressing.
I have noticed on the osciloscope that when read data is not correct the MOSI signal for the corresponding writing data is not as should be, so Im not suprised that I cannot obtain the right result. The IC signal is absolutly correct. So I dont know how to force MOSI signal to be right. Somebody knows how to do it ????
2024-12-07 01:22 PM - edited 2024-12-10 06:36 AM
I have noticed on the osciloscope that saved and read data are exactly the same as I obtained by the uart.
bytes written:
Test byte to write into EEPROM: spi_buf = 0xA0
Test byte to write into EEPROM: spi_buf = 0xA1
Test byte to write into EEPROM: spi_buf = 0xA2
Test byte to write into EEPROM: spi_buf = 0xA3
Test byte to write into EEPROM: spi_buf = 0xA4
Test byte to write into EEPROM: spi_buf = 0xA5
Test byte to write into EEPROM: spi_buf = 0xA6
Bytes read:
Test byte read: 0xA0
Test byte read: 0xAF
Test byte read: 0xA2
Test byte read: 0x0
Test byte read: 0xA4
Test byte read: 0xA4
Test byte read: 0xA6