001package cases.case_16_readDeviceID.protocols;
002
003import com.advantest.itee.tmapi.protocolaccess.IProtocolInterfaceResults;
004import com.advantest.itee.tmapi.protocolaccess.ProtocolAccess;
005import com.advantest.itee.tmapi.protocolaccess.Transaction;
006import com.advantest.itee.tmapi.protocolaccess.stdprotocols.I2C;
007
008import xoc.dta.datatypes.MultiSiteLong;
009
010/**
011 * I2C protocol example of I2C usage with ProtocolAccess
012 * <p> The class extends {@link I2C} provided by {@link ProtocolAccess} and serves I2C protocol setup of an example DUT.
013 * The specificiation of I2C in the example for register operations is as below:
014 * <p><b>Register Write</b>
015 * <ol>
016 *   <li>Start Condtion</i>
017 *   <li>Send byte 0xAE and expects ack</li>
018 *   <li>Send byte address(8 MSB) and expects ack</li>
019 *   <li>Send byte address(8 LSB) and expects ack</li>
020 *   <li>Send byte Data(8 MSB) and expects ack</li>
021 *   <li>Send byte Data(8 LSB) and expects ack</li>
022 *   <li>Stop Condtion</i>
023 * </ol>
024 * <p><b>Register Read</b>
025 * <ol>
026 *   <li>Start Condtion</i>
027 *   <li>Send byte 0xAE and expects ack</li>
028 *   <li>Send byte address(8 MSB) and expects ack</li>
029 *   <li>Send byte address(8 LSB) and expects ack</li>
030 *   <li>Send byte 0xAF and expects ack</li>
031 *   <li>Receive byte data(8 MSB) and no ack</li>
032 *   <li>Receive byte data(8 LSB) and ack low</li>
033 *   <li>Stop Condtion</i>
034 * </ol>
035 * <p>This protocol expects the wavetable defintion of the protocol signal below:
036 * <li>SCL</li>
037 * <pre>
038 *   0: d1:F00;
039 *   1: d1:F10;
040 *   P: d1:F00 d2:F10 d3:F00;
041 *   N: d1:N;
042 * </pre>
043 * <li>SDA</li>
044 * <pre>
045 *   0: d1:F00 r1:X;
046 *   1: d1:F10 r1:X;
047 *   L: d1:FNZ r1:L;
048 *   X: d1:FNZ r1:X;
049 *   C: d1:FNZ r1:C;
050 *   N: d1:N;
051 * </pre>
052 * <p><b>Note:</b>Result mode of <b>SDA</b> must enable <b>capture</b>
053 */
054public class ExampleI2C extends I2C {
055    private static final int SLAVE_ADDR = 0x7;
056    private static final int CMD_WR = 0xA0 | (SLAVE_ADDR << 1) | 0x0/* write */;
057    private static final int CMD_RD = 0xA0 | (SLAVE_ADDR << 1) | 0x1/* read */;
058
059    public ExampleI2C() {
060        // SCL, SDA
061        setSignals("IO_0", "IO_1");
062    }
063
064    /**
065     * Write data to register
066     * @param addr Address of the register.
067     * @param data Data to be written.
068     */
069    @Transaction
070    public void write(int addr, int data) {
071        startCondition();
072        sendByteWithAck(CMD_WR);
073        sendByteWithAck((addr >> 8) & 0xFF);
074        sendByteWithAck(addr & 0xFF);
075        sendByteWithAck((data >> 8) & 0xFF);
076        sendByteWithAck(data & 0xFF);
077        stopCondition();
078    }
079
080    /**
081     * Write dynamic data to register
082     * <p>The dynamic data is decided in runtime before the execution of the measurement
083     * <p><b>Note:</b>Use {@link #setDynamicData(String, MultiSiteLong)} to update dynamic data before the execution of the measurement
084     * @param addr Address of the register
085     * @param id String ID to address to the dynamic data. Uto set dynamic data.
086     * @see #setDynamicData(String, MultiSiteLong)
087     */
088    @Transaction
089    public void writeDynamic(int addr, String id) {
090        startCondition();
091        sendByteWithAck(CMD_WR);
092        sendByteWithAck((addr >> 8) & 0xFF);
093        sendByteWithAck(addr & 0xFF);
094        sendByteWithAck(getIDMSB(id));
095        sendByteWithAck(getIDLSB(id));
096        stopCondition();
097    }
098
099    /**
100     * Read register data
101     * <p><b>Note:</b>Use {@link #getReadResult(IProtocolInterfaceResults, String)} to retrieve the register read result
102     * @param addr Address of the register
103     * @param id String ID to address to the read result
104     * @see #getReadResult(IProtocolInterfaceResults, String)
105     */
106    @Transaction
107    public void read(int addr, String id) {
108        startCondition();
109        sendByteWithAck(CMD_WR);
110        sendByteWithAck((addr >> 8) & 0xFF);
111        sendByteWithAck(addr & 0xFF);
112        startCondition();
113        sendByteWithAck(CMD_RD);
114        receiveByteAckLow(getIDMSB(id));
115        receiveByteNoAck(getIDLSB(id));
116        stopCondition();
117    }
118
119    /**
120     * Compare register data
121     * <p><b>Note:</b>Use {@link #getReadResult(IProtocolInterfaceResults, String)} to retrieve the register read result
122     * @param addr Address of the register
123     * @param id String ID to address to the read result
124     * @see #getReadResult(IProtocolInterfaceResults, String)
125     */
126    @Transaction
127    public void compare(int addr, int expected, int mask) {
128        startCondition();
129        sendByteWithAck(CMD_WR);
130        sendByteWithAck((addr >> 8) & 0xFF);
131        sendByteWithAck(addr & 0xFF);
132        startCondition();
133        sendByteWithAck(CMD_RD);
134        compareByteAckLow((expected >> 8) & 0xFF, (mask >> 8) & 0xFF);  // 8 MSB
135        compareByteNoAck(expected & 0xFF, mask & 0xFF); // 8 LSB
136        stopCondition();
137    }
138    /**
139     * Update the dynamic data before the execution of the measurement.
140     * @param id String ID used by {@link #writeDynamic(int, String)}
141     * @param dynamicData MultiSite data to be updated.
142     * @see #writeDynamic(int, String)
143     */
144    public static void setDynamicData(String id, MultiSiteLong dynamicData) {
145        MultiSiteLong msbData = dynamicData.rightShift(8).and(0xFF);
146        MultiSiteLong lsbData = dynamicData.and(0xFF);
147        ProtocolAccess.setDynamicData(getIDMSB(id), msbData);
148        ProtocolAccess.setDynamicData(getIDLSB(id), lsbData);
149    }
150
151    /**
152     * Get the register read results
153     * @param paResult Result hanlder from perserving result of ProtocolAccess
154     * @param id String id used in transaction {@link #read(int, String)}
155     * @return Register read out value
156     * @see ExampleI2C#read(int, String)
157     */
158    public static MultiSiteLong getReadResult(IProtocolInterfaceResults paResult, String id) {
159        MultiSiteLong msbData = paResult.getLongResult(getIDMSB(id));
160        MultiSiteLong lsbData = paResult.getLongResult(getIDLSB(id));
161        return msbData.leftShift(8).or(lsbData);
162    }
163
164
165    private static String getIDMSB(String id) {
166        return id + "#MSB";
167    }
168
169    private static String getIDLSB(String id) {
170        return id + "#LSB";
171    }
172}