0% found this document useful (0 votes)
31 views40 pages

Peripheral Driver Operation Guide

Peripheral Driver Operation Guide
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views40 pages

Peripheral Driver Operation Guide

Peripheral Driver Operation Guide
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 40

Peripheral Driver

Operation Guide

Issue 01

Date 2018-05-15
Copyright © HiSilicon Technologies Co., Ltd. 2018. All rights reserved.
No part of this document may be reproduced or transmitted in any form or by any means without prior
written consent of HiSilicon Technologies Co., Ltd.

Trademarks and Permissions

, , and other HiSilicon icons are trademarks of HiSilicon Technologies Co., Ltd.
All other trademarks and trade names mentioned in this document are the property of their respective
holders.

Notice
The purchased products, services and features are stipulated by the contract made between HiSilicon and
the customer. All or part of the products, services and features described in this document may not be
within the purchase scope or the usage scope. Unless otherwise specified in the contract, all statements,
information, and recommendations in this document are provided "AS IS" without warranties, guarantees
or representations of any kind, either express or implied.
The information in this document is subject to change without notice. Every effort has been made in the
preparation of this document to ensure accuracy of the contents, but all statements, information, and
recommendations in this document do not constitute a warranty of any kind, express or implied.

HiSilicon Technologies Co., Ltd.


Address: Huawei Industrial Base
Bantian, Longgang
Shenzhen 518129
People's Republic of China

Website: http://www.hisilicon.com
Email: [email protected]

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) i
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide About This Document

About This Document

Purpose
This document describes how to manage the peripherals connecting to the modules that have
the gigabit media access control (GMAC) and universal serial bus (USB) 2.0 Host driver
installed. It covers the following topics, namely, preparations, operation procedures,
precautions to be taken during operation, and operation instances.

The Hi35xx refers to Hi3531D V100, Hi3521D V100, or Hi3520D V400.

Related Version
The following table lists the product version related to this document.

Product Name Version


Hi3531D V100
Hi3521D V100
Hi3520D V400

Intended Audience
This document is intended for:
 Technical support personnel
 Software development engineers

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) ii
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide About This Document

Change History
Changes between document issues are cumulative. Therefore, the latest document issue
contains all changes made in previous issues.

Issue 01 (2018-05-15)
This issue is the first official release.
The description of the Hi3520D V400 is added.

Issue 00B05 (2018-02-10)


This issue is the fifth draft release, which incorporates the following changes:
Section 4.3.2 is modified.

Issue 00B04 (2017-11-20)


This issue is the fourth draft release, which incorporates the following changes:
Section 5.3.1 is modified.

Issue 00B03 (2017-03-27)


This issue is the third draft release, which incorporates the following changes:
Section 1.2 is modified.

Issue 00B02 (2017-02-13)


This issue is the second draft release, which incorporates the following changes:
The description of the Hi3521D V100 is added.

Issue 00B01 (2016-12-20)


This issue is the first draft release.

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) iii
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide Contents

Contents

About This Document .................................................................................................................... ii


1 Operation Guide to the GMAC Module .................................................................................. 1
1.1 Operation Instance ........................................................................................................................................... 1
1.2 IPv6 .................................................................................................................................................................. 1
1.3 Configuring the IEEE 802.3x Flow Control Function ..................................................................................... 3
1.3.1 Function Description ............................................................................................................................... 3
1.3.2 Configuring the Flow Control Function by Using the Kernel menuconfig ............................................. 3
1.3.3 Configuring the Flow Control Function by Using the ethtool ................................................................ 4

2 Operation Guide to the USB 2.0 /USB 3.0 Host Module ....................................................... 5
2.1 Preparations ...................................................................................................................................................... 5
2.2 Procedure ......................................................................................................................................................... 5
2.3 Operation Instances .......................................................................................................................................... 6
2.3.1 Operation Instance Related to the USB Flash Drive ............................................................................... 6
2.3.2 Using the Keyboard ................................................................................................................................ 8
2.3.3 Using the Mouse ..................................................................................................................................... 8
2.4 Precautions ....................................................................................................................................................... 8

3 Operation Guide to the SATA .................................................................................................. 10


3.1 Preparations .................................................................................................................................................... 10
3.2 Procedure ....................................................................................................................................................... 10
3.3 Operation Instances ........................................................................................................................................ 11
3.4 Precautions ..................................................................................................................................................... 11

4 Operation Guide to the I2C ....................................................................................................... 12


4.1 Preparations .................................................................................................................................................... 12
4.2 Procedure ....................................................................................................................................................... 12
4.3 Operation Instances ........................................................................................................................................ 12
4.3.1 I2C Read and Write Commands ............................................................................................................ 12
4.3.2 I2C Read and Write Programs in Kernel Mode ..................................................................................... 13
4.3.3 I2C Read and Write Programs in User Mode ........................................................................................ 16

5 Operation Guide to the SPI ....................................................................................................... 20


5.1 Preparations .................................................................................................................................................... 20
5.2 Procedure ....................................................................................................................................................... 20

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) iv
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide Contents

5.3 Operation Instances ........................................................................................................................................ 20


5.3.1 SPI Read and Write Commands ............................................................................................................ 20
5.3.2 SPI Read and Write Programs in Kernel Mode..................................................................................... 21
5.3.3 SPI Read and Write Programs in User Mode ........................................................................................ 26

6 Appendix ...................................................................................................................................... 30
6.1 Partitioning a Storage Device ......................................................................................................................... 30
6.1.1 Checking the Current Partition Status of a Storage Device................................................................... 30
6.1.2 Creating Partitions for a Storage Device ............................................................................................... 30
6.1.3 Saving the Partition Information ........................................................................................................... 32
6.2 Formatting a Partition..................................................................................................................................... 32
6.3 Mounting a Directory ..................................................................................................................................... 32
6.4 Reading/Writing to a File ............................................................................................................................... 32

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) v
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide Figures

Figures

Figure 1-1 Configuration options of the IPv6 protocol ......................................................................................... 2


Figure 1-2 Configuring parameters by running menuconfig ................................................................................. 3

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) vi
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 1 Operation Guide to the GMAC Module

1 Operation Guide to the GMAC Module

The following addresses are only examples. You need to configure the addresses as required.

1.1 Operation Instance


The gigabit media access controller (GMAC) drivers for the Hi35xx are compiled in the kernel by
default. Therefore, you can configure IP addresses without loading GMAC drivers.

Note the following when using the network interface under the kernel:
 You can configure the IP address and subnet mask by running the following command:
ifconfig eth0 xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx up

 You can set the default gateway by running the following command:
