2’s complement data format convertion

A few years ago I wrote this to do the thing with a MLX90393.

void fMLX90393_1( void * pvParameters )
{
  int rx[10] = { 0 };
  int _gain = MLX90393_GAIN_1X;
  int xyResoultion = 0;
  int zResoultion = 1;
  int xRes;
  int yRes;
  int zRes;
  float xAverage = 0.0f;
  esp_err_t intError;
  vTaskDelay( 500 ); // delay to let the other sensor come online 1st
  intError = fWriteSPIdata8bits2( _hMLX90393_1, MLX90393_REG_RT ); // reset
  vTaskDelay( 300 ); // allow reset time to complete
  // set gain
  intError = fWriteSPIdata32bits( _hMLX90393_1, MLX90393_REG_WR, 0x00, (((_gain & 0x7) << MLX90393_GAIN_SHIFT) | MLX90393_HALL_CONF), (MLX90393_CONF1 & 0x3F) << 2 );
  vTaskDelay( 10 );
  // MLX90393_CONF2 for comm mode TRIG_INT_SEL 0x1 + 0x10 use spi + relative measurement 0x1 + temp compensation 0x1 = 0xD0
  intError = fWriteSPIdata32bits( _hMLX90393_1, MLX90393_REG_WR, 0x00, 0xD0, (MLX90393_CONF2 & 0x3f) << 2 ); // using 0x00 for the lower 8 bits of the register
  vTaskDelay( 10 );
  //
  fMLX90393_ChangeResoultion( _hMLX90393_1, 0 );
  vTaskDelay( 10 );
  // read MLX90393_CONF3 for resolution
  intError = fReadSPIdataXbits( _hMLX90393_1, (MLX90393_CONF3 & 0x3F) << 2, rx, 3 );
  // combine response into 16bit
  //  Serial.print ( rx[2], BIN );
  //  Serial.print ( " : ");
  //  Serial.print( rx[1], BIN );
  //  Serial.print ( " " );
  int temp = ( rx[2] << 8) | rx[1];
  //  Serial.print ( temp, BIN );
  //  Serial.print ( " " );
  // find resoultion being used
  temp = temp >> 5;
  //   Serial.print ( temp, BIN );
  //   Serial.print ( " " );
  // extract 1st 2 bits, x resolution
  xRes = temp & 3;
  temp = temp >> 2;
  yRes = temp & 3;
  temp = temp >> 2;
  zRes = temp & 3;
//  Serial.print ( zRes, BIN );
//  Serial.print ( " " );
//  Serial.print ( yRes, BIN );
//  Serial.print ( " " );
//  Serial.print ( xRes, BIN );
//  Serial.println ( );
  attachInterrupt( MLX90393int_1, fMLX90393_triggerReadSensor_1, RISING );
  while (1)
  {
    xEventGroupWaitBits ( eg, evtTriggerMLX90393_1, pdTRUE, pdTRUE, portMAX_DELAY);
    // Serial.println( " wakie wakie 1 ");
    // request a single data read
    intError = fWriteSPIdata8bits2( _hMLX90393_1, MLX90393_REG_SM | MLX90393_AXIS_ALL ); // single measurement all axis and temprature
    //triggered  from void IRAM_ATTR triggerMLX90393read(), when the unit has data available
    xEventGroupWaitBits ( eg, evtfMLX90393_ReadSensor_1, pdTRUE, pdTRUE, portMAX_DELAY );
    intError = fReadSPIdataXbits( _hMLX90393_1, MLX90393_REG_RM | MLX90393_AXIS_ALL, rx, 9 );
    /* rx[0] = status bit
       rx[1] & rx[2] = temprature
       rx[3] & rx[4] x
       rx[5] & rx[6] y
       rx[7] & rx[8] z
    */
    // Convert data to 16 bit
    int16_t xi, yi, zi;
    xi = (rx[3] << 8) | rx[4]; // shift MSB over to the left by 8 & with LSB
    yi = (rx[5] << 8) | rx[6];
    zi = (rx[7] << 8) | rx[8];
    // determine gain being used
    float xT = 0.0f, yT = 0.0f, zT = 0.0f;
    xT = (float)xi *  mlx90393_lsb_lookup[_gain][xRes][xyResoultion];
    yT = (float)yi * mlx90393_lsb_lookup[_gain][yRes][xyResoultion];
    zT = (float)zi * mlx90393_lsb_lookup[_gain][zRes][zResoultion];
    xMag.x -= xT;
    xMag.y -= yT;
    xMag.z -= zT;

    // multiply by 10 for milliGauss
//    Serial.print ( " MLX90393_1 ");
//    Serial.print( " X uT: " );
//    Serial.print( xT , 6 );
//    Serial.print( ", Y uT: " );
//    Serial.print( yT, 6 );
//    Serial.print( ", Z uT: " );
//    Serial.print( zT, 6 );
//    Serial.println();

//    Serial.print ( "Summed readings: " );
    // Serial.print( " X uT: ");
    Serial.print( "DATA," );
    Serial.print( String(xMag.x) );
   Serial.print( ", " );
    // Serial.print( " Y uT: ");
     Serial.print( String(xMag.y) );
     Serial.print( ", " );
    // Serial.print( " Z uT: ");
    Serial.print( String(xMag.z) );
    Serial.print( ", " );
    Serial.print( "AUTOSCROLL_20" );
    Serial.println();

  }
  vTaskDelete(NULL);
}