----- Original Message -----
Sent: Tuesday, July 25, 2000 3:08 PM
Subject: [PIC]:Cannot initialize hardware SPI properly in slave mode with
'F87X.
Turns out that this problem was due to my prototype hardware. The device
that is the SPI master on my bus appears to not maintain proper timing as it
asserts the Slave Select line. This device appears to be asserting a valid
signal; The Slave Select signal asserts low before the first bit is clocked
out, and continues to assert low until the last bit is clocked out. The
signal then asserts high. However, it seems that this signal keeps the
PIC's SPI subsystem in reset, hence the Serial Data Out pin remains an input
during the entire byte exchange, as described in my original mailing
(below). Merely grounding the Slave Select line (when the SPI is configured
in slave mode to reset when the SS line deasserts in mode "4") or by setting
the SPI subsystem to operate with the Slave Select signal ignored (SPI mode
"5") allowed the system to operate correctly.
Special thanks to T. C. Sefranek who responded privately to my request for
help and described this solution exactly.
Sincere thanks,
David Kott
>
> Dear PICsters,
>
> I have been having a bit of a time trying to initialize my hardware
SPI
> to perform in slave mode.
>
> I cannot seem to get the Serial Data Out (SDO on RC5 on my 'F876) to
> initialize to an output.
> I explicitly reset bit TRISC<5> to make RC5 an output before enabling the
> SPI subsystem. Here is a snip of my code's compiler output. Note that
this
> is done with CCS's PCM v2.716.
>
>
> .................... void SPIInit(void)
> ....................
>
> ....................
> .................... // One must set the TRIS registers for the Sync.
> Serial
> .................... // (via the CCS compiler functions output_xxx()
and
> input())
> .................... // before enabling the SSP (with the setup_spi()
> function)
> .................... // or the SPI's I/O pins will be left the same way
> they
> .................... // were configured before the setup_spi()
function.
> ....................
> .................... input(SPI_SS);
> BSF 03,5 ;Select bank 1. Want to access TRIS registers.
> BSF 05,5 ;Set TRISA<5>. Makes PORTA<5> an input. PORTA<5> is SS,
which
> is an input.
> .................... output_high(SPI_SDO);
> BCF 07,5 ;Reset TRISC<5>. Makes PORTC<5> an output. PORTC<5> is SDO,
> which is an output.
> BCF 03,5 ;Select bank 0. Want to assert a high level on RC5
> BSF 07,5 ;Set PORTC<5>. Asserting high on RC5.
> .................... input(SPI_SCK);
> BSF 03,5 ;Select bank 1. Want to access TRIS registers.
> BSF 07,3 ;Set PORTC<3>. Makes PORTC<3> an input. PORTC<3> is SCK,
which
> is an input.
> ....................
> .................... setup_spi(SPI_SLAVE | SPI_L_TO_H);
> BCF 07,5 ;Reset TRISC<5>. Makes PORTC<5> an output. PORTC<5> is SDO,
> which is an output.
> BSF 07,4 ;Set TRISC<4>. Makes PORTC<4> an input. Manual says SDI is
> controlled by SPI, but... Ok... set it anyways.
> BSF 05,5 ;Set TRISA<5>. Makes PORTA<5> an input. PORTA<5> is SS,
which
> is an input.
> BSF 07,3 ;Set PORTC<3>. Makes PORTC<3> an input. PORTC<3> is SCK,
which
>
> is an input.
> MOVLW 24 ;SSPCON setting for SPI Slave, with SS active. Enables SPI port
> with SSPEN=1.
> BCF 03,5 ;Select bank 0. SSPCON is at 0x14, which is, naturally, in
bank
> 0.
> MOVWF 14 ;Write 0x24 to SSPCON. SPI is now in slave mode, with SS
active.
{Quote hidden}> MOVLW 00 ;Clear W register.
> BSF 03,5 ;Select bank 1. SSPSTAT is in Bank1 at 0x94.
> MOVWF 14 ;Write to SSPSTAT at 0x94. SSPSTAT appears to only be used for
> I2C configuration.
> ....................
> .................... enable_interrupts(INT_SSP);
> MOVLW 8C ;Put a 0x8c into W.
> MOVWF 04 ;Put a 0x8c into 0x84, FSR register. 0x8c is address of PIE1.
> BCF 03,7 ;Redundant bit clear of STATUS<7> to address bank 1.
> BSF 00,3 ;Set bit 3 of PIE1. Enables SPI interrupts.
> BCF 03,5 ;Clear bank bits. We are now in bank 0.
> BCF 0A,3 ;Clear PCLATH<3:4>. We want to continue executing in 0-800
> BSF 0A,4
> GOTO 025 ;Jump to 0+0x025, to continue executing.
>
> I have, as you will notice, added comments to the above instructions. My
> specific problem is with regard to the proper sequence with which to
> initialize the SPI for slave operation.
> The above code leaves my SPI's Serial Data Output (PORTC<5>) as an input.
> It is at a high impedance.
> However, as one watches this code execute with a scope on PORTC<5>, one
> notes that the pin *does* change to an output, and assert a high level,
when
> the "output_high(SPI_SDO)" instruction executes. That level asserts
solidly
> for about 1.8 uS, then decays exponentially with a T of about 480nS, which
I
> presume to just be my systemic network. In any case, it's definately a
high
> impedance input at this point.
>
> I tried the SPI slave initialization code at
>
techref.massmind.org/techref/default.asp?from=/techref/microchip/lang
{Quote hidden}> uage/c/&url=spiinit.htm
> converted to something that CCS PCM could understand.
>
> void init_spi_communication ( void )
> {
> TRISC4 = 1; // SPI Slave In
> TRISC5 = 0; // SPI Slave Out
> TRISC3 = 1; // SPI Slave CLK In
> TRISA5 = 1; // SPI SS Enabled In, used for other purpose then SPI
> SMP = 0; // SPI slave mode
> SSPEN = 1; // SPI port pins enabled
> SSPM0 = 0; // Slave Mode SS pin Disabled
> SSPM1 = 0;
> SSPM2 = 1;
> SSPM3 = 0;
> CKP = 1; // Clock idle is high
> CKE = 0; // Data on rising edge
> }
>
> However, even *that* known working code left my Serial Data Out pin as an
> input.
>
> MPLab simulates both codesets, and TRISC<5> is indeed a 0.
>
> Has anyone out there experienced something like this?
> Any other PCM users running the SPI in slave mode? Care to share a
snippet
> of code? I would really appreciate any feedback to that end.
>
> Sincere thanks,
> -d
>
>
--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics