' *****************************************************************************
' * MAX6675 Thermocouple Temperature Sensor - Compact Software SPI Library
' * ---------------------------------------------------------------------------
' * Device:      MAX6675
' * Sensor:      K-type thermocouple
' * Interface:   Read-only SPI-compatible serial interface (software bit-bang)
' * Data format: 16-bit serial word, MSB first
' * Resolution:  0.25 °C per LSB
' * ----------------------------------------------------------------------------
' * By COS (dogflu66@yahoo.es)
' * PIC18F46K22 (64MHz/4)
' * Pic18 Conpiler Oshonsoft v6.10
' * v.20260927
' * ----------------------------------------------------------------------------
' *
' * The MAX6675 performs cold-junction compensation and converts the
' * thermocouple voltage into a digital temperature value.
' *
' * Communication is read-only: the MAX6675 does not receive commands or data.
' * The PIC controls CS and SCK and reads the serial data from the SO pin.
' *
' * MAX6675_Read() returns the measured temperature directly in degrees Celsius.
' * The error argument is also updated:
' *
' *     error = 0  -> Thermocouple connected
' *     error = 1  -> Thermocouple open or disconnected
' *
' * If an open thermocouple is detected, the function returns -99 °C
' * as an error indication.
' *
' * NOTE:
' * The MAX6675 starts a new temperature conversion when CS returns HIGH.
' * Conversion continues while CS remains HIGH.
' *****************************************************************************


' -----------------------------------------------------------------------------
' MAX6675 pin configuration
' -----------------------------------------------------------------------------
Symbol MAX6675_CS =       LATC.2      ' Chip Select output
Symbol MAX6675_SCK =      LATC.3      ' Serial Clock output
Symbol MAX6675_SO =       PORTC.5     ' Serial Data input (SO / MISO)

Symbol MAX6675_CS_IO =    TRISC.2     ' CS direction control
Symbol MAX6675_SCK_IO =   TRISC.3     ' SCK direction control
Symbol MAX6675_SO_IO =    TRISC.5     ' SO direction control

'Dim MAX6675_ERROR_THERMOCOUPLE As Byte

' -----------------------------------------------------------------------------
' Initialize MAX6675 interface
' -----------------------------------------------------------------------------
Function MAX6675_Init() As Byte

    Low MAX6675_CS_IO             ' Configure CS as output
    Low MAX6675_SCK_IO            ' Configure SCK as output
    High MAX6675_SO_IO            ' Configure SO as input

    High MAX6675_CS               ' MAX6675 initially deselected
    Low MAX6675_SCK               ' Clock idle state = LOW

	'MAX6675_ERROR_THERMOCOUPLE = 0 ' No error

End Function


' -----------------------------------------------------------------------------
' Read temperature from MAX6675
'
' Returns:
'   Temperature in degrees Celsius.
'
' ByRef error:
'   0 = Thermocouple connected
'   1 = Thermocouple open or disconnected
'
' The MAX6675 sends a 16-bit word, MSB first.
' Bits D14..D3 contain the 12-bit temperature value.
' Bit D2 indicates an open thermocouple.
' Each temperature LSB represents 0.25 °C.
' -----------------------------------------------------------------------------
Function MAX6675_Read(ByRef error As Byte) As Integer

    Dim i As Byte
    Dim data_raw As Word
    Dim input_SO As Byte

    data_raw = 0
    input_SO = 0

    Low MAX6675_CS                ' Select MAX6675 and start data transfer
    WaitUs 2                      ' Short settling delay

    ' Read the complete 16-bit serial word using software SPI
    CFor (i = 0; i < 16; i++)

        High MAX6675_SCK          ' Rising clock edge
        WaitUs 1

        ' Shift previous data left and append the new received bit
        input_SO.0 = MAX6675_SO
        data_raw = (data_raw << 1) | input_SO

        Low MAX6675_SCK           ' Falling clock edge
        WaitUs 1

    CNext

    High MAX6675_CS               ' End transfer and start a new conversion

    ' D2 = 1 indicates an open or disconnected thermocouple
    If data_raw.2 Then
        error = 1
        ReturnValue -99         ' Error indication
    Else
        error = 0

        ' D14..D3 contain the 12-bit temperature value.
        ' Shift right by 3 and multiply by 0.25 °C (equivalent to / 4).
        ReturnValue (data_raw >> 3) / 4
    Endif

End Function
