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 support@ccsinfo.com

Can't read data with SPI using PIC16f18346
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Aug 24, 2020 10:30 am     Reply with quote

this...
Quote:
In the TI code, UART pins and SPI pins are different.


Concerns me, as I downloaded the 'slau817.pdf' from TI that describes the EVM, which I think you have.

It shows that SPI and UART are the same pins, so there has to be some 'magical' code to configure the device for SPI vs UART vs OW mode of communications.

This might be in the
#include "pga460_spi_430.h" file.
or the ...
#include <Energia.h> file.

TI makes a vague reference that using SPI you must use 'Energia'. I suspect the #include <Energia.h> file has some fancy 'setup routine' to configure the device to the SPI interface.

In your program, SOMETHING has to 'configure' the device otherwise HOW can it KNOW which serial protocol to operate ??
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Mon Aug 24, 2020 11:30 pm     Reply with quote

I'm using the demo code which is "slac741i".

Now, I want to change the SPI's frequency only. If you can help me about this problem, I would be very happy.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Aug 25, 2020 1:44 am     Reply with quote

Let's look at the .LST file.

You're running software SPI. Do you know that ?
You are running your PIC at 16 MHz. This means the instruction clock
is 4 MHz.

You are not going to get a baud rate of 4 MHz in this situation.
It will be way, way less. That's also why you can't change the baud rate.
You can put in 1 MHz, or 2 MHz, etc, for your "baud=" parameter and it
won't make any difference at all. Your true baud rate will always be some
very low number because you're running software SPI.

In addition to that, you have not specified bits=8 in the #use spi()
statement. This means it will default to 32 bit code. You have specified
8 bits in your spi_xfer() statement. That's good, but the #use spi() code
is still setup as 32 bits by CCS in this case. It generates a lot of useless
churning code when you do that. It slows you down a lot.

You would get much faster software SPI code if you added bits=8:
#use spi(DI=PIN_B4, DO=PIN_C7, CLK=PIN_B6, baud=4000000, bits=8, MODE=2, stream=PGA)

See my comments that show how slow this code really is:
Code:
...... #use delay(internal=16000000)
....... #use spi(DI=PIN_B4, DO=PIN_C7, CLK=PIN_B6, baud=4000000, MODE=2, stream=PGA)
0003:  MOVF   @SPI_XFER_1.P1,W
0004:  SUBLW  20        // Is the number of bits = 32 ?  (It's = 8)
0005:  BTFSC  STATUS.Z  // Skip if not  (ie, got to 0007)
0006:  GOTO   00E

0007:  MOVWF  @@2A     // Rotate byte 0 into byte 3 position
0008:  RLF    data,F   // This takes a lot of time (no kidding)
0009:  RLF    data+1,F
000A:  RLF    data+2,F
000B:  RLF    data+3,F
000C:  DECFSZ @@2A,F   // Go through this loop 24 times (ouch !)
000D:  GOTO   008

000E:  MOVLB  01
000F:  BSF    TRISB.TRISB4
0010:  BCF    TRISC.TRISC7
0011:  BCF    TRISB.TRISB6
0012:  MOVLB  02
0013:  BSF    LATB.LATB6   // set CLK = 1
0014:  MOVLB  00
0015:  MOVF   @SPI_XFER_1.P1,W
0016:  MOVWF  @@2A
0017:  BTFSC  data+3.7  // Is top data bit = 0 ?
0018:  GOTO   01C         
0019:  MOVLB  02           
001A:  BCF    LATC.LATC7  // If so, set DO = 0
001B:  MOVLB  00

001C:  BTFSS  data+3.7  // Is top data bit = 1 ?
001D:  GOTO   021
001E:  MOVLB  02           
001F:  BSF    LATC.LATC7  // If so, set DO = 1
0020:  MOVLB  00

0021:  RLF    data,F        // Rotate 4 bytes left by 1 bit position
0022:  RLF    data+1,F    // This takes more time
0023:  RLF    data+2,F
0024:  RLF    data+3,F

0025:  MOVLB  02
0026:  BCF    LATB.LATB6  // set CLK = 0
0027:  RLF    @77,F           // Rotate incoming data left by 1 bit
0028:  RLF    @78,F
0029:  RLF    @79,F
002A:  RLF    @7A,F
002B:  MOVLB  00
002C:  BTFSS  PORTB.RB4   
002D:  BCF    @77.0   // If pin DI = 0, then record incoming bit as 0
002E:  BTFSC  PORTB.RB4   
002F:  BSF    @77.0    // if pin DI = 1, then record incoming bit as 1
0030:  MOVLB  02
0031:  BSF    LATB.LATB6    // set CLK = 1
0032:  MOVLB  00
0033:  DECFSZ @@2A,F
0034:  GOTO   017
0035:  MOVLP  00
0036:  GOTO   071 (RETURN)


