[[MenuBar]] - Nexys4 付属のI2C温度計を miniCPUで駆動して、温度を計測し、LEDに計測した温度を表示します。 - miniCPUアセンブラのソースコード PUSHI rtnval // push arg1... the address for receiving the result(temprature) PUSH tempReadReg // push the register no. 0 push tempAddr // push the I2C temprature sensor address, 0x4b pushi rtn0 // push the return address JMP ri2c2 // call the ri2c2 ... read 2 byte data from the i2c device, // rtn0: pop rtncode PUSH rtnval // push arg1... the i2c slave Addr PUSHI 7 // push the return address shr OUT HALT // rtnval: 0x0000 rtncode: 0x0000 tempReadReg: 0x0000 tempAddr: 0x004b // // wi2c1 // Write 1 byte to an i2c device // arg 0: return address, arg1:device address, arg2:register no, arg3:1 byte value // return ... if 1: ok, 0: error // wi2c1: PUSH wi2c1_jmp // subroutine. the 1st step to make the return instruction BOR // make the return instruction using arg1 and the previous instruction POP wi2c1_rtn // save the return instruction POP wi2c1_addr // save the arg1, the i2c slave address pop wi2c1_reg // save the arg2, destination register address pop wi2c1_val // save the value which will be assiinged to the destination register. // PUSHI i2cStart // push arg1... the i2c slave Addr PUSHI wi2c1_l1 // push the return address JMP SubI2C1 // call the subroutine // wi2c1_l1: push wi2c1_addr pushi 1 shl // make the i2c device address with the write flag // pushi wi2c1_l2 jmp si2c1 // wi2c1_l2: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c1_l3 // JMP SubI2C1 // call the subroutine // wi2c1_l3: pushi wi2c1_reg pushi wi2c1_l4 jmp si2c1 // wi2c1_l4: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c1_l5 // JMP SubI2C1 // call the subroutine // wi2c1_l5: push wi2c1_val pushi wi2c1_l6 jmp si2c1 // wi2c1_l6: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c1_l7 // JMP SubI2C1 // call the subroutine // wi2c1_l7: PUSHI i2cStop // push arg1 .... write the ack PUSHI wi2c1_l8 // push the return address JMP SubI2C1 // call the subroutine // wi2c1_l8: pushI 1 wi2c1_rtn: jmp 0x000 // return wi2c1_jmp: 0x4000 wi2c1_addr: 0x0000 wi2c1_reg: 0x0000 wi2c1_val: 0x0000 // // wi2c2 // Write 2 byte to an i2c device // arg 0: return address, arg1:device address, arg2:register no, arg3:two byte values // return ... if 1: ok, 0: error // wi2c2: PUSH wi2c2_jmp // subroutine. the 1st step to make the return instruction BOR // make the return instruction using arg1 and the previous instruction POP wi2c2_rtn // save the return instruction POP wi2c2_addr // save the arg1, the i2c slave address pop wi2c2_reg // save the arg2, destination register address pop wi2c2_val // save the value which will be assiinged to the destination register. // PUSHI i2cStart // push arg1... the i2c slave Addr PUSHI wi2c2_l1 // push the return address JMP SubI2C1 // call the subroutine // wi2c2_l1: push wi2c2_addr pushi 1 shl // make the i2c device address with the write flag pop wi2c2_waddr // pushi wi2c2_l2 jmp si2c1 // wi2c2_l2: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c2_l3 // JMP SubI2C1 // call the subroutine // wi2c2_l3: push wi2c2_reg pushi wi2c2_l4 jmp si2c1 // wi2c2_l4: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c2_l5 // JMP SubI2C1 // call the subroutine // wi2c2_l5: push wi2c2_val pushi 0x00ff band pushi wi2c2_l6 jmp si2c1 // wi2c2_l6: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c2_l7 // JMP SubI2C1 // call the subroutine // wi2c2_l7: push wi2c2_val pushi 8 shr pushi wi2c2_l8 jmp si2c1 // wi2c2_l8: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c2_l9 // JMP SubI2C1 // call the subroutine // wi2c2_l9: PUSHI i2cStop // push arg1 .... write the ack PUSHI wi2c2_l10 // push the return address JMP SubI2C1 // call the subroutine // wi2c2_l10: pushI 1 wi2c2_rtn: jmp 0x000 // return wi2c2_jmp: 0x4000 wi2c2_addr: 0x0000 wi2c2_reg: 0x0000 wi2c2_val: 0x0000 // // wi2c4 // Write 4 byte to an i2c device // arg 0: return address, arg1:device address, arg2:register no, arg3:1st 2 byte, arg4: 2nd 2byte, // return ... if 1: ok, 0: error // wi2c4: PUSH wi2c4_jmp // subroutine. the 1st step to make the return instruction BOR // make the return instruction using arg1 and the previous instruction POP wi2c4_rtn // save the return instruction POP wi2c4_addr // save the arg1, the i2c slave address pop wi2c4_reg // save the arg2, destination register address pop wi2c4_val1 // save the 1st value which will be assiinged to the destination registers. pop wi2c4_val2 // save the 2nd value which will be assiinged to the destination register2. // PUSHI i2cStart // push arg1... the i2c slave Addr PUSHI wi2c4_l1 // push the return address JMP SubI2C1 // call the subroutine // wi2c4_l1: push wi2c4_addr pushi 1 shl // make the i2c device address with the write flag pushi wi2c4_l2 jmp si2c1 // wi2c4_l2: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c4_l3 // JMP SubI2C1 // call the subroutine // wi2c4_l3: push wi2c4_reg pushi wi2c4_l4 jmp si2c1 // wi2c4_l4: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c4_l5 // JMP SubI2C1 // call the subroutine // wi2c4_l5: push wi2c4_val1 pushi 0x00ff band pushi wi2c4_l6 jmp si2c1 // wi2c4_l6: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c4_l7 // JMP SubI2C1 // call the subroutine // wi2c4_l7: push wi2c4_val1 pushi 8 shr pushi wi2c4_l8 jmp si2c1 // wi2c4_l8: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c4_l9 // JMP SubI2C1 // call the subroutine // wi2c4_l9: push wi2c4_val2 pushi 0x00ff band pushi wi2c4_l10 jmp si2c1 // wi2c4_l10: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c4_l11 // JMP SubI2C1 // call the subroutine // wi2c4_l11: push wi2c4_val2 pushi 8 shr pushi wi2c4_l12 jmp si2c1 // wi2c4_l12: PUSHI i2cRAck // push arg1 .... read the ack PUSHI wi2c4_l13 // JMP SubI2C1 // call the subroutine // wi2c4_l13: PUSHI i2cStop // push arg1 .... write the ack PUSHI wi2c4_l14 // push the return address JMP SubI2C1 // call the subroutine // wi2c4_l14: pushI 1 wi2c4_rtn: jmp 0x000 // return wi2c4_jmp: 0x4000 wi2c4_addr: 0x0000 wi2c4_reg: 0x0000 wi2c4_val1: 0x0000 wi2c4_val2: 0x0000 // // si2c1 // Write 1 byte series to an i2c device // ... arg1 ... device address, arg1... register no. arg2... 1 byte value // return ... if 1: ok, 0: error // si2c1: PUSH si2c1_jmp // subroutine. the 1st step to make the return instruction BOR // make the return instruction using arg1 and the previous instruction POP si2c1_rtn // save the return instruction POP si2c1_val PUSHI 8 POP si2c1_i si2c1_a3: push si2c1_val pushi 0x0080 band JNZ si2c1_a1 pushi 0x0000 out pushi 0x0002 out pushi 0x0000 out jmp si2c1_a2 si2c1_a1: pushi 0x0001 out pushi 0x0003 out pushi 0x0001 out si2c1_a2: push si2c1_val pushi 1 shl pop si2c1_val push si2c1_i pushi 1 sub pop si2c1_i push si2c1_i jnz si2c1_a3 si2c1_rtn: jmp 0x000 si2c1_jmp: 0x4000 si2c1_val: 0x0000 si2c1_i: 0x0000 // // ri2c1 // Read 1 byte from an i2c device // ... arg1 ... device address, arg2 ... register number, arg3 .... the address for receiving the data // return ... if 1:ok, 0:error // ri2c1: PUSH ri2c1_jmp // subroutine. the 1st step to make the return instruction BOR // make the return instruction using arg1 and the previous instruction POP ri2c1_rtn // save the return instruction POP ri2c1_addr // save the arg1, the i2c slave address pop ri2c1_reg // save the arg2, destination register address pop ri2c1_raddr // save the address which receives the value of the destination register. // PUSHI i2cStart // push arg1... the i2c slave Addr PUSHI ri2c1_a1 // push the return address JMP SubI2C1 // call the subroutine // ri2c1_a1: push ri2c1_addr pushi 1 shl // make the i2c device address with the write flag pop wi2c1_waddr // pushi ri2c1_a2 jmp si2c1 // ri2c1_a2: PUSHI i2cRAck // push arg1 .... read the ack PUSHI ri2c1_a3 // JMP SubI2C1 // call the subroutine // ri2c1_a3: push ri2c1_reg pushi ri2c1_a4 jmp si2c1 // ri2c1_a4: PUSHI i2cRAck // push arg1 .... read the ack PUSHI ri2c1_a5 // JMP SubI2C1 // call the subroutine // ri2c1_a5: PUSHI i2cStart // push arg1... the i2c slave Addr PUSHI ri2c1_a6 // push the return address JMP SubI2C1 // call the subroutine // ri2c1_a6: push ri2c1_addr pushi 1 shl // make the i2c device address with the read flag pushi 0x0001 BOR pushi ri2c1_a7 jmp si2c1 // ri2c1_a7: PUSHI i2cRAck // push arg1 .... read the ack PUSHI ri2c1_a8 // JMP SubI2C1 // call the subroutine // ri2c1_a8: pushi i2cRead pushi ri2c1_a9 jmp SubI2C1 // ri2c1_a9: push ri2c1_raddr in st // PUSHI i2cNAck // push arg1 .... Ack PUSHI ri2c1_a10 // JMP SubI2C1 // call the subroutine // ri2c1_a10: PUSHI i2cStop // push arg1 .... write the ack PUSHI ri2c1_a11 // push the return address JMP SubI2C1 // call the subroutine // ri2c1_a11: pushI 1 ri2c1_rtn: jmp 0x000 // return ri2c1_jmp: 0x4000 ri2c1_addr: 0x0000 ri2c1_reg: 0x0000 ri2c1_raddr: 0x0000 // // ri2c2 // Read 2 byte series from an i2c device // ... arg1 ... device address, arg2 ... register number, arg3 ... the address for receiving the data // return ... if 1: ok, 0:error // ri2c2: PUSH ri2c2_jmp // subroutine. the 1st step to make the return instruction BOR // make the return instruction using arg1 and the previous instruction POP ri2c2_rtn // save the return instruction POP ri2c2_addr // save the arg1, the i2c slave address pop ri2c2_reg // save the arg2, destination register address pop ri2c2_raddr // save the address which receives the value of the destination register. // PUSHI i2cStart // push arg1... the i2c slave Addr PUSHI ri2c2_a1 // push the return address JMP SubI2C1 // call the subroutine // ri2c2_a1: push ri2c2_addr pushi 1 shl // make the i2c device address with the write flag // pushi ri2c2_a2 jmp si2c1 // ri2c2_a2: PUSHI i2cRAck // push arg1 .... read the ack PUSHI ri2c2_a3 // JMP SubI2C1 // call the subroutine // ri2c2_a3: push ri2c2_reg pushi ri2c2_a4 jmp si2c1 // ri2c2_a4: PUSHI i2cRAck // push arg1 .... read the ack PUSHI ri2c2_a5 // JMP SubI2C1 // call the subroutine // ri2c2_a5: PUSHI i2cStart // push arg1... the i2c slave Addr PUSHI ri2c2_a6 // push the return address JMP SubI2C1 // call the subroutine // ri2c2_a6: push ri2c2_addr pushi 1 shl // make the i2c device address with the read flag pushi 0x0001 BOR pushi ri2c2_a7 jmp si2c1 // ri2c2_a7: PUSHI i2cRAck // push arg1 .... read the ack PUSHI ri2c2_a8 // JMP SubI2C1 // call the subroutine // ri2c2_a8: pushi i2cRead pushi ri2c2_l9 jmp SubI2C1 // ri2c2_l9: in pushi 8 shl pop ri2c2_val1 // PUSHI i2cWAck // push arg1 .... write the ack PUSHI ri2c2_a10 // JMP SubI2C1 // call the subroutine // ri2c2_a10: pushi i2cRead pushi ri2c2_a11 jmp SubI2C1 // ri2c2_a11: push ri2c2_raddr in push ri2c2_val1 bor st // PUSHI i2cNAck // push arg1 .... Ack PUSHI ri2c2_a12 // JMP SubI2C1 // call the subroutine // ri2c2_a12: PUSHI i2cStop // push arg1 .... write the ack PUSHI ri2c2_a13 // push the return address JMP SubI2C1 // call the subroutine // ri2c2_a13: pushI 1 ri2c2_rtn: jmp 0x000 // return ri2c2_jmp: 0x4000 ri2c2_addr: 0x0000 ri2c2_reg: 0x0000 ri2c2_raddr: 0x0000 ri2c2_val1: 0x0000 // // SubI2C1 ... send the [arg1] steps of I2C [scl,sda] sequence after the address of [arg1 +1] to the i2c bus. // SubI2C1: PUSH LblJMP // subroutine. the 1st step to return instruction BOR // make the return instruction using arg1 and the previous instruction POP RtnSub1 // save the return instruction POP Sub1Data2 // save the arg1 PUSH Sub1Data2 LD POP N PUSH Sub1Data2 PUSHI 1 ADD POP Sub1SA PUSHI 0 POP i L1: PUSH i PUSH Sub1SA ADD LD //... Sub1S[i]; OUT //... print(Sub1S[i]) ; PUSH i PUSHI 1 ADD POP i PUSH i PUSH N SUB JNZ L1 // if(i<n) goto L1; RtnSub1: JMP 0x000 // return LblJMP: 0x4000 Sub1Data2: 0x0000 Sub1SA: 0x0000 i: 0x0000 N: 0x0000 // // data for controlling i2c // (MSB) ...... scl, sda (LSB) // // I2C start i2cStart: 3 1 //01 3 //11 2 //10 0 //00 // // I2C AddrWrite i2cAddrW: 3 0 // 00 2 // 10 send 0 ... write 0 // 00 // // I2C AddrRead i2cAddrR: 3 1 // 01 3 // 11 ... read 1 // 01 // // I2C i2cRAck: 3 1 // 01 3 // 11 read ack 1 // 01 // // I2C Write Ack i2cWAck: 3 0 // 00 2 // 10 send 0 ... write 0 // 00 // // I2C NAck i2cNAck: 3 1 //01 3 // ... read 1 // // // // stop i2cStop: 3 2 // 10 3 // 11 stop the transfering 3 // 11 // // I2C read 1byte i2cRead: 0x0011 1 // 01 3 // 11 1 // 01 3 // 11 1 // 01 3 // 11 1 // 01 3 // 11 1 // 01 3 // 11 1 // 01 3 // 11 1 // 01 3 // 11 1 // 01 3 // 11 1 // 01 - 目的コード+アセンブラソース