W!o+ 的《小伶鼬工坊演義》︰ 一窺全豹之系統設計《解讀》

事實上 GrovePi 的『應用軟體界面』 API

GrovePi/Software/Python/grovepi.py

# 【所需程式庫】
44 import smbus
45 import time
46 import math
47 import RPi.GPIO as GPIO
48 import struct
49 import sys
50

# 【除錯模式】
51 debug =0
52

# 【派生版本】
53 if sys.version_info<(3,0):
54         p_version=2
55 else:
56         p_version=3
57

# 【 GPIO 版本/樹莓派版本】
58 rev = GPIO.RPI_REVISION
59 if rev == 2 or rev == 3:
60         bus = smbus.SMBus(1)
61 else:
62         bus = smbus.SMBus(0)
63

# 【 Arduino I2C 地址】
64 # I2C Address of Arduino
65 address = 0x04

# 【 Arduino 提供之命令】
67 # Command Format

# 【 主從 I2C 通訊】
158 # Function declarations of the various functions used for encoding and sending
159 # data from RPi to Arduino

# 【應用程式界面 API 】
190 # Arduino Digital Read
191 def digitalRead(pin):
192 write_i2c_block(address, dRead_cmd + [pin, unused, unused])
193 time.sleep(.1)
194 n = read_i2c_byte(address)
195 return n
196
197 # Arduino Digital Write
198 def digitalWrite(pin, value):
199 write_i2c_block(address, dWrite_cmd + [pin, value, unused])
200 return 1
201
202
203 # Setting Up Pin mode on Arduino
204 def pinMode(pin, mode):
205 if mode == "OUTPUT":
206 write_i2c_block(address, pMode_cmd + [pin, 1, unused])
207 elif mode == "INPUT":
208 write_i2c_block(address, pMode_cmd + [pin, 0, unused])
209 return 1
210
211
212 # Read analog value from Pin
213 def analogRead(pin):
214 bus.write_i2c_block_data(address, 1, aRead_cmd + [pin, unused, unused])
215 time.sleep(.1)
216 bus.read_byte(address)
217 number = bus.read_i2c_block_data(address, 1)
218 time.sleep(.1)
219 return number[1] * 256 + number[2]

 

,與之『韌體』

GrovePi/Firmware/Source/v1.2/grove_pi_v1_2_5/grove_pi_v1_2_5.ino

# 【對應的 Arduino 之指令】
101 //Digital Read
102 else if(cmd[0]==1)
103   val=digitalRead(cmd[1]);
104
105 //Digital Write
106 else if(cmd[0]==2)
107   digitalWrite(cmd[1],cmd[2]);
108
109 //Analog Read
110 else if(cmd[0]==3)
111 {
112   aRead=analogRead(cmd[1]);
113   b[1]=aRead/256;
114   b[2]=aRead%256;
115 }
116
117 //Set up Analog Write
118 else if(cmd[0]==4)
119   analogWrite(cmd[1],cmd[2]);
120
121 //Set up pinMode
122 else if(cmd[0]==5)
123   pinMode(cmd[1],cmd[2]);

 

,都是平鋪直敘,沒有太多疑惑之處。但想深入『解讀』者,或許需要先了解

Linux/Documentation/i2c/

Back Parent directory
Folder busses/
Folder muxes/
File dev-interface 8885 bytes
File fault-codes 5042 bytes
File functionality 6119 bytes
File i2c-protocol 3041 bytes
File i2c-stub 2323 bytes
File instantiating-devices 9755 bytes
File old-module-parameters 1899 bytes
File slave-eeprom-backend 474 bytes
File slave-interface 7087 bytes
File smbus-protocol 9176 bytes
File summary 1920 bytes
File ten-bit-addresses 1260 bytes
File upgrading-clients 6954 bytes
File writing-clients 15331 bytes

 

相關文件。此處僅列出『 I2C 』和『 SMBus 』摘要︰

Linux/Documentation/i2c/summary

I2C and SMBus
=============

I2C (pronounce: I squared C) is a protocol developed by Philips. It is a
slow two-wire protocol (variable speed, up to 400 kHz), with a high speed extension (3.4 MHz). It provides an inexpensive bus for connecting many types of devices with infrequent or low bandwidth communications needs. I2C is widely used with embedded systems. Some systems use variants that don’t meet branding requirements, and so are not advertised as being I2C.

SMBus (System Management Bus) is based on the I2C protocol, and is mostly a subset of I2C protocols and signaling. Many I2C devices will work on an SMBus, but some SMBus protocols add semantics beyond what is required to achieve I2C branding. Modern PC mainboards rely on SMBus. The most common devices connected through SMBus are RAM modules configured using I2C EEPROMs,
and hardware monitoring chips.

Because the SMBus is mostly a subset of the generalized I2C bus, we can use its protocols on many I2C systems. However, there are systems that don’t meet both SMBus and I2C electrical constraints; and others which can’t implement all the common SMBus protocol semantics or messages.

Terminology
===========

When we talk about I2C, we use the following terms:
Bus -> Algorithm
Adapter
Device -> Driver
Client

An Algorithm driver contains general code that can be used for a whole class of I2C adapters. Each specific adapter driver either depends on one algorithm driver, or includes its own implementation.

A Driver driver (yes, this sounds ridiculous, sorry) contains the general code to access some type of device. Each detected device gets its own data in the Client structure. Usually, Driver and Client are more closely integrated than Algorithm and Adapter.

For a given configuration, you will need a driver for your I2C bus, and
drivers for your I2C devices (usually one driver for each device).

 

至於『 python-smbus 』的說明簡介,也許讀者可以參考

Using the I2C Interface

。然而為何如此的規劃『架構』??作者亦莫宰羊的耶!!