Android platform read/write i2c Device Development Note 1

Source: Internet
Author: User

During Android development and transplantation, you sometimes need to read and write a device, but the system may not provide the corresponding services. We need to develop our own hardware access service to control devices. The following example is the process of reading and writing the most simple I2C device EEPROM, I2C driver writing there are two ways, one is to use the i2c-dev.c provided by the system to achieve a I2C adapter device file, the I2C device is then controlled by operating the I2C adapter at the application layer; the other is to write a device driver independent of the I2C device, without the need for i2c-dev.c files. Since the former is relatively simple and versatile, we use the former to expand.

Based on the android hierarchy, we take the following steps for Development as an example:

1. Add the Hal interface module to access the device

2. Use JNI to add service access interfaces at the application framework layer

3. Use the service interface API to develop applications


1. Add the Hal interface module to access the device

First, confirm that the physical device is normal. According to the Development Board instructions that the device mounted on the/dev/i2c-1, the existence of the device is detected, the general device drive is normal.

The EEPROM device is of the at24c ** series. According to the instruction, the device address is 0x50. The preparation is complete.

1. Compile the IIC. h header file of the Hal interface module.

Go to the hardware/libhardware/include/hardware directory under the source code root directory to create IIC. h. The Code is as follows:

# Ifndef android_iic_interface_h # define android_iic_interface_h # include <Hardware/hardware. h> _ begin_decls/* define module ID */# define iic_hardware_module_id "IIC"/* hardware module struct */struct iic_module_t {struct hw_module_t common ;}; /* hardware interface struct */struct iic_device_t {struct hw_device_t common; int FD; int (* iic_write) (struct iic_device_t * Dev, unsigned char * databuf, unsigned short slaveaddr, unsigned short subaddr, int Len); int (* iic_read) (struct iic_device_t * Dev, unsigned char * databuf, unsigned short slaveaddr, int Len);}; _ end_decls # endif


 

The iic_write and iic_read interfaces are defined here. The header file is compiled according to Hal specifications.

2. Compile the Hal interface module File

Go to the hardware/libhardware/modules directory under the source code root directory to create an IIC directory and add IIC. C to the IIC directory. The Code is as follows:

