|
|
View previous topic :: View next topic |
Author |
Message |
temtronic
Joined: 01 Jul 2010 Posts: 9097 Location: Greensville,Ontario
|
|
Posted: Mon Aug 24, 2020 10:30 am |
|
|
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
|
|
Posted: Mon Aug 24, 2020 11:30 pm |
|
|
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
|
|
Posted: Tue Aug 25, 2020 1:44 am |
|
|
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
|
|
Posted: Tue Aug 25, 2020 3:10 am |
|
|
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
|
|
Posted: Tue Aug 25, 2020 3:13 am |
|
|
Look more closely at what I wrote.
Electronics is about attention to detail. Without that, nothing works. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9097 Location: Greensville,Ontario
|
|
Posted: Tue Aug 25, 2020 6:37 am |
|
|
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: 19215
|
|
Posted: Tue Aug 25, 2020 6:48 am |
|
|
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
|
|
Posted: Wed Aug 26, 2020 6:29 am |
|
|
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: 19215
|
|
Posted: Wed Aug 26, 2020 7:13 am |
|
|
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
|
|
Posted: Wed Aug 26, 2020 11:37 pm |
|
|
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
|
|
Posted: Thu Aug 27, 2020 12:35 am |
|
|
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
|
|
Posted: Thu Aug 27, 2020 1:27 am |
|
|
Post the code that sends the data. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19215
|
|
Posted: Thu Aug 27, 2020 2:30 am |
|
|
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
|
|
Posted: Thu Aug 27, 2020 3:02 am |
|
|
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
|
|
Posted: Thu Aug 27, 2020 3:05 am |
|
|
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 |
|
|
|
|
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
|