; PIC 16F688 code for reading temperatures from a TMP36 device
;
; ### license
;
; MCU frequency of 8 MHz (F.osc), means: T.osc = 0.125 µS
;
; T.ad is the cycle time for the A/D converter, and must be larger than
; 1.6 µS. Using <F.osc / 16> produces T.ad = T.osc * 16 = 2.0 µS.
;
; 11 T.ad cycles are needed for A/D conversion, which is 22.0 µS.
; At 8 MHz, an instruction cycle is 0.5 µS; thus a conversion will
; consume 44 instruction cycles.
;
; Interrupt overhead is about 14(?) instructions, so we will
; busy-wait during the TMP36 data acquisition.
;
; Note: I2C operation is generally based around T.hd.sta which is
; a mere 4 µS. Thus, this module will use polling rather than a
; busy-wait algorithm.
;

        list p = 16f688
        include p16f688.inc
        include ../include/handy.inc

tmp36:  code                   ; relocatable

; Assume defaults for the DATA and CLOCK outputs, if not defined externally.
; The pins must reside on the same port (A or C).
;
; NOTE: the application MUST initialize these port pins to analog inputs.
 ifndef TMP36_PIN
  constant TMP36_PIN = RA0
 endif


; Initialize the A/D system for reading TMP36_PIN.
; Note: assume Bank 0 on entry.
tmp36_init:
        bank1s

        ADC_init_ADCS

        bsf     TRISA, TMP36_PIN ; Set pin to input
        bsf     ANSEL, TMP36_PIN ; Set input pin to analog

        bank0s
        ADC_select_pin TMP36_PIN

        ; Note: no interrupts enabled.

        return


; Read, and return the 8 most significant bits in W.
; Note: assume Bank 0 on entry.
tmp36_read:
        ; Equation 8-1: T.acq = 19.72 µS
        ; ### caller should have:
        ; ###     assign converter to AN* pin
        ; ###     wait T.acq

        ; Start the conversion
        ADC_begin

        ; Loop until GO is cleared. (11 periods of T.ad; 22.0 µS)
wait:   btfsc   ADCON0, GO
        goto    wait

        ; Fetch the value into W.
        ADC_value
        return


; stupid assemblers don't realize EOF means *end*
        end