route add default gw xxx.xxx.xxx.xxx

 You can mount to the NFS by running the following command:


mount -t nfs -o nolock xxx.xxx.xxx.xxx:/your/path /mount-dir

 You can upload or download files over TFTP in the shell.


Ensure that the TFTP service software is running on the server.
− To download a file, run the tftp -r XX.file serverip –g command.
Where, XX.file is the file to be downloaded, and serverip is the IP address of the
server where the file to be downloaded is located.
− To upload a file, run the tftp -l xx.file remoteip -p command.
Where, xx.file is the file to be uploaded, and remoteip is the IP address of the server
that the file is uploaded to.

1.2 IPv6
The IPv6 function is disabled in the release package by default. If the IPv6 function is
required, you need to modify the kernel options and recompile the kernel as follows:
cd kernel/linux-3.18.y

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 1
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 1 Operation Guide to the GMAC Module

cp arch/arm/configs/hi35xx_full_defconfig .config
make ARCH=arm CROSS_COMPILE=arm-hisivXXX-linux- menuconfig

There are two cases for CROSS_COMPILE=arm-hisivXXX-linux-:


 Hi35xx_V100R001C01SPCxxx corresponds to Uclibc. CROSS_COMPILE=arm-hisiv500-linux-
indicates the Uclibc tool chain.
 Hi35xx_V100R001C02SPCxxx corresponds to Glibc. CROSS_COMPILE=arm-hisiv600-linux-
indicates the Glibc tool chain.

Go to the following directories and configure the options, as shown in Figure 1-1.
[*] Networking support --->
Networking options --->
<*> The IPv6 protocol --->

Figure 1-1 Configuration options of the IPv6 protocol

The IPv6 configurations are as follows:


 Configure the IP address and the default gateway by running the following command:
ip -6 addr add <ipv6address>/<ipv6_prefixlen> dev <port>

Example: ip -6 addr add 2001:da8:207::9402/64 dev eth0


 Ping a website by running the following command:
ping -6 <ipv6address>

Example: ping -6 2001:da8:207::9403

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 2
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 1 Operation Guide to the GMAC Module

1.3 Configuring the IEEE 802.3x Flow Control Function


1.3.1 Function Description
The GMAC network supports the flow control function defined in IEEE 802.3x, and it can
transmit pause frames as well as receive and process pause frames sent by the peer end.
 Transmitting the pause frame
At the RX end, when the space of the current descriptor RX queue is insufficient, some
of the received data packets may fail to be transmitted to software. In this case, a pause
frame is sent to the peer end to instruct the peer end to stop sending packets for a
specified period.
 Receiving the pause frame
When a pause frame is received, the GMAC delays the transmission based on the flow
control time field in the frame, and restarts the transmission when the flow control period
expires or when the GMAC receives the pause frame with zero flow control time from
the peer end during waiting.

1.3.2 Configuring the Flow Control Function by Using the Kernel


menuconfig
Six configurable parameters are provided for controlling pause frame transmission and
reception. You can set these parameters by running menuconfig during kernel compilation.
The parameters of the network driver are configured as follows by running menuconfig:

Figure 1-2 Configuring parameters by running menuconfig

The configurable flow control parameters are described as follows:


 rx flow ctrl supported
Pause frame RX enable

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 3
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 1 Operation Guide to the GMAC Module

 tx flow ctrl supported


Pause frame TX enable
 tx flow ctrl pause time
Pause time value carried in the transmitted pause frame. The unit is the time required for
transmitting 512 bits. The maximum value and the default value are 0xFFFF.
 tx flow ctrl pause interval
Interval for retransmitting pause frames when the conditions are met. The unit is the time
required for transmitting 512 bits. The maximum value is 0xFFFF, and the default value
is 0x002F. tx flow ctrl pause interval must be less than tx flow ctrl pause time.
 tx flow ctrl active threshold
Threshold for activating the process of transmitting pause frames. When the number of
available descriptors in the RX queue is less than tx flow ctrl active threshold, the
process of transmitting pause frames by the logic is activated.
 tx flow ctrl deactive threshold
Threshold for deactivating the process of transmitting pause frames. When the number of
available descriptors in the RX queue is greater than or equal to tx flow ctrl deactive
threshold and flow control is enabled, current flow control is disabled.

The threshold for activating the process of transmitting pause frames must be less than the threshold for
deactivating the process of transmitting pause frames.

1.3.3 Configuring the Flow Control Function by Using the ethtool


You can enable flow control by using the standard ethtool.
You can view the flow control status of the eth0 port by running ethtool –a eth0. The
following information is displayed:
# ./ethtool -a eth0
Pause parameters for eth0:
Autonegotiate: on
RX: on
TX: on

As shown in the preceding displayed information, both RX flow control and TX flow control
are enabled.
You can enable or disable TX/RX flow control by running the following commands:
# ./ethtool -A eth0 rx off (Disable RX flow control)
# ./ethtool -A eth0 rx on (Enable RX flow control)
# ./ethtool -A eth0 tx off (Disable TX flow control)
# ./ethtool -A eth0 tx on (Enable TX flow control)

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 4
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver 2 Operation Guide to the USB 2.0 /USB 3.0 Host
Operation Guide Module

2 Operation Guide to the USB 2.0 /USB 3.0


Host Module

The USB 2.0 and USB 3.0 of the Hi3531D V100 support the host mode.
The USB 2.0 of the Hi3521D V100 and Hi3520D V400 support the host mode.

2.1 Preparations
Before using the USB 2.0 host/USB 3.0 host module, ensure that the following items are
available:
 U-boot and Linux kernel released in the SDK
 File systems
You can use the local file system YAFFS2, JFFS2, or Cramfs (Jffs2 is recommended)
released in the SDK or mounted to the NFS.

2.2 Procedure
The operation procedure is as follows:
Step 1 Start the board, and load the NFS or the file system YAFFS2, JFFS2, Cramfs.
By default, all drivers related to the USB 2.0 module are compiled in the kernel. Therefore,
you do not need to load the drivers.
Step 2 Insert a USB device such as the USB flash drive, mouse, or keyboard, and then perform
operations on the USB device. For details, see section 2.3 "Operation Instance Related to the
USB Flash Drive."
The drivers related to USB are as follows:
 Drivers related to the file system and storage devices
− vfat
− scsi_mod
− sd_mod

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 5
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver 2 Operation Guide to the USB 2.0 /USB 3.0 Host
Operation Guide Module

− nls_ascii
− nls_iso8859-1
 Drivers related to the keyboard
− evdev
− usbhid
 Drivers related to the mouse