Here is the code with bits=8. Notice it's much tighter code.
Code:
.......... #use spi(DI=PIN_B4, DO=PIN_C7, CLK=PIN_B6, baud=4000000, bits=8, MODE=2, stream=PGA)
0003:  MOVF   @SPI_XFER_1.P1,W
0004:  SUBLW  08   
0005:  BTFSC  STATUS.Z
0006:  GOTO   00B
0007:  MOVWF  @@28
0008:  RLF    data,F
0009:  DECFSZ @@28,F
000A:  GOTO   008
000B:  MOVLB  01
000C:  BSF    TRISB.TRISB4
000D:  BCF    TRISC.TRISC7
000E:  BCF    TRISB.TRISB6
000F:  MOVLB  02
0010:  BSF    LATB.LATB6
0011:  MOVLB  00
0012:  MOVF   @SPI_XFER_1.P1,W
0013:  MOVWF  @@28
0014:  BTFSC  data.7
0015:  GOTO   019
0016:  MOVLB  02
0017:  BCF    LATC.LATC7
0018:  MOVLB  00
0019:  BTFSS  data.7
001A:  GOTO   01E
001B:  MOVLB  02
001C:  BSF    LATC.LATC7
001D:  MOVLB  00
001E:  RLF    data,F
001F:  MOVLB  02
0020:  BCF    LATB.LATB6
0021:  RLF    @78,F
0022:  MOVLB  00
0023:  BTFSS  PORTB.RB4
0024:  BCF    @78.0
0025:  BTFSC  PORTB.RB4
0026:  BSF    @78.0
0027:  MOVLB  02
0028:  BSF    LATB.LATB6
0029:  MOVLB  00
002A:  DECFSZ @@28,F   // Decrement bit counter (8 bits only)
002B:  GOTO   014
002C:  MOVLP  00
002D:  GOTO   065 (RETURN)
....................
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Tue Aug 25, 2020 3:10 am     Reply with quote

when I wrote 'bit=8" like you, I get an error.

Compiling D:\Yazilim\PGA460_V1.4_19082020\GetDistance on 25-A�u-20 at 12:08
D:\Yazilim\PGA460_V1.4_19082020\PGA460_SPI.h:3:5: Error#99 Option invalid Bad Option: BIT
D:\Yazilim\PGA460_V1.4_19082020\PGA460_SPI.h:45:21: Error#12 Undefined identifier PGA
2 Errors, 0 Warnings.
Build Failed.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Aug 25, 2020 3:13 am     Reply with quote

Look more closely at what I wrote.

Electronics is about attention to detail. Without that, nothing works.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Aug 25, 2020 6:37 am     Reply with quote

I'm curious...as I've never used a 'PPS' PIC, can you not configure this PIC to use the SPI hardware. My gut says it should be possible...I downloaded the datasheet and it looks like PPS 'configures' some of the I/O pins to some of the internals, similar to FPGA devices ?

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Aug 25, 2020 6:48 am     Reply with quote

Yes, of course you can.
Limitations:
Some PPS pins are 'input only'.
On some of the chips the devices can only map to pins in particular groups.
If the pins are suitable, and support PPS, and the SPI peripheral supports
PPS, then 'yes' you can map the SPI peripheral to the pins.
But, he then has to reverse the bytes before feeding them to the peripheral,
and after reading them from the peripheral, since the SPI hardware
always operates MSb first, while his target device receives and sends LSb
first.
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Wed Aug 26, 2020 6:29 am     Reply with quote

I changed the frequency.

Now, I have a new problem. Frequency is increased. I send the data. However, since I speed up the oscillator with manual settings and adjust the SPI settings, I do not use structures such as use_spi. I provide data transfer as follows. MSB to LSB conversion in another functions for avoid wasting time.

Code:
mSSP1BUF.reg = _data;
    while(SSP1IF == 0);      //wait
_regdata=mSSP1BUF.reg;


You can see my settings about oscillator and SPI:

