2022-10-05 07:12 AM
Hi All.!!!
I am working on STM32F103 and using its 4-wire SPI for communication with slave whose data is 32bit and addr is 16bit.
What I am trying to do is to write and read slave but i could not below is the settings that
I have done in STM cube MX.
Mode:- Full Duplex Master
Data Size 16 bit
Pre scaler 32 selected.
For write operation
uint8 WriteBronco(uint32 Data,uint16 Addr)
{
uint32_t data[2];
data[0] = Addr; // multibyte write enabled
data[1] = Data; //32bit of data slave
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // pull the cs pin low to enable the slave
HAL_SPI_Transmit (&hspi1, data, 2, 100); // transmit the address and data
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave
return 0;
}
For Read operation
void adxl_read (uint16_t address)
{
address = 0x8000; //
address = 0x4000; //
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // pull the cs pin low to enable the slave
HAL_SPI_Transmit (&hspi1, &address, 2, 100); // send the address from where you want to read data
HAL_SPI_Receive (&hspi1, data_rec, 6, 100); // read 6 BYTES of data
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave
}
Kindly let me know how I can do this ??
2022-10-05 11:48 AM
> uint32_t data[2];
> HAL_SPI_Transmit (&hspi1, data, 2, 100); // transmit the address and data
This is 8 bytes. But you're sending 2.
2022-10-05 02:42 PM
I've made modifications to your code.
uint8_t WriteBronco(uint32_t Data, uint16_t Addr)
{
uint8_t data[8] = {0}; // change to 8 bit type
int i;
uint8_t dataSize = 6;
// Writing LSB>MSB. You will have to adjust if the register needs to be written MSB>LSB.
data[0] = Addr; // multibyte write enabled
data[1] = Addr >> 8;
data[2] = Data; //32bit of data slave
data[3] = Data >> 8;
data[4] = Data >> 16;
data[5] = Data >> 24;
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // pull the cs pin low to enable the slave
HAL_SPI_Transmit (&hspi1, data, 6, 100); // transmit the address and data <-- writing 6 bytes total
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave
return 0;
}
void adxl_read (uint16_t address)
{
uint8_t addr[2];
address = 0x8000; //
address = 0x4000; //
addr [0] = address;
addr [1] = address >> 8;
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // pull the cs pin low to enable the slave
HAL_SPI_Transmit (&hspi1, addr, 2, 100); // send the address from where you want to read data
HAL_SPI_Receive (&hspi1, data_rec, 4, 100); // read 6 BYTES of data <-- a 32bit register is 4 bytes, not 6 bytes.
// Let's assume data_rec is an uint8_t array, size of at least 4 bytes.
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave
}
2022-10-05 09:20 PM
Thanks for the reply.
You are sending 6x8 bytes of data.
But slave has three registers as ADDR--16bit, Data_L--16bit(LSB), and Data_H--16bit(MSB).
By doing 6x8 how slave will figure out the data and address.??
I configured 16-bit data spi in cube mx.
Below is the code I have made some changes as below
Will it work ?
void spi_wr_flash(uint16 addr, uint16 dat_h, uint16 dat_l)
{
//set_data_cmd_flash(0x08,dat_l);//This is the code taken from slave datasheet they have done as this.They `broke data into 2 parts 16bit each. Sending cmd for writing sending 16bit LSB.
//set_data_cmd_flash(0x0a,dat_h); //Sending cmd for writing sending 16bit MSB.
//set_data_cmd_flash(0x0c,addr);//Sending addr
uint16_t Data_L[2];
Data_L[0]=0x08;
Data_L[1]=dat_l;
uint16_t Data_H[2];
Data_H[0]=0x0a;
Data_H[1]=data_h;
uint16_t ADDR[2];
ADDR[0]=0x0c;
ADDR[1]=addr;
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // pull the cs pin low to enable the slave
HAL_SPI_Transmit (&hspi1, DATA_L, 2, 100); // transmit the address and data
HAL_SPI_Transmit (&hspi1, DATA_H, 2, 100);
HAL_SPI_Transmit (&hspi1, ADDR, 2, 100);
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave
}
2022-10-06 08:26 AM
The SPI bus writes 8 bits at a time whether the register size is 16 or 32 bits.
In your original post you had
uint32_t data[2];
data[0] = Addr; // multibyte write enabled
data[1] = Data; //32bit of data slave
you copied the 16 bit address into a 32bit array. So the SPI peripheral is clocking in the upper 16 bits of the array which will be 0x0000 for the address. Then the next 16 bits which is the address is being clocked in as the register data. So all your address/data is off by 16 bits.
Change you variable declaration to
uint16_t data[3];
So even though data size is three 16 bits array, you still have to pass the argument of 6 for the amount of bytes being clocked into the register.