CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

SPI not working on 18F26J50
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jim Oram



Joined: 01 Jan 2010
Posts: 24
Location: Charlotte

View user's profile Send private message

SPI not working on 18F26J50
PostPosted: Sat Mar 30, 2013 7:31 am     Reply with quote

Support, using my new PCW compiler:
For several days I have been trying to get the SPI to work on a 18F26J50, (28 pin dip).
I am using:
Code:

#use SPI (MASTER, di=pin_b5, do=pin_c7, clk=pin_b4)
//                  pin 26     pin 18      pin 25
#use rs232 (baud=4800,parity=N,xmit=PIN_C0,rcv=PIN_C1,bits=8,errors)
setup_spi(SPI_MASTER | SPI_L_TO_H | spi_clk_div_16);

On the digital storage scope I can see the 8 clocks on pin 25 but no data on the data output pin_c7 pin 18 which remains high all the time.
I tested the output on pin_c7 using another simple program that toggles pin_c7 high and low to make sure it was able to work ok.

Some of the code:
Code:

spi_write('X');   // write X to to the SPI pin 18.
while (bit_test(PIR1,SSP1IF) == 0)
{  };                     //wait till data is sent out RCSTA1
bit_clear(PIR1,SSP1IF);

spi_data_in = spi_read(0xFF);
// required to use "0xFF" to generate a clock

bit_clear(PIR1,SSP1IF);
delay_ms(2);
TXREG1 = 'R'; 
// send 'R' debug info to PC Comm Operator via mcp2200 USB chip.

I get the debug 'R' on the PC indicating the program got to the "Read".
Is there something I am doing wrong in the way I am using SPI?

I hope you can help, time is becoming short.

Thanks Kindly,
Jim
_________________
Jim Oram
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Mar 30, 2013 8:38 am     Reply with quote

setup_spi, only works with the hardware SPI. No need to tell it the pins
except where you have re-mappable pins.
So:
Code:

//Get rid of #use spi- Use it if you want streams, or software
//spi. Only use setup_spi, or #use, not both.

//Device headers etc..

//Now setup the UART pins
#pin_select TX2=PIN_C0
#pin_select RX2=PIN_C1 //Uart 2

#use rs232 (baud=4800,parity=N,UART2,bits=8,errors)
//Tell the compiler you want to use the hardware UART - note 'UART2'
//Only UART2 can be mapped to the pins you want. Might as well use the
//hardware since it is there!...

void main(void)
{
   int8 spi_data_in;
   setup_uart(FALSE); //Should be default, but this will override
   //pins C6/7, so better to be safe.

   setup_spi(SPI_MASTER | SPI_L_TO_H | spi_clk_div_16);

   while (TRUE)
   {
      spi_write('X'); // write X to to the SPI pin 18.
      //If you do want to wait, that is what the spi_data_is_in function is for
      while (!spi_data_is_in()) ;
      //wait till data is sent out RCSTA1
      //You don't actually need this the CCS function defaults to testing
      //The interrupt flag is also cleared by the compiler when a new
      //transfer is done
      spi_data_in = spi_read(0xFF);
      //required to use "0xFF" to generate a clock
      //No - _any_ byte will generate a clock
      delay_ms(1);
   }
}

'Setup_spi' only works with the hardware SPI. #use spi can be used instead, but then you should use sfi_xfer to do the I/O. Mixing both gets into 'black arts'. They are two different ways of doing things, and you will find they don't refer to each other in the manual entries. This is reported now to work, but can be asking for problems (especially on TRIS control, with chips with re-mappable peripherals), and depending on the compiler version.
So this may be the problem.
Other things, would depend on the code around. A small compilable 'demo', is the way to go. One classic would be if you have the USB driver loading, and debugging enabled. This defaults to using UART1, which would override the SDO pin.
I've added, showing how to use the second hardware UART for your serial output, which will avoid the timing errors that will otherwise appear if interrupts occur....

Best Wishes
Jim Oram



Joined: 01 Jan 2010
Posts: 24
Location: Charlotte

View user's profile Send private message

SPI not working on 18F26J50
PostPosted: Sun Mar 31, 2013 11:20 pm     Reply with quote

