[[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
- 目的コード+アセンブラソース


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS