LIS3DSH SPI address increment problem
I am using an ST Micro MCU via SPI to the LIS3DSH to read x,y,z data(using CubeMX HAL). I can read in single byte mode fine but the multi byte access bit in Control register 6 has no effect. I have tried Control register 6 : ADD_INC disabled or enabled with no difference in behavior. If I request a read starting from a known non-zero address, that same data is just repeated for the number of bytes requested.
LIS3DSH initialization:
transmitData[0] = LIS3DSH_WRITE | LIS3DSH_CTRL_REG6;
transmitData[1] = LIS3DSH_CTRL_REG6_BOOT | LIS3DSH_CTRL_REG6_ADD_INC;
SPISend( transmitData, receiveData, 2);
transmitData[0] = LIS3DSH_WRITE | LIS3DSH_CTRL_REG4;
transmitData[1] = (LIS3DSH_CTRL_REG4_ODR100 << LIS3DSH_CTRL_REG4_ODR_SHIFT)
| LIS3DSH_CTRL_REG4_BDU
| LIS3DSH_CTRL_REG4_Z_EN
| LIS3DSH_CTRL_REG4_Y_EN
| LIS3DSH_CTRL_REG4_X_EN;
SPISend( transmitData, receiveData, 2);
transmitData[0] = LIS3DSH_WRITE | LIS3DSH_CTRL_REG5;
transmitData[1] = (LIS3DSH_CTRL_REG5_BW_800HZ << LIS3DSH_CTRL_REG5_BW_SHIFT)
| (LIS3DSH_CTRL_REG5_FSCALE_2G << LIS3DSH_CTRL_REG5_FSCALE_SHIFT)
| (LIS3DSH_CTRL_REG5_ST_OFF << LIS3DSH_CTRL_REG5_ST_SHIFT)
| LIS3DSH_CTRL_REG5_SIM_4WIRE;
SPISend( transmitData, receiveData, 2);
where:
void SPISend(uint8_t* transmit, uint8_t* receive, uint16_t length) {
HAL_StatusTypeDef status;
HAL_GPIO_WritePin( Accel_SPI_NSS_GPIO_Port, Accel_SPI_NSS_Pin, GPIO_PIN_RESET);
status = HAL_SPI_TransmitReceive( &hspi2, transmit, receive, length, 100);
HAL_GPIO_WritePin( Accel_SPI_NSS_GPIO_Port, Accel_SPI_NSS_Pin, GPIO_PIN_SET);
if (status != HAL_OK) {
Error_Handler();
}
}
My single byte reads:
transmitData[1] = (uint8_t) DUMMY;
transmitData[0] = (uint8_t) (LIS3DSH_READ | LIS3DSH_X_L);
SPISend( transmitData, receiveData, 2);
xl = receiveData[1];
transmitData[0] = (uint8_t) (LIS3DSH_READ | LIS3DSH_X_H);
SPISend( transmitData, receiveData, 2);
xh = receiveData[1];
transmitData[0] = (uint8_t) (LIS3DSH_READ | LIS3DSH_Y_L);
SPISend( transmitData, receiveData, 2);
yl = receiveData[1];
transmitData[0] = (uint8_t) (LIS3DSH_READ | LIS3DSH_Y_H);
SPISend( transmitData, receiveData, 2);
yh = receiveData[1];
transmitData[0] = (uint8_t) (LIS3DSH_READ | LIS3DSH_Z_L);
SPISend( transmitData, receiveData, 2);
zl = receiveData[1];
transmitData[0] = (uint8_t) (LIS3DSH_READ | LIS3DSH_Z_H);
SPISend( transmitData, receiveData, 4);
zh = receiveData[1];
x = (xh << 8) | xl;
y = (yh << 8) | yl;
z = (zh << 8) | zl;
My multi byte read:
transmitData[0] = (uint8_t) (LIS3DSH_READ | LIS3DSH_X_L);
SPISend( transmitData, receiveData, 7);
x = (int16_t) (receiveData[2] << 8) | (int16_t) receiveData[1];
y = (int16_t) (receiveData[4] << 8) | (int16_t) receiveData[3];
z = (int16_t) (receiveData[6] << 8) | (int16_t) receiveData[5];
Since the part supports multi byte reads, it seems that I must be missing something in the part initialization?
My HAL spi initialization is the same on both mcu spi channels and my other spi device (not LIS3DSH) supports multi byte transfers without an issue.
static void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_Init 2 */
}
Any help appreciated.
Thanks,
-Phil
