|
|
View previous topic :: View next topic |
Author |
Message |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
Does PIC18F support 3 pin SPI? |
Posted: Tue Apr 05, 2022 4:32 pm |
|
|
I'm currently using an SPI EEPROM that requires the normal SPI port configuration with /CS CLK SDI and SDO and now I want to add a device in the same port that only uses 3 SPI pins /CS CLK and SDIO.
I wonder if the hardware and the CCS library will support this. _________________ Electric Blue |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Wed Apr 06, 2022 1:39 am |
|
|
Post what the device is, and what the PIC is.
This can't be done normally be done by by SPI, since there is no direction
control line. SPI always clock 'in' at the same time it clocks 'out'. This is
three standard the wire SPI (the CS line is not normally 'counted').
Analog devices do some bi-directional SPI devices, and what you have to do
to drive these on most chips, is add a transceiver with an 'enable' line to
the SDO pin. then a resistor (2KR), and then connect this to SPIIN, and
the line to the device.
For all your transmissions you turn on the enable. Since SDIIN is an input,
this then sees everything you transmit, and the receiving device also sees
this. Then at the the point where the device returns data, you turn off the
enable. What is then being sent by the PIC SPI is then not seen, but the
data coming back is.
Now on _some_ 18F PIC's, SDO requires that it's TRIS is set to output
(on a lot of the later PIC's this is not the case, the peripheral overrides
the TRIS). So on an 18F4550, you don't need a buffer. what you do it set
TRIS for the SDO to 0, and use the CCS spi_xfer function. Read the data
for each write (and discard). Then for the reads, simply set the TRIS to
1 (which turns off SDO), and again use spi_xfer, and read the data, which
is the reply.
On the PIC's that override the TRIS, you instead need the buffer, and
control this instead of setting/clearing TRIS.
Read the data sheet.
So for instance the 18FK22 says,
"Master mode (SCKx is the clock output)".
Note no mention of TRIS.
However the 18F47K40 says:
"SDO must have corresponding TRIS bit cleared".
So, no generic answer. Depends on your PIC. |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Wed Apr 06, 2022 2:01 am |
|
|
I'm using a PIC18F67J50.
I was reading this thread from Microchip forum
https://www.microchip.com/forums/m851648.aspx
They say that they can use a resistor to connect both data lines but I have an EEPROM in the same port and it haves and SDI and SDO.
I'm not sure how healthy is this method and if the CCS library can handle it. _________________ Electric Blue |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Wed Apr 06, 2022 5:15 am |
|
|
You potentially can do this easily on this chip!...
The reason is it supports open-drain drives. So you add a resistive pull-up to
the SDO pin, and program this pin to be open drain. For SPI at any reasonable
rate the pull-up will need to be something quite low. Perhaps 820R.
You have to program all the bits in the port being used.
Byte value for the port, all zeros, except for this one bit.
set_open_drain_x(value);
where 'x' is the port involved.
However because you then have to join the two lines together, this will
cause problems for your other chips. Can you use a second MSSP?
For your use, if you can only use one port, then the resistive solution
is easier. So:
PIC SDO --- connect to the other chips --- resistor to the 2 wire device
SDIO.
PIC SDI ---- connect to the other chips and to the 2 wire SDIO pin.
Use the spi_xfer as normal, except make sure you read the byte on
every write. Just ignore this. for the writes. For the read transfer use
spi_xfer(0xFF). This then means the PIC will output all ones on the
SDO line, making this act as a pullup to the SDIO pin. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Wed Apr 06, 2022 5:27 am |
|
|
as Mr. T says 'no'
however....
it CAN be done, if YOU create the 'SDIO' driver. This will be a 'bit banged' software driver.
conceptually....
cs goes low
set IOpin to output
transmit outgoing data....
set IOpin to input
receive incoming data....
cs goes high
... you'll have to calculate bit width time based on the slave device
also then number of incoming and outgoing data do not have to be the same.
Providing you get the timing right, this will work.
It would be nice to know what 'slave' device you're using. |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Wed Apr 06, 2022 9:52 am |
|
|
So, the final circuit would be something like this?
Can I still keep using the CCS SPI libraries? _________________ Electric Blue |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Thu Apr 07, 2022 2:19 am |
|
|
Yes, and yes.
Do your transfer like:
Code: |
int val;
output_low(cs);
//perform the write transactions
val=spi_xfer(val_to_write);
//etc.
//then when you have programmed the chip to send data
val=spi_xfer(0xFF);
//now val is what the slave has sent
output_high(cs); //deselect the chip
|
You don't have to use bit banging. The point is that the SPI output
drivers will merrily drive the resistor, and when talking to the other
chip it drives the SDI line which overrides what the resistor is doing.
When the 2wire slave device sends data out, it uses an open collector
drive, which is then pulled up by the high and resistor from the PIC's
SDO line. So the SDI pin then sees what the slave is sending. |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Fri Apr 08, 2022 9:07 am |
|
|
Thanks.
With EEPROM I'm currently using the normal SPI command spi_write.
Do I need to change something? _________________ Electric Blue |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Sun Apr 10, 2022 10:39 am |
|
|
I'd suggest you switch to using spi_xfer throughout.
spi_write is _not_ (now) the CCS standard command.
Baisically two different ways of using SPI. Historical one (the old way),
you setup the SPI with spi_setup, and used spi_read and spi_write.
The new way is to use #use spi, and spi_xfer.
If you look in the manual for #use spi, you will see it does not refer to
spi_read and spi_write. Instead referring to spi_xfer.
If instead you look in the manual at spi_setup, this refers you to spi_read
and spi_write.
With the hardware SPI, it is possible to use #use spi, and spi_read/write,
but it is not the recommended way to work, and can sometimes cause
problems.
Spi_xfer (historically) had more overheads. However the current
implementation is as fast as spi_read/write.
#use has the big advantage of using the same commands for both
software and hardware SPI, allowing multiple SPI ports to be setup with
stream names. It also gives you support for the different modes by
name as opposed to having to work these out yourself. Also adds support
for multibyte transfers (8, 16, 32 bits). You can even have the same
port setup with two stream names, and different modes, then perform a
transfer to one stream, and then do a transfer to the other, and the port
will change mode. |
|
|
|
|
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
|