I have an acceleration sensor (ADXL355) that returns 20-bit data in three bytes, formatted as 2s complement :
- acc3 (bits 19-12) in byte register 3 (mapped to bits 7-0)
- acc2 (bits 11-4) in byte register 2 (mapped to bits 7-0)
- acc1 (bits 3-0) in byte register 1 (mapped to bits 7-4 while 3-0 are unused)
the acceleration value is taken as a signed 32 bit integer from the above 3 registers as follows :
int32_t acc32 = ((uint32_t)acc3 << 12) | ((uint16_t)acc2 << 4) | (acc1 >> 4);
if (acc32 & (1UL << 19)) acc32 -= 1UL << 20;
Then, I am doing some statistical analysis on acceleration values to calculate an offset trim as a signed 32 bit integer.
int32 off32;
This offset has to be written back to sensor as a 16 bit 2s complement value as follows :
- offset high byte (bits 15-8)
- offset low byte (bits 7-0)
The datasheet says that "The significance of offset bits 15-0 matches the significance of acceleration bits 19-4".
I found this rather tricky so I am asking how to convert this signed 32 bit offset integer to a 16 bit offset integer that follows the above specification.
I had this idea but don't know whether it is correct :
int16_t off16[i] = (int16_t)(off32[i] / 16);
sendSPI((uint8_t)(off16 >> 8));
sendSPI((uint8_t)off16);
Any comment should be greatly appreciated !