0
\$\begingroup\$

I have a problem making the MCP795W10 RTCC chip working with a PIC24F16KA102 MCU. I tried RTCC chip with an Arduino and there it works perfectly. Here's is my SPI initialization code:

void configSpi() {
IFS0bits.SPI1IF = 0; //clear spif see datasheet
IEC0bits.SPI1IE = 1; //enable spi interru
 IPC2bits.SPI1IP = 0b100;
SPI1CON1bits.DISSCK = 0;
SPI1CON1bits.DISSDO = 0;
SPI1CON1bits.MODE16 = 0;
SPI1CON1bits.SSEN = 0;
SPI1CON1bits.SMP = 0;
SPI1CON1bits.MSTEN = 1;
SPI1CON1bits.CKP = 0;
SPI1CON1bits.CKE = 0;
SPI1CON1bits.SPRE = 0b110;
SPI1CON1bits.PPRE = 0b11;
SPI1STATbits.SISEL=0b101;
SPI1STATbits.SPIROV = 0;
SPI1STATbits.SPIEN = 1;     
LATBbits.LATB12 = 1;}

To write to the RTCC chip I use the following function

void  writeSPI1( unsigned char data )
{SPI1BUF = data;    }

When I use this function MCU automatically goes to the SPI interrupt and in the interrupt I do this:

void __attribute__((interrupt, auto_psv)) _SPI1Interrupt(void) {

IFS0bits.SPI1IF = 0;  // clear this bit. This bit will be set when a new reading is recieved
LATBbits.LATB8=~ LATBbits.LATB8;

if (!SPI1STATbits.SPIROV)// no overflow, you may more than one byte,it will take last byte
{
        //My_Slave_Array = My_Slave_Array[spiCount++] + 1;  // loop with data + 1
    while (!SPI1STATbits.SPIRBF);
    spiBufR = SPI1BUF;
    //SPI1BUF = spiBufT;                // send back
}   

}

The problem is that in the main code when I configure the config register (for example) and I want to read it back, but I get something wrong.

Main code:

int main(void) {
LATBbits.LATB2 = 0; //wake up xbee
 __C30_UART = 2;
configOscillator();
pinsetup();

//enableINT0IE(); //interrupt reed switch
//enableINT1IE(); //interrupt rtc
//enableINT2IE(); //interrupt btn config
//uart2Set();
configSpi();
//configxbee();

//getpanid();

//LATBbits.LATB2 = 1; //xbee in sleep 
//setAlarmsec(10);
while(1){
    unsigned char i;
     LATBbits.LATB12 = 0; //begin spi
     writeSPI1(0x12);
     writeSPI1(0x08);
     writeSPI1(0x00);
     LATBbits.LATB12 = 1;
     __delay_ms(10);
     LATBbits.LATB12 = 0; //begin spi
     writeSPI1(0x13);
     writeSPI1(0x08);
     writeSPI1(0x00);
     i=spiBufR;
     LATBbits.LATB12 = 1;
     __delay_ms(10);}
return 0;

I tried a lot of stuff but none worked for me so far. Thanks in advance.

\$\endgroup\$
  • \$\begingroup\$ You may be overwriting the SPI transmit register with the 3 calls to writeSPI1() without checking the SPI status in between to see if the prior transmit has completed. \$\endgroup\$ – Entrepreneur Jun 3 '17 at 12:06
  • \$\begingroup\$ thats no true i check it in the interrupt \$\endgroup\$ – Zinedine Jun 3 '17 at 15:27
  • \$\begingroup\$ "but I get something wrong." - what exactly is 'wrong'? \$\endgroup\$ – Bruce Abbott Jun 3 '17 at 16:17
  • \$\begingroup\$ on the first line i put in register 0x08 0x00 so everything is zero but when i read it after the i dont get 0x00 but something random \$\endgroup\$ – Zinedine Jun 3 '17 at 17:26
  • \$\begingroup\$ Try inserting delays after each writeSPI1() for troubleshooting purposes, and to see if the symptom changes. \$\endgroup\$ – Entrepreneur Jun 3 '17 at 20:56
1
\$\begingroup\$

hello i fix the probleme i removed the interrupt and i wait for an answer when i wirte to to rtc see my code bellow thanks for your time

void configSpi() {
SPI1STATbits.SPIEN      = 0;
SPI1BUF                 = 0;
IFS0bits.SPI1IF = 0; //clear spif see datasheet
IEC0bits.SPI1IE = 0; //enable spi interrupt
IPC2bits.SPI1IP = 0b100;
SPI1CON1bits.DISSCK = 0;
SPI1CON1bits.DISSDO = 0;
SPI1CON1bits.MODE16 = 0;
SPI1CON1bits.SSEN = 0;
SPI1CON1bits.SMP = 0;
SPI1CON1bits.MSTEN = 1;
SPI1CON1bits.CKP = 0;
SPI1CON1bits.CKE = 1;
SPI1CON1bits.SPRE = 0b110;
SPI1CON1bits.PPRE = 0b11;
//SPI1STATbits.SISEL=0b101;
SPI1STATbits.SPIROV = 0;
SPI1CON2bits.FRMEN = 0; // desactivation du mode framed
SPI1CON2bits.SPIBEN = 0;    // desactivation du buffer
SPI1STATbits.SPIEN = 1;     
LATBbits.LATB12 = 1;

}

and this is for writing and reading

unsigned short writeSPI1( unsigned short data ){
SPI1BUF = data;                 // write to buffer for TX
while(!SPI1STATbits.SPIRBF);    // wait for transfer to complete
return SPI1BUF;                 // read the received value
}//writeSPI1
\$\endgroup\$
0
\$\begingroup\$

You should read the SPI1BUF on entry to writeSPI1() then poll the SPIRBF bit before exiting writeSPI1().

Your interrupt routine as it stands does not execute until AFTER the entire SPI transmit completes, which means multiple bytes might be stuffed into the transmit register before the interrupt ISR executes, and by then an overwrite error has already occurred.

In addition, you are removing the SS slave select too soon, immediately after loading the transmit register, and before the slave can completely receive the transmitted byte or send back the return byte.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.