Author Topic: SPI Driver - PIC18F25K22  (Read 5775 times)

0 Members and 1 Guest are viewing this topic.

Offline aboodiTopic starter

  • Contributor
  • Posts: 18
SPI Driver - PIC18F25K22
« on: May 26, 2014, 12:00:53 pm »
Hello everyone,

I am trying to build a header file to control SPI, but I started with a simple function within the main c file just to see if everything is good to start building the library, but unfortunately, I have been trying to get it working for 3 days (3 hours a day  |O ).

I also tried this code another chip, but the problem remains, so the problem is definitely a software problem. ><

Hopefully someone can spot the problem and help me.

MCU: PIC18F25K22, datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf

Code: [Select]

void main(void) {
       
    init_PIC();


writeSPI(0b11001100);

    while(1);

void writeSPI(unsigned char x){
   
    SSP1BUF = x;    //
    while(!SSP1STATbits.BF);

}


and this is from picInititialization.c

Code: [Select]
#include <xc.h>
#include "picInitializing.h"

#define _XTAL_FREQ 16000000

void init_PIC(){

    OSCCONbits.IRCF = 0x7; // 0x7: 16MHz, 0x5: 4MHz

    INTCONbits.GIE = 0; // global interrupts desabled

    PMD0 = 0xFF; // UART2 , UART1 &  timers 1- 6 modules are disabled
    PMD1 = 0b10111111; // MSSP2, CCP5-1 modules are disabled, except MSSP1
    PMD2 = 0xFF; // CTMU, comparator C2, comparator C1, ADC modules are disabled

    RCONbits.IPEN = 0;
    RCONbits.SBOREN = 0;

    ANSELA = 0x00; // digital input, not analog
    ANSELB = 0x00;
    ANSELC = 0x00;

    WPUB = 0;               // weak pull ups are disabled
    IOCB = 0;               // IOC is disabled
    SLRCON = 0x0F;          // slew rate control, disabled for all ports
    T0CONbits.TMR0ON = 0;   // timer0 module is disabled

    ADCON0bits.ADON = 0;    // ADC is disabled

    SRCON0bits.SRLEN = 0; // p. 340 // RS Latch is disabled

    VREFCON0bits.FVREN = 0; // (p.344) fixed voltage reference disabled
    VREFCON1bits.DACEN = 0; // (p.347) DAC disabled
    HLVDCONbits.HLVDEN = 0; // (p.349) high low voltage detect disabled

    TRISA = 0b11110000;   // 0xF0
    TRISB = 0b11110011;   // 0xF3
    TRISC = 0b11010100;   //

    SSP1CON1 = 0x20;// no collision, no OverFLow, ssp1 enabled
                      // clock polarity is low in idle state,
                      // SSP mode is MASTER (clock = Fosc/4)

    SSP1STAT = 0x40;// spi sampling: middle,   spi clock edge: idle>active (0x40)
                    // least 6 bits are read only


    SSP1ADD = 0x09; // baud generator ..
       
    return;

}


and from picInitialization.h

Code: [Select]

#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.


// PIC18F25K22 Configuration Bit Settings

// CONFIG1H
#pragma config FOSC = INTIO67   // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF     // 4X PLL Enable (Oscillator used directly)
#pragma config PRICLKEN = OFF   // Primary clock enable bit (Primary clock can be disabled by software)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRTEN = OFF     // Power-up Timer Enable bit (Power up timer disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 190       // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)

// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = PORTC1  // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)
#pragma config CCP3MX = PORTB5  // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5)
#pragma config HFOFST = OFF     // HFINTOSC Fast Start-up (HFINTOSC output and ready status are delayed by the oscillator stable status)
#pragma config T3CMX = PORTC0   // Timer3 Clock input mux bit (T3CKI is on RC0)
#pragma config P2BMX = PORTB5   // ECCP2 B output mux bit (P2B is on RB5)
#pragma config MCLRE = EXTMCLR  // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = OFF     // Stack Full/Underflow Reset Enable bit (Stack full/underflow will not cause Reset)
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF        // Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF        // Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF        // Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF       // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF       // Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF       // Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)

#define _XTAL_FREQ 16000000

// TRANSCEIVER SIGNALS                  // pinouts of cc2500 module
#define MOSI LATCbits.LATC5             // pin 2
#define SCLK LATCbits.LATC3             // pin 3
#define MISO PORTCbits.RC4              // pin 4
#define GD02_DCLK PORTBbits.RB1         // pin 5
#define GDO0_DIO PORTBbits.RB0          // pin 7
#define CC2500_module_CSN LATBbits.LATB3    // pin 8

« Last Edit: May 26, 2014, 12:05:57 pm by aboodi »
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: SPI Driver - PIC18F25K22
« Reply #1 on: May 26, 2014, 01:33:40 pm »
Quote
the problem remains

"the problem" is?
================================
https://dannyelectronics.wordpress.com/
 

Offline aboodiTopic starter

  • Contributor
  • Posts: 18
Re: SPI Driver - PIC18F25K22
« Reply #2 on: May 26, 2014, 02:41:50 pm »
Aah my bad,  sorry ????

The problem is that i cannot get any output from both of the clock and output data pins.

Thanks.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: SPI Driver - PIC18F25K22
« Reply #3 on: May 26, 2014, 02:57:53 pm »
Quote
The problem is that i cannot get any output from both of the clock and output data pins.

As in what? The output is floating / high / low?

As written, the code will just send the data once. So if you measured the lines a little bit late, you would have missed.

The code, for debugging purposes, makes no sense.
================================
https://dannyelectronics.wordpress.com/
 

Online mariush

  • Super Contributor
  • ***
  • Posts: 5012
  • Country: ro
  • .
Re: SPI Driver - PIC18F25K22
« Reply #4 on: May 26, 2014, 03:07:53 pm »
Add a loop, put in the loop something  for i = 32 to 126 , print  character with ascii code i , wait 250ms or so.  ascii table: http://commons.wikimedia.org/wiki/File:ASCII-Table-wide.svg

Set your scope to trigger properly and you should see those bits coming up every 250ms or so if everything's right..
 

Offline aboodiTopic starter

  • Contributor
  • Posts: 18
Re: SPI Driver - PIC18F25K22
« Reply #5 on: May 26, 2014, 03:39:27 pm »
Im probing both signals, but i cannot catch any change. Both signals go low and that is all.

From what I understood is that once I write to the SSP1BUF, data are copied to the shift register to be transferred with no need for the user to do anything.

I will try to use a loop as mariush suggested.

Abdullah
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: SPI Driver - PIC18F25K22
« Reply #6 on: May 26, 2014, 09:07:46 pm »
Also remember that after each SPI write you need to do a dummy read.  If you don't the next write will not work.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: SPI Driver - PIC18F25K22
« Reply #7 on: May 26, 2014, 09:59:22 pm »
The code simulated just fine.

I think the issue is that it is only run once so s/he like missed capturing it right after power on.

Code: [Select]
    SSP1BUF = x;    //
    while(!SSP1STATbits.BF);

This is the most efficient approach in terms of code / coding, but least efficient in terms of time: It waits until the transmission is over, which negates the purpose of having the buffer.

A more efficient approach is to use an interrupt; or to test the buffer full flag, load the buffer and exit. So the mcu can do other stuff when the spi module is shifting out the data. Very important if the spi transmission speed is low.

Unfortunately the way the spi module is set up, that kind of approach is not as straight forward is it sounds, for this (family) of chips.

The newer chips, like PIC24F, are much nicer in this regard: you can do seamless transmission there, via either interrupt or polling.
================================
https://dannyelectronics.wordpress.com/
 

Offline aboodiTopic starter

  • Contributor
  • Posts: 18
Re: SPI Driver - PIC18F25K22
« Reply #8 on: May 27, 2014, 04:00:29 am »
David_AVD: thanks for the reminder, I will try it as soon as I get back home.

dannyf: ( It's a "he").
that's for the simulation. I tried to add a 1 sec delay, but I will try it again with more than a sec.

An idea for the time efficiency, is to do something like:

Code: [Select]
void main(){
.
.
.

SPIwrite(x); // without checking the BF bit.

... // continue doing other stuff

if (!SSP1CON1bit.BF) { // check the BF bit

}



(a workaround that I have never tried, just had it as a thought)

Thanks for the help guys, will get back with results.

Abdullah
 

Offline aboodiTopic starter

  • Contributor
  • Posts: 18
Re: SPI Driver - PIC18F25K22
« Reply #9 on: May 28, 2014, 03:38:38 am »
still with the same issue ( that I can't see anything on the output), however, I noticed that the output data pin of the SPI module is trying to take the output HIGH, but it cannot, one it get's it high, something cancels that and it becomes LOW again. This happens every 4 secs. Strange!

I tried to play with the settings of the module but with no luck, the problem remains.
( also I have tried another chip on another circuit board but with no luck).

what do you think guys, I'm out of idea? >.<
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: SPI Driver - PIC18F25K22
« Reply #10 on: May 28, 2014, 03:56:14 am »
Is the watchdog timer disabled?
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: SPI Driver - PIC18F25K22
« Reply #11 on: May 28, 2014, 10:44:16 am »
Quote
trying to take the output HIGH, but it cannot, one it get's it high, something cancels that and it becomes LOW again. This happens every 4 secs.

That's hard to understand - maybe it is a hardware / pcb / connection issue  - in that case, no one can help you unfortunately.

Quote
what do you think guys

I would flip a pin in the main loop and see if you could see action on that pin.

Also, post a complete but minimalist piece of code that exhibits the problem.
================================
https://dannyelectronics.wordpress.com/
 

Offline aboodiTopic starter

  • Contributor
  • Posts: 18
Re: SPI Driver - PIC18F25K22
« Reply #12 on: May 28, 2014, 05:09:39 pm »
"
The code tries to take the SPI output HIGH, but it cannot, once it gets it high, something interrupts and it takes it LOW again. This happens every 4 secs.
"

***

Yes the WDT is disabled.

***

I do have an LED indicator, but i deleted it from the code just to save your time ^_^
 

Offline Vasi

  • Regular Contributor
  • *
  • Posts: 60
  • Country: ro
    • Visual Pin Configurator for Nucleo L152RE - produces SPL code.
Re: SPI Driver - PIC18F25K22
« Reply #13 on: June 01, 2014, 04:15:44 pm »
@aboodi, take Firewing for a test. You will be pleasantly surprised (free and with good performance). It supports PIC18F25K22 out of the box and also have a board for it.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf