Question regarding extracting 12-bit two's complement out of two bytes

Hi everyone,

I am presently in the process of experimenting with a ADC122S625 ADC from National Semiconductor. It samples two channels worth of data and sends it out in a four byte train. The data is in two's complement format, where the first byte is the MSB, the second byte is the LSB for each channel (Channel A and B). (see page 7 for a timing diagram)

Within the MSB, the first four bits are always zero. The remaining 4 bits hence presumably indicate the sign and so on. Thanks to help from others, I discovered casting the MSB results as an int in order to extract the sign. However, I wonder what the correct approach is on a number that only consists of 4 bits. Here is what I attempted, I wonder if anyone more knowledgeable could comment:

void readADC()
{
  byte a1,a2,b1,b2;
  digitalWrite(slaveSelectPin,LOW);
  a1=SPI.transfer(0x00); //MSB, Channel A
  a2=SPI.transfer(0x00); //LSB, Channel A
  b1=SPI.transfer(0x00); //MSB, Channel B
  b2=SPI.transfer(0x00); //LSB, Channel B
  digitalWrite(slaveSelectPin,HIGH);
  //now convert all four bytes into two 12-bit numbers. The first four bits of the MSBs
  //are zero, hence no need to  MSB = MSB & B00001111 to zero them out like with other ADCs.
  //The remaining 4 bits determine the first four bits of the ADC result.
  //Results are two's complement, so they can range from -2048 to +2047, hence the (int) casting

  Channel_A = (int)(a1<<4)<<4|a2;
  Channel_B = (int)(b1<<4)<<4|b2;
}

In other words, right shift the results four bits, cast into int to extract the sign, then right shift another bits, then append the LSB.

Does that seem reasonable?

Just assemble the parts at the top end of the integer and shift right - shift right is an arithmetic shift in C

  Channel_A = ((a1 << 12) | (a2 << 4)) >> 4 ;
  Channel_B = ((b1 << 12) | (b2 << 4)) >> 4 ;

I should clarify that - right shift is an arithmetic shift in C for signed variables. unsigned variables will use logical shift right, so make sure channel_A and channel_B are declared as "int".

Yup, they were and thanks, it works perfectly, including the signing.

Now if only I could figure out what else is off with this chip / program...