( ADS1115sForth)
( June 2016)
( 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)
( *** uses RiscOS IIC calls, but NOT 'Tank' GPIO module ***)

( OSCLI" RMEnsure GPIO 0.00 RMLoad GPIO"
OSCLI" RMEnsure GPIO 0.40 ERROR HELP can't find GPIO module")

( setbasereg called in GetBoard)
HEX GPIOsel_fn 5000 +
( HEX 20205000 200 SWAP DECIMAL 13 SPI_reg)
CONSTANT IIC_C                      ( IIC Control Reg)
( IIC_C CR U. KEY DROP)

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

HEX
IIC_C    4 + CONSTANT   IIC_S       ( IIC Status Reg)
IIC_S    4 + CONSTANT   IIC_DLEN    ( Data Length Reg)
IIC_DLEN 4 + CONSTANT   IIC_A       ( Slave Address Reg)
IIC_A    4 + CONSTANT   IIC_FIFO    ( Data FIFO Reg)
IIC_FIFO 4 + CONSTANT   IIC_DIV     ( Clock Divider Reg)
IIC_DIV  4 + CONSTANT   IIC_DEL     ( Data Delay Reg)
IIC_DEL  4 + CONSTANT   IIC_CLKT    ( Clock Timeout Reg)

( Codes for different operations:)
( Control Reg:)
00008000 CONSTANT I2CEN     ( BSC controller enabled - bit 15)
00000080 CONSTANT Start     ( Start Transfer when 1 - bit 7)
00000030 CONSTANT CLR_FIFO  ( Clear FIFO when x1 or 1x - bits 5 & 4)
00000001 VARIABLE Rd/Wr     ( 0=write; 1=read packet transfer - bit 0)

( Status Reg:)
00000200 CONSTANT CLKT      ( 1=slave has held signal low for > CLKT reg value - bit 9)
00000100 CONSTANT ERR       ( 1=slave not acknowledged its address - bit 8)
00000080 CONSTANT RXF       ( 1=read FIFO is full - bit 7)
00000040 CONSTANT TXE       ( 1=FIFO is empty - bit 6)
00000020 CONSTANT RXD       ( 0=empty - bit 5)
00000010 CONSTANT TXD       ( 0=Full - bit 4)
00000002 CONSTANT DONE      ( 1=Transfer complete - bit 1)
00000001 CONSTANT TA        ( 1=Transfer acive - bit 0)


( 0 GPEnabI2C)  ( replaced by Forth word below)

: gEnabI2C
  4 pinmode !        ( 4=100 - alt mode 0)
  2 set_pinmode
  3 set_pinmode ;    ( pins 2 & 3 for B+)

gEnabI2C

HEX
48 CONSTANT ADCaddr   ( bus address of ADC chip)

DECIMAL
0 VARIABLE channel    ( channels 0 to 3)

( 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!
  ( 01000010) C3 channel @ 4 << OR 1 Data_1 C!  ( single-shot conversion)
  ( 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! ;

DECIMAL
( speed selection samples/sec)
: 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 

( short delay using only Forth words:)
4500 VARIABLE smt
: sm_delay  0 DO I I * DROP LOOP ;  ( n ...) 
: dt smt @ sm_delay ;

DECIMAL
( low-level GPIO control:)
( val,pin...)
: start
  1 2 gWrData dt   1 3 gWrData dt
  0 2 gWrData dt   0 3 gWrData dt ;

: stop
  0 2 gWrData dt   0 3 gWrData dt
  1 2 gWrData dt   1 3 gWrData dt ;

( Setup registers:)
: request_ADC
 start
 ADCaddr 1 <<    0 Data_1   3  IIC_Ctrl
 stop ;

DECIMAL
: 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@ +  ;

HEX
: sel_channel  ( 0 to 3....)
  channel ! C3 channel @ 4 << OR 1 Data_1 C! 
  request_ADC rd_ADS1115 ;     ( setup for single-shot reading)

DECIMAL

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