Support,
Thank you for the suggested code to get SPI running.
The SPI does output data now, but the reassignment of UART2 port pins to C0 and C1 does not seem to work. Is is something with the Tris setting?
I think I need more explanation about pin reassignments.

Thank You Very Kindly,
Jim
Here is what you suggested ... but I added some LED test code.
Code:

// ---------- from CCS - modified with test LEDs ------------
//
//Get rid of #use spi- Use it if you want streams, or software
//spi. Only use setup_spi, or #use, not both.

//Device headers etc..

//Now setup the UART pins
#pin_select TX2=PIN_C0
#pin_select RX2=PIN_C1 //Uart 2

#use rs232 (baud=4800,parity=N,UART2,bits=8,errors)
//Tell the compiler you want to use the hardware UART - note 'UART2'
//Only UART2 can be mapped to the pins you want. Might as well use the
//hardware since it is there!...

void main(void)
{
   int8 spi_data_in;
   int8 x;
   set_tris_a(0x07); // 07);
   set_tris_b(0xE3); // E3);  // 1110 0011
   set_tris_c(0x36); // );    // 0011 0110

   setup_uart(FALSE); // Should be default, but this will override
   // pins C6/7, so better to be safe.

   setup_spi(SPI_MASTER | SPI_L_TO_H | spi_clk_div_16);

   TXREG2 = '1';     // output S to Comm Operator for start.
   output_high(REDLED); // indicator off

   while (TRUE)
   {
      TXREG2 = 'S';     // output S to Comm Operator for Start. (does not show up on pin_c0)
      for(x = 0 ; x < 5 ; x++){
       output_low(GRNLED);  // green led on.
       delay_ms(100);
       output_high(GRNLED); // green led off.
       delay_ms(100);
      }

      output_low(REDLED);   // red led on.
      delay_ms(200);

      spi_write('X'); // write X to to the SPI pin 18.

      output_high(REDLED);  // red led off

      //If you do want to wait, that is what the spi_data_is_in function is for.

      bit_clear(SSP1CON1, SSPOV);  // clear any overflo, may not be needed.

      while (!spi_data_is_in());

      //
      //wait till data is sent out RCSTA1
      //You don't actually need this the CCS function defaults to testing
      //The interrupt flag is also cleared by the compiler when a new
      //transfer is done
      spi_data_in = spi_read(0xFF);
      output_low(REDLED);  // red led on.
      delay_ms(50);
      output_high(REDLED); // red led off.
      delay_ms(50);

      //required to use "0xFF" to generate a clock
      //No - _any_ byte will generate a clock
      restart_wdt();
   }
}

_________________
Jim Oram
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Apr 01, 2013 1:14 am     Reply with quote

Yes. Forgot this (I often use use fast_io, and set the tris myself). Because the compiler doesn't 'know' what pin your UART it on, it doesn't handle TRIS for you. So you need to specify 'output_float' for the RX pin, and 'output_drive' for the TX pin.
Use fputc, rather than sending values directly to TXREG. You are not checking the buffer is empty before sending, so could overflow the UART. fputc does this for you.

Best Wishes
Jim Oram



Joined: 01 Jan 2010
Posts: 24
Location: Charlotte

View user's profile Send private message

SPI not working on 18F26J50, but TX2 using fputc('x') hangs
PostPosted: Mon Apr 01, 2013 6:52 am     Reply with quote

Dear Ttelmah,
I tried as you suggested using fputc(char) ... but the program hangs right there. This is strange. Looking up fputc in the new PCW compiler manual on page 175 does not seem to have anything about fputc .

As suggested I am using:
Code:

#use fast_io(C)
//Now setup the UART pins
#pin_select TX2=PIN_C0  // (no data seen there)
#pin_select RX2=PIN_C1  // Uart 2
set_tris_c(0x36);             // 0011 0110

#use rs232 (baud=4800,parity=N,UART2,bits=8,errors)

using TXREG2 = '1'; // (0xFA9)
// but no data from UART2 on C0, and using fputc('1') hangs;

SPI does work thanks to you! Now the USART2 must be made to work.

But I still must be doing something wrong on the USART2. Any of your suggestions are very helpful.

Thank You Very Kindly,
Jim
_________________
Jim Oram
jeremiah



Joined: 20 Jul 2010
Posts: 1345

