( ADS1115s)
( Application: 4-channel 16-bit ADC on prototying board with I2C bus transfer)
( Note: Rev 1 Pi uses BSC0 on pins 3 & 5; Rev 2 uses BSC1)
(       Rev 1: &2020_5000; Rev 2: 2080_4000 for base address of registers)
( set address and bit positions in SPI_CS etc)

( board nos: 12 for Rev2; 17 for B+)
( DECIMAL getboard )  ( in GPio_pi module)


( : setbasereg brdno @ 12 17 twixt IF [ HEX 20804000 ] LITERAL ELSE [ HEX 20205000 ] LITERAL ENDIF ;
setbasereg
 CR HEX DUP .)


HEX
240 CONSTANT IIC_Control

( R0,R1,R2....)
CODE IIC_Ctrl
R2 POP,
R1 POP,
R0 POP,
IIC_Control SWI,
PC R14 MOV,
END-CODE

0 GPEnabI2C

48 CONSTANT ADCaddr

DECIMAL
0 VARIABLE channel

( Define BYTE arrays:)
: byte_array 4/ 1+ 4* <BUILDS ALLOT DOES> + ;
4 byte_array Data_1
4 byte_array Data_3
4 byte_array adc_val

HEX
( Fill BYTE arrays:)
: fill_struct_1
  ( 00000001) 01 0 Data_1 C!
  ( 11000011) C3 channel @ 4 << OR 1 Data_1 C!
  ( 10000011) 83 2 Data_1 C!     ( 128 sps - default)
;

: fill_struct_3
  ( 10010000)  90 0 Data_3 C!
  ( 00000000)   0 1 Data_3 C!   ( now points to Conversion reg)
  ( 10010001)  91 2 Data_3 C! ;

: SPS  ( n...) 5 <<  3 +  2 Data_1 C! ;
: 8sps   0 SPS ;  : 16sps  1 SPS ;  : 32sps  2 SPS ;  : 64sps  3 SPS ;
: 128sps 4 SPS ;  : 250sps 5 SPS ;  : 465sps 6 SPS ;  : 860sps 7 SPS ;

( fill structures for channel no. and speed:)

128sps fill_struct_1 fill_struct_3 

: sel_channel  ( 0 to 3....)
  channel ! C3 channel @ 4 << OR 1 Data_1 C! ;

DECIMAL
( low-level GPIO control:)
( short delay using only Forth words:)
4500 VARIABLE smt
: sm_delay  0 DO I I * DROP LOOP ;  ( n ...) 
: dt smt @ sm_delay ;
( : nNOOP 0 DO NOOP LOOP ;)

( val,pin...)
: start
  1 0 GPWrData DROP DROP dt   1 1 GPWrData DROP DROP dt
  0 0 GPWrData DROP DROP dt   0 1 GPWrData DROP DROP dt ;

: stop
  0 1 GPWrData DROP DROP dt   0 0 GPWrData DROP DROP dt
  1 1 GPWrData DROP DROP dt   1 0 GPWrData DROP DROP dt ;

: request_ADC
 start
 ADCaddr 1 <<    0 Data_1   3  IIC_Ctrl
 stop ;

: wait_bit15
 start
 BEGIN
  ADCaddr 1 <<  1+    0 adc_val   2   IIC_Ctrl
  128  0 adc_val C@  AND
 UNTIL stop ;

: read_ADC
 start
 ADCaddr 1 <<       0 Data_3    2  IIC_Ctrl  ( select conversion reg)
 ADCaddr 1 << 1+    0 adc_val   2  IIC_Ctrl  ( read 2 x 8-bit values from ADC)
 stop ;

: rd_ADS1115        ( .....n)
   request_ADC
   wait_bit15 
   read_ADC
   0 adc_val C@ 8 <<
   1 adc_val C@ +  ;

: ADC_loop   ( n...)
  4500 smt !  860sps
  0 TIME=
  0 DO rd_ADS1115 . LOOP
  TIME ." csec= " . CR
;