#include 
# Define device_name "/dev/i2c-1" # define module_name "IIC" # define module_author "mfayz@sohu.com" # define i2c_retries 0x0701/* Number of times a device address shocould be polled when not acknowledging */# define i2c_timeout 0x0702/* set timeout in units of 10 MS */# define i2c_rdwr 0x0707/******* define struct i2c_rdwr_ioctl_data and struct i2c_msg, to be consistent with the kernel ******/struct i2c_msg {unsigned short ADDR; unsigned Short flags; # define i2c_m_ten 0x0010 # define i2c_m_rd 0x0001 unsigned short Len; unsigned char * Buf;}; struct i2c_rdwr_ioctl_data {struct i2c_msg * msgs; /* pointers to i2c_msgs */INT nmsgs;/* Number of i2c_msgs */};/* interface for enabling and disabling devices */static int iic_device_open (const struct hw_module_t * module, const char * Name, struct hw_device_t ** device); static int iic_device_close (struct hw_device_t * Device);/* Set Standby access interface */static int iic_write (struct iic_device_t * Dev, unsigned char * databuf, unsigned short slaveaddr, unsigned short subaddr, int Len); static int iic_read (struct login * Dev, unsigned char * databuf, unsigned short slaveaddr, int Len);/* module method table */static struct functions iic_module_methods = {open: iic_device_open}; struct functions iic_data; int ret; /* module instance variable */struct Iic_module_t detail = {common: {Tag: hardware_module_tag, version_major: 1, version_minor: 0, ID: Role, name: module_name, Author: module_author, Methods: & role, // implements an open method called by the JNI layer to instantiate eeprom_device_t}; static int iic_device_open (const struct hw_module_t * module, const char * Name, struct hw_device_t ** device) {struct iic_device_t * dev; Dev = (S Truct iic_device_t *) malloc (sizeof (struct iic_device_t); If (! Dev) {LogE ("IIC stub: failed to alloc space"); Return-efault;} else {LogE ("HAL: alloc space succ! ");} Memset (Dev, 0, sizeof (struct iic_device_t); Dev-> common. tag = hardware_device_tag; Dev-> common. version = 0; Dev-> common. module = (hw_module_t *) module; Dev-> common. close = iic_device_close; Dev-> iic_write = iic_write; Dev-> iic_read = iic_read; * Device = & Dev-> common; // return the instantiated iic_device_t address to the JNI layer, in this way, the JNI layer can directly call the method. If (Dev-> FD = open (device_name, o_rdwr) =-1) {LogE ("IIC stub HAL: failed to open/dev/i2c-1 -- % S. ", strerror (errno); free (Dev); Return-efault;} else {Logi (" IIC stub HAL: Open/dev/i2c-1 successfully. "); iic_data.nmsgs = 2; iic_data.msgs = (struct i2c_msg *) malloc (iic_data.nmsgs * sizeof (struct i2c_msg); If (! Iic_data.msgs) {LogE ("malloc error"); close (Dev-> FD); exit (1) ;}ioctl (Dev-> FD, i2c_timeout, 2 ); // set the timeout value IOCTL (Dev-> FD, i2c_retries, 1); // set the number of resends} return 0;} static int iic_device_close (struct hw_device_t * device) {struct iic_device_t * iic_device = (struct iic_device_t *) device; If (iic_device) {close (iic_device-> FD); free (iic_device);} return 0 ;} static int iic_write (struct iic_device_t * Dev, unsigned char * databuf, unsigned short slaveaddr, unsigned short subaddr, int Len) {int COUNT = 0; unsigned char data [2]; unsigned char bytes; Logi ("IIC stub HAL: Set Value % s to device. ", databuf); iic_data.nmsgs = 1; (iic_data.msgs [0]). len = 2; // write address bit and Data Length (iic_data.msgs [0]). ADDR = slaveaddr; // The device address is 0x50 (iic_data.msgs [0]). flags = 0; // write (iic_data.msgs [0]). buf = (unsigned char *) malloc (2); While (count <Len) {bytes = 0; data [bytes ++] = subaddr; // first write the subaddress data [bytes] = databuf [count]; // then write value Logi ("IIC write HAL: % x, % x", data [0], data [1]); (iic_data.msgs [0]). buf = data; // the data to write ret = IOCTL (Dev-> FD, i2c_rdwr, (unsigned long) & iic_data); If (Ret <0) {Logi ("IIC Hal IOCTL error");} count ++; subaddr ++; usleep (3000 ); // delay 3 ms} Logi ("You have write % s into IIC at % x address Len: % d", databuf, subaddr, Len); Return 0 ;} static int iic_read (struct iic_device_t * Dev, unsigned char * databuf, unsigned short slaveaddr, int Len) {int COUNT = 0; iic_data.nmsgs = 1; (iic_data.msgs [0]. len = 1; (iic_data.msgs [0]). ADDR = slaveaddr; // device address (iic_data.msgs [0]). flags = i2c_m_rd; // read (iic_data.msgs [0]). buf = (unsigned char *) malloc (1); While (count <Len) {(iic_data.msgs [0]). buf = databuf ++; If (IOCTL (Dev-> FD, i2c_rdwr, (unsigned long) & iic_data) <0) {LogE ("IOCTL read error ");} logi ("IIC read HAL: % x", databuf [count]); count ++;} return 0 ;}

Note: You need to open the device/dev/i2c-1 permission, otherwise you will encounter the pemission denied error. Go to the system/CORE/rootdir directory from the source code root directory, open ueventd. RC and add a line:/dev/i2c-1 0666 Root (the device may vary with the Development Board)

3. Compile Android. mk In the IIC directory

LOCAL_PATH := $(call my-dir)      include $(CLEAR_VARS)      LOCAL_MODULE_TAGS := optional      LOCAL_PRELINK_MODULE := false      LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw      LOCAL_SRC_FILES := iic.c      LOCAL_MODULE := iic.default      include $(BUILD_SHARED_LIBRARY)

Compile command: After mmm-B Hardware/libhardware/module/IIC is compiled successfully, IIC. Default. So is returned. If it is packaged into IMG, it is loaded by default.


(To be continued)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.