Reputation: 97
I am new to programming and I am trying to read a page (64Bytes) from an SPI Eeprom and I got it working when reading to an array[67] (3 transmitted Bytes to start the read process via SPI + 64 Bytes data).
I am using IAR Workbench working on a STM32L475.
When I try to use pointers it does not work, probably a stupid no brainer of a beginners mistake, but I appreciate some help to solve this.
I am using a union like this (I know I am wasting mem but for the test it is like this):
//Production Data union
union Production_Data_union
{
struct
{
uint8_t Dummy_Array[3];
char Xxxx_Sn[16];
char Yyyy_Sn[16];
char Prod_Date[8];
char Firmware_Ver[8];
};
uint8_t Eeprom_Page0_Buffer[67];
};
union Production_Data_union Prod_Data;
uint8_t *Eeprom_Page0_Ptr;
uint8_t Read_Cmd[3] = {0x03, 0x00, 0x00};
uint8_t Buff[67];
uint8_t Eeprom_Page_Size = 64;
void Eeprom_Page_Read(uint8_t *Data, uint8_t Page_No);
My Main looks like this:
Eeprom_Page0_Ptr = (uint8_t*)&Prod_Data.Eeprom_Page0_Buffer;
Eeprom_Page_Read(Eeprom_Page0_Ptr, 0);
The Eeprom_Page_Read function:
void Eeprom_Page_Read(uint8_t *Data, uint8_t Page_No)
{
uint16_t Address;
Address = Page_No * Eeprom_Page_Size;
Read_Cmd[2] = Address & 0xFF;
Read_Cmd[1] = (Address >> 8) & 0xFF;
//Send READ command to Eeprom
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
if(HAL_SPI_TransmitReceive(&hspi3, (uint8_t*)Read_Cmd, (uint8_t *)&Data, (Eeprom_Page_Size +3), 5000) != HAL_OK)
{
Error_Handler();
}
printf("Prod_Data:\n - Xxxx SN %s\n - Yyyy SN %s\n - Prod date %s - Firmware %s\n - Cmd - %d - %d - %d\n",
Prod_Data.Xxxx_Sn,
Prod_Data.Yyyy_Sn,
Prod_Data.Prod_Date,
Prod_Data.Firmware_Ver,
Read_Cmd[0],
Read_Cmd[1],
Read_Cmd[2]);
//Wait for SPI transfer to complete
while (HAL_SPI_GetState(&hspi3) != HAL_SPI_STATE_READY)
{
}
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
Read_E2prom = 0;
}
I know the content of the Eeprom is ok and I can read it if I replace “&Data” with “Buff” (Array[67]) in the HAL_SPI_TransmitReceive(...) call.
Pointer value is the start address of the structure (0x20000090). So addressing a.s.o. should be ok but the struct is empty when using a pointer.
I am mostly interested in why this does not work and a fix to this, not so much in comments like "why don't you do it like this instead, I want to learn what I have done wrong cause this approach, I believe, should work.
Please remember that I AM NEW at programming so please explain "for Dummies".
Upvotes: 0
Views: 249
Reputation: 947
I am not sure why that is ?
The function HAL_SPI_TransmitReceive
wants a pointer to know where to store the data it receives. It essentially wants an address of where to go place the bytes. In your case, according to line
void Eeprom_Page_Read(uint8_t *Data, uint8_t Page_No){...}
Data
is already a pointer, because it's denoted with a *
. This means that Data
is a pointer pointing to some uint8_t
number/array somewhere. That somewhere is where you want your SPI to write to.
When you added the &
you basically gave the SPI the pointer to the pointer of where you want to write. So the SPI is writing the received data over the pointer, instead of at where the pointer points?
If that doesn't make sense then ask me again. It's a hard thing to explain.
Update:
This is as I understand it, not a pointer but an array?
The compiler only see's it as an pointer. In your case the pointer happen to point to an array, but it could have been to anywhere (almost) in memory. I implore you to rather think in terms of a pointer pointing to the first element of an array (*ptr==array[0]
), and not in terms of an array.
Is it somehow implicit so the compiler knows what I want to do so it just accepts and compiles correctly?
I'm not sure if the compiler should compile successfully or not. But you should not rely on that. It's happens often where one could send pointers of pointers around (**ptr
), so the compiler is just going to assume you know what you are doing. So you must take great care of how you work with your pointers.
Upvotes: 1
Reputation: 97
Ok, after trying to solve this for a day or so, I finally found the mistake, it should not be &Data but just Data so it must look like this:
if(HAL_SPI_TransmitReceive(&hspi3, (uint8_t*)Read_Cmd, (uint8_t *)Data, (Eeprom_Page_Size +3), 5000) != HAL_OK)
{
/* Transfer error in transmission process */
Error_Handler();
}
I am not sure why that is ?
Upvotes: 0