View user's profile Send private message

Re: SPI not working on 18F26J50
PostPosted: Mon Apr 01, 2013 8:08 am     Reply with quote

Jim Oram wrote:
Support


Just as a quick note, to avoid confusion, we are not members of support. This is a user forum. CCS support is reached by email/phone. We'll definitely try to help, but please be aware that per the note on the top left corner of this webpage that CCS doesn't always monitor these threads on a regular basis.

In terms of the UART issue: perhaps take a step back and just do a simply UART only program on your chip to see if you can get it working at all. Something simple:
Code:

#include for your pic
#FUSES
#use delay() call
#pin_select lines
#use rs232() call
void main(){
   printf("hello world\r\n");
   while(TRUE);
}

That's mostly pseudo code. Leave out things like fast I/O and TRIS settings and just pare it down to a very simple program to test out the UART. If you still have issues, post that small code (in full...FUSES and all) so we can see it.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Apr 01, 2013 8:19 am     Reply with quote

fputc needs a stream name. so you use:
Code:

#use rs232 (baud=4800,parity=N,UART2,bits=8,errors,stream=COMM2)

fputc('1',COMM2);


fputc, is under putc in the manual. It's what allows you to have multiple UARTs (software of hardware) enabled, and use the right one.
However the TXREG2 approach should give data. It just risks corruption....

The second UART should work. I'm using it on my own code (but routed to different pins, with:
Code:

   #pin_select TX2=PIN_B2
   #pin_select RX2=PIN_B3 //Uart 2

#use rs232(baud=57600,parity=N,UART2,bits=8,stream=PORT2,errors) //controller

    fputc(temp,PORT2);

//where temp is the character I'm sending - it's in INT_TBE2,
//since I'm using interurpt driven TX/RX.

Only thing that would stop it, is if some other peripheral is on the pins. Just like with the SPI, where I make 'sure' the UART is off. The one that could apply here is Timer1.

Best Wishes
Jim Oram



Joined: 01 Jan 2010
Posts: 24
Location: Charlotte

View user's profile Send private message

"hello world" is working, but now the SPI does not
PostPosted: Mon Apr 01, 2013 4:30 pm     Reply with quote

Hello Ttelmah,
The "hello world" is working, but now the SPI does not work.
Redirecting pin assignments seem to work.

Prior to adding the "hello world" the SPI WAS working.
So something is not right.... I thought I could use UART2 with pin assignments and SPI at the same time.
Your comments are most needed and appreciated.

Here is the whole code as constructed from helpful CCS forum comments:
// ---------- from CCS user forum - modified with test LEDs ------------
//
//Get rid of #use spi- Use it if you want streams, or software
//spi. Only use setup_spi, or #use, not both.

//Tell the compiler you want to use the hardware UART - note 'UART2'
//Only UART2 can be mapped to the pins you want. Might as well use the
//hardware since it is there!...

#include <18F26J50.h>
#FUSES wdt,noprotect //,HS
#use fast_io(C)
#use delay(clock=8000000,RESTART_WDT)
#byte OSCCON = 0x0FD3
#byte BAUDCON1 = 0x0F7E
#byte BAUDCON2 = 0x0F7C
#byte SPBRG1 = 0x0FB0 // low byte
#byte SPBRG2 = 0x0FAB // low byte
#byte SPBRGH1 = 0x0F7F // EUSART1 Baud Rate Generator Register High Byte
#byte SPBRGH2 = 0x0F7D // EUSART2 Baud Rate Generator Register High Byte
#byte SSP1CON1 = 0x0FC6

#pin_select TX2=PIN_C0 // I/O pin assignment:
#pin_select RX2=PIN_C1 // use Uart 2 connect to PIN_C0 and C1

#use rs232 (baud=4800,parity=N,UART2,bits=8,errors,stream=COMM2)

#define STREAM_ARRAY_SIZE 35 // array size yet to be used.
#define GRNLED PIN_B6
#define REDLED PIN_B7
#define SSPOV 6

int8 x; // Test program to sort out UART2 and SPI

