From 80d26ca9c1e8ec5c620285f29b1d2b1c76536b96 Mon Sep 17 00:00:00 2001 From: Jimmy Hu Date: Tue, 24 Oct 2023 10:41:11 +0800 Subject: [PATCH] add support for legacy i2c implementation --- super_i2c/super_i2c.tbs | 122 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 3 deletions(-) diff --git a/super_i2c/super_i2c.tbs b/super_i2c/super_i2c.tbs index c2bd3d3..90ec5bd 100644 --- a/super_i2c/super_i2c.tbs +++ b/super_i2c/super_i2c.tbs @@ -43,12 +43,21 @@ register_normal_slot: si2c_in_use(f)=YES si2c_user_signature(f)=signature si2c_register=f - +#IF I2C_AVAILABLE i2c.num=f i2c.sdamap=sda i2c.sclmap=scl i2c.enabled=YES - +#ELSE + si2c_sda(f)=sda + si2c_scl(f)=scl + io.num=scl + io.state=HIGH + io.enabled=YES + io.num=sda + io.state=HIGH + io.enabled=NO +#ENDIF #if SI2C_DEBUG_PRINT si2c_debugprint("'"+si2c_user_signature(f)+"' register i2c #"+str(f)) #endif @@ -69,11 +78,23 @@ register_normal_slot: si2c_in_use(f)=YES si2c_user_signature(f)=signature si2c_register=f - +#IF I2C_AVAILABLE i2c.num=f i2c.sdamap=sda i2c.sclmap=scl i2c.enabled=YES +#ELSE + si2c_sda(f)=sda + si2c_scl(f)=scl + si2c_register=f + + io.num=scl + io.state=HIGH + io.enabled=YES + io.num=sda + io.state=HIGH + io.enabled=NO +#ENDIF #if SI2C_DEBUG_PRINT si2c_debugprint("'"+si2c_user_signature(f)+"' register i2c #"+str(f)) @@ -137,11 +158,30 @@ sub si2c_get(num as byte) end sub sub si2c_start() +#IF I2C_AVAILABLE i2c.start() +#ELSE + io.num=si2c_sda(si2c_num) + io.enabled=YES + + io.lineset(si2c_scl(si2c_num),HIGH) + io.lineset(si2c_sda(si2c_num),HIGH) + io.lineset(si2c_sda(si2c_num),LOW) + io.lineset(si2c_scl(si2c_num),LOW) +#ENDIF end sub sub si2c_stop() +#IF I2C_AVAILABLE i2c.stop() +#ELSE + io.num=si2c_sda(si2c_num) + io.enabled=YES + + io.lineset(si2c_sda(si2c_num),LOW) + io.lineset(si2c_scl(si2c_num),HIGH) + io.lineset(si2c_sda(si2c_num),HIGH) +#ENDIF end sub sub si2c_write(data as byte) @@ -150,7 +190,43 @@ sub si2c_write(data as byte) dim BitData as boolean 'Comparison result (1 or 0) if i2c.num>3 then +#IF I2C_AVAILABLE i2c.write(data) +#ELSE + compval = &h80 'Initialize the MASK + + io.num = si2c_scl(si2c_num) 'Select SSI_CLK line + io.state = LOW 'Initialize the transmition + + io.num = si2c_sda(si2c_num) 'Select SSI_SDA line + io.enabled=YES 'Set as output + + for bitCnt = 0 to 7 step 1 + BitData = data AND compval 'Define the state of the bit(MSB-->LSB) + compval = compval / 2 'Move the comparision to the next bit(MSB-->LSB) + + if(BitData) then + io.state = HIGH 'Bit is 1 + else + io.state = LOW 'Bit is 0 + end if + + io.num = si2c_scl(si2c_num) 'Write the bit to I2C device + io.state = HIGH + io.invert(si2c_scl(si2c_num)) + + io.num = si2c_sda(si2c_num) 'Select SSI_SDA line, NOTE: this must be the last + 'statement in the loop so we can release the SSI_SDA + 'line as soon as possible to alow for the ack + next bitCnt + + io.num = si2c_sda(si2c_num) + io.enabled=NO 'Set SSI_SDA as input to allow ack receive + + io.num = si2c_scl(si2c_num) 'Emulate the ACK frame + io.state = HIGH + io.invert(si2c_scl(si2c_num)) 'Finish the ACK frame +#ENDIF else ssi.channel=i2c.num ssi.str(chr(data),PL_SSI_ACK_RX) @@ -162,7 +238,47 @@ function si2c_read(acknak_request as boolean) as byte dim compval as byte 'Value to compare - MASK if i2c.num>3 then +#IF I2C_AVAILABLE si2c_read = i2c.read(acknak_request) +#ELSE + si2c_read=0 + compval=&h80 'Initialize the MASK + + io.num=si2c_sda(si2c_num) 'Select SSI_SDA line + io.enabled=NO 'Set as input + + io.num=si2c_scl(si2c_num) 'Select SSI_CLK line + io.state=LOW 'Initialize the transmition + + for bitCnt=0 to 7 step 1 + io.state=HIGH 'Read one bit from I2C device + io.num=si2c_sda(si2c_num) + if(io.state=HIGH) then 'Devine the state of the bit + si2c_read=si2c_read OR compval 'Store the value of the bit + end if + compval=compval/2 'Move the comparision to the next bit(MSB-->LSB) + + io.num=si2c_scl(si2c_num) + io.state=LOW 'Clear the clock line (the data can change now...) + next bitCnt + + io.num = si2c_sda(si2c_num) 'Select SSI_SDA line + io.enabled=YES 'Enable SSI_DO as output + + if acknak_request=TRUE then 'Does user want to send an ack or not + io.state = LOW 'Bring Low for ACK + else + io.state = HIGH 'Bring high for NACK + end if + + io.num=si2c_scl(si2c_num) 'Select SSI_CLK line + io.state=HIGH 'Set SSI_CLK line + io.invert(si2c_scl(si2c_num)) 'Clear SSI_CLK line + +#ENDIF + #if SI2C_DEBUG_PRINT + si2c_debugprint("i2c read data:"+ hex(si2c_read)) + #endif else dim tmp as word=0 ssi.channel=i2c.num