Code:
   //OSCILLATOR
   mOSCCON1.nosc=0;
   mOSCCON1.ndiv=1;
   
   //OSCCON2
   mOSCCON2.cdiv=1;
   mOSCCON2.cosc=0;

    SSP1CON1bitsSSPEN = 0;
   //Fosc/4
   SSPCON1bitsSSP1M0 = 1;
   SSPCON1bitsSSP1M1 = 0;
   SSPCON1bitsSSP1M2 = 0;
   SSPCON1bitsSSP1M3 = 0;
   //Mode 2
   SSPCON1bitsCKP = 0;
   SSPSTATbitsCKE = 0;
   SSPSTATbitsBF = 0;
   //High speed mode
   SSPSTATbitsSMP =0;
   SSP1CON1bitsSSPEN = 1;


You can see the sent and received signals below when my code is used.
https://imgur.com/uH3QjJM

You can see the sent and received signals below when demo code is used.
https://imgur.com/WNrpWZt

Blue is transmitted signal, yellow is received signal.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed Aug 26, 2020 7:13 am     Reply with quote

Attempting to write to OSCCON2, is wrong.
OSCCON2, is a _read only_ register, that will match what was written to
OSCCON1, once the chip changes speed to the new selections.
You should wait for this to match OSCCON1, not attempt to write to it.
Then your mode setting is wrong. CKP=0, CKE=0 is mode 0, not mode 2.
Mode 2, requires CKE=1 & CKP=1.
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Wed Aug 26, 2020 11:37 pm     Reply with quote

Ttelmah wrote:
Attempting to write to OSCCON2, is wrong.
OSCCON2, is a _read only_ register, that will match what was written to
OSCCON1, once the chip changes speed to the new selections.
You should wait for this to match OSCCON1, not attempt to write to it.
Then your mode setting is wrong. CKP=0, CKE=0 is mode 0, not mode 2.
Mode 2, requires CKE=1 & CKP=1.


I solved this problem too. Memset function works slowly and datas are transmitted lately. I changed the memset's place and works good.

Actually I know CKE and CKP must be 1 but it didn't work before if I set CKE and CKP as 1. Now, It works too but I have a problem with falling edge. I don't know why, but part of the data is corrupted. I loaded the oscilloscope's screen again below and I wonder your opinion.

I circled the problematic signal with a red pencil.

It must be as follows:
https://imgur.com/bdslnQz

It is:
https://imgur.com/DAYXRTG
If I zoom to problematic signal for you see better:
https://imgur.com/bFwXY4w

I think I couldn't catch the data at the true time. You can see my settings below:


Code:
void usscSPI_begin()
{
   //OSCILLATOR
   mOSCCON1.nosc=0;
   mOSCCON1.ndiv=0;
   //OSCEN
   // OSCENbitsHFOEN = 1;
   //OSCFRQ
    OSCFRQbitsHFFRQ0 = 1;
    OSCFRQbitsHFFRQ1 = 0;
    OSCFRQbitsHFFRQ2 = 1;
    OSCFRQbitsHFFRQ3 = 0;

    SSP1CON1bitsSSPEN = 0;
   //Fosc/16
   SSPCON1bitsSSP1M0 = 1;
   SSPCON1bitsSSP1M1 = 0;
   SSPCON1bitsSSP1M2 = 0;
   SSPCON1bitsSSP1M3 = 0;
   //Mode 2
   SSPCON1bitsCKP = 1;
   SSPSTATbitsCKE = 1;
   SSPSTATbitsBF = 0;
   //High speed mode
   SSPSTATbitsSMP =0;
   SSP1CON1bitsSSPEN = 1;
}


Code:
uint8 usscSPI_transfer(uint8 _data) {
   mSSP1BUF.reg = _data;
   _regdata=mSSP1BUF.reg;
   return _regdata;
}


I converted MSB to LSB in different place.
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Thu Aug 27, 2020 12:35 am     Reply with quote

Actually data I sent is 10101010 10100000 01011111 01111111 01111111 01111111 01111111 01111111.

The problem occurs in the section I wrote in red. Actually it sends 10100000 data, I don't know why at the end of the data is 1, it should have remained 0.

https://imgur.com/jiH2cB5

Everything is okay instead of this part. I didn't send 1. The clock signal was already finished in that part, even if I send data, it should be sending at the next clock signal.

And I caught another problem. It should have remained 1 at the end of the 01011111 data.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 27, 2020 1:27 am     Reply with quote

Post the code that sends the data.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Thu Aug 27, 2020 2:30 am     Reply with quote

It looks as if your CKE setting is not actually '1'.
With CKE==1, the data should extend half a clock time after the rising
edge of CKP. It'd change at the rising edge (as you show), if CKE was zero.
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Thu Aug 27, 2020 3:02 am     Reply with quote