void main(){
OSCCON = 0x70; // 8mhz
SPBRGH2 = 0; // Data sheet Page 329
SPBRG2 = 103; // 103;
BAUDCON2 = 0x00; // 0x08; BRG16 bit 3

SPBRGH1 = 0; //
SPBRG1 = 103; // 103;

setup_spi(SPI_MASTER | SPI_L_TO_H | spi_clk_div_16);

while(TRUE){
fputc('1',COMM2); // fputc to COMM2 works.
delay_ms(1);
printf("hello CCS\r\n");

// bit_clear(SSP1CON1, SSPOV); // clear any overflo, may not be needed.
// Hangs on the next line when uncommented:

// spi_write('X'); // write X to to the SPI pin 18. HANGS !

delay_ms(500);
for(x = 0 ; x < 3 ; x++){
output_low(GRNLED); // green led on.
delay_ms(100);
output_high(GRNLED); // green led off.
delay_ms(100);
}
}
}

Thanks Kindly,
Jim
_________________
Jim Oram
jeremiah



Joined: 20 Jul 2010
Posts: 1345

View user's profile Send private message

PostPosted: Mon Apr 01, 2013 5:26 pm     Reply with quote

You should still simplify it. You are doing a lot of things that CCS can handle and you still have some code not needed to test out SPI and UART (such as WDT)

Also, please use "code" tags so your code is more readable. I don't have your chip to test on, but try this out:
Code:

#case
#include <18F26J50.h>
#FUSES NOWDT,NOPROTECT,INTRC
#use delay(clock=8000000)

#pin_select TX2=PIN_C0 // I/O pin assignment:
#pin_select RX2=PIN_C1 // use Uart 2 connect to PIN_C0 and C1

#use rs232 (baud=4800,parity=N,UART2,bits=8,errors,stream=COMM2)


void main(){

   setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);

   while(TRUE){
      fputc('1',COMM2); // fputc to COMM2 works.
      fprintf(COMM2," hello CCS\r\n");
     
      spi_write('X'); // write X to to the SPI pin 18. HANGS !
     
      delay_ms(500);
     
   }
}


Take a look at the fuses I specified. Also take a look at your SPI setup and make sure it is in the mode you want it to be (can do a search on this forum for SPI mode to find out about how to set those). I didn't make changes to the SPI setup. I took out a lot of direct register code and the fast IO

This code should just print out stuff continuously and also spew out some SPI data every so often.
Jim Oram



Joined: 01 Jan 2010
Posts: 24
Location: Charlotte

View user's profile Send private message

Code for the 18F26J50 to use USART2 and spi_write() together
PostPosted: Mon Apr 01, 2013 8:08 pm     Reply with quote

jeremiah,
Thank you for the test code. Most appreciated.
I used your code and included LEDs for DeBug.
The code hangs on spi_write('X') . (Green LED stays on)
The pin assignments work, and data appears on C0 and is sent to Comm Operator at 4800 baud through a MCP2200 USB chip.
The MCP2200 chip will offload the 18F chip when I load the TCP/IP stack with TLS. That is why I need USART2 and SPI at the same time.

Code:
// ---- test code from jeremiah CCS forum, modified with LEDs for DeBug ------
//  Hangs on spi_write('X')
#case
#include <18F26J50.h>

#FUSES NOWDT,NOPROTECT,INTRC
#use  delay(clock=8000000)
#byte OSCCON   = 0x0FD3
#byte BAUDCON1 = 0x0F7E
#byte BAUDCON2 = 0x0F7C
#byte SPBRG1   = 0x0FB0  // low byte
#byte SPBRG2   = 0x0FAB  // low byte
#byte SPBRGH1  = 0x0F7F  // EUSART1 Baud Rate Generator Register High Byte
#byte SPBRGH2  = 0x0F7D  // EUSART2 Baud Rate Generator Register High Byte
#byte SSP1CON1 = 0x0FC6

#pin_select TX2=PIN_C0 // I/O pin assignment:
#pin_select RX2=PIN_C1 // use Uart 2 connect to PIN_C0 and C1

#use rs232 (baud=4800,parity=N,UART2,bits=8,errors,stream=COMM2)
#define GRNLED  PIN_B6
#define REDLED  PIN_B7

int8 x;   // Test program to sort out UART2 and SPI