− mousedev
− usbhid
− evdev
 Drivers related to the USB 2.0 module
− ohci-hcd
− ehci-hcd
− usb-storage
− hiusb-hi35xx
 Drivers related to the USB 3.0 module
− ohci-hcd
− ehci-hcd
− xhci-hcd
− usb-storage
− hiusb3.0
----End

The USB 3.0 module is not supported by Hi3521D V100 and Hi3520D V400.

2.3 Operation Instances


2.3.1 Operation Instance Related to the USB Flash Drive
Inserting and Detecting a USB Flash Drive
Insert a USB flash drive, and then check whether it can be detected.
If the USB 2.0 host module works properly, the following information is displayed over the
serial port:
~ # usb 1-1: new high-speed USB device number 7 using hiusb-ehci
scsi2: usb-storage 1-1:1.0
scsi 2:0:0:0: Direct-Access Kingston DT 101 G2 1.00 PQ: 0 ANSI:

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 6
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver 2 Operation Guide to the USB 2.0 /USB 3.0 Host
Operation Guide Module

4
sd 2:0:0:0: [sda] 15131636 512-byte logical blocks: (7.74 GB/7.21 GiB)
sd 2:0:0:0: [sda] Write Protect is off
sd 2:0:0:0: [sda] Write cache: disabled, read cache: enabled, does not
support DPO or FUA
sda: sda1
sd 2:0:0:0: [sda] Attached SCSI removable disk

If the USB 3.0 host module works properly, the following information is displayed over the
serial port:
usb 4-1: new SuperSpeed USB device number 2 using xhci-hcd
scsi1 : usb-storage 4-1:1.0
usbdev42 -> /dev/usbdev4.2
scsi 1:0:0:0: Direct-Access SanDisk Extreme 0001 PQ: 0 ANSI: 6
sd 1:0:0:0: [sda] 31277232 512-byte logical blocks: (16.0 GB/14.9 GiB)
sd 1:0:0:0: Attached scsi generic sg0 type 0
sd 1:0:0:0: [sda] Write Protect is off
sd 1:0:0:0: [sda] Mode Sense: 33 00 00 08
sd 1:0:0:0: [sda] Write cache: enabled, read cache: enabled, does not
support DPO or FUA
sda: sda1
sd 1:0:0:0: [sda] Attached SCSI disk
udisk4110 -> /dev/sda
udisk4110p1 -> /dev/sda1

Where, sda1 is the first partition of the USB flash drive or the portable drive. If there are
multiple partitions, information such as sda1, sda2, sda3, …, and sdaN is displayed.

Using the USB Flash Drive


Perform the following initialization steps after the related drivers are loaded:

In sdXY, X indicates the disk ID, and Y indicates the partition ID. You need to change them as required.
 The sdX device node is partitioned by running the partition command such as $ fdisk
/dev/sda.
 The sdXY partition is formatted by running the mkdosfs command such as ~ $ mkdosfs
–F 32 /dev/sda1.
 The sdXY partition is mounted by running the mount command such as ~ $ mount -t
vfat /dev/sda1 /mnt.
Step 1 Check whether the USB flash drive is partitioned.
 Run ls /dev to view system device files. If sdXY is not displayed, the USB flash drive is
not partitioned. In this case, run the ~ $ fdisk /dev/sda command to partition it. For
details, see section 6.1 "Partitioning a Storage Device.", and then go to Step 2.
 If sdXY is displayed, the USB flash drive is detected and partitioned. In this case, go to
Step 2.

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 7
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver 2 Operation Guide to the USB 2.0 /USB 3.0 Host
Operation Guide Module

Step 2 Check whether the USB flash drive is formatted.


 If it is not formatted, run the ~ $ mkdosfs –F 32 /dev/sdaX command to format it. For
details, see section 6.2 "Formatting a Partition."
 If it is formatted, go to Step 3.
Step 3 Check whether a directory is mounted.
 If no directory is mounted, run the ~ $ mount -t vfat /dev/sdaX /mnt command to
mount a directory. For details, see section 6.3 "Mounting a Directory."
 If a directory is mounted, go to Step 4.
Step 4 Read/write to the USB flash drive. For details, see section 6.4 "Reading/Writing to a File."
----End

2.3.2 Using the Keyboard


Before you can use the keyboard, you need to perform the following steps:
Step 1 Load the drivers related to the keyboard.
After the drivers related to the keyboard are loaded, the event0 node is generated in
/dev/input.
Step 2 Receive the keyboard inputs by running the following command:
cat /dev/input event0

Step 3 Press any keys on the keyboard.


If no error occurs, the content that you entered is displayed on the screen.
----End

2.3.3 Using the Mouse


Before you can use the mouse, perform the following steps:
Step 1 Load the drivers related to the mouse.
After the drivers related to the mouse are loaded, the mouse0 node is generated in /dev/input.
Step 2 Run a standard test program (mev recommended) of the gpm tool.
Step 3 Click randomly on the screen or move the pointer.
If the mouse functions properly, the corresponding code value is displayed.
----End

2.4 Precautions
Note the following when performing the operations related to the USB 2.0 module:
 You need to run the mount command, operate a file, and then run the umount command
in sequence each time. This avoids exceptions in the file system.

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 8
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver 2 Operation Guide to the USB 2.0 /USB 3.0 Host
Operation Guide Module

 The drivers of the keyboard and mouse must work with the upper layer. For example,
mouse events are displayed on the graphical user interface (GUI) of the upper layer. You
only need to operate the keyboard by accessing the event node in /dev/input. However,
standard libraries are required for mouse operations.
 Mouse application libgpm libraries are provided in Linux. If you need to use the mouse,
these libraries must be compiled. You are recommended to use the standard kernel
interface gpm-1.20.5 that has passed the test.
In addition, a set of test programs (such as mev) is provided in the gpm tool. You can
perform encoding by using the test programs, making the development easier.

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 9
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 3 Operation Guide to the SATA

3 Operation Guide to the SATA

3.1 Preparations
Before using the I2C, ensure that the following items are available:
 Standard serial advanced technology attachment (SATA) hard disk
 U-boot and Linux kernel released in the SDK
 File systems
You can use the local file system Yaffs2, UBIFS, JFFS2, or SquashFS released in the
SDK or mounted to the NFS.

3.2 Procedure
Before testing an SATA hard disk, perform the following steps:
Step 1 Start the board, and load the local file system Yaffs2, UBIFS, JFFS2, or SquashFS or mount
the local file system to the NFS.
Step 2 Load the drivers. By default, all drivers related to the SATA module are compiled in the
kernel, you do not need to run the command for loading drivers. For details, see section 3.3
"Operation Instances."
 Drivers related to the file system and storage devices
