- 追加された行はこの色です。
- 削除された行はこの色です。
[[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
- 目的コード+アセンブラソース