//------------------------------------------------------ // DS1624 Temperature Sensor: XJEase device file // DS1624_THERMOMETER.xje Revision: 1.12 // (c)2001-2007 XJTAG Limited // // Disclaimer: XJTAG makes no guarantees whatsoever // about this code. You use it at your own risk ... // // This code requires XJTAG version 1.4 or later. //------------------------------------------------------ DEVICE NAME := "DS1624" // Pin description PINS SCL := 2; SDA := 1; ADD := 7, 6, 5; END; DISABLE DEVICE SCL := Z; SDA := Z; END; TEST COVERAGE SCL := OPEN HI LO; SDA := OPEN HI LO; END; END; //------------------------------------------------------ // Constants //------------------------------------------------------ CONST INT DEVICE_ADDRESS WIDTH 8 := 0x90; CONST INT COMMAND_READ_TEMP WIDTH 8 := 0xaa; CONST INT COMMAND_START_CONVERT WIDTH 8 := 0xee; CONST INT COMMAND_STOP_CONVERT WIDTH 8 := 0x22; CONST INT COMMAND_ACCESS_MEMORY WIDTH 8 := 0x17; CONST INT COMMAND_ACCESS_CONFIG WIDTH 8 := 0xac; CONST INT EXIT_ON_IIC_ERROR := TRUE; CONST INT OK := 0; //------------------------------------------------------ // Prints out the current temperature reading. // 'result' is always OK (0). Test()(INT result) //------------------------------------------------------ INT temp WIDTH 16; PRINT("Testing DS1624 temperature sensor ", DEVICE_REF, "\n"); I2C_Write(COMMAND_START_CONVERT, DEVICE_ADDRESS); I2C_Read(COMMAND_READ_TEMP, DEVICE_ADDRESS)(temp); PRINT("\t Local temperature is ", (temp[15..3] * 3125)/100000, " degC\n"); result := OK; END; //------------------------------------------------------------------ // Generic I2C Code // (c)2002-2007 XJTAG Limited // // Access is through the following functions: // I2C_FindDevice - prints out the I2C address of all devices that acknowledge. // I2C_Write - transmits a single byte to the given address. // I2C_Read - reads a single byte from the given address. // N.B. This code assumes that we can't exceed the IIC clock speed. // // Disclaimer: XJTAG makes no guarantees whatsoever // about this code. You use it at your own risk ... //------------------------------------------------------------------ //------------------------------------------------------------------ I2C_FindDevice()() //------------------------------------------------------------------ INT i,j := 0; INT ack; FOR i := 0 TO 128 I2C_Start(); I2C_Transmit(j)(ack); IF (ack = 0) THEN PRINT("IIC device found at address ", j, " HEX 0x", HEX(j), "\n"); END; I2C_Stop(); j := j + 2; END; END; //------------------------------------------------------------------ // Write one byte, including IIC start and stop. I2C_Write(INT byteAddress, INT deviceAddress)() //------------------------------------------------------------------ INT ack WIDTH 1; I2C_Start(); I2C_Transmit(deviceAddress)(ack); IF (ack = 1) THEN I2C_Stop(); I2C_Start(); I2C_Transmit(deviceAddress)(ack); IF (ack = 1) THEN PRINT("I2C_Write Error: Interface failed to acknowledge device address.\n"); IF EXIT_ON_IIC_ERROR THEN EXIT; END; END; END; I2C_Transmit(byteAddress)(ack); IF (ack = 1) THEN PRINT("I2C_Write Error: Interface failed to acknowledge byteL address.\n"); IF EXIT_ON_IIC_ERROR THEN EXIT; END; END; I2C_Stop(); END; //------------------------------------------------------------------ // Read one byte, including IIC start and stop. I2C_Read(INT byteAddress, INT deviceAddress)(INT byteRead) //------------------------------------------------------------------ INT ack; INT d1 WIDTH 8, d2 WIDTH 8; I2C_Start(); I2C_Transmit(deviceAddress)(ack); IF (ack = 1) THEN I2C_Stop(); I2C_Start(); I2C_Transmit(deviceAddress)(ack); IF (ack = 1) THEN PRINT("I2C_Read Error: Interface failed to acknowledge device address.\n"); IF EXIT_ON_IIC_ERROR THEN EXIT; END; END; END; // Transmit address to read from. I2C_Transmit(byteAddress)(ack); IF (ack = 1) THEN PRINT("I2C_Read Error: Interface failed to acknowledge byteL address.\n"); IF EXIT_ON_IIC_ERROR THEN EXIT; END; END; // Now terminate write operation and do a read. I2C_Start(); // Transmit address to read from. I2C_Transmit(deviceAddress | 1)(ack); // Bottom bit denotes read. IF (ack = 1) THEN PRINT("I2C_Read Error: Slave failed to ack read access.\n"); IF EXIT_ON_IIC_ERROR THEN EXIT; END; END; // Read from address and ack. I2C_Receive(0)(d1); I2C_Receive(1)(d2); byteRead := d1[7..0] : d2[7..0]; I2C_Stop(); END; //------------------------------------------------------------------ // Transmit 8 bits and check for an ACK. I2C_Transmit(INT byte)(INT ack) //------------------------------------------------------------------ INT i; FOR i := 0 FOR 8 I2C_WriteBit(byte[7 - i]); END; I2C_ReadBit()(ack); END; //------------------------------------------------------------------ // Read 8 bits and send an ACK (or not). I2C_Receive(INT ack)(INT byte WIDTH 8) //------------------------------------------------------------------ INT bit WIDTH 1; INT i; // Clear the byte so that top bits don't become set. byte := 0; FOR i := 0 FOR 8 I2C_ReadBit()(bit); byte := (byte << 1) | bit; END; I2C_WriteBit(ack)(); END; //------------------------------------------------------------------ // I2C start condition is high to low transition on SDA while SCK is high. I2C_Start()() //------------------------------------------------------------------ INT c WIDTH 1, d WIDTH 1; // Check whether the bus is free. SET c := SCL, d := SDA; DO WHILE (~c || ~d) SET c := SCL, d := SDA; END; SET SDA := 0; // Set clock low ready for first data bit. SET SCL := 0; END; //------------------------------------------------------------------ // I2C stop condition is low to high transition on SDA while SCK is high. I2C_Stop()() //------------------------------------------------------------------ SET SDA := 0; SET SCL := I; SET SDA := I; END; //------------------------------------------------------------------ // Read one bit over IIC. I2C_ReadBit()(INT bit) //------------------------------------------------------------------ SET SCL := I, SDA := I; SET SCL := 0, bit := SDA; // Get data at end of cycle. END; //------------------------------------------------------------------ // Send one bit over IIC. I2C_WriteBit(INT bit)() //------------------------------------------------------------------ IF (bit[0]) THEN SET SDA := I; ELSE SET SDA := 0; END; // Ensure that the data is stable during the high period. SET SCL := I; SET SCL := 0; END;