− nls_base
− nls_cp437
− fat
− vfat
− msdos
− nls_iso8859-1
− nls_ascii
− scsi_mod
− sd_mod
 Drivers related to hard disks
− libata
− ahci

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 10
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 3 Operation Guide to the SATA

----End

3.3 Operation Instances


Note the following:

In the following commands, X indicates the disk ID, and Y indicates the partition ID. You need to
change them as required.
 The sdX device node is partitioned by running the partitioning command such as $ fdisk
/dev/sda or $ parted /dev/sda.
 The sdXY partition is formatted by running the mkdosfs command such as ~ $ mkdosfs
–F 32 /dev/sda1.
 The sdXY partition is mounted by running the mounting command such as $ mount -t
vfat /dev/sda1 /mnt.
Perform the following steps:
Step 1 Check whether the SATA hard disk is partitioned.
 Run ls /dev to view the system device files. If partition information sdXY is not displayed,
the SATA hard disk has not been partitioned yet. In this case, partition the SATA hard
disk by following section 6.1 "Partitioning a Storage Device."
 If sdXY is displayed, the hard disk is detected and partitioned. In this case, go to step 2.
Step 2 Check whether the SATA hard disk is formatted.
 If the SATA hard disk is not formatted, format it by following section 6.2 "Formatting a
Partition."
 If it is formatted, go to step 3.
Step 3 Mount the directory by following section 6.3 "Mounting a Directory."
Step 4 Read/Write to the SATA hard disk by following section 6.4 "Reading/Writing to a File."
----End

3.4 Precautions
The Hi35xx SATA drivers support hot plug. After the hot plug, you need to unmount the
nodes mounted to the hard disk. Otherwise, the device nodes of the SATA hard disk change
after the SATA hard disk is reinserted.

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 11
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 4 Operation Guide to the I2C

4 Operation Guide to the I2C

4.1 Preparations
Before using the I2C, ensure that the following items are available:
 Linux kernel released in the SDK
 File systems
You can use the local file system YAFFS2, JFFS2, or SquashFS released in the SDK or
mounted to the NFS.

4.2 Procedure
To use the I2C, perform the following steps:
Step 1 Start the board, and load the local file system YAFFS2, JFFS2, or SquashFS or mount the
local file system to the NFS.
Step 2 Load the kernel. By default, all drivers related to the I2C module are compiled in the kernel.
Therefore, you do not need to load the drivers.
Step 3 Run I2C read and write commands on the console or compile I2C read and write programs in
kernel mode or user mode to read/write to the peripherals mounted on the I2C controller. For
details, see section 4.3 "Operation Instances."
----End

4.3 Operation Instances


4.3.1 I2C Read and Write Commands
The following instances describe how to read and write to I2C peripherals by running I2C read
and write commands:
 To read I2C peripherals on the console, run i2c_read:
~ $ i2c_read <i2c_num> <device_addr> <reg_addr> <end_reg_addr>
<reg_width> <data_width> <reg_step>

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 12
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 4 Operation Guide to the I2C

 For example, to read the register (address of 0x8) of the sil9024 device mounted on I2C
controller 2, run the following command:
~ $ i2c_read 2 0x72 0x8 0x8 0x1 0x1

 i2c_num: I2C controller ID (corresponding to I2C controller in the Hi35xx H.265 Codec Processor
Data Sheet)
 device_addr: peripheral address (The Hi35xx supports the 7-bit standard address and 10-bit
extended address.)
 reg_addr: start address for reading peripheral registers
 end_reg_addr: end address for reading peripheral registers
 reg_width: bit width of peripheral registers (The Hi35xx supports 8-bit and 16-bit width.)
 data_width: data width of peripherals (The Hi35xx supports 8-bit and 16-bit data width.)
 reg_step: incremental step when peripheral registers are read consecutively. The default value is 1,
indicating that two or more registers are read consecutively. This parameter is not used when only
one register is read.
 To write to I2C peripherals on the console, run i2c_write:
~ $ i2c_write <i2c_num> <device_addr> <reg_addr> <value> <reg_width>
<data_width>

For example, to write 0xa5 to the register (address of 0x8) of the sil9024 device mounted
on I2C controller 2, run the following command:
~ $ i2c_write 2 0x72 0x8 0xa5 0x1 0x1

 i2c_num: I2C controller ID (corresponding to I2C controller in the Hi35xx H.265 Codec Processor
Data Sheet)
 device_addr: peripheral address (The I2C controller of the Hi35xx supports the 7-bit standard
address and 10-bit extended address.)
 reg_addr: address for writing to peripheral registers
 value: data written to peripheral registers
 reg_width: bit width of peripherals (The I2C controller of the Hi35xx supports 8-bit and 16-bit
width.)
 data_width: data bit width of peripherals (The I2C controller of the Hi35xx supports 8-bit and 16-bit
data width.)

4.3.2 I2C Read and Write Programs in Kernel Mode


The following instance describes how to read/write to I2C peripherals by compiling I2C read
and write programs in kernel mode:
Step 1 Call functions at the I2C core layer. i2c_adap is obtained, which is a structure of the I2C
controller.
i2c_adap = i2c_get_adapter(2);

Assume that the new peripheral is mounted on I2C controller 2, the parameter value of i2c_get_adapter
can be set to 2.

Step 2 Associate the I2C controller with the new I2C peripheral. hi_client is obtained, which is a data
structure that describes the client of I2C peripherals.
hi_client = i2c_new_device(i2c_adap, &hi_info);

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 13
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 4 Operation Guide to the I2C

The hi_info structure provides the address of the I2C peripheral.

Step 3 In a non-interrupt context, call the standard read and write functions provided by the I2C core
layer to read/write to peripherals.
ret = i2c_master_send(client, buf, count);
ret = i2c_master_recv(client, buf, count);

In an interrupt context, call the read and write functions provided by the I2C driver layer to
read/write the peripherals.
ret = hi_i2c_master_send(client, buf, count);
ret = hi_i2c_master_recv(client, buf, count);

 The client parameter is the hi_client structure obtained in step 2, which is a data structure that
describes the client of I2C peripherals.
 The buf parameter is the register or data needs to be read or written.
 The count parameter is the length of buf.

The code instance is as follows:

The following code instance is a sample program, which only serves as a reference for customers when
they develop kernel-mode I2C peripheral drivers. The code has no actual functions.
For details about kernel-mode I2C peripheral drivers, see tlv320aic31 in
mpp/extdrv/tlv320aic31/tlv320aic31.c of the SDK.

