Real-Time Embedded Systems Lab
Download
Report
Transcript Real-Time Embedded Systems Lab
Quark GPIO and I2C
(ESP – Fall 2014)
Computer Science & Engineering Department
Arizona State University
Tempe, AZ 85287
Dr. Yann-Hang Lee
[email protected]
(480) 727-7507
Real-time Systems Lab, Computer Science and Engineering, ASU
GPIO interface
From programmer’s view
GPIO pin numbering
enable GPIO (pin multiplexing)
set direction
read/write data
interrupt
There may be various physical connections
GPIO pins in IO expender
GPIO ports
GPIO devices on PCI bus
various GPIO controllers
GPIO driver (user-level interface) : /driver/gpio/gpiolib.c
Drivers for gpio chips
For Galileo board:
gpio_sch.c (Poulsbo SCH) + intel_cln_gip_gpio.c + cy8c9540a.c
Real-time Systems Lab, Computer Science and Engineering, ASU
1
GPIO Sysfs Interface
Example of shell commands for GPIO:
echo -n $led > /sys/class/gpio/export
echo -n $DIR > /sys/class/gpio/gpio$led/direction
echo -n $ON > /sys/class/gpio/gpio$led/value
Sysfs interface
to export kernel data structures, their attributes, and the linkages
between them to user space.
two methods for read and write operations
struct device_attribute {
struct attribute
attr;
ssize_t (*show)(struct device *dev, ….);
ssize_t (*store)(struct device *dev, ….);
};
So, in gpiolib.c, the following functions are provided
export_store(), gpio_value_store(), gpio_direction_show(), ….
Real-time Systems Lab, Computer Science and Engineering, ASU
2
Linux GPIO Driver
A GPIO (General Purpose Input/Output) pin can be configured,
set up its direction, and value if it is an output pin
A SoC chip may have several GPIO components
Multiple “gpio chips”
A global number in the integrated GPIO namespace, i.e., 0, 1,
2,…,n
sysfs interface to user space
GPIO framework
(gpiolib.c)
CY8C9540A
40 GPIO pins in 6 ports
Quark GIP
controller
Quark legacy
GPIO[7:0]
GPIO_SUS[5:0]
GPIO[9:8]
GPIO
Real-time Systems Lab, Computer Science and Engineering, ASU
3
GPIO on Galileo (1)
Quark X1000
Sysfs
GPIO #
Signal Name / Arduino Port #
Function and Comments
GPIO_SUS0
GPIO_SUS1
GPIO_SUS2
gpio2
gpio3
gpio4
INT_N_S3
GP LED
LVL_OE
Don’t touch, or bad things will happen :-)
LED between CY8C9540A and RTC battery
TXS0108E level shifter output enable.
GPIO_SUS3
gpio5
GPIO_SUS3_PCIE_RESET_N
Reset to Mini PCI-E slot
GPIO_SUS4
gpio6
GPIO_SUS4_W_DISABLE_N
Wireless disable (RF Kill to PCI-E Slot)
GPIO_SUS5
gpio7
A0_N
Jumper J2 (Cypress CY8C9540A I2C
address select)
GPIO0
GPIO1
gpio8
gpio9
SPI0_CS_N
Not Connected
Select SPI for AD7298
GPIO2
gpio10
SPI1_CS_N
Routed to IO10 if selected by IO10_MUX
GPIO3
GPIO4
GPIO5
GPIO6
GPIO7
GPIO8
GPIO9
gpio11
gpio12
gpio13
gpio14
gpio15
gpio0
gpio1
Not Connected
XRES
INT_N_S0
IO2
IO3
GLN_IO2_PU_EN
GLN_IO3_PU_EN
Reset to Cypress CY8C9540A
Don’t touch too :-)
Selected by IO2_MUX (gpio31=0)
Selected by IO3_MUX (gpio30=0)
Enable pullup on IO2/GPIO6
Enable pullup on IO3/GPIO7
Real-time Systems Lab, Computer Science and Engineering, ASU
4
GPIO on Galileo (1)
CY8C9540A
Sysfs GPIO Signal Name /
#
Arduino Port #
GPORT0_BIT0
gpio16
IO10
GPORT0_BIT1
gpio17
IO5
GPORT0_BIT2
gpio18
IO3
GPORT0_BIT3
gpio19
IO9
GPORT0_BIT4
gpio20
A5_MUX
GPORT0_BIT5
gpio21
A4_MUX
GPORT0_BIT6
gpio22
A3_MUX
GPORT0_BIT7
gpio23
A2_MUX
GPORT1_BIT0
gpio24
IO6
GPORT1_BIT1
gpio25
IO11
GPORT1_BIT2
gpio26
IO8
Function and Comments
Selected by IO10_MUX (GPORT3_BIT6, gpio42)
Also controlled by pwm7
Also controlled by pwm5
Selected by IO3_MUX (gpio30=1)
Also controlled by pwm3
Also controlled by pwm1
A5 pin routing: 0 = AD7298 (VIN5)
1 = Cypress CY8C9540A (GPORT4_BIT5, gpio49)
A4 pin routing: 0 = AD7298 (VIN4)
1 = Cypress CY8C9540A (GPORT4_BIT4, gpio48)
A3 pin routing: 0 = AD7298 (VIN3)
1 = Cypress CY8C9540A (GPORT4_BIT3, gpio47)
A2 pin routing: 0 = AD7298 (VIN2)
1 = Cypress CY8C9540A (GPORT4_BIT2, gpio46)
Also controlled by pwm6
Selected by IO11_MUX (GPORT3_BIT7, gpio43)
Also controlled by pwm4
Real-time Systems Lab, Computer Science and Engineering, ASU
5
GPIO on Galileo (2)
Real-time Systems Lab, Computer Science and Engineering, ASU
6
GPIO Chip Driver
A driver for each GPIO controller to provide
methods to establish GPIO direction and to access GPIO values
method to return the IRQ number associated to a given GPIO
flag saying whether calls to its methods may sleep
optional base number
In intel_qrk_gip_gpio.c
/* The base GPIO number under GPIOLIB framework */
#define INTEL_QRK_GIP_GPIO_BASE
8
/* The default number of South-Cluster GPIO on Quark. */
#define INTEL_QRK_GIP_NGPIO
8
In include/linux/gpio/driver.h, “gpio_chip” is defined, including
base: identifies the first GPIO number handled by this chip.
ngpio: the number of GPIOs handled by this controller; the last GPIO
handled is (base + ngpio - 1).
Real-time Systems Lab, Computer Science and Engineering, ASU
7
Binding of GPIOs to Pins
Example: gpio 26 is bit 2 of port 1 in CY8C9540A chip
Each GPIO chip is represented by “struct gpio_chip”
standard methods such as get, set, etc.
“int base;” and “u16 ngpio;”
When a gpio chip is added, use “base” and “ngpio” to
determine “pin range” of the chip
In cy8C9540a.c
#define NGPIO
40
static const u8 cy8c9540a_port_offs[] = {0, 8, 16, 20, 28, 36,};
#define GPIO_BASE_ID 16
When cy8c9540a_gpio_get_value is called,
an input argument: gpio=26
invoke cypress_get_port(26) to find port 1
invoke cypress_get_offs(26) to find bit 2
Real-time Systems Lab, Computer Science and Engineering, ASU
8
GPIO Driver Operation
GPIO chip driver request to add “gpio_chip” to the platform
gc->base = pdata->gpio_base;
gc->ngpio = NGPIO;
ret = gpiochip_add(&dev->gpio_chip);
gpiolib.c exports methods to work on GPIO pins
from GPIO # to find chip and to invoke teh corresponding
methods provided by the chip
gpio_request_one(LED1, GPIOF_OUT_INIT_LOW, "led1");
gpio_desc desc1 = gpio_to_desc(LED1);
gpio_set_value(desc1, data);
sysfs gpio interfaces, such as
gpiod_export, gpio_unexport, gpiod_set_value,
gpio_direction_input
Real-time Systems Lab, Computer Science and Engineering, ASU
9
GPIO Programming
GPIO Programming
In user space – via sysfs
int fd = open("/sys/class/gpio/export", O_WRONLY);
sprintf(buffer, "%d", gpio);
// int gpio
write(fd, buffer, strlen(buffer));
close(fd);
In kernel space – use the exported interface of gpiolib.c
gpio_request_one(GP_3, GPIOF_OUT_INIT_LOW, "led1");
gpio_set_value(GP_3, 0);
Poll and GPIO interrupt
configure GPIO pin as an interrupt source via
/sys/class/gpio/gpioX/edge
poll() system call to block on the gpio value until an interrupt
occurs. When the content changes, poll will return
POLLERR|POLLPRI.
Real-time Systems Lab, Computer Science and Engineering, ASU
10
GIP controller in Quark
A PCI device: B:0, D:21, F:2
MMIO –
use two base registers in configuration
registers
Offset Start
10h
14h
Offset End
13h
17h
Register ID
BAR0
BAR1
Default Value
00000000h
00000000h
I2C memory registers – BAR0+offset
I2C Master mode operation
Disable the I2C controller by writing 0 to IC_ENABLE.ENABLE.
Write to the IC_CON register
Write to the IC_TAR register.
Enable the I2C controller by writing a 1 in IC_ENABLE.
Write the transfer direction and data to be sent to the IC_DATA_CMD
register.
Real-time Systems Lab, Computer Science and Engineering, ASU
11
Quark GPIO IRQ Enable in GIP
Allows each bit of Port A to be configured for interrupts.
In drivers/mfd/intel_cln_gip_gpio.c,
#define PORTA_INT_EN
0x30/* Interrupt enable */
#define PORTA_INT_MASK
0x34/* Interrupt mask */
#define PORTA_INT_TYPE_LEVEL
0x38/* Interrupt level*/
.......
static void intel_cln_gpio_irq_enable(struct irq_data *d)
{....
void __iomem *reg_inte = reg_base + PORTA_INT_EN;
gpio = d->irq - irq_base;
spin_lock_irqsave(&lock, flags);
val_inte = ioread32(reg_inte);
iowrite32(val_inte | BIT(gpio % 32), reg_inte);
spin_unlock_irqrestore(&lock, flags);
}
Real-time Systems Lab, Computer Science and Engineering, ASU
12
Bit-Transfer on I2C Bus
One clock pulse is
generated for each data
bit that is transferred
Data Validity
The data on the SDA line
must be stable during
the HIGH(1) period of
the clock. The data
line(SDA) can change
data only when the clock
signal (SCL) is LOW(0)
Wired-and function
open-drain or opencollector
Real-time Systems Lab, Computer Science and Engineering, ASU
13
Data Transfer With 7-Bit Device Address
After START condition (S), a slave address(7-bit) is sent.
A read/write (R/W’) direction is then sent(8th bit)
Data transfer occurs, and then always terminated by STOP condition.
However, repeated START conditions can occur.
Real-time Systems Lab, Computer Science and Engineering, ASU
14
Master-Transmitter to Slave-Receiver Data Transfer
In this, the transmission direction never changes. The set-up and
transfer is straight-forward
Real-time Systems Lab, Computer Science and Engineering, ASU
15
Master-Receiver and Slave-Transmitter Data Transfer
Master initiates the data transfer by generating the START condition
followed by the start byte (with read/write bit set to 1 i.e. read mode)
After the first ack from the slave, the direction of data changes and the
master becomes receiver and slave transmitter.
The STOP condition is still generated by the master (master sends notACK before generating the STOP)
Real-time Systems Lab, Computer Science and Engineering, ASU
16
Example I2C Device – 24FC256 EEPROM
32K bytes in 512 pages of 64 bytes
I2C interface with A2, A1, A0 address pins
Page write operation:
Random read operation:
Real-time Systems Lab, Computer Science and Engineering, ASU
17
I2C Controller in Quark
GIP controller: Bus 0, Device 21, Function 2
PCI configuration registers
Base Address Register (BAR0) — Offset 10h
Base Address Register (BAR1) — Offset 14h
I2C Controller Memory Mapped Registers – Based on BAR0
register offsets are defined in /deriver/i2c/buses/i2c-designware-core.c
I2C algorithm
static struct i2c_algorithm i2c_dw_algo = {
.master_xfer
= i2c_dw_xfer,
.functionality
= i2c_dw_func, };
major steps of i2c_dw_xfer in i2c-designware-core.c,
i2c_dw_wait_bus_not_busy(dev);
i2c_dw_xfer_init(dev);
/* wait for tx to complete
*/
wait_for_completion_interruptible_timeout
to write to control reg:
dw_writel(dev, 1, DW_IC_ENABLE); /* Enable the adapter */
Real-time Systems Lab, Computer Science and Engineering, ASU
18
I2C Drivers in Linux
A driver for I2C bus
adapter and algorithm drivers
manages I2C bus transactions
Drivers for I2C devices
A client has the device’s I2C bus
address and a pointer to a driver
which is attached with an adapter
When a user program issues a file
operation that needs an I2C
transaction
i2C_transfer (i2C-core.c) to invoke
adap_algo_master_xfer
command or data is in an msg array
the adapter issues reads/writes to
hardware I/O addresses.
(https://i2c.wiki.kernel.org/index.php/Driver_Architecture)
Real-time Systems Lab, Computer Science and Engineering, ASU
19
I2C and SMBus
In general, a system can have multiple I2C
buses via different adapters and many
I2C devices
2-wire synchronous serial buses
Master and slave, addressable
Processor
ICH8
SMBus
PCI bus
PCI to I2c
I2C bus and SMBus
Adapter
EEPROM
compatible with each other.
I2C
Differences
EEPROM
Timeout (in SMBus, reset interfaces when
sensor
clock is low forlonger than 35ms))
Maximum clock speed: 100MHz(Smbus) but I2C bus has both 400kHz
and 3.4MHz versions.
Logic level: 1: 3V in I2C and 2.1V in SMBus
General call and alert response.
Real-time Systems Lab, Computer Science and Engineering, ASU
20
Example of Accessing I2C/SMBus Devices
i2c_smbus_xfer(adapter, addr, …., data)
user
program
device
driver
I2C
core
I2C
algorithm
I2C
adapter
read(……)
I2C
device
I2C bus signals
12c_dw_xfer(adapter, msg[ ], num)
user space
kernel space
adapter->algo->i2c_transfer(adapter, msg, num);
// for each i2c device
struct i2c_client {
unsigned short flags;
unsigned short addr;
char name[I2C_NAME_SIZE];
struct i2c_adapter * adapter;
struct i2c_driver * driver;
struct device dev;
int irq;
struct list_head list;
struct completion released;
};
Real-time Systems Lab, Computer Science and Engineering, ASU
21
Driver Operations (1)
When intel_cln_gip_core module is installed,
register itself as a PCI driver
provide the probe callback function intel_cln_gip_probe which calls
intel_cln_i2c_probe of intel_cln_gip_i2c.c to initiate gip i2c controller
In intel_cln_i2c_probe
construct and initiate a struct dw_i2c_dev to model dw_i2c controller
register it as a i2c adapter and add callback functions
struct i2c_adapter /* to identify a physical i2c bus */
struct i2c_algorithm /* the algorithm to access the bus*/
i2c-dev – a char device driver to access all devices on an i2c
adapter from userspace
user programs call “read”, “write”, “ioctl”, etc., to control i2c bus
transactions on an adapter (master).
Real-time Systems Lab, Computer Science and Engineering, ASU
22
Driver Operations (2)
i2c-dev creates a device i2c-x for each i2c adapter where “x” is
the adapter number, starting from 0.
So, user program can
open /dev/i2c-0
set slave address, i.e. client->addr (the i2c address of the device on the
bus)
write a “msg” to the bus with i2c_transfer in i2c-core.c which eventually
calls adap->algo->master_xfer
In i2c_dw_xfer,
lock the device
check bus busy or not
start the transfers -- i2c_dw_xfer_init
wait for completion
In i2c_dw_isr (isr for GIP i2c controller)
indicates the completion of a transfer (complete(&dev->cmd_complete))
Real-time Systems Lab, Computer Science and Engineering, ASU
23