I2C test code for MCP23017 16-Bit I/O Expander in FemtoBasic
Duane C. Johnson
Posts: 955
I'm experimenting with I2C and tried it out on an MCP23017.
I wrote this program to see how it worked.
I found the sequence of commands is very complicated"
Especially with Sequenced and Non-Sequenced reads and writes.
This program loads setup bytes into the registers using sequenced writes.
Then changes to non-sequenced mode for reading and writing.
Have fun!
Duane
I wrote this program to see how it worked.
I found the sequence of commands is very complicated"
Especially with Sequenced and Non-Sequenced reads and writes.
This program loads setup bytes into the registers using sequenced writes.
Then changes to non-sequenced mode for reading and writing.
Have fun!
Duane
1 PRINT "MCP23017 16-Bit I/O Expander with I2C Serial Interface" 2 PRINT "PIN[17..16] SDA, SCL" 3 PRINT "Duane C. Johnson 2011/03/15" 4 PRINT "Red Rock Energy" 5 PRINT "SCL on PIN[17} SDL on PIN[16]" 49 PRINT "" 50 REM A = I2C Address 51 REM B = Device Opcode 52 REM C = Register Address 53 REM D = R/W 54 REM V = VALUE 55 REM W = VALUE 56 REM E = IO BIT 57 REM T = FOR NEXT 58 REM F,G,X = SCRATCH 69 REM Z = TEST FLAG 70 REM Unused Variables HIJKLMNOPQRSUY 80 B=$20:A=0:X=INA[17]:X=INA[16]:Z=0 90 GOSUB 1000 : REM RESET 92 GOSUB 1200 : REM INIT CHIP O 94 GOSUB 1400 : REM INIT CHIP 1 100 REM 300 REM OUTPUT 1 BYTE AT A TIME NON-SEQUENTIAL 310 B=$20 320 INPUT "Reg 0-21, Chip 0-1, R/w 1/0 ? "; C,A,D 330 IF D=1 THEN GOTO 370 340 PRINT " WRITE REGISTER ";C;" ";A;" ? ";:INPUT V 350 REM WRITE 351 GOSUB 2160 :REM START BIT 352 B=B:A=A:D=0 :GOSUB 2200 :REM OUTPUT CONTROL BYTE 353 C=C :GOSUB 2300 :REM OUTPUT REGISTER ADDRESS 354 C=V :GOSUB 2300 :REM OUTPUT DATA BYTE 358 GOSUB 2140 :REM STOP BIT 369 GOTO 300 370 REM READ 371 GOSUB 2160 :REM START BIT 372 B=B:A=A:D=0 :GOSUB 2200 :REM OUTPUT CONTROL BYTE 373 C=C :GOSUB 2300 :REM OUTPUT REGISTER ADDRESS 374 GOSUB 2150 :REM RESTART BIT 375 B=B:A=A:D=1 :GOSUB 2200 :REM OUTPUT CONTROL BYTE 376 GOSUB 2400 :REM 377 V=G:PRINT " READ REGISTER ";C;" ";A;" = ";V :REM INPUT DATA BYTE 378 GOSUB 2140 :REM STOP BIT 379 GOTO 300 390 RETURN 820 GOTO 100 910 END 1000 REM INITILIZATION 1110 OUTA[15]=0:X=INA[15]:PAUSE 500 1190 RETURN 1200 REM SETUP CONTROLL REGISTERS USING SEQUENTIAL MODE 1210 GOSUB 2160 :REM START BIT 1220 B=$20:A=0:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1230 C=$00 : GOSUB 2300 :REM OUTPUT REGISTER ADDRESS 1240 GOSUB 2150 :REM RESTART BIT 1310 B=$20:A=0:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1320 C=$FF : GOSUB 2300 :REM OUTPUT IODIRA 0 1321 C=$FF : GOSUB 2300 :REM OUTPUT IODIRB 1 1322 C=$00 : GOSUB 2300 :REM OUTPUT IPOLA 2 1323 C=$00 : GOSUB 2300 :REM OUTPUT IPOLB 3 1324 C=$00 : GOSUB 2300 :REM OUTPUT GPINTENA 4 1325 C=$00 : GOSUB 2300 :REM OUTPUT GPINTENB 5 1326 C=$00 : GOSUB 2300 :REM OUTPUT DEFVALA 6 1327 C=$00 : GOSUB 2300 :REM OUTPUT DEFVALB 7 1330 C=$00 : GOSUB 2300 :REM OUTPUT INTCONA 8 1331 C=$00 : GOSUB 2300 :REM OUTPUT INTCONB 9 1332 C=$00 : GOSUB 2300 :REM OUTPUT IOCON 10 1333 C=$00 : GOSUB 2300 :REM OUTPUT IOCON 11 1334 C=$00 : GOSUB 2300 :REM OUTPUT GPPUA 12 1335 C=$00 : GOSUB 2300 :REM OUTPUT GPPUB 13 1336 C=$00 : GOSUB 2300 :REM OUTPUT INTFA 14 1337 C=$00 : GOSUB 2300 :REM OUTPUT INTFB 15 1340 C=$00 : GOSUB 2300 :REM OUTPUT NTCAPA 16 1341 C=$00 : GOSUB 2300 :REM OUTPUT NTCAPB 17 1342 C=$FF : GOSUB 2300 :REM OUTPUT GPIOA 18 1343 C=$FF : GOSUB 2300 :REM OUTPUT GPIOB 19 1344 C=$FF : GOSUB 2300 :REM OUTPUT OLATA 20 1345 C=$FF : GOSUB 2300 :REM OUTPUT OLATB 21 1350 GOSUB 2140 :REM STOP BIT 1360 REM FORCE NON-SEQUENTIAL MODE 1361 GOSUB 2160 :REM START BIT 1362 B=$20:A=0:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1363 C=10 : GOSUB 2300 :REM OUTPUT REGISTER ADDRESS 1364 GOSUB 2150 :REM RESTART BIT 1365 B=$20:A=0:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1366 C=$20 : GOSUB 2300 :REM OUTPUT IOCON 10 1367 GOSUB 2140 :REM STOP BIT 1371 GOSUB 2160 :REM START BIT 1372 B=$20:A=0:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1373 C=11 : GOSUB 2300 :REM OUTPUT REGISTER ADDRESS 1374 GOSUB 2150 :REM RESTART BIT 1375 B=$20:A=0:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1376 C=$20 : GOSUB 2300 :REM OUTPUT IOCON 11 1377 GOSUB 2140 :REM STOP BIT 1390 RETURN 1400 REM SETUP CONTROLL REGISTERS USING SEQUENTIAL MODE 1410 GOSUB 2160 :REM START BIT 1420 B=$20:A=1:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1430 C=$00 : GOSUB 2300 :REM OUTPUT REGISTER ADDRESS 1440 GOSUB 2150 :REM RESTART BIT 1510 B=$20:A=1:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1520 C=$FF : GOSUB 2300 :REM OUTPUT IODIRA 0 1521 C=$FF : GOSUB 2300 :REM OUTPUT IODIRB 1 1522 C=$00 : GOSUB 2300 :REM OUTPUT IPOLA 2 1523 C=$00 : GOSUB 2300 :REM OUTPUT IPOLB 3 1524 C=$00 : GOSUB 2300 :REM OUTPUT GPINTENA 4 1525 C=$00 : GOSUB 2300 :REM OUTPUT GPINTENB 5 1526 C=$00 : GOSUB 2300 :REM OUTPUT DEFVALA 6 1527 C=$00 : GOSUB 2300 :REM OUTPUT DEFVALB 7 1530 C=$00 : GOSUB 2300 :REM OUTPUT INTCONA 8 1531 C=$00 : GOSUB 2300 :REM OUTPUT INTCONB 9 1532 C=$00 : GOSUB 2300 :REM OUTPUT IOCON 10 1533 C=$00 : GOSUB 2300 :REM OUTPUT IOCON 11 1534 C=$00 : GOSUB 2300 :REM OUTPUT GPPUA 12 1535 C=$00 : GOSUB 2300 :REM OUTPUT GPPUB 13 1536 C=$00 : GOSUB 2300 :REM OUTPUT INTFA 14 1537 C=$00 : GOSUB 2300 :REM OUTPUT INTFB 15 1540 C=$00 : GOSUB 2300 :REM OUTPUT NTCAPA 16 1541 C=$00 : GOSUB 2300 :REM OUTPUT NTCAPB 17 1542 C=$FF : GOSUB 2300 :REM OUTPUT GPIOA 18 1543 C=$FF : GOSUB 2300 :REM OUTPUT GPIOB 19 1544 C=$FF : GOSUB 2300 :REM OUTPUT OLATA 20 1545 C=$FF : GOSUB 2300 :REM OUTPUT OLATB 21 1550 GOSUB 2140 :REM STOP BIT 1560 REM FORCE NON-SEQUENTIAL MODE 1561 GOSUB 2160 :REM START BIT 1562 B=$20:A=1:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1563 C=10 : GOSUB 2300 :REM OUTPUT REGISTER ADDRESS 1564 GOSUB 2150 :REM RESTART BIT 1565 B=$20:A=1:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1566 C=$20 : GOSUB 2300 :REM OUTPUT IOCON 10 1567 GOSUB 2140 :REM STOP BIT 1571 GOSUB 2160 :REM START BIT 1572 B=$20:A=1:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1573 C=11 : GOSUB 2300 :REM OUTPUT REGISTER ADDRESS 1574 GOSUB 2150 :REM RESTART BIT 1575 B=$20:A=1:D=0:GOSUB 2200 :REM OUTPUT CONTROL BYTE 1576 C=$20 : GOSUB 2300 :REM OUTPUT IOCON 11 1577 GOSUB 2140 :REM STOP BIT 1590 RETURN 1910 RETURN 2000 REM I2C DRIVERS 2100 OUTA[17]=0:IF INA[16]=0 THEN GOTO 2100:REM CHECK FOR CLOCK STRETCHING 2101 OUTA[16]=0 :RETURN:REM OUT 0 BIT 2110 X=INA[17] :IF INA[16]=0 THEN GOTO 2110:REM CHECK FOR CLOCK STRETCHING 2111 OUTA[16]=0 :RETURN:REM OUT 1 BIT 2120 X=INA[17] :IF INA[16]=0 THEN GOTO 2120:REM CHECK FOR CLOCK STRETCHING 2121 E=INA[17] :OUTA[16]=0 :RETURN:REM INPUT BIT 2130 X=INA[17] :IF INA[16]=0 THEN GOTO 2130:REM CHECK FOR CLOCK STRETCHING 2131 E=INA[17] :OUTA[16]=0:RETURN : REM INPUT ACK 2140 OUTA[17]=0:OUTA[16]=0 :REM MAKE BOTH LOW 2141 IF INA[16]=0 THEN GOTO 2141:REM CHECK FOR CLOCK STRETCHING 2142 IF INA[17]=0 THEN GOTO 2142:REM WAIT FOR DATA TO GO HIGH :RETURN :REM STOP BIT 2143 RETURN:REM STOP BIT 2150 OUTA[17]=0:OUTA[16]=0 :REM MAKE BOTH LOW 2151 IF INA[16]=0 THEN GOTO 2151:REM CHECK FOR CLOCK STRETCHING 2152 IF INA[17]=0 THEN GOTO 2152:REM WAIT FOR DATA TO GO HIGH :RETURN :REM STOP BIT 2153 OUTA[16]=0 :REM FORCE CLOCK LOW 2154 IF INA[16]=0 THEN GOTO 2154 :REM WAIT FOR CLOCK TO BE HIGH 2155 OUTA[17]=0:OUTA[16]=0 :RETURN:REM RESTART BIT 2150 OUTA[16]=0:OUTA[17]=0 :REM MAKE BOTH LOW 2151 IF INA[16]=0 THEN GOTO 2151:REM CHECK FOR CLOCK STRETCHING 2152 IF INA[17]=0 THEN GOTO 2152:REM WAIT FOR DATA TO GO HIGH :RETURN :REM STOP BIT 2153 OUTA[16]=0 :REM FORCE CLOCK LOW 2154 IF INA[16]=0 THEN GOTO 2154 :REM WAIT FOR CLOCK TO BE HIGH 2155 OUTA[17]=0:OUTA[16]=0 :RETURN:REM RESTART BIT 2160 IF INA[17]=0 THEN GOTO 2160:REM WAIT FOR DATA TO BE HIGH 2161 IF INA[16]=0 THEN GOTO 2161:REM WAIT FOR CLOCK TO BE HIGH 2162 OUTA[17]=0:OUTA[16]=0 :RETURN:REM START BIT 2200 REM OUTPUT CONTROL BYTE 2210 G =((B+A) SHL 1 + D) REV 8 2211 IF Z=1 THEN PRINT "2200 ";((B+A) SHL 1 + D), 2220 FOR T = 0 TO 7 2221 IF Z=1 THEN PRINT G & 1; 2225 IF G & 1 = 0 THEN GOSUB 2100 2230 IF G & 1 = 1 THEN GOSUB 2110 2235 G = G SHR 1 2240 NEXT T 2245 GOSUB 2130 : REM TEST ACK 2250 IF H = 1 THEN Z=1:DISPLAY 7:IF Z=1 THEN PRINT " NACK ";:REM IO ERROR 2251 IF Z=1 THEN PRINT "" 2255 RETURN 2300 REM OUTPUT REGISTER ADDRESS, OR BYTE 2310 G = C REV 8 2311 IF Z=1 THEN PRINT "2300 ";C, 2320 FOR T = 0 TO 7 2321 IF Z=1 THEN PRINT G & 1; 2325 IF G & 1 = 0 THEN GOSUB 2100:REM OUT 0 BIT 2330 IF G & 1 = 1 THEN GOSUB 2110:REM OUT 1 BIT 2335 G = G SHR 1 2340 NEXT T 2345 GOSUB 2130 : REM TEST ACK 2350 IF E = 1 THEN Z=1:DISPLAY 7:IF Z=1 THEN PRINT " NACK ";:REM IO ERROR 2351 IF Z=1 THEN PRINT "" 2355 RETURN 2400 REM INPUT DATA BYTE 2410 G = 0 2411 IF Z=1 THEN PRINT "2400 "; 2420 FOR T = 0 TO 7 2425 GOSUB 2120 2430 G = (G SHL 1) + E 2431 IF Z=1 THEN PRINT G & 1; 2440 NEXT T 2445 GOSUB 2130 : REM TEST ACK 2450 IF H = 1 THEN Z=1:DISPLAY 7:IF Z=1 THEN PRINT " NACK ";:REM IO ERROR 2451 IF Z=1 THEN PRINT "" 2455 RETURN
Comments
Still, it is impressive how much can be done with FemtoBasic as it stands. Good work.
I haven't seen code like that since 1975:-)