//Information list for I2C peripherals


static struct i2c_board_info hi_info = {

//Each I2C_BOARD_INFO structure represents a supported I2C peripheral. The device name
is hi_test and the device address is 0x72.
I2C_BOARD_INFO("hi_test", 0x72),
};

static struct i2c_client *hi_client;

static int i2c_drv_write(char *buf, unsigned int count,


unsigned int reg_addr_num, unsigned int data_byte_num)
{
int ret;
char *tmp;
struct i2c_client *client = hi_client;

//Set the flag according to the register bit width parameter.


if (reg_addr_num == 2)
client->flags |= I2C_M_16BIT_REG;

//Set the flag according to the data bit width parameter.

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 14
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 4 Operation Guide to the I2C

if (data_byte_num == 2)
client->flags |= I2C_M_16BIT_DATA;

//In a non-interrupt context, call the I2C standard write function provided by the kernel to
perform the write operation.
ret = i2c_master_send(client, buf, count);

//In an interrupt context, call the write function provided by the driver layer to perform the
write operation.
ret = hi_i2c_master_send(client, buf, count);
return ret;
}

static int i2c_drv_read(char *buf, unsigned int count,


unsigned int reg_addr_num, unsigned int data_byte_num)
{
int ret;

struct i2c_client *client = hi_client;

//Set the flag according to the register bit width parameter.


if (reg_addr_num == 2)
client->flags |= I2C_M_16BIT_REG;

//Set the flag according to the data bit width parameter.


if (data_byte_num == 2)
client->flags |= I2C_M_16BIT_DATA;

//In a non-interrupt context, call the I2C standard read function provided by the kernel to
perform the read operation.
ret = i2c_master_recv(client, buf, count);

//In an interrupt context, call the read function provided by the driver layer to perform the read
operation.
ret = hi_i2c_master_recv(client, buf, count);
return ret;
}
static int hi_dev_init(void)
{

//Allocate an I2C controller pointer.


struct i2c_adapter *i2c_adap;

//Call functions at I2C core layer to obtain i2c_adap, which is a structure of the I2C controller.
Assume that the new peripheral is mounted on I2C controller 2.
i2c_adap = i2c_get_adapter(2);

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 15
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 4 Operation Guide to the I2C

//Associate the I2C controller with the new I2C peripheral by mounting the I2C peripheral on
I2C controller 2. The address is 0x72. In this way, hi_client is formed.
hi_client = i2c_new_device(i2c_adap, &hi_info);
i2c_put_adapter(i2c_adap);
return 0;
}
static void hi_dev_exit(void)
{
i2c_unregister_device(hi_client);
}

----End

4.3.3 I2C Read and Write Programs in User Mode


The following instance describes how to read/write to I2C peripherals by compiling I2C read
and write programs in user mode:
Step 1 Open the device file corresponding to the I2C bus to obtain the file descriptor.
fd = open("/dev/i2c-0", O_RDWR);

Step 2 Run the following ioctl commands to configure the peripheral address, bit width of peripheral
registers, and data bit width of peripherals.
ret = ioctl(fd, I2C_SLAVE_FORCE, device_addr);
ioctl(fd, I2C_16BIT_REG, 0);
ioctl(fd, I2C_16BIT_DATA, 0);

For the register bit width and data bit width, when the third parameter of ioctl is set to 0, the bit width is
8 bits. When the third parameter of ioctl is set to 1, the bit width is 16 bits.

Step 3 Call the read and write functions to read/write the data.
read(fd, recvbuf, reg_width);
write(fd, buf, (reg_width + data_width));

The code instance is as follows:

The following code instance is a sample program, which only serves as a reference for customers when
they develop user-mode I2C peripheral drivers. The code has no actual functions.
For details about user-mode I2C peripheral drivers, see i2c_ops in osdrv/tools/board/reg-tools-
1.0.0/source/tools/i2c_ops.c of the SDK.
unsigned int reg_width = 1;
unsigned int data_width = 1;
unsigned int reg_step = 1;

HI_RET i2c_read(int argc, char* argv[])


{
int fd = -1;

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 16
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 4 Operation Guide to the I2C

int ret;
unsigned int i2c_num, device_addr, reg_addr, reg_addr_end;
char data;
char recvbuf[4];
int cur_addr;

memset(recvbuf, 0x0, 4);

fd = open("/dev/i2c-0", O_RDWR);

if (fd<0)
{
printf("Open i2c dev error!\n");
return -1;
}

ret = ioctl(fd, I2C_SLAVE_FORCE, device_addr);

if (reg_width == 2)
ret = ioctl(fd, I2C_16BIT_REG, 1);
else
ret = ioctl(fd, I2C_16BIT_REG, 0);
if (ret < 0) {
printf("CMD_SET_REG_WIDTH error!\n");
close(fd);
return -1;
}

if (data_width == 2)
ret = ioctl(fd, I2C_16BIT_DATA, 1);
else
ret = ioctl(fd, I2C_16BIT_DATA, 0);
if (ret < 0) {
printf("CMD_SET_DATA_WIDTH error!\n");
close(fd);
return -1;
}

for (cur_addr = reg_addr; cur_addr < reg_addr_end + reg_width;


cur_addr += reg_step)
{
if (reg_width == 2) {
recvbuf[0] = cur_addr & 0xff;
recvbuf[1] = (cur_addr >> 8) & 0xff;

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 17
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 4 Operation Guide to the I2C

} else
recvbuf[0] = cur_addr & 0xff;

ret = read(fd, recvbuf, reg_width);


if (ret < 0) {
printf("CMD_I2C_READ error!\n");
close(fd);
return -1;
}

if (data_width == 2) {
data = recvbuf[0] | (recvbuf[1] << 8);
} else
data = recvbuf[0];

printf("0x%x 0x%x\n", cur_addr, data);


}

close(fd);
return 0;
}

HI_RET i2c_write(int argc , char* argv[])


