Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Documentation
rigado-hsm-server
Commits
9bd8fdc9
Commit
9bd8fdc9
authored
Feb 28, 2019
by
apapkovskiy
Browse files
Added patch fom NXP ro resolve problem with I2C
parent
7e6b0c93
Changes
4
Hide whitespace changes
Inline
Side-by-side
middleware/hostlib/hostLib/platform/imx/i2c_a7.c
View file @
9bd8fdc9
/**
* @file i2c_a7.c
* @author NXP Semiconductors
* @version 1.0
* @par License
* Copyright 2017 NXP
*
* This software is owned or controlled by NXP and may only be used
* strictly in accordance with the applicable license terms. By expressly
* accepting such terms or by downloading, installing, activating and/or
* otherwise using the software, you are agreeing that you have read, and
* that you agree to comply with and are bound by, such license terms. If
* you do not agree to be bound by the applicable license terms, then you
* may not retain, install, activate or otherwise use the software.
*
* @par Description
* i.MX6UL board specific i2c code
* @par History
*
**/
#include "i2c_a7.h"
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <time.h>
#include "nxLog_smCom.h"
static
int
axSmDevice
;
static
int
axSmDevice_addr
=
0x48
;
// 7-bit address
static
char
devName
[]
=
"/dev/i2c-1"
;
// Change this when connecting to another host i2c master port
/**
* Opens the communication channel to I2C device
*/
i2c_error_t
axI2CInit
()
{
unsigned
long
funcs
;
/*
* Open the file in /dev/i2c-1
*/
LOG_D
(
"I2CInit: opening %s
\n
"
,
devName
);
if
((
axSmDevice
=
open
(
devName
,
O_RDWR
))
<
0
)
{
LOG_E
(
"opening failed..."
);
perror
(
"Failed to open the i2c bus"
);
return
I2C_FAILED
;
}
if
(
ioctl
(
axSmDevice
,
I2C_SLAVE
,
axSmDevice_addr
)
<
0
)
{
LOG_E
(
"I2C driver failed setting address
\n
"
);
}
// clear PEC flag
if
(
ioctl
(
axSmDevice
,
I2C_PEC
,
0
)
<
0
)
{
LOG_E
(
"I2C driver: PEC flag clear failed
\n
"
);
}
else
{
LOG_D
(
"I2C driver: PEC flag cleared
\n
"
);
}
// Query functional capacity of I2C driver
if
(
ioctl
(
axSmDevice
,
I2C_FUNCS
,
&
funcs
)
<
0
)
{
LOG_E
(
"Cannot get i2c adapter functionality
\n
"
);
return
I2C_FAILED
;
}
else
{
if
(
funcs
&
I2C_FUNC_I2C
)
{
LOG_D
(
"I2C driver supports plain i2c-level commands.
\n
"
);
if
(
(
funcs
&
I2C_FUNC_SMBUS_READ_BLOCK_DATA
)
==
I2C_FUNC_SMBUS_READ_BLOCK_DATA
)
{
LOG_D
(
"I2C driver supports Read Block.
\n
"
);
}
else
{
LOG_E
(
"I2C driver does not support Read Block!
\n
"
);
return
I2C_FAILED
;
}
}
else
{
LOG_E
(
"I2C driver CANNOT support plain i2c-level commands!
\n
"
);
return
I2C_FAILED
;
}
}
return
I2C_OK
;
}
/**
* Closes the communication channel to I2C device (not implemented)
*/
void
axI2CTerm
(
int
mode
)
{
AX_UNUSED_ARG
(
mode
);
LOG_I
(
"axI2CTerm: not implemented.
\n
"
);
return
;
}
/**
* Write a single byte to the slave device.
* In the context of the SCI2C protocol, this command is only invoked
* to trigger a wake-up of the attached secure module. As such this
* wakeup command 'wakes' the device, but does not receive a valid response.
* \note \par bus is currently not used to distinguish between I2C masters.
*/
i2c_error_t
axI2CWriteByte
(
unsigned
char
bus
,
unsigned
char
addr
,
unsigned
char
*
pTx
)
{
int
nrWritten
=
-
1
;
i2c_error_t
rv
;
if
(
bus
!=
I2C_BUS_0
)
{
LOG_E
(
"axI2CWriteByte on wrong bus %x (addr %x)
\n
"
,
bus
,
addr
);
}
nrWritten
=
write
(
axSmDevice
,
pTx
,
1
);
if
(
nrWritten
<
0
)
{
// I2C_LOG_PRINTF("Failed writing data (nrWritten=%d).\n", nrWritten);
rv
=
I2C_FAILED
;
}
else
{
if
(
nrWritten
==
1
)
{
rv
=
I2C_OK
;
}
else
{
rv
=
I2C_FAILED
;
}
}
return
rv
;
}
i2c_error_t
axI2CWrite
(
unsigned
char
bus
,
unsigned
char
addr
,
unsigned
char
*
pTx
,
unsigned
short
txLen
)
{
int
nrWritten
=
-
1
;
i2c_error_t
rv
;
#ifdef LOG_I2C
int
i
=
0
;
#endif
if
(
bus
!=
I2C_BUS_0
)
{
LOG_E
(
"axI2CWrite on wrong bus %x (addr %x)
\n
"
,
bus
,
addr
);
}
LOG_MAU8_D
(
"TX (axI2CWrite) > "
,
pTx
,
txLen
);
nrWritten
=
write
(
axSmDevice
,
pTx
,
txLen
);
if
(
nrWritten
<
0
)
{
LOG_E
(
"Failed writing data (nrWritten=%d).
\n
"
,
nrWritten
);
rv
=
I2C_FAILED
;
}
else
{
if
(
nrWritten
==
txLen
)
// okay
{
rv
=
I2C_OK
;
}
else
{
rv
=
I2C_FAILED
;
}
}
LOG_D
(
"Done with rv = %02x "
,
rv
);
return
rv
;
}
i2c_error_t
axI2CWriteRead
(
unsigned
char
bus
,
unsigned
char
addr
,
unsigned
char
*
pTx
,
unsigned
short
txLen
,
unsigned
char
*
pRx
,
unsigned
short
*
pRxLen
)
{
struct
i2c_rdwr_ioctl_data
packets
;
struct
i2c_msg
messages
[
2
];
int
r
=
0
;
int
i
=
0
;
if
(
bus
!=
I2C_BUS_0
)
// change if bus 0 is not the correct bus
{
LOG_E
(
"axI2CWriteRead on wrong bus %x (addr %x)
\n
"
,
bus
,
addr
);
}
messages
[
0
].
addr
=
axSmDevice_addr
;
messages
[
0
].
flags
=
0
;
messages
[
0
].
len
=
txLen
;
messages
[
0
].
buf
=
pTx
;
// NOTE:
// By setting the 'I2C_M_RECV_LEN' bit in 'messages[1].flags' one ensures
// the I2C Block Read feature is used.
messages
[
1
].
addr
=
axSmDevice_addr
;
messages
[
1
].
flags
=
I2C_M_RD
|
I2C_M_RECV_LEN
;
messages
[
1
].
len
=
256
;
messages
[
1
].
buf
=
pRx
;
messages
[
1
].
buf
[
0
]
=
1
;
// NOTE:
// By passing the two message structures via the packets structure as
// a parameter to the ioctl call one ensures a Repeated Start is triggered.
packets
.
msgs
=
messages
;
packets
.
nmsgs
=
2
;
LOG_MAU8_D
(
"TX (axI2CWriteRead ) > "
,
packets
.
msgs
[
0
].
buf
[
i
],
txLen
);
// Send the request to the kernel and get the result back
r
=
ioctl
(
axSmDevice
,
I2C_RDWR
,
&
packets
);
// NOTE:
// The ioctl return value in case of a NACK on the write address is '-1'
// This impacts the error handling routine of the caller.
if
(
r
<
0
)
{
// LOG_E("axI2CWriteRead: ioctl cmd I2C_RDWR fails with value %d (hex: 0x%08X)\n", r, r);
// perror("Errorstring: ");
// I2C_LOG_PRINTF("axI2CWriteRead: ioctl value %d (hex: 0x%08X)\n", r, r);
return
I2C_FAILED
;
}
else
{
int
rlen
=
packets
.
msgs
[
1
].
buf
[
0
]
+
1
;
//I2C_LOG_PRINTF("packets.msgs[1].len is %d \n", packets.msgs[1].len);
LOG_MAU8_D
(
"RX (axI2CWriteRead) < "
,
packets
.
msgs
[
1
].
buf
[
i
],
rlen
);
for
(
i
=
0
;
i
<
rlen
;
i
++
)
{
pRx
[
i
]
=
packets
.
msgs
[
1
].
buf
[
i
];
}
*
pRxLen
=
rlen
;
}
return
I2C_OK
;
}
i2c_error_t
axI2CRead
(
unsigned
char
bus
,
unsigned
char
addr
,
unsigned
char
*
pRx
,
unsigned
short
rxLen
)
{
int
nrRead
=
-
1
;
i2c_error_t
rv
;
#ifdef LOG_I2C
int
i
=
0
;
#endif
if
(
bus
!=
I2C_BUS_0
)
{
LOG_E
(
"axI2CRead on wrong bus %x (addr %x)
\n
"
,
bus
,
addr
);
}
nrRead
=
read
(
axSmDevice
,
pRx
,
rxLen
);
if
(
nrRead
<
0
)
{
//LOG_E("Failed Read data (nrRead=%d).\n", nrRead);
rv
=
I2C_FAILED
;
}
else
{
if
(
nrRead
==
rxLen
)
// okay
{
rv
=
I2C_OK
;
}
else
{
rv
=
I2C_FAILED
;
}
}
LOG_D
(
"Done with rv = %02x "
,
rv
);
LOG_MAU8_D
(
"TX (axI2CRead): "
,
pRx
[
i
],
rxLen
);
return
rv
;
}
/**
* @file i2c_a7.c
* @author NXP Semiconductors
* @version 1.0
* @par License
* Copyright 2017 NXP
*
* This software is owned or controlled by NXP and may only be used
* strictly in accordance with the applicable license terms. By expressly
* accepting such terms or by downloading, installing, activating and/or
* otherwise using the software, you are agreeing that you have read, and
* that you agree to comply with and are bound by, such license terms. If
* you do not agree to be bound by the applicable license terms, then you
* may not retain, install, activate or otherwise use the software.
*
* @par Description
* i.MX6UL board specific i2c code
* @par History
*
**/
#include "i2c_a7.h"
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <time.h>
#include "nxLog_smCom.h"
static
int
axSmDevice
;
static
int
axSmDevice_addr
=
0x48
;
// 7-bit address
static
char
devName
[]
=
"/dev/i2c-1"
;
// Change this when connecting to another host i2c master port
/**
* Opens the communication channel to I2C device
*/
i2c_error_t
axI2CInit
()
{
unsigned
long
funcs
;
/*
* Open the file in /dev/i2c-1
*/
LOG_D
(
"I2CInit: opening %s
\n
"
,
devName
);
if
((
axSmDevice
=
open
(
devName
,
O_RDWR
))
<
0
)
{
LOG_E
(
"opening failed..."
);
perror
(
"Failed to open the i2c bus"
);
return
I2C_FAILED
;
}
if
(
ioctl
(
axSmDevice
,
I2C_SLAVE
,
axSmDevice_addr
)
<
0
)
{
LOG_E
(
"I2C driver failed setting address
\n
"
);
}
// clear PEC flag
if
(
ioctl
(
axSmDevice
,
I2C_PEC
,
0
)
<
0
)
{
LOG_E
(
"I2C driver: PEC flag clear failed
\n
"
);
}
else
{
LOG_D
(
"I2C driver: PEC flag cleared
\n
"
);
}
// Query functional capacity of I2C driver
if
(
ioctl
(
axSmDevice
,
I2C_FUNCS
,
&
funcs
)
<
0
)
{
LOG_E
(
"Cannot get i2c adapter functionality
\n
"
);
return
I2C_FAILED
;
}
else
{
if
(
funcs
&
I2C_FUNC_I2C
)
{
LOG_D
(
"I2C driver supports plain i2c-level commands.
\n
"
);
if
(
(
funcs
&
I2C_FUNC_SMBUS_READ_BLOCK_DATA
)
==
I2C_FUNC_SMBUS_READ_BLOCK_DATA
)
{
LOG_D
(
"I2C driver supports Read Block.
\n
"
);
}
else
{
LOG_E
(
"I2C driver does not support Read Block!
\n
"
);
return
I2C_FAILED
;
}
}
else
{
LOG_E
(
"I2C driver CANNOT support plain i2c-level commands!
\n
"
);
return
I2C_FAILED
;
}
}
return
I2C_OK
;
}
/**
* Closes the communication channel to I2C device (not implemented)
*/
void
axI2CTerm
(
int
mode
)
{
AX_UNUSED_ARG
(
mode
);
LOG_I
(
"axI2CTerm: not implemented.
\n
"
);
return
;
}
/**
* Write a single byte to the slave device.
* In the context of the SCI2C protocol, this command is only invoked
* to trigger a wake-up of the attached secure module. As such this
* wakeup command 'wakes' the device, but does not receive a valid response.
* \note \par bus is currently not used to distinguish between I2C masters.
*/
i2c_error_t
axI2CWriteByte
(
unsigned
char
bus
,
unsigned
char
addr
,
unsigned
char
*
pTx
)
{
int
nrWritten
=
-
1
;
i2c_error_t
rv
;
if
(
bus
!=
I2C_BUS_0
)
{
LOG_E
(
"axI2CWriteByte on wrong bus %x (addr %x)
\n
"
,
bus
,
addr
);
}
nrWritten
=
write
(
axSmDevice
,
pTx
,
1
);
if
(
nrWritten
<
0
)
{
// I2C_LOG_PRINTF("Failed writing data (nrWritten=%d).\n", nrWritten);
rv
=
I2C_FAILED
;
}
else
{
if
(
nrWritten
==
1
)
{
rv
=
I2C_OK
;
}
else
{
rv
=
I2C_FAILED
;
}
}
return
rv
;
}
i2c_error_t
axI2CWrite
(
unsigned
char
bus
,
unsigned
char
addr
,
unsigned
char
*
pTx
,
unsigned
short
txLen
)
{
int
nrWritten
=
-
1
;
i2c_error_t
rv
;
#ifdef LOG_I2C
int
i
=
0
;
#endif
if
(
bus
!=
I2C_BUS_0
)
{
LOG_E
(
"axI2CWrite on wrong bus %x (addr %x)
\n
"
,
bus
,
addr
);
}
LOG_MAU8_D
(
"TX (axI2CWrite) > "
,
pTx
,
txLen
);
nrWritten
=
write
(
axSmDevice
,
pTx
,
txLen
);
if
(
nrWritten
<
0
)
{
LOG_E
(
"Failed writing data (nrWritten=%d).
\n
"
,
nrWritten
);
rv
=
I2C_FAILED
;
}
else
{
if
(
nrWritten
==
txLen
)
// okay
{
rv
=
I2C_OK
;
}
else
{
rv
=
I2C_FAILED
;
}
}
LOG_D
(
"Done with rv = %02x "
,
rv
);
return
rv
;
}
i2c_error_t
axI2CWriteRead
(
unsigned
char
bus
,
unsigned
char
addr
,
unsigned
char
*
pTx
,
unsigned
short
txLen
,
unsigned
char
*
pRx
,
unsigned
short
*
pRxLen
)
{
struct
i2c_rdwr_ioctl_data
packets
;
struct
i2c_msg
messages
[
2
];
int
r
=
0
;
int
i
=
0
;
if
(
bus
!=
I2C_BUS_0
)
// change if bus 0 is not the correct bus
{
LOG_E
(
"axI2CWriteRead on wrong bus %x (addr %x)
\n
"
,
bus
,
addr
);
}
messages
[
0
].
addr
=
axSmDevice_addr
;
messages
[
0
].
flags
=
0
;
messages
[
0
].
len
=
txLen
;
messages
[
0
].
buf
=
pTx
;
// NOTE:
// By setting the 'I2C_M_RECV_LEN' bit in 'messages[1].flags' one ensures
// the I2C Block Read feature is used.
messages
[
1
].
addr
=
axSmDevice_addr
;
messages
[
1
].
flags
=
I2C_M_RD
|
I2C_M_RECV_LEN
;
messages
[
1
].
len
=
256
;
messages
[
1
].
buf
=
pRx
;
messages
[
1
].
buf
[
0
]
=
1
;
// NOTE:
// By passing the two message structures via the packets structure as
// a parameter to the ioctl call one ensures a Repeated Start is triggered.
packets
.
msgs
=
messages
;
packets
.
nmsgs
=
2
;
LOG_MAU8_D
(
"TX (axI2CWriteRead ) > "
,
packets
.
msgs
[
0
].
buf
[
i
],
txLen
);
// Send the request to the kernel and get the result back
r
=
ioctl
(
axSmDevice
,
I2C_RDWR
,
&
packets
);
// NOTE:
// The ioctl return value in case of a NACK on the write address is '-1'
// This impacts the error handling routine of the caller.
if
(
r
<
0
)
{
// LOG_E("axI2CWriteRead: ioctl cmd I2C_RDWR fails with value %d (hex: 0x%08X)\n", r, r);
// perror("Errorstring: ");
// I2C_LOG_PRINTF("axI2CWriteRead: ioctl value %d (hex: 0x%08X)\n", r, r);
return
I2C_FAILED
;
}
else
{
int
rlen
=
packets
.
msgs
[
1
].
buf
[
0
]
+
1
;
//I2C_LOG_PRINTF("packets.msgs[1].len is %d \n", packets.msgs[1].len);
LOG_MAU8_D
(
"RX (axI2CWriteRead) < "
,
packets
.
msgs
[
1
].
buf
[
i
],
rlen
);
for
(
i
=
0
;
i
<
rlen
;
i
++
)
{
pRx
[
i
]
=
packets
.
msgs
[
1
].
buf
[
i
];
}
*
pRxLen
=
rlen
;
}
return
I2C_OK
;
}
i2c_error_t
axI2CRead
(
unsigned
char
bus
,
unsigned
char
addr
,
unsigned
char
*
pRx
,
unsigned
short
rxLen
)
{
int
nrRead
=
-
1
;
i2c_error_t
rv
;
#ifdef LOG_I2C
int
i
=
0
;
#endif
if
(
bus
!=
I2C_BUS_0
)
{
LOG_E
(
"axI2CRead on wrong bus %x (addr %x)
\n
"
,
bus
,
addr
);
}
nrRead
=
read
(
axSmDevice
,
pRx
,
rxLen
);
if
(
nrRead
<
0
)
{
//LOG_E("Failed Read data (nrRead=%d).\n", nrRead);
rv
=
I2C_FAILED
;
}
else
{
if
(
nrRead
==
rxLen
)
// okay
{
rv
=
I2C_OK
;
}
else
{
rv
=
I2C_FAILED
;
}
}
LOG_D
(
"Done with rv = %02x "
,
rv
);
LOG_MAU8_D
(
"TX (axI2CRead): "
,
pRx
[
i
],
rxLen
);
return
rv
;
}
patches/i2c_a7.patch
View file @
9bd8fdc9
--- a/i2c_a7.c 2018-11-07 14:58:42.000000000 +0300
+++ b/i2c_a7.c 2018-12-26 18:14:53.768660501 +0300
@@ -32,8 +32,8 @@
#include "nxLog_smCom.h"
static int axSmDevice;
-static int axSmDevice_addr = 0x48; // 7-bit address
-static char devName[] = "/dev/i2c-1"; // Change this when connecting to another host i2c master port
+static int axSmDevice_addr = 0x49; // 7-bit address
+static char devName[] = "/dev/i2c-3"; // Change this when connecting to another host i2c master port
/**
* Opens the communication channel to I2C device
#include "nxLog_smCom.h"
static int axSmDevice;
-static int axSmDevice_addr = 0x48; // 7-bit address
-static char devName[] = "/dev/i2c-1"; // Change this when connecting to another host i2c master port
+static int axSmDevice_addr = 0x49; // 7-bit address
+static char devName[] = "/dev/i2c-3"; // Change this when connecting to another host i2c master port
/**
* Opens the communication channel to I2C device
patches/i2c_a7_nxp.patch
0 → 100644
View file @
9bd8fdc9
diff --git a/hostLib/platform/imx/i2c_a7.c b/hostLib/platform/imx/i2c_a7.c
index 6eb8912..1943b40 100755
--- a/hostLib/platform/imx/i2c_a7.c
+++ b/hostLib/platform/imx/i2c_a7.c
@@ -31,6 +31,8 @@
#include <time.h>
#include "nxLog_smCom.h"
+#include <sm_timer.h>
+
static int axSmDevice;