0
votes

I have a MPLAB Starter Kit Board with a µC PIC24FJ256GB106, communicating with an connected Accelerometer Chip ADXL375 Board (which seems not to be the cause for my problem) via SPI in 3-Wire SPI Connection (SDO is not used) I configured the Peripheral Pin Select activating the SPI module 1:

void MapSPIModulPins()
{
__builtin_write_OSCCONL(OSCCON&0xbf); //! PPSUnLock
RPOR1bits.RP3R = 8 ; //! Assign RP3 as Output Pin To SPI1 Clock Output.
RPOR2bits.RP4R = 7 ; //! Assign RP4 as Output Pin SPI1 Data Output.
//RPOR1bits.RP2R = 9 ; //! Assign RP2 as Output Pin Where is SPI1 Slave Select Output. SS1OUT
__builtin_write_OSCCONL(OSCCON|0x40);    //! PPSLock

//! Extra digital output as Chip Select
TRISDbits.TRISD8 = 0; // Thomas 18.11.2014
}

The SPI is configured with:

void SPIsetup1ForMasterMode()
{
IFS0bits.SPI1IF = 0; // Clear the Interrupt flag
IEC0bits.SPI1IE = 0; // Disable the interrupt

// SPI1CON1 Register Settings
SPI1STATbits.SPIEN  = 0; //! Thomas(THOMAHPS) 20.11.2014  Disable SPI module
SPI1CON1bits.DISSCK = 0; // Internal serial clock is enabled
SPI1CON1bits.DISSDO = 0; // SDOx pin is controlled by the module
SPI1CON1bits.MODE16 = 0;// Communication is byte-wide (8 bits) // Thomas 17.11.2014

SPI1CON1bits.MSTEN = 1; // Master mode enabled
SPI1CON1bits.SMP = 0; // Input data is sampled at the middle of data output time
SPI1CON1bits.CKE = 0; // Serial output data changes on transition from Idle clock state to active clock state

// Idle clock state to active clock state
SPI1CON1bits.CKP = 0; // Idle state for clock is a low level;

// active state is a high level
SPI1STATbits.SPIEN = 1; // Enable SPI module
SPI1STATbits.SPIROV = 0 ; //! Thomas 20.11.2014 Clear the SPIROV bit !

// Interrupt Controller Settings
IFS0bits.SPI1IF = 0; // Clear the Interrupt flag
IEC0bits.SPI1IE = 1; // Enable the interrupt
}

IMHO an asymmetrical behave between SPI transmission and reception can not be establised.

The interrupt handler is:

void __attribute__((interrupt,no_auto_psv)) _SPI1Interrupt(void)
{
   IFS0bits.SPI1IF = 0;     //Clear Interrupt status of SPI1
}

Then I transmitted a data byte with

SPI1BUF = anyBytePattern;

which I could observe on an oscilloscope together with the clock. Receiving data can be triggered with (I omitted here the status flag checks!)

unsigned int recvData = SPI1BUF;

Neither in single operation nor in an endless loop, there is NO CLOCK on the signal line!

I embedded my code in proper places of the demo application, which should have no interference with my issue.
I tried a lot of stuff with delays, sample code of the producer, communities, etc.
In debugging sessions no unusual register values (SPI error flags) were observed.
The separation of the slave electronic makes no difference in the behave.

Is this a PPS issue?

I stumbled over the SPI description of the manufacturer.
In the document PIC24FJ256GB110 Family Data Sheet Section 15.0 SERIAL PERIPHERAL INTERFACE (SPI) was written
"The SPI serial interface consists of four pins:
SDIx: Serial Data Input
SDOx: Serial Data Output
SCKx: Shift Clock Input or Output
SSx: Active-Low Slave Select or Frame Synchronization I/O Pulse
The SPI module can be configured to operate using 2, 3 or 4 pins. In the 3-pin mode, SSx is not used. In the 2-pin mode, both SDOx and SSx are not used."
I the same document was the pinout of the 64-PIN Chip PIC24FJ256GB106, which has only one SPI-Data Signal called SDA1, located physically on pin nr 43.
How can a 3++ wire SPI solution be realized with this Chip?

I mapped this signal and the SPI clock with the PPS commands as shown above, referring TABLE 10-3: SELECTABLE OUTPUT SOURCES (MAPS FUNCTION TO OUTPUT):
Function SDO1 (SPI1 Data Output) with the code 7 and function SCK1OUT (SPI1 Clock Output) as 8.

The communication with my SPI slave requires a write-read-cycle, I tell him the register nr and he answered me with that value.
Is this PPS mapping sufficient to do that job?

What about the input mapping?

In TABLE 10-2: SELECTABLE INPUT SOURCES (MAPS INPUT TO FUNCTION) are lines with
Funcions SCK1IN( SPI1 Clock Input), register RPINR20, bits SCK1R(5:0)
and SDI1(SPI1 Data Input), register RPINR20, bits SDI1R(5:0)

I added the code lines to MapSPIModulPins():

RPINR20bits.SCK1R = 3 ; // because SCL1/RP“3“/PMCS2/CN55/RD10  
RPINR20bits.SDI1R = 4 ; // because DPLN/SDA1/RP“4“/CN54/RD9  

The clock cycles on a master read were still NOT generated by my PIC24 SPI module 1.

What is wrong?

If anybody can help - Thanks in advance!
Thomas

1
You wrote "(I omitted here the status flag checks!)" Don't omit that part. That was precisely where I got screwed with the PIC24 and the SPI module. Let us see that section of code.User.1
The final 3-wire SPI communication has to write the ADXL375 register address on the bus + data to write or read, which the slave should be supply. The SPITBF and SPIRBF bits must be checked. I tried: unsigned int SPItransmit1Byte(unsigned char b) { SPI1BUF = b; //write to buffer for TX //@@ while (SPI1STATbits.SPITBF); //uncommenting makes no difference while(!SPI1STATbits.SPIRBF);//wait for transfer to complete return SPI1BUF ; // read the received value } In this code the PIC24 has to supply 2*8 clock cycles,but on the line there were only 8!anatom13
I put the issue to the Microchip forum and it is fixed now. See microchip.com/forums/m836595.aspx?tree=trueanatom13

1 Answers

1
votes

Is this a PPS issue? PPS seems fine

How can a 3++ wire SPI solution be realized with this Chip? - Simply by controlling the CS pin independently. The attributed CS pin is for slave mode. - SDA is for I2C not SPI.

What about the input mapping? Input is done as follow:

_SDIxR=16;          //SDI

16 being RP16 / RPi16, becarefull de RPi pins can only be input, so don't map the clock on a RPI (RPi) pin, it won't work.

On the code above, we cannot see were you set the timing of the SPI module, it might be either too slow or too fast. This is done on the SPIxCON1 register.

SPIxCON1bits.SPRE = 0b110; //secondary scale 111= prescale 1:1
SPIxCON1bits.PPRE = 0b00; // primary scale 10 = prescale 4:1
                          //  16 MIPS -> 4MIPS

Further checks:

  • Make sure the pins are not in analog mode if they are multiplexed with it (AN on the pin on the datasheet).

  • For debug, you also need to make sure the main clock is running, for instance you can toggle one pin and run a probe on it.

  • Check your electronic, make sure nothing drives the line down like another IC. If the chip heats more than usual or consume more power, that's a sign. With the pin set as input, you can try to drive down/up the click line see if you have any short. You can also if you can un-solder the pin.