PCM programmer wrote:
Post the code that sends the data.


Code:

typedef struct{
   uint8 s_syncBYTE;
   uint8 s_UMR;
   uint8 s_pga460_calcChecksum;
}pga_bufs5;

typedef union{
   pga_bufs5 pgab5;
   uint8 pga_bufdizi5[sizeof(pga_bufs5)];
}pga_bufu5;

BYTE datareverse(BYTE* senddat, BYTE size)
{
   for(uint16 t=0; t<size; t++)
   {
      // // MSB --> LSB /////////////////////////////////////////////////
      senddat[t] = (((senddat[t] & 0b11110000)>>4) | ((senddat[t] & 0b00001111)<<4));
      senddat[t] = (((senddat[t] & 0b11001100)>>2) | ((senddat[t] & 0b00110011)<<2));
      senddat[t] = (((senddat[t] & 0b10101010)>>1) | ((senddat[t] & 0b01010101)<<1));
      ///////////////////////////////////////////////////////////////////      
   }
   return senddat;
}   
BOOLEAN pga460_pullUltrasonicMeasResult(BOOLEAN busDemo)
{
   memset(ultraMeasResult, 0, sizeof(ultraMeasResult));
   memset(misoBuf, 0x00, sizeof(misoBuf)); // idle-low receive buffer data   
      pgau5.pgab5.s_syncBYTE=0b01010101;
      pgau5.pgab5.s_UMR=0b00000101;
   pgau5.pgab5.s_pga460_calcChecksum=11111010;
      pgau5.pga_bufdizi5[sizeof(pga_bufs5)] = datareverse(pgau5.pga_bufdizi5, sizeof(pga_bufs5));
      pga460_spiTransfer(pgau5.pga_bufdizi5, sizeof(pga_bufs5));
   return true;
}
void pga460_spiTransfer(uint8* mosi, uint8 size )
{
      memset(misoBuft, 0x00, sizeof(misoBuft)); // idle-low receive buffer data
      
      for (int i = 0; i<size; i++)
      {
         misoBuft[i] = usscSPI_transfer(mosi[i]);;
      }
}



01111111 bits are necessary for PGA's answer. I sent it 5 times these from another place in code.


Last edited by L.T. on Thu Aug 27, 2020 3:15 am; edited 2 times in total
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Thu Aug 27, 2020 3:05 am     Reply with quote

How should I set the CKE bit Unlike that?

Ttelmah wrote:
It looks as if your CKE setting is not actually '1'.
With CKE==1, the data should extend half a clock time after the rising
edge of CKP. It'd change at the rising edge (as you show), if CKE was zero.


I set CKE as 1 you can see. How is it not 1?

L.T. wrote:
I think I couldn't catch the data at the true time. You can see my settings below:

Code:

void usscSPI_begin()
{
   //OSCILLATOR
   mOSCCON1.nosc=0;
   mOSCCON1.ndiv=0;
   //OSCEN
   // OSCENbitsHFOEN = 1;
   //OSCFRQ
    OSCFRQbitsHFFRQ0 = 1;
    OSCFRQbitsHFFRQ1 = 0;
    OSCFRQbitsHFFRQ2 = 1;
    OSCFRQbitsHFFRQ3 = 0;

    SSP1CON1bitsSSPEN = 0;
   //Fosc/16
   SSPCON1bitsSSP1M0 = 1;
   SSPCON1bitsSSP1M1 = 0;
   SSPCON1bitsSSP1M2 = 0;
   SSPCON1bitsSSP1M3 = 0;
   //Mode 2
   SSPCON1bitsCKP = 1;
   SSPSTATbitsCKE = 1;   ///////////////////////////////////IN HERE
   SSPSTATbitsBF = 0;
   //High speed mode
   SSPSTATbitsSMP =0;
   SSP1CON1bitsSSPEN = 1;
}



Again, I have photographed the signal that should be, and share it with you below. I may have just shared the signal that should have been with you incorrectly. The following are now displayed on MSP pins.

I zoomed step by step.
https://imgur.com/gWL87NE
https://imgur.com/FjwNaLa
https://imgur.com/wwqwsSy

Signals obtained using my code:
https://imgur.com/FLnQUa2
https://imgur.com/DAYXRTG
If I zoom to problematic signal for you see better:
https://imgur.com/bFwXY4w


Last edited by L.T. on Thu Aug 27, 2020 3:10 am; edited 1 time in total
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 Previous  1, 2, 3, 4, 5, 6, 7  Next
Page 6 of 7

 
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