I am using the SLKS12 with option "C128", MC9S12 C128 MCU, 80 LQFP. The accelerometer module that I am trying to communicate with is the HitachiH48C3 from Parallax. It only has one data pin so I have no choice but to use bidirectional mode. The datasheet is not very specific about the communication protocol but I found the data sheet for the ATD chip on the accelerometer module. I have read a lot of threads concerning this mode but to no avail. Hopefully Peg or BigMac can help with these short comings. Here is the code I have been working with:
void main(void)
{
float gforce[] = {0.0,0.0,0.0}; //Calculated G-forces
//0 is X axis
//1 is Y axis
//2 is Z axis
SPIinit();
//Forever loop
for(;
{
if( gforce[0]!=0.0 || gforce[1]!=0.0 || gforce[2]!=0.0) //Test to see if motion
PTT_PTT1 = 1;
else
PTT_PTT1 = 0;
for (i=0 ; i<3 ; i++)
gforce[i] = axis_acceleration(i); //Interrogate accelerometer and calc G's
}/* loop forever */
/* please make sure that you never leave main */
}//end of main
void SPIinit(void)
{
SPICR1 = 0x70; //Load pattern for SPI control register 1
//Interrupt disabled
//System enabled
//Trans interrupt enabled
//Master mode
//Clock polarity (idle low)
//Clock phase (rising)
//Slave select output disabled
//MSB first
SPICR2 = 0x03; //Load pattern for SPI control register 2
//Mode fault disabled
//Bidirectional mode(recieve)
//Stop in wait mode
//Serial pin control(bidirectional)
SPIBR = 0x01; //Load pattern for SPI baud rate
//Bus clock divide by 4
//1MHz
//500ns minimum clokc for accelerometer
//2MHz clock maximum
}//SPI initialize subroutine
float axis_acceleration(int i)
{
//Developed from example code "HitachiH48C3AxisAccelerometer.pdf"
//Also referenced MCP3204/3208 datasheet from Microchip for SPI
//Routine for reading accelerometer
//To interogate accelerometer send 000110"axis"
//000 are just fill bits for the 8bit SPIDR register
//1 for start bit
//1 for single ended operation of the ATD chip
//0 is actually a don't care b/c there are only 4 ATD channels
//"axis" is where the analog inputs are connected to the ATD
//X axis is channel 00
//Y axis is channel 01
//Z axis is channel 10
//Ref is channel 11
//Next series of words will contain 12bit channel conversion
//First High-Z then "null" bit and then as MSB then LSB
//high-z,null,11,10,9,8,7,6
//5,4,3,2,1,0,1,2
//3,4,5,6,7,8,9,10
//11,0,0,0,0,0,0,0
//then repeating nulls until interrogated again
const int clkStall = 3; //Used to stall clock in communication with accelerometer
const float G_convert =0.055000055; //Constant used to convert ADC data to G-forces
//4095 for max voltage on 12bit ADC
//3.3V operational voltage
//0.3663V = 1g output
//G = (axis-vref)/4095*(3.3/0.3663)
//G = (axis - vref)*0.0022000022
//G/4 for shifting the data to align "0" bit
//G*100 to make output unit 0.01g
int j = 0; //Variable used for looping
float gforce = 0.0; //Calculated G-forces
word refCount = 0; //Refernce data from accelerometer
word axisCount = 0; //Axis data from accelerometer
//0 is X axis
//1 is Y axis
//2 is Z axis
//Get reference conversion
SPICR2_BIDIROE = 1; //Set pin for ouput
PTT_PTT0 = 0; //Turn accelerometer on
PORTA = SPI_trans(3 + 24); //Request reference
//Reads erroneous data
SPICR2_BIDIROE = 0; //Set pin for input
PORTA = SPI_trans(0xFF); //Save MSB data
PORTB = SPI_trans(0xFF); //Save LSB data
PTT_PTT0 = 1; //Turn accelerometer off
refCount = PORTAB; //Save reference count
for( j=0 ; j<clkStall ; j++ ){} //Delay loop for next accelerometer data
//500ns minimum
//3 * 250 = 750ns
//Get Axis conversion
SPICR2_BIDIROE = 1; //Set pin for output
PTT_PTT0 = 0; //Turn accelerometer on
PORTA = SPI_trans(i + 24); //Request axis
//Reads erroneous data
SPICR2_BIDIROE = 0; //Set pin for input
PORTA = SPI_trans(0xFF); //Save MSB data
PORTB = SPI_trans(0xFF); //Save LSB data
PTT_PTT0 = 1; //Turn accelerometer off
axisCount = PORTAB; //Save axis count
//calculate g-forces
gforce = (axisCount - refCount) * G_convert;
return gforce;
}//axis acceleration subroutine
byte SPI_trans(byte val)
//SPI tranmit subroutine developed from
//https://community.freescale.com/message/35017#35017
{
volatile byte garbage = 0; //Variable used to collect "garbage"
while (!SPISR_SPTEF); //Loops unitl Transmit Empty Flag is set
garbage = SPISR; //First step to clear flags
SPIDR = val; //Loads data and clears Flags
while (!SPISR_SPIF); //Loops until data is transfered(8 clocks)
garbage = SPISR; //First step to clear flags
return SPIDR; //Returns data in SPI data register to caller and clears flags
}//SPI transmit subroutine
Thanks!