• AVR Freaks

Hot!SPI not working in pic24ep64gp206

Author
JosepIzquierdo
New Member
  • Total Posts : 4
  • Reward points : 0
  • Joined: 2018/12/28 03:16:53
  • Location: 0
  • Status: offline
2019/02/11 05:35:14 (permalink)
0

SPI not working in pic24ep64gp206

Hi! i'm pretty new programmer, i'm trying to comunicate to a ADC (ADS1248) to SPI.
 
I'm not seeing any response from the pic with that code, i will apreciate some help.
 
void initADC(){ //SPI 1

SPI1STATbits.SPIEN = 0; // Disable SPI module, just in case

//Ports configuration

TRISCbits.TRISC11 = 0; //Pin RC11 as an output pin (START)
TRISBbits.TRISB7 = 1; //Pin RB7 as an input (_DRDY)
PORTCbits.RC11 = 1; //START pin HIGH

// SPI1CON1 Register Settings
SPI1CON1bits.DISSCK = 0; // Internal serial clock is enabled
SPI1CON1bits.DISSDO = 0; // SDOx pin is controlled by the module
SPI1CON1bits.MODE16 = 0; // Communication is byte-wide (8 bits)
SPI1CON1bits.MSTEN = 1; // Master mode enabled
SPI1CON1bits.SMP = 0; // Input data is sampled at the middle of data output time
SPI1CON1bits.CKE = 0; // Serial output data changes on transition from
/*SPI1 frequency
* Fsck = Fcy/(Primary * secondary prescaler)
* Fsck = 60MIPS/(16*1) = 3.75 MHz
*/
SPI1CON1bits.PPRE = 0b01; //Primary prescaler
SPI1CON1bits.SPRE = 0b111; //Secondary prescaler
//SPI1CON1bits.MSTEN = 1;
SPI1CON1bits.CKP = 0; //Idle in low lvl, active in rising edges

SPI1STATbits.SPIEN = 1; // Enable SPI module
}

 

ulong SPI1_recive(){
SPI1BUF = 0x00; //Send NOPS to the AD1247
while(SPI1STATbits.SPITBF); // Wait until data is loaded to the buffer Tx
while(!SPI1STATbits.SPIRBF); //Wait until buffer Rx is completed
unsigned char data_Rx = SPI1BUF;
while(SPI1STATbits.SPIRBF); //Waits until all the buffer Rx is read

return data_Rx;
}

post edited by JosepIzquierdo - 2019/02/13 01:12:26
#1

