Hi,
I have problems trying to communicate a MCF51MM256 with PCF2127A RTC through SPI. I am using a TWR_MCF51MM-Kit. I set MCF51MM256 as master and it seems that the transfer of commands and data go out but i am not getting the answer I hope from the RTC, i.e, when I try to do a sequential red i just got a byte with an illogical value. I'll put my code below:
//************************************* // MCF51MM256 Init //***************************************/ void MCU_Init(void) { SOPT1 = 0x23; /* disable COP, enable stop mode, enable BKGD and RESET pin */ SCGC1 = 0x00; /* Disable Bus clock to unused peripherals */ SCGC2 = 0x01; /* Bus Clock to the SPI1 module is enable */ SCGC3 = 0x00; /* Disable Bus clock to unused peripherals */ } //************************************* // SPI_Init //**********************************/ void SPI_Init(void) { SPI1C1 = 0x54;// Enable SPI1, sets SPI as master Device, // transfers start with most significant bit SPI1C2 = 0x00;// SPI1 in 8-bit mode, separate pins for input/ output SPI1BR = 0x04; // prescale divisor 1, baudrate divisor 32 // getting aprox 131 kHz SPI2C1 = 0x00; //0 0 0 0 0 0 0 0 // Disable SPI2 SPI1S = 0x00; // Wait until ready to send while ( !(SPI1S & SPI1S_SPTEF_MASK) ); SPI1ML = 0xFF; } //********************************* // Init_RTC //***************************************/ void Init_RTC( void) { byte i, buffer[ 2 ]; buffer[0] = 0x20 | 0x03; // command for writng Seconds register on RTC buffer[1] = i2bcd( 15 ); // value to write on Seconds register CS_ON; // set chip enable sign for RTC through a GPIO while ( !(SPI1S & SPI1S_SPTEF_MASK) ); for ( i = 0; i < 2; i++ ) { SPI1DL = buffer[i]; // Send byte value while( !(SPI1S & SPI1S_SPTEF_MASK) ); } CS_OFF; // disable connection sign to RTC } //******************************** // Read_RTC //**************************************/ byte Read_RTC( void) { byte i, buffer[ 2]; buffer[0] = 0xA0 | 0x03; // command for reading Seconds register on RTC CS_ON; // set chip enable sign for RTC through a GPIO while ( !(SPI1S & SPI1S_SPTEF_MASK) ); SPI1D = buffer[0]; // Send command byte while ( !(SPI1S & SPI1S_SPTEF_MASK) ); while ( !(SPI1S & SPI1S_SPRF_MASK) ); buffer[1]= SPI1DL; CS_OFF; return bcd2i(buffer[1]); } //*************************************** // MainLoop //*************************************/ void main(void) { EnableInterrupts; /* enable interrupts */ /* include your code here */ MCU_Init(); // ... Use here some code that initializes the Ports of the MCU SPI_Init(); Init_RTC(); // ... Use here some dummy code to introduce a time delay byte s = Read_RTC(); for(;;) { __RESET_WATCHDOG(); } // // please make sure that you never leave main }
Some suggestions about causes for not getting the "logical" values ?
While I am trying to debug this code with CodeWarrior Real Time Debugger I can not see changes in the contents of the Memory at the address of SPI1DL register after
SPI1DL = buffer[i];
instructions is executed.
i2bcd() and bcd2i() are just funstions for coding numbers.
Thanks for your attention, in advance
Solved! Go to Solution.
Do you know what FLS module is? You disabled clock to them, but maybe it is somehow coupled to SPI?
S08 have similar SPI modules. Try searching 8-bitters forum for code examples.
I think your code should produce some SPI clocks, though I don't have MCF51MM to try what's wrong. I can only advice that routine for master I/O, both read from spi and write to spi should look like this
char spiio(char tosend)
{
while ( !(SPI1S & SPI1S_SPTEF_MASK) );
SPIDL = tosend;
while ( !(SPI1S & SPI1S_SPRF_MASK) );
return SPIDL;.
}
Doing master SPI you can't receive without sending something. Also when sending, you receive some data, like you that or not. Routine is for both send and receive.
2. You are setting CS off prematurely in Init_RTC(). SPTEF flag is set long before transfer is complete. I hope you have scope to check it.
3. You can't read SPID output buffer. Reads from data register return data from SPI input buffer.
Thank you very much Kef for your answer.
I have archived a lot of progress... However, I can not found the way to read data from the slave. As I understand, master have to generate the clock signal to the slave but I have not found in the documentation how set it. I have tested using the GPIO ports and I get data from the RTC properly. But when I use the SPI module, I see in the scope that clock is stoped when I want to get data. I guess I am missing something but not idea about what.
Thanks in advance,
Do you know what FLS module is? You disabled clock to them, but maybe it is somehow coupled to SPI?
S08 have similar SPI modules. Try searching 8-bitters forum for code examples.
I think your code should produce some SPI clocks, though I don't have MCF51MM to try what's wrong. I can only advice that routine for master I/O, both read from spi and write to spi should look like this
char spiio(char tosend)
{
while ( !(SPI1S & SPI1S_SPTEF_MASK) );
SPIDL = tosend;
while ( !(SPI1S & SPI1S_SPRF_MASK) );
return SPIDL;.
}
Doing master SPI you can't receive without sending something. Also when sending, you receive some data, like you that or not. Routine is for both send and receive.
Thanks kef, yesterday I made some tests and everything went right.
I consider that the sentence
"Doing master SPI you can't receive without sending something"
is the principal point that I was not applying.
Best regards,