Hello Sir,
This is regarding the SPI communication with RF transceiver. I am trying to establish Master- Slave communication using SPI with microcontroller (Master) and RF transceiver (Slave). The microcontroller used is S12X series : MC9S12XEQ512 (SPI1 port is used), RF transceiver which has 3 wire interface for SPI communication (SCLK, DIO, CS).
The microcontroller pins MISO1 and MOSI1 are shorted together on board to interface with DIO line of 3 wire- SPI Transceiver IC.
Here is the following code:
#define W_OSC 0x45; //write command: 0x1 and register address as 0x05: transceiver//
#define W_PC 0x40;
#define RD_OSC 0x85; //read command: 0x2 and register address as 0x05: transceiver//
void SPI_TXR_Init(void)
{
unsigned char Test0;
unsigned char STATUS1;
unsigned char STATUS2;
STATUS1=0;
STATUS2=0;
{
SPI1DR=0x00FF; //start of sending SCK //
Test0=SPI1SR;
}
{
SPI1DRH=W_OSC; //for writing//
SPI1DRL=0xB0; // 0000 1100 oscillator frequency which is 176//
delay(50); //defined//
Test0=SPI1SR;
SPI1DRH=RD_OSC; // for reading//
SPI1DRL=0x00;
delay(50);
PTP_PTP3=1; // CS high//
delay(10);
PTP_PTP3=0; // CS low//
delay(10);
DDRP_DDRP0=0; //Micro SPI pins, MISO_R for input//
DDRP_DDRP1=0; // Micro SPI pins MOSI_R for input//
PTP_PTP1=0; // Micro SPI pins MOSI_R is low/
PTP_PTP0=0; // Micro SPI pins MISO_R is low/
delay(150);
delay(150);
Test0=SPI1SR;
STATUS1=SPI1DRH; //tried to store data here//
STATUS2=SPI1DRL;
delay(50);
}
{
SPI1DRH=W_PC; //for writing//
SPI1DRL=0x30; // 0011 0000 Enable Mixer, Baseband enable , disable PA only//
delay(50);
Test0=SPI1SR; //want to read this as well//
}
}
void main(void)
{
//code for clock setting to 25MHz//
//port setting//
DDRP_DDRP0=0; //MISO_R for input//
DDRP_DDRP1=1; //MOSI_R for output//
DDRP_DDRP2=1; //SCK_R for output//
DDRP_DDRP3=1; //CS_R is output//
PTP_PTP3=1; // CS_R is high/
PTP_PTP1=0; // MOSI_R is low/
PTP_PTP0=0; // MOSI_R is low/
PTP_PTP2=1; // SCK is set high//
//SPI initialization//
SPI1CR1_SPE=1; //SPI enabled, port pins are dedicated to SPI functions.//
SPI1CR1_SPIE=0; // SPI interrupts disabled.//
SPI1CR1_SPTIE=0; // interrupt request are disabled//
SPI1CR1_MSTR=1; //SPI is in master mode.//
SPI1CR1_CPOL=0; //Active-high clocks selected. In idle state SCK is low.//
SPI1CR1_CPHA=0; //Sampling of data occurs at odd edges//
SPI1CR1_SSOE=0; //SS is not enabled//
SPI1CR1_LSBFE=0; //MSB first//
SPI1CR2=0x49; // 0100 1001 (16 bit transfer, MODFEN=0, BIDIROE=1, SPC0=1, SS pin used, ouput buffer disabled,master mode //
SPI1BR=0x07; // Baud rate: 97.66 kbit/s in D-10B (25MHz / 256)//
SPI1CR1_SSOE=1; //SS is enabled//
//Powering up of TXR//
PORTA_PA0=1; // Drive high for normal operation of MAX7032//
delay(200);
PTP_PTP3=0; // CS_R is low to enable the slave/
delay(200);
PORTA_PA1=1; // Drive high for normal operation of MAX7032, TX/-RX_R//
SPI_TXR_Init();
….
}
For this code, I am able to send commands to RF transceiver from microcontroller, but when it comes to reading, I didn’t get any data.
I tried reading for address register: 0x05 and 0x00, but the code does not return any value.
Could you please check and let me know where is the problem?
Also, would like to know what is the procedure of reading the data from SPI so as to ensure the data is written to slave is correct.
To read from slave device you need to send something to it.
Test0=SPI1SR;
STATUS1=SPI1DRH; //tried to store data here//
STATUS2=SPI1DRL;
^^ this clears SPIF but only pulls data from data register, it doesn't clock SPICLK, so doesn't read anything new from your slave. This is simple read write routine for master:
unsigned char putspi(unsigned char data)
{
SPIDR = data; /* initiate transfer, first status reg read is done in init routine*/
// wait while clocking
while(!(SPISR & SPISR_SPIF_MASK))
{
}
// read and return data received from slave
return SPIDR;
}
To send
putspi(data);
to read
data=putspi(0/*any data or data according to your protocol*/);
Since you have bidirectional data line
SPICR2 &= ~SPICR2_BIDIROE_MASK; /* disable output buffer*/
data = putspi(0);
SPICR2 |= SPICR2_BIDIROE_MASK; /* enable output buffer */
I don't know details of your CS pin requirements, but usually automatic SS toggle by S12(X) doesn't match slave protocol requirements, just toggle CS when necessary bitbanging I/O pin. Since slave may drive data pin while CS is asserted, reenable BIDIROE after releasing CS.
Your initialization toggling different SPICRx pins may not work operating standalone without BDM debugger, you'd better write all SPICRx bits simultaneously.
void SPIInit(void)
{
(void)SPISR; //read status, required
SPIBR = 0; /*set bit rate, use appropriate value */
// set up CR1/2 bits all at once. Don't guess CPOL/CPHA settings, guessed CPOL/CPHA will
// sometimes work and 99% bite you later.
SPICR1 = SPICR1_SPE_MASK | SPICR1_MSTR_MASK /*| SPICR1_CPOL_MASK*/ /*| SPICR1_CPHA_MASKCPHA*/;
SPICR2 |= SPICR2_SPISWAI_MASK | SPICR2_BIDIROE_MASK | SPICR2_SPC0_MASK;
}
Edward