void main(){
    OSCCON   = 0x70;   // 8mhz
    SPBRGH2  = 0;      // Data sheet Page 329
    SPBRG2   = 103;    // 103;
    BAUDCON2 = 0x00;   // 0x08;  BRG16  bit 3

    SPBRGH1  = 0;      //
    SPBRG1   = 103;    // 103;

   setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);

   while(TRUE){
      fputc('1',COMM2); // fputc to COMM2 ~works. (a ÿ character appears "ÿ1 hello CCS")
      delay_ms(5);
      fprintf(COMM2," hello CCS\r\n");
      delay_ms(15);
      output_low(GRNLED);   // LED 'on' to indicate SPI write.
      spi_write('X');       // Hangs ... write X to to the SPI pin 18. HANGS here!
      output_high(GRNLED); // green led off.

      delay_ms(150);
      // delay_ms(500);
        for(x = 0 ; x < 3 ; x++){
         output_low(GRNLED);  // green led on.
         delay_ms(100);
         output_high(GRNLED); // green led off.
         delay_ms(100);
        }

   }
}

I need the USART2 and SPI to both be active as needed in the program.
Any suggestions?
Thank You Very Kindly,
Jim
_________________
Jim Oram
jeremiah



Joined: 20 Jul 2010
Posts: 1345

View user's profile Send private message

PostPosted: Mon Apr 01, 2013 8:15 pm     Reply with quote

What compiler revision are you using?

The next step would be to look at the LST file and see where the assembly for that spi_write call would hang up. Also, you might explicitly turn off any other peripherals using the same pins as your SPI interface
Jim Oram



Joined: 01 Jan 2010
Posts: 24
Location: Charlotte

View user's profile Send private message

Versions
PostPosted: Mon Apr 01, 2013 8:28 pm     Reply with quote

Using Versions:
PCW versions:
IDE 4.138
PCB 4.138
PCM 4.141
PCH 4.141
_________________
Jim Oram
Jim Oram



Joined: 01 Jan 2010
Posts: 24
Location: Charlotte

View user's profile Send private message

List file section for spi_write
PostPosted: Mon Apr 01, 2013 8:38 pm     Reply with quote

jeremiah, here is the list for spi_write:
Code:

....................       spi_write('X');       // recompile, now not hanging, but no clock signal. ?
00FA:  MOVF   FC9,W
00FC:  MOVLW  58
00FE:  MOVWF  FC9
0100:  RRCF   FC7,W
0102:  BNC   0100
....................       output_high(GRNLED);  // green led off.
0104:  BCF    F93.6
0106:  BSF    F8A.6

Jim
_________________
Jim Oram
Jim Oram



Joined: 01 Jan 2010
Posts: 24
Location: Charlotte

View user's profile Send private message

spi_write() no clock...
PostPosted: Mon Apr 01, 2013 8:47 pm     Reply with quote

jeremiah,
As far as I know, with this simple program, I do not have any extra
peripherals using the same pins as the SPI interface.
It seems that it is possible to get the spi running, or the uasrt2 running, but not both. Any ideas?

Thanks Kindly,
Jim
_________________
Jim Oram
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue Apr 02, 2013 12:31 am     Reply with quote

Stop talking to the registers...
This is the assembler approach, and is not needed/wanted. There are a few (very few) occasions, when accessing registers directly is wanted/needed. This is not one of them.

You are programming part of UART1. You must not do this, since UART1 uses the same pins as the SPI. This is why I had the line 'setup_uart(FALSE)', to make _sure_ UART1 was turned off, since otherwise it'll stop the SPI from working. This is the line missing from Jeremiah's code.
Code:

#case
#include <18F26J50.h>
#FUSES NOWDT,NOPROTECT,INTRC
#use delay(clock=8000000)

#pin_select TX2=PIN_C0 // I/O pin assignment:
#pin_select RX2=PIN_C1 // use Uart 2 connect to PIN_C0 and C1

#use rs232 (baud=4800,parity=N,UART2,bits=8,errors,stream=COMM2)


void main(){
   setup_uart(FALSE); //needs to be here.
   setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);

   while(TRUE){
      fputc('1',COMM2); // fputc to COMM2 works.
      fprintf(COMM2," hello CCS\r\n");
     
      spi_write('X'); // write X to to the SPI pin 18. HANGS !
     
      delay_ms(500);
     
   }
}


Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group