9 Replies Related Threads

    qhb
    Superb Member
    • Total Posts : 9998
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: SPI not working in pic24ep64gp206 2019/02/11 12:50:22 (permalink)
    0
    Probably not your problem, but I don't think you need either of the crossed out lines.
     
    ulong SPI1_recive(){
    SPI1BUF = 0x00; //Send NOPS to the AD1247
    while(SPI1STATbits.SPITBF); // Wait until data is loaded to the buffer Tx
    while(!SPI1STATbits.SPIRBF); //Wait until buffer Rx is completed
    unsigned char data_Rx = SPI1BUF;
    while(SPI1STATbits.SPIRBF); //Waits until all the buffer Rx is read
    return data_Rx;
    }
     
    and really, the last three lines could be replaced with just
    return SPI1BUF;

    Nearly there...
    #2
    Aussie Susan
    Super Member
    • Total Posts : 3565
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: SPI not working in pic24ep64gp206 2019/02/11 18:44:36 (permalink)
    0
    1) please use code tags
    2) Use the LAT registers to write to the pins (PORT registers are for reading only)
    3) please show us all of the code - you miss out the config settings, the I/O (and PPS) setup, how the oscillator is set up (and that can be important) and how the SPI calls are made
    4) are you sure the code is actually executing? How?
     
    On that device, SPI1 has dedicated pins you need to make sure that SCK1 (RC3) and SDO1 ((RA4) and set to output and SDI1 (RA9) is set to input. Whatever pin you want to use the the \SS\ signal to the slave also should be an output and you should be controlling that yourself as it is needed. RP20, RPI25 and RPI51 also map to those pins named above and so make sure that you are *NOT* mapping something else to those pins (although the SPI peripheral should take precedence).
    Susan
    #3
    FIDELE N
    New Member
    • Total Posts : 8
    • Reward points : 0
    • Joined: 2019/02/06 03:51:47
    • Location: UK
    • Status: offline
    Re: SPI not working in pic24ep64gp206 2019/02/12 09:13:13 (permalink)
    0
    Please use MCC, to setup SPI, It is then look one of the function to send and receive as I was stack last week in this 
    https://www.microchip.com/forums/m1085623.aspx
    Let me know if it is helping you on SPI, other side of your ADC, more reading the datasheet is needed I did on my 25AA256/25LC256.
    Cheers.
    #4
    Aussie Susan
    Super Member
    • Total Posts : 3565
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: SPI not working in pic24ep64gp206 2019/02/12 18:30:56 (permalink)
    0
    I disagree about using MCC for SPI - while it might reduce the work to a few clicks now, the code that it generates is (in my opinion) hideous and unnecessarily overly complex.
    What the OP has written is basically OK but it needs to be cleaned up as suggested above.
    Susan
    #5
    JosepIzquierdo
    New Member
    • Total Posts : 4
    • Reward points : 0
    • Joined: 2018/12/28 03:16:53
    • Location: 0
    • Status: offline
    Re: SPI not working in pic24ep64gp206 2019/02/13 00:59:28 (permalink)
    0
    Thanks for your help i will try your hints, if works i will post the solution
     
    I'm using only in this SPI1 the ADC so, i fix it by hardware, no ss signal need.
    And my internal clock is set to 120MHz (60MIPS)
    void clockRegisters()
    {
        CLKDIVbits.FRCDIV = 0b000; // Clock FRC (7.37 MHz) divided by 0
        
        PLLFBD=63; // M=65
        CLKDIVbits.PLLPOST=0; // N2=2
        CLKDIVbits.PLLPRE=1; // N1=3
    }

     
    And i know the code is executing because i'm debuging it with a ICD 3ç
     
    And here is my full SPI code (with your hints)
    void initADC(){ //SPI 1
        
        //Ports configuration
        TRISAbits.TRISA9 = 1 ; // SDI1
        TRISAbits.TRISA4 = 0 ; // SDO1
        TRISCbits.TRISC3 = 0 ; // SCK1
          
        SPI1STATbits.SPIEN = 0; // Disable SPI module, just in case

        TRISCbits.TRISC11 = 0; //Pin RC11 as an output pin (START)
        TRISBbits.TRISB7 = 1; //Pin RB7 as an input (_DRDY)
        LATCbits.LATC11 = 1; //START pin HIGH
                           
        // SPI1CON1 Register Settings
        SPI1CON1bits.DISSCK = 0; // Internal serial clock is enabled
        SPI1CON1bits.DISSDO = 0; // SDOx pin is controlled by the module
        SPI1CON1bits.MODE16 = 0; // Communication is byte-wide (8 bits)
        SPI1CON1bits.MSTEN = 1; // Master mode enabled
        SPI1CON1bits.SMP = 0; // Input data is sampled at the middle of data output time
        SPI1CON1bits.CKE = 0; // Serial output data changes on transition from
        /*SPI1 frequency
         * Fsck = Fcy/(Primary * secondary prescaler)
         * Fsck = 60MIPS/(16*1) = 3.75 MHz
        */
        SPI1CON1bits.PPRE = 0b01; //Primary prescaler
        SPI1CON1bits.SPRE = 0b111; //Secondary prescaler
        //SPI1CON1bits.MSTEN = 1;
        SPI1CON1bits.CKP = 0; //Idle in low lvl, active in rising edges
        
        SPI1STATbits.SPIEN = 1; // Enable SPI module
    }

    void SPI1_send(uchar data_Tx){
        SPI1BUF = data_Tx; //Data Tx transfered to general buffer
        while(SPI1STATbits.SPITBF); //Wait until data is loaded to the buffer Tx
        while(!SPI1STATbits.SPIRBF); //Wait until buffer Rx is completed

        SPI1STATbits.SPIRBF = 0; //Clear the receive buffer status bit
    }

    ulong SPI1_recive(){
        SPI1BUF = 0x00; //Send NOPS to the AD1247
        while(!SPI1STATbits.SPIRBF); //Wait until buffer Rx is completed

        return SPI1BUF;
    }

    void SPI1_sendInit(uchar data){
        int tmp;
        tmp = SPI1BUF ; //dummy read to clear SPIRBF flag
        SPI1BUF = data; //Data Tx transfered to general buffer
        while(SPI1STATbits.SPITBF); //Wait until data is loaded to the buffer Tx
        while(!SPI1STATbits.SPIRBF); //Wait until buffer Rx is completed
        
        SPI1STATbits.SPIRBF = 0; //Clear the receive buffer status bit
    }

    void InicializaADC(){
        
        SPI1_sendInit(0x06); //Send reset
        DELAYADC(600); //Delay 0.6ms
        SPI1_sendInit(0x16); //Send SDATAC
        //Send WREG
        SPI1_sendInit(0x43); //Write SYS0 (0 PGA[2:0] DR[3:0])
        SPI1_sendInit(0x01);
        SPI1_sendInit(0x00 | 0b01010000 | 0b00000010);
        DELAYADC(20);
        //End Send WREG
        SPI1_sendInit(0x04); //Send SYNC
        DELAYADC(2);
    }

    ulong getADCSample(){
        ulong tmp = 0;
        DELAYADC(5);
        FastTriggerSet(&timeoutADC,200000); //timeout 200ms
        Nop(); //wait 1 instruction
        while(DREADY_ADC){ //wait until data ready or timeout
            if( FastTriggerActivado(&timeoutADC) )
                return 99999;
        }
        DELAYADC(20); //Delay tcssc
        SPI1_send(0x12); //Send RDATA
        DELAYADC(6); //WAIT(24CLK) -> 24/4.096MHz = 5.911*10^-6 = 6us
        tmp = SPI1_recive();
        DELAYADC(2); //Delay tsccs

        return tmp;
    }

     
    Getting all the time the timeout (has to got it because i can't stay stack here in case ADC not responding) and i shuld get 20 samples per second (50000 ns period). 
     
    And sorry for not using the code tags, first time posting, i will edit in a few seconds
    post edited by JosepIzquierdo - 2019/02/13 01:32:00
    #6
    Aussie Susan
    Super Member
    • Total Posts : 3565
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: SPI not working in pic24ep64gp206 2019/02/13 19:08:32 (permalink)
    5 (1)
    Not using the \SS\ signal is a mistake - any stray clock pulse seen by the slave on the SCK line will get it out of sync and you will not get proper communications.
    I would recommend that you wait to get a PLL lock after changing the PLL configuration. The oscillator will be varying until the lock is obtained so any timing will probably be out. While this may not affect the SPI protocol (which really only looks at when the clock transitions occur) it is good practice.
    Backing up a little, what exactly is the problem?
    I would suggest that you forget all about the ADC slave for now and just code a very simply app that sets the oscillator (if you want - this is really optional as long as you have an oscillator running), initialises the SPI and then sends the 0x55 or 0xaa character over and over. Then do the following tests (which you can also do on your code but might be harder to see):
    Can you see the SCK1 line active when a character is being sent?
    Can you see the correct pattern on the SDO1 line?
    What do you see on the SDI1 line (even if you short the SDO1 and SDI1 pins together for this test)?
    What character do you receive in the SSP1BUF after the exchange completes? IS it the same as you saw on the SDI1 line?
    Susan
    #7
    JosepIzquierdo
    New Member
    • Total Posts : 4
    • Reward points : 0
    • Joined: 2018/12/28 03:16:53
    • Location: 0
    • Status: offline
    Re: SPI not working in pic24ep64gp206 2019/02/18 00:43:28 (permalink)
    0
    I was trying it this weekend, and it seems SPI works fine at least, my problem now supose is with the ADC.
     
    Thanks for your help.
     
    EDIT: btw the highest voltage i measure in the clock line is 500 mV, it's that ok? my Vcc is 3.3V
    post edited by JosepIzquierdo - 2019/02/18 04:24:45
    #8
    Aussie Susan
    Super Member
    • Total Posts : 3565
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: SPI not working in pic24ep64gp206 2019/02/18 18:27:56 (permalink)
    0
    Sounds like the SCK line is being loaded down.
    How are you measuring the SCK line - DMM or scope?
    Susan
    #9
    JosepIzquierdo
    New Member
    • Total Posts : 4
    • Reward points : 0
    • Joined: 2018/12/28 03:16:53
    • Location: 0
    • Status: offline
    Re: SPI not working in pic24ep64gp206 2019/02/21 03:22:13 (permalink)
    0
    After some test i realize the 47 ohm resistance i got in the MOSI and CLK line was broken (mesured 25.6 Mohm), and finaly the SPI works, now i got to face the ADC.
     
    Thanks for your help.
    #10
    Jump to:
    © 2019 APG vNext Commercial Version 4.5