{
int fd = -1;
int ret =0, index = 0;
unsigned int i2c_num, device_addr, reg_addr, reg_value;
char buf[4];

fd = open("/dev/i2c-0", O_RDWR);
if(fd < 0)
{
printf("Open i2c dev error!\n");
return -1;
}

ret = ioctl(fd, I2C_SLAVE_FORCE, device_addr);

if (reg_width == 2)
ret = ioctl(fd, I2C_16BIT_REG, 1);
else
ret = ioctl(fd, I2C_16BIT_REG, 0);

if (data_width == 2)

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 18
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 4 Operation Guide to the I2C

ret = ioctl(fd, I2C_16BIT_DATA, 1);


else
ret = ioctl(fd, I2C_16BIT_DATA, 0);

if (reg_width == 2) {
buf[index] = reg_addr & 0xff;
index++;
buf[index] = (reg_addr >> 8) & 0xff;
index++;
} else {
buf[index] = reg_addr & 0xff;
index++;
}

if (data_width == 2) {
buf[index] = reg_value & 0xff;
index++;
buf[index] = (reg_value >> 8) & 0xff;
index++;
} else {
buf[index] = reg_value & 0xff;
index++;
}

write(fd, buf, (reg_width + data_width));


if(ret < 0)
{
printf("I2C_WRITE error!\n");
return -1;
}

close(fd);
return 0;
}

----End

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 19
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

5 Operation Guide to the SPI

5.1 Preparations
Before using the serial peripheral interface (SPI), ensure that the following items are available:
 Linux kernel released in the SDK
 File systems
You can use the local file system YAFFS2, JFFS2, or SquashFS released in the SDK or
mounted to the NFS.

5.2 Procedure
To use the SPI, perform the following steps:
Step 1 Start the board, and load the local file system YAFFS2, JFFS2, or SquashFS or mount the
local file system to the NFS.
Step 2 Load the kernel. By default, all drivers related to the SPI module are compiled in the kernel.
Therefore, you do not need to load the drivers.
Step 3 Run SPI read and write commands on the console or compile SPI read and write programs in
kernel mode or user mode to read/write to the peripherals mounted on one of the chip selects
(CSs) of the SPI controller. For details, see section 5.3 "Operation Instances."
----End

5.3 Operation Instances


5.3.1 SPI Read and Write Commands
The following instances describe how to read and write to SPI peripherals by running SPI
read and write commands:
 To read SPI peripherals on the console, run spi_read:
~ $ ssp_read <spi_num> <csn> <dev_addr> <reg_addr> [num_reg] [dev_width]
[reg_width] [data_width]

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 20
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

[num_reg] can be omitted and its default value is 1 (indicating reading one register).
[dev_width], [reg_width], and [data_width] can be omitted and their default values are 1
(indicating one byte).
For example, to read the register (address of 0x0) of the device (address of 0x2) mounted on
CS 0 of the SPI controller 0, run the following command:
~ $ ssp_read 0x0 0x0 0x2 0x0 0x10 0x1 0x1 0x1

 spi_num: SPI controller ID (corresponding to SPI controller 0 and SPI controller 1 in the Hi35xx
H.265 Codec Processor Data Sheet)
 csn: CS ID
 dev_addr: peripheral address
 reg_addr: address of the first peripheral register to be read among multiple peripheral registers
whose addresses are consecutive
 num_reg: number of peripheral registers to be read
 dev_width: address bit width of peripherals (8/16 bits)
 reg_width: address bit width of peripheral registers (8/16 bits)
 data_width: data bit width of peripherals (8/16 bits)
 To write to SPI peripherals on the console, run spi_write:
~ $ ssp_write <spi_num> <csn> <dev_addr> <reg_addr> <data> [dev_width]
[reg_width] [data_width]
[dev_width], [reg_width], and [data_width] can be omitted and their default values are
1 (indicating one byte).
For example, to write 0x65 to the register (address of 0x0) of the device (address of 0x2)
mounted on CS 0 of the SPI controller 0, run the following command:
~ $ ssp_write 0x0 0x0 0x2 0x0 0x65 0x1 0x1 0x1

 spi_num: SPI controller ID (corresponding to SPI controller 0 and SPI controller 1 in the Hi35xx
H.265 Codec Processor Data Sheet)
 csn: CS ID
 dev_addr: peripheral address
 reg_addr: peripheral register address
 data: data written to peripheral registers
 dev_width: address bit width of peripherals (8/16 bits)
 reg_width: address bit width of peripheral registers (8/16 bits)
 data_width: data bit width of peripherals (8/16 bits)

The SPI read and write commands can be used only to read and write to sensors.

5.3.2 SPI Read and Write Programs in Kernel Mode


The following instance describes how to read/write to SPI peripherals by compiling SPI read
and write programs in kernel mode:
Step 1 Call functions at the SPI core layer. A structure of the SPI controller is obtained.
hi_master = spi_busnum_to_master(bus_num);

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 21
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

 bus_num is the ID of the SPI controller connected to the SPI peripherals to be read or written to.
 hi_master is a pointer to the spi_master structure that describes the SPI controller.

Step 2 Call functions at the SPI core layer by name of each SPI CS at the core layer to obtain a
structure that describes an SPI peripheral mounted to one CS of an SPI controller.
sprintf(spi_name, "%s.%u", dev_name(&hi_master->dev),csn);
d = bus_find_device_by_name(&spi_bus_type, NULL, spi_name);
hi_spi = to_spi_device(d);

 spi_bus_type is a pointer to the bus_type structure that describes the SPI bus and is defined at the
core layer.
 hi_spi is a pointer to the spi_device structure that describes SPI peripherals.

Step 3 Configure members in the spi_transfer structure, call functions at the SPI core layer, and add
spi_transfer to the queue of spi_message.
spi_message_init(&m);
spi_message_add_tail(&t, &m);

 Parameter t is a pointer to the spi_transfer structure that describes a transferred message frame.
 Parameter m is a pointer to the spi_message structure that describes a transferred message queue.

Step 4 Call the standard read and write functions provided by the SPI core layer to read/write to
peripherals.
status = spi_async(spi, &m);
status = spi_sync(spi, &m);

 Parameter spi is a pointer to the spi_device structure that describes SPI peripherals.
 The spi_async function is used to perform asynchronous SPI read and write operations.
 The spi_sync function is used to perform synchronous SPI read and write operations.

The code instance is as follows:

 The following code instance is a sample program for asynchronously reading and writing to the SPI
peripheral imx185. The code only serves as a reference for customers when they develop kernel-
mode SPI peripheral drivers and has no actual functions.
 For details about kernel-mode SPI peripheral drivers, see sensor_spi in
mpp/extdrv/sensor_spi/sensor_spi.c of the SDK.

//Module parameters. The transferred SPI controller ID is the SPI bus ID and the SPI CS ID.
static unsigned bus_num = 0;
static unsigned csn = 0;
module_param(bus_num, uint, S_IRUGO);
MODULE_PARM_DESC(bus_num, "spi bus number");
module_param(csn, uint, S_IRUGO);
MODULE_PARM_DESC(csn, "chip select number");

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 22
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

//A structure that describes the SPI controller


struct spi_master *hi_master;

//A structure that describes SPI peripherals


struct spi_device *hi_spi;

