Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
en:xu4_hardware_hsi2c [2015/08/20 16:12] charles.park |
en:xu4_hardware_hsi2c [2017/04/26 14:57] (current) charles.park |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== HS-I2C (HighSpeed) ====== | ||
+ | This page introduces how you can I2C interface using Expansion Board. | ||
+ | |||
+ | The Expansion Board have two I2C devices.\\ | ||
+ | You can use the devices via H/W I2C(I2C-A : HS-I2C). | ||
+ | |||
+ | {{:en:xu4:xu4_hsi2c_with_expansion.png?700|}} | ||
+ | |||
+ | **H/W I2C(I2C-A : HS-I2C)** | ||
+ | ^ Kernel 3.10.y\\ (node name) ^ Kernel 4.9.y\\ (node name) ^ Pin Number\\ (XU4-CON11) ^ Net Name ^ Export Number ^ Description ^ | ||
+ | | /dev/i2c-1 | /dev/i2c-5 | 4 | GPA2[2](I2C_5.SDA) | 187 | SDA | | ||
+ | | ::: | ::: | 6 | GPA2[3](I2C_5.SCL) | 188 | SCL | | ||
+ | |||
+ | |||
+ | <note warning>I2C-A(HS-I2C) doesn't work with i2cdetect command on Kenrnel 3.10.y</note> | ||
+ | |||
+ | * Using the H/W I2C(I2C-A : HS-I2C) with Expansion Board. I2C Physical Address : 0x12CB0000 | ||
+ | |||
+ | |||
+ | **HW-HSI2C Test Code** | ||
+ | |||
+ | <file c xu4_hsi2c.c> | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | // | ||
+ | // ODROID-XU4 with Shifter Shield I2C Test Application. | ||
+ | // I2C Node : /dev/i2c-3 | ||
+ | // | ||
+ | // Compile : gcc -o <create excute file name> <source file name> | ||
+ | // Run : sudo ./<created excute file name> | ||
+ | // | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <stdint.h> | ||
+ | #include <errno.h> | ||
+ | #include <string.h> | ||
+ | #include <fcntl.h> | ||
+ | #include <sys/ioctl.h> | ||
+ | |||
+ | #include <unistd.h> | ||
+ | #include <string.h> | ||
+ | #include <time.h> | ||
+ | |||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | // | ||
+ | // Global handle Define | ||
+ | // | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | |||
+ | // I2C definitions | ||
+ | |||
+ | #define I2C_SLAVE 0x0703 | ||
+ | #define I2C_SMBUS 0x0720 /* SMBus-level access */ | ||
+ | |||
+ | #define I2C_SMBUS_READ 1 | ||
+ | #define I2C_SMBUS_WRITE 0 | ||
+ | |||
+ | // SMBus transaction types | ||
+ | |||
+ | #define I2C_SMBUS_QUICK 0 | ||
+ | #define I2C_SMBUS_BYTE 1 | ||
+ | #define I2C_SMBUS_BYTE_DATA 2 | ||
+ | #define I2C_SMBUS_WORD_DATA 3 | ||
+ | #define I2C_SMBUS_PROC_CALL 4 | ||
+ | #define I2C_SMBUS_BLOCK_DATA 5 | ||
+ | #define I2C_SMBUS_I2C_BLOCK_BROKEN 6 | ||
+ | #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ | ||
+ | #define I2C_SMBUS_I2C_BLOCK_DATA 8 | ||
+ | |||
+ | // SMBus messages | ||
+ | #define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ | ||
+ | #define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */ | ||
+ | |||
+ | // Structures used in the ioctl() calls | ||
+ | |||
+ | union i2c_smbus_data | ||
+ | { | ||
+ | uint8_t byte; | ||
+ | uint16_t word; | ||
+ | uint8_t block [I2C_SMBUS_BLOCK_MAX + 2] ; // block [0] is used for length + one more for PEC | ||
+ | }; | ||
+ | |||
+ | struct i2c_smbus_ioctl_data | ||
+ | { | ||
+ | char read_write; | ||
+ | uint8_t command ; | ||
+ | int size; | ||
+ | union i2c_smbus_data *data; | ||
+ | }; | ||
+ | |||
+ | static inline int i2c_smbus_access (int fd, char rw, uint8_t command, int size, union i2c_smbus_data *data) | ||
+ | { | ||
+ | struct i2c_smbus_ioctl_data args ; | ||
+ | |||
+ | args.read_write = rw ; | ||
+ | args.command = command ; | ||
+ | args.size = size ; | ||
+ | args.data = data ; | ||
+ | return ioctl (fd, I2C_SMBUS, &args) ; | ||
+ | } | ||
+ | |||
+ | int i2c_smbus_read_byte_data(int fd, int reg) | ||
+ | { | ||
+ | union i2c_smbus_data data; | ||
+ | |||
+ | if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, &data)) | ||
+ | return -1 ; | ||
+ | else | ||
+ | return data.byte & 0xFF ; | ||
+ | } | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | // | ||
+ | // I2C: | ||
+ | // | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | // kernel 4.9.y device node | ||
+ | // const char *i2cHandleNode = "/dev/i2c-5"; | ||
+ | |||
+ | // kernel 3.10.y device node | ||
+ | const char *i2cHandleNode = "/dev/i2c-1"; | ||
+ | static int i2c_fd = -1; | ||
+ | |||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | // | ||
+ | // LCD Update Function: | ||
+ | // | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | static void data_update (void) | ||
+ | { | ||
+ | int val1, val2; | ||
+ | static unsigned long count = 0; | ||
+ | |||
+ | if(i2c_fd == -1) return; | ||
+ | | ||
+ | // set BH1780 Sensor I2C Address | ||
+ | if(ioctl(i2c_fd, I2C_SLAVE, 0x29) < 0) { | ||
+ | fprintf(stdout, "%s : ioctl BH1780 I2C_SLAVE Setup Error!\n", __func__); | ||
+ | return; | ||
+ | } | ||
+ | | ||
+ | // BH1780 Part ID Read | ||
+ | val1 = i2c_smbus_read_byte_data(i2c_fd, 0x0A); | ||
+ | | ||
+ | // set Pressure Sensor I2C Address | ||
+ | if(ioctl(i2c_fd, I2C_SLAVE, 0x77) < 0) { | ||
+ | fprintf(stdout, "%s : ioctl PRESSURE I2C_SLAVE Setup Error!\n", __func__); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // Pressure Sensor CHIP ID Read | ||
+ | val2 = i2c_smbus_read_byte_data(i2c_fd, 0xD0); | ||
+ | |||
+ | fprintf(stdout, "%s : count = %ld BH1780 ID = 0x%02X, PRESSURE ID = 0x%02X\n", __func__, count++, val1, val2); | ||
+ | } | ||
+ | |||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | // | ||
+ | // system init | ||
+ | // | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | int system_init(void) | ||
+ | { | ||
+ | if((i2c_fd = open(i2cHandleNode, O_RDWR)) < 0) { | ||
+ | fprintf(stdout, "%s : %s Open Error!\n", __func__, i2cHandleNode); | ||
+ | return -1; | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | // | ||
+ | // Start Program | ||
+ | // | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | int main (int argc, char *argv[]) | ||
+ | { | ||
+ | if (system_init() < 0) | ||
+ | { | ||
+ | fprintf (stderr, "%s: System Init failed\n", __func__); fflush(stdout); | ||
+ | return -1; | ||
+ | } | ||
+ | |||
+ | for(;;) { | ||
+ | usleep(100000); | ||
+ | data_update(); fflush(stdout); | ||
+ | } | ||
+ | |||
+ | return 0 ; | ||
+ | } | ||
+ | |||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | //------------------------------------------------------------------------------------------------------------ | ||
+ | |||
+ | </file> | ||