fl { I/O Expanda(PCAL9554BPW) PropForth 5.5 2015/04/29 23:01:59 PCAL9554BPW Propeller SDA ------ SDA SCL ------ SCL A0 -------- GND A1 -------- GND A2 -------- GND } \ =========================================================================== \ Constants \ =========================================================================== \ Slave addres h20 for PCAL9554BPW h40 wconstant PCAL9554BPW \ register 0 wconstant InPort 1 wconstant OutPort 2 wconstant Porality 3 wconstant Config h40 wconstant Output_st0 h41 wconstant Output_st1 h42 wconstant InLatch h43 wconstant Pull_u/d_ena h44 wconstant Pull_u/d_sel h45 wconstant Interrupt_mask h46 wconstant Interrupt_status h4F wconstant OutputConfig variable reg_num -4 allot h00 c, h01 c, h02 c, h03 c, h40 c, h41 c, h42 c, h43 c, h44 c, h45 c, h46 c, h4F c, \ =========================================================================== \ Main \ =========================================================================== \ allocate string \ ( -- ) : s, parsenw dup C@ 1+ bounds dup rot2 do C@++ c, loop drop ; wvariable string -2 allot s, InputPort s, OutputPort s, PoralityInversion s, Configuration s, OutputDriveStrength0 s, OutputDriveStrength1 s, InputLatch s, Pull_up/down_enable s, Pull_up/down_selection s, InteruptMask s, InterruptStatus s, OutputPortConfiguration \ Display allocated string above \ ( n1 n2 -- ) n1:string index n2:string's top address : dispStr swap dup 0 <> if 0 do dup C@ + 1+ loop else drop then .cstr ; \ TAB \ ( -- ) : tab 9 emit ; : 2tab tab tab ; \ Display all registers from mode1 to ALLCALLADR \ ( -- ) : rd_allreg cr hex d12 0 do reg_num i + C@ PCAL9554BPW i2c_rd err? i string dispStr ." :" i 2 < if 2tab else i 3 u/mod drop 0= if 2tab else i d11 < if tab thens ." h" . cr loop decimal cr ; \ Invert logic of input port \ ( n1 -- ) n1:0-hFF 1=inverting 0= normal \ [b7 b6 b5 b4 b3 b2 b1 b0]=[P7 P6 P5 P4 P3 P2 P1 P0] \ b7-b0 is data on i2c P7-P0 is port on device : porality_inv Porality PCAL9554BPW i2c_wr err? ; \ Set port to input or output \ ( n1 -- ) n1:0-hFF 1=input 0=output : config Config PCAL9554BPW i2c_wr err? ; \ Set drive-capability for each pin \ OutputDriveStrength0 [port3 port2 port1 port0]=[b7-6 b5-4 b3-2 b1-0] \ OutputDriveStrength1 [port7 port6 port5 port4]=[b7-6 b5-4 b3-2 b1-0] \ 00=x0.25 01=x0.5 10=x0.75 11=x1.0 \ ( n1 n2 -- ) n1:OutputDriveStrength0 n2:OutputDriveStrength1 : setDrive Output_st1 PCAL9554BPW i2c_wr err? Output_st0 PCAL9554BPW i2c_wr err? ; \ Enable/Disable pull-up/pull-down resistor \ ( n1 -- ) n1:0-hFF 1=enable 0=disable : pull_up/dn_ena Pull_u/d_ena PCAL9554BPW i2c_wr err? ; \ Selection port to pull-up or pull-down resistor \ ( n1 -- ) n1:0-hFF 1=pull-up resistor 0=pull-down resistor : pull_up/dn_sel Pull_u/d_sel PCAL9554BPW i2c_wr err? ; \ Select output type to pushpull or open-drain \ ( n1 -- ) n1:0-hFF 1=open-drain 0=pushpull : output_sel OutputConfig PCAL9554BPW i2c_wr err? ; \ Test for input and output \ ( -- ) : demo cr ." [Input port test]" cr \ Set all port to input (porality is normal) hFF config 0 porality_inv \ Set all port to enable hFF pull_up/dn_ena \ Set all port to pull-down resistor 0 pull_up/dn_sel ." b7 b6 b3 b4 b3 b2 b1 b0" cr 8 0 do 1 i lshift pull_up/dn_sel \ Set only 1bit to pull-up InPort PCAL9554BPW i2c_rd err? \ Rwad Inport \ Display bit h80 8 0 do 2dup and if ." 1" else ." 0" then 1 rshift loop 2drop cr loop cr ." [Reverse input porality]" cr hFF porality_inv ." b7 b6 b3 b4 b3 b2 b1 b0" cr 8 0 do 1 i lshift pull_up/dn_sel \ Set only 1bit to pull-up InPort PCAL9554BPW i2c_rd err? \ Rwad Inport \ Display bit h80 8 0 do 2dup and if ." 1" else ." 0" then 1 rshift loop 2drop cr loop cr ." [Output port test]" cr \ Set output to open-drain (Default:push-pull) hFF output_sel \ Set all port to output 0 config ." b7 b6 b3 b4 b3 b2 b1 b0" cr 8 0 do \ Set only 1bit to 1 1 i lshift OutPort PCAL9554BPW i2c_wr err? OutPort PCAL9554BPW i2c_rd err? \ Display bit h80 8 0 do 2dup and if ." 1" else ." 0" then 1 rshift loop 2drop cr loop ;