int ssp_write_alt(unsigned char devaddr,unsigned char addr, unsigned char


data)
{
struct spi_master *master = hi_master;
struct spi_device *spi = hi_spi;
static struct spi_transfer t;
static struct spi_message m;
static unsigned char buf[4];
int status = 0;
unsigned long flags;

/* check spi_message is or no finish */


spin_lock_irqsave(&master->queue_lock, flags);

//After the transfer of the message queue is complete, the state member of spi_message
is set to null at the core layer.
if (m.state != NULL) {
spin_unlock_irqrestore(&master->queue_lock, flags);
return -EFAULT;
}
spin_unlock_irqrestore(&master->queue_lock, flags);

//Configure the SPI transfer mode.


spi->mode = SPI_MODE_3 | SPI_LSB_FIRST;

memset(buf, 0, sizeof buf);


buf[0] = devaddr;
buf[0] &= (~0x80);
buf[1] = addr;
buf[2] = data;

t.tx_buf = buf;
t.rx_buf = buf;
t.len = 3;
t.cs_change = 1;
t.bits_per_word = 8;
t.speed_hz = 2000000;

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 23
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

//Initialize and configure the SPI transfer queue.


spi_message_init(&m);
spi_message_add_tail(&t, &m);
m.state = &m;

When the function is returned after calling, the SPI read and write operations may not be complete
because the operations are asynchronous. Therefore, the address space pointed by the transferred
parameters must be a local static variable or a global variable to prevent the address space transferred to
spi_async from being released when the function is returned.
status = spi_async(spi, &m);
return status;
}

int ssp_read_alt(unsigned char devaddr,unsigned char addr, unsigned char


*data)
{
struct spi_master *master = hi_master;
struct spi_device *spi = hi_spi;
static struct spi_transfer t;
static struct spi_message m;
static unsigned char buf[4];
int status = 0;
unsigned long flags;

/* check spi_message is or no finish */


spin_lock_irqsave(&master->queue_lock, flags);

//After the transfer of the message queue is complete, the state member of spi_message
is set to null at the core layer.
if (m.state != NULL) {
spin_unlock_irqrestore(&master->queue_lock, flags);
return -EFAULT;
}
spin_unlock_irqrestore(&master->queue_lock, flags);

//Configure the SPI transfer mode.


spi->mode = SPI_MODE_3 | SPI_LSB_FIRST;

memset(buf, 0, sizeof buf);


buf[0] = devaddr;
buf[0] |= 0x80;
buf[1] = addr;
buf[2] = 0;

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 24
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

t.tx_buf = buf;
t.rx_buf = buf;
t.len = 3;
t.cs_change = 1;
t.bits_per_word = 8;
t.speed_hz = 2000000;

//Initialize and configure the SPI transfer queue.


spi_message_init(&m);
spi_message_add_tail(&t, &m);
m.state = &m;

When the function is returned after calling, the SPI read and write operations may not be complete
because the operations are asynchronous. Therefore, the address space pointed by the transferred
parameters must be a local static variable or a global variable to prevent the address space transferred to
spi_async from being released when the function is returned.
status = spi_async(spi, &m);
*data = buf[2];
return status;
}

//External reference declaration for the spi_bus_type structure that describes the SPI bus and
is defined at the SPI core layer.
extern struct bus_type spi bus_type;

static int __init sspdev_init(void)


{
int status = 0;
struct device *d;
char *spi_name;

//The structure that describes the SPI controller is obtained by using the SPI controller ID.
hi_master = spi_busnum_to_master(bus_num);
if (hi_master) {
spi_name = kzalloc(strlen(dev_name(&hi_master->dev)) + 10 ,
GFP_KERNEL);
if (!spi_name) {
status = -ENOMEM;
goto end0;
}

sprintf(spi_name, "%s.%u", dev_name(&hi_master->dev),csn);

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 25
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

//The pointer to the device member of spi_device is obtained by name of each CS at the SPI
core layer.
d = bus_find_device_by_name(&spi_bus_type, NULL, spi_name);
if (d == NULL) {
status = -ENXIO;
goto end1;
}

//The structure that describes SPI peripherals is obtained by using the pointer to the device
member of spi_device.
hi_spi = to_spi_device(d);
if(hi_spi == NULL) {
status = -ENXIO;
goto end2;
}
} else {
status = -ENXIO;
goto end0;
}

status = 0;
end2:
put_device(d);
end1:
kfree(spi_name);
end0:
return status;
}

----End

5.3.3 SPI Read and Write Programs in User Mode


The following instance describes how to read/write to SPI peripherals mounted on CS 0 of
SPI controller 0 by compiling SPI read and write programs in user mode:
Step 1 Open the device file corresponding to the SPI bus to obtain the file descriptor.
fd = open("/dev/spidev0.0", O_RDWR);

Step 2 Configure the SPI transfer mode by using ioctl.


value = SPI_MODE_3 | SPI_LSB_FIRST;
ret = ioctl(fd, SPI_IOC_WR_MODE, &value);

 SPI_MODE_3 indicates the mode in which the SPI clock and phase are both 1.

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 26
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

 SPI_LSB_FIRST indicates that the format of each data segment is big endian during the SPI
transfer.

For details about macros SPI_MODE_3 and SPI_LSB_FIRST, see include/linux/spi/spi.h.


When these two macros are used in user mode, the code in user mode can include
osdrv/tools/board/reg-tools-1.0.0/include/common/hi_spi.h in the SDK.

For details about the clock, phase, endian mode of the SPI, see the Hi35xx H.265 Codec
Processor Data Sheet.
Step 3 Use ioctl to read and write data.
ret = ioctl(fd, SPI_IOC_MESSAGE(1), mesg);

 mesg indicates the start address of the spi_ioc structure array that transfers a message frame.
 SPI_IOC_MESSAGE(n) indicates commands used to read and write n message frames in full-
duplex mode.

The code instance is as follows:

 The following code instance is a sample program for synchronously reading and writing to IMX185
(an SPI peripheral). The code only serves as a reference for customers when they develop the
operation program for user-mode SPI peripherals and has no actual functions.
 For details about user-mode SPI peripheral drivers, see ssp_rw in osdrv/tools/board/reg-tools-
