Coming back to this after another exhausting week.
SDO (also called MOSI) is driven by the PIC. SDI (MISO) is driven by Max. Check your connections. Do you have anything else connected to these pins.
Also, whewn you write this:
SSP1CON1 = (1<<5); //set bit 5, enable serial port
you overwrite all the bits of the register. It's the same as if you wrote
I see, thank you for pointing this out. I changed the code such that I am not clearing any bits that were previously set accidently.
Your code is overcomplicated.
The MAX31865 only reads/write one byte for each register, so there's little sense on using a pointer to the buffer and data length.
Also the two sepparate read/write functions are 99% redundant, that's why I showed how to unify them, the result will be the same.
Why are you setting CKE low? You've been warned about the errata, also CKP=0,CKE=1 is the most common SPI mode.
Why so many functions always returning 0 when there're no checks of any kind, or anything else to return? Just make them void.
The delay_ms function is redundant, simply use __delay_ms();
Remember for the delay to work correctly, _XTAL_FREQ must be defined somewhere, matching the crystal frequency in Hz.
You're defining it as 1MHz, is that correct? Seems too low?
I did change it to CKP = 0 and CKE = 1 to avoid the errata; thank you for pointing this out (again). I also consolidated everything to the single read/write duplex function as you suggested. The "return 0" was a part of the max31865 library I was attempting to use. I discarded the library as you will see below and I'm trying to make my code as simple as possible so I can first understand what is (or isn't) working.
I am running the Fosc at 1MHz, so CLK is 250 kHz (Fosc/4). I don't think running on the slower side should somehow "break" SPI?
Keeping things as simple as possible, here is what I am trying:
/*
* File: max_test_1.c
* Author: kev
*
* Created on November 6, 2022, 1:05 PM
*/
#include <xc.h>
#include <stdint.h>
#include <stdio.h>
#include "configs.h"
#define _XTAL_FREQ 1000000
void spi_init(){
SSP1CON1 = (0<<5); //clear bit 5, disable serial port
TRISC = (0<<3) | (1<<4) | (0<<5) | (0<<6); //clear RC3, RC5, RC6 (output: SCK1, SDO, CS) and set RC4 (input: SDI)
SSP1CON1 = (0<<4) | (0<<3) | (0<<2) | (0<<1) | (0<<0); // 4: (CKP), 3-0:(SSPM = 0000; Master mode , Fosc/4)
SSP1STAT = (0<<7) | (1<<6); //6: (CKE) transmit on clock transition to active
SSP1ADD = 0;
SSP1CON1bits.SSPEN = 1; //set bit 5, enable serial port
}
uint8_t max31865_interface_spi_readwrite(uint8_t reg, uint8_t data)
{
LATCbits.LATC6 = 0; // CS low
NOP(); // Small delay
SSP1BUF = reg; // Send address
while(!SSP1IF); // Wait
SSP1BUF = data; // Send data (Or dummy byte in read mode)
PIR1bits.SSP1IF = 0; // Clear flag
while(!SSP1IF);SSP1IF=0; // Wait, clear flag
LATCbits.LATC6 = 1; // CS low
return SSP1BUF; // Return received data if any (Ignore in write mode)
}
void main(void) {
spi_init();
OSCCONbits.IRCF = 0x0B; //set internal osc to 1mhz
OSCCONbits.SCS = 0x00; //system clock setup
max31865_interface_spi_readwrite(0x00,0x62);
__delay_ms(100);
while (1){
max31865_interface_spi_readwrite(0x01,0x00); //read RTD MSBs
max31865_interface_spi_readwrite(0x02,0x00); //read RTD LSBs
// max31865_interface_spi_readwrite(0x03,0x00); //read high fault threshold status
// max31865_interface_spi_readwrite(0x04,0x00); //read low fault threshold status
// max31865_interface_spi_readwrite(0x05,0x00); //read low fault threshold MSB
// max31865_interface_spi_readwrite(0x06,0x00); //read low fault threshold LSB
// max31865_interface_spi_readwrite(0x07,0x00); //read fault status
__delay_ms(1000);
}
}
The first command is to set the configuration register: max31865_interface_spi_readwrite(0x00,0x62). Here's what that looks like on the scope:
The second two commands which run once a second in the while loop are to read the RTD MSB and LSB registers. Here's what that looks like on scope:
I have a tested PT100 hooked up across the RTD. My board is using a 400 Ohm reference resistor. Also attached full schematic project in case something here is obviously wrong, which I don't believe it is since I am using the MAX31865 reference design and I'm sure I have the SPI pins mapped correctly between the PIC and this chip.
What I'm not sure of is the data that I'm reading from the MAX31865 on SDO. The RTD MSB register reads empty. The RTD LSB register is all high, and there is this strange decay during the end of each transmission. It looks to be capacitive, which I don't understand.
Also, when I plug and unplug my RTD, nothing changes in the RTD MSB/LSB data from what I can see.
Room temperature (20C) for the PT100 with a 400 Ohm Rreference should yield the following data from the RTD registers:
Do I need to set the fault threshold registers as well? I don't see anything else that could be wrong here.
I also replaced the MAX31865 chip. Digikey was out of stock when I first made the board, so I bought a breakout on eBay to get the part. Now that the QFN20 package is in stock again I ordered 10 brand new ones, so I'm sure the chip itself is genuine and functional.