{ I2C transaction wrappers } { Copyright (C)2017-2018, Philip Munts, President, Munts AM Corp. } { } { Redistribution and use in source and binary forms, with or without } { modification, are permitted provided that the following conditions are met: } { } { * Redistributions of source code must retain the above copyright notice, } { this list of conditions and the following disclaimer. } { } { THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" } { AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE } { IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE } { ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE } { LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR } { CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF } { SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS } { INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN } { CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) } { ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE } { POSSIBILITY OF SUCH DAMAGE. } UNIT I2C_Compat; USES errno; PROCEDURE I2C_Transaction(devaddr : Byte; cmd : ^Byte; cmdlen : Byte; resp : ^Byte; resplen : Byte; delay : Word; VAR error : Byte); IMPLEMENTATION { Figure out what platform we are compiling for } {$IFDEF P16} {$DEFINE PICI2C} {$ENDIF} {$IFDEF P18} {$DEFINE PICI2C} {$ENDIF} {$IFDEF P32} {$DEFINE PICI2C} {$ENDIF} PROCEDURE I2C_Transaction(devaddr : Byte; cmd : ^Byte; cmdlen : Byte; resp : ^Byte; resplen : Byte; delay : Word; VAR error : Byte); VAR i : Byte; BEGIN {$IFDEF PICI2C} I2C_Start(); { Send some data to the I2C slave device } IF cmdlen > 0 THEN BEGIN I2C_Write(devaddr SHL 1); FOR i := 1 TO cmdlen DO BEGIN I2C_Write(cmd^); Inc(cmd); END END; { Pause between the write and read operations, if necessary } IF (cmdlen > 0) AND (resplen > 0) THEN BEGIN delay := delay SHR 4; WHILE delay > 0 DO BEGIN Delay_us(16); Dec(delay); END; I2C_Restart(); END; { Receive some data from the I2C slave device } IF resplen > 0 THEN BEGIN I2C_Write((devaddr SHL 1) + 1); FOR i := 1 TO resplen - 1 DO BEGIN resp^ := I2C_Read(_I2C_ACK); Inc(resp); END; resp^ := I2C_Read(_I2C_NACK); END; I2C_Stop(); {$ENDIF} {$IFDEF STM32} I2C_Start(); { Send some data to the I2C slave device } IF cmdlen > 0 THEN IF resplen > 0 THEN I2C_Write(devaddr, cmd, cmdlen, END_MODE_RESTART) ELSE I2C_Write(devaddr, cmd, cmdlen, END_MODE_STOP); { Pause between the write and read operations, if necessary } IF (cmdlen > 0) AND (resplen > 0) AND (delay > 0) THEN WHILE delay > 0 DO BEGIN Delay_us(10); delay := delay - 10; END; { Receive some data from the I2C slave device } IF resplen > 0 THEN I2C_Read(devaddr, resp, resplen, END_MODE_STOP); {$ENDIF} error := EOK; END; END.