1.0.0/source/tools/ssp_rw.c of the SDK.
int sensor_write_register(unsigned int addr, unsigned char data)
{
int fd = -1;
int ret;
unsigned int value;
struct spi_ioc_transfer mesg[1];
unsigned char tx_buf[4];
unsigned char rx_buf[4];
char file_name[] = "/dev/spidev0.0";

fd = open(file_name, 0);
if (fd < 0) {
return -1;
}

memset(tx_buf, 0, sizeof tx_buf);


memset(rx_buf, 0, sizeof rx_buf);
tx_buf[0] = (addr & 0xff00) >> 8;
tx_buf[0] &= (~0x80);

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 27
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

tx_buf[1] = addr & 0xff;


tx_buf[2] = data;

memset(mesg, 0, sizeof mesg);


mesg[0].tx_buf = (__u32)tx_buf;
mesg[0].rx_buf = (__u32)rx_buf;
mesg[0].len = 3;
mesg[0].speed_hz = 2000000;
mesg[0].bits_per_word = 8;
mesg[0].cs_change = 1;

value = SPI_MODE_3 | SPI_LSB_FIRST;


ret = ioctl(fd, SPI_IOC_WR_MODE, &value);
if (ret < 0) {
close(fd);
return -1;
}

ret = ioctl(fd, SPI_IOC_MESSAGE(1), mesg);


if (ret != mesg[0].len) {
close(fd);
return -1;
}
close(fd);
return 0;
}

int sensor_read_register(unsigned int addr,unsigned char *data)


{
int fd = -1;
int ret = 0;
unsigned int value;
struct spi_ioc_transfer mesg[1];
unsigned char tx_buf[4];
unsigned char rx_buf[4];
char file_name[] = "/dev/spidev0.0";

fd = open(file_name, 0);
if (fd < 0) {
return -1;
}

memset(tx_buf, 0, sizeof tx_buf);


memset(rx_buf, 0, sizeof rx_buf);

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 28
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 5 Operation Guide to the SPI

tx_buf[0] = (addr & 0xff00) >> 8;


tx_buf[0] |= 0x80;
tx_buf[1] = addr & 0xff;
tx_buf[2] = 0;

memset(mesg, 0, sizeof mesg);


mesg[0].tx_buf = (__u32)tx_buf;
mesg[0].rx_buf = (__u32)rx_buf;
mesg[0].len = 3;
mesg[0].speed_hz = 2000000;
mesg[0].bits_per_word = 8;
mesg[0].cs_change = 1;

value = SPI_MODE_3 | SPI_LSB_FIRST;


ret = ioctl(fd, SPI_IOC_WR_MODE, &value);
if (ret < 0) {
close(fd);
return -1;
}

ret = ioctl(fd, SPI_IOC_MESSAGE(1), mesg);


if (ret != mesg[0].len) {
close(fd);
return -1;
}
*data = rx_buf[2];
close(fd);
return 0;
}

----End

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 29
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 6 Appendix

6 Appendix

6.1 Partitioning a Storage Device


You can check the current partition status of a device by following section 6.1.1 "Checking
the Current Partition Status of a Storage Device." If the device is not partitioned, you need to
partition it as follows:
 If partitions exist, skip the operations in this section and go to section 6.2 "Formatting a
Partition."
 If partitions do not exist, enter the fdisk command at the command prompt of the console:
~ $ fdisk device node

Press Enter and enter the m command. Continue with the operations based on the help
information.
The device node depends on the type of the actual storage device. For details, see the
operation instances in preceding chapters.

6.1.1 Checking the Current Partition Status of a Storage Device


To check the current partition status of a storage device, enter the p command at the command
prompt of the console:
Command (m for help): p

The partition status similar to the following is displayed:


Disk /dev/mmc/blk1/disc: 127 MB, 127139840 bytes
8 heads, 32 sectors/track, 970 cylinders
Units = cylinders of 256 * 512 = 131072 bytes
Device Boot Start End Blocks Id System

The preceding information indicates that the device is not partitioned. In this case, you need to
partition the device by following section 6.1.2 "Creating Partitions for a Storage Device.", and
save the partition information by following section 6.1.3 "Saving the Partition Information."

6.1.2 Creating Partitions for a Storage Device


Perform the following steps:
Step 1 Create partitions.

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 30
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 6 Appendix

Under the prompt, enter the n command to create partitions.


Command (m for help): n

The following information is displayed on the console:


Command action
e extended
p primary partition (1-4)

Step 2 Create the primary partition.


Enter the p command to select the primary partition:
p

Step 3 Select the number of partitions.


In this example, set the number to 1, that is, enter 1.
Partition number (1-4): 1

The following information is displayed on the console:


First cylinder (1-970, default 1):

Step 4 Select the start cylinder.


This example takes the default value 1. Press Enter.
Using default value 1

Step 5 Select the end cylinder.


This example takes the default value 970. Press Enter.
Last cylinder or +size or +sizeM or +sizeK (1-970, default 970):
Using default value 970

Step 6 Select a data format for the storage device.


The default value is Linux. This example takes Win95 FAT; therefore, run the t command to
change the value.
Command (m for help): t
Selected partition 1

Then run the following command:


Hex code (type L to list codes): b

Run the l command to view the details of all the partitions of the fdisk.
Changed system type of partition 1 to b (Win95 FAT32)

Step 7 Check the status of partitions.


Enter the p command to view the partition information:
Command (m for help): p

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 31
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 6 Appendix

If the partition information is displayed on the console, the partitioning is successful.


----End

6.1.3 Saving the Partition Information


To save the partition information, run the following command:
Command (m for help): w

If the following information is displayed on the console, the partition information is


successfully saved:
The partition table has been altered!
Calling ioctl() to re-read partition table.
…………
~ $

6.2 Formatting a Partition


Perform the following operations:
 If partitions are formatted, skip the operations in this section and go to section 6.3
"Mounting a Directory."
 If partitions are not formatted, run the mkdosfs command to format the partitions:
~ $ mkdosfs –F 32 Partition name

The name of a partition depends on the type of the actual storage device. For details, see
the operation instances in preceding chapters.
If no error information is displayed on the console, a partition is formatted successfully:
~ $

6.3 Mounting a Directory


Run the mount command to mount the partitions to the /mnt directory. Then you can read
and write files.
~ $ mount -t vfat Partition name /mnt

The name of a partition depends on the type of the actual storage device. For details, see the
operation instances in the preceding chapters.

6.4 Reading/Writing to a File


There are various read and write operations. This section takes the cp command as an
example to read and write to a file.

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 32
Copyright © HiSilicon Technologies Co., Ltd
Peripheral Driver
Operation Guide 6 Appendix

To write to a file, copy the test.txt file in the current directory to the mnt directory of a
storage device by running the following command:
~ $ cp ./test.txt /mnt

HiSilicon Proprietary and Confidential


Issue 01 (2018-05-15) 33
Copyright © HiSilicon Technologies Co., Ltd

You might also like