［ET2016:ハードウェアトラック］

I2C通信の技術説明とドライバ作成方法

ＴＯＰＰＥＲＳプロジェクト教育ＷＧ 主査

竹内良輔
2016/11/18

ET2016ハードウェアトラック

1エレキ屋さんが、プログラム開発
ソフト屋さんが、ロジック合成• エレキとソフトの垣根がなくなりつつある・・・• 自宅のパソコンでFPGA開発：ALTREA(Intel)
EK-10M50F484ボードでロジック合成

ＭＡＸ１０でniosIIとuastとgpioを合成、aspカーネルを動かす

2016/11/18

ET2016ハードウェアトラック

21.シリアルデバイスI/F
2.Ｉ２Ｃ仕様(v2.1)
3.開発環境構築（ハード）4.開発環境構築（ソフト）
5.デバイス・ドライバ内容紹介
6.各デバイス通信ソフトウェア

1.シリアルデバイスI/F

2016/11/18

ET2016ハードウェアトラック

3

デバイスとのシリアル通信• LCD、センサー、EEPROM等MPU外にあるデバ
イスとデータ交換を行う通信としてシリアル通信が主流となっている– 少ない外部ピンでペリフェラルと接続したい– SoCに関係なくペリフェラルを活用したい• 現在、主流の周辺デバイスとのシリアル通信– UART(一対一の通信)• 二点式（ハードフローを使用の場合４点）、低速– I2C(Inter-Integrated Circuit)• 二点式、低速– SPI(Serial Peripheral Interface)• 四点式、中速
2016/11/18

ET2016ハードウェアトラック

41.シリアルデバイスI/F
2.Ｉ２Ｃ仕様(v2.1)
3.開発環境構築（ハード）4.開発環境構築（ソフト）
5.デバイス・ドライバ内容紹介
6.各デバイス通信ソフトウェア

2.I2C仕様(V2.1)

2016/11/18

ET2016ハードウェアトラック

5

I2C通信（１）：概要• I2C通信のもとになる設計は1980年代の初めにフィリップス社(現NXP社)が内部バス用に設計したものである• 2014年までに、いくつかのバージョンアップを行っているが、一般的に搭載されているものは、2001年に制定されたV2.1の仕様に準じている– 拡張仕様を使うと、接続できないSoCが多くなる• 現在では、特許が失効しており、ロイヤリティなしで使用が可能となっている

2016/11/18

ET2016ハードウェアトラック

6

I2C通信（１）：特徴V2.1• シリアル・データ・ライン(SDA)とシリアル・クロック・ライン(SCL)の２本のバス・ラインのみで構成• バスに接続される各デバイスはそれぞれ固有のアドレスをもち、それを元にソフトウェアによる各デバイスのアドレス指定が可能．また、デバイス間には、マスターとスレーブという関係が成立．
マスターはマスター・トランスミッタまたはマスターレシーバとして機能• 万一、複数のマスターが同時にデータ転送を開始しようとした場合でも、データ破壊を防ぐために衝突検出機能およびアービテーションを備えたマルチ・マスター・バス
2016/11/18

ET2016ハードウェアトラック

7

I2C通信（２）：特徴V2.1• ８ビットの双方向シリアル・データ転送を標準モードでは100kbit/s、ファースト・モードでは400kbit/s、ハイスピード(Hs)モードでは3.4Mbit/sで行うことが可能• オンチップ・フィルタによりバス上のスパイクを防ぎ、データの信頼性を維持• バス上の静電容量が400pF以下であれば、１つのバス上にICをいくつでも接続することが可能

2016/11/18

ET2016ハードウェアトラック

8

I2C通信（１）：仕様• 一般的な用語の定義
トランスミッタ

データをバスに送信するデバイス

レシーバ

データをバスから受信するデバイス

マスター

データ転送を開始し、クロック信号を生成し、データ転送を終了するデバイス

スレーブ

マスターからアドレス指定されるデバイス

マルチ・マスター

メッセージを失うことなく、複数のマスターが同時にバスをコントロールすること

アービトレーショ 複数のマスターが同時にバスをコントロールしようとした
ン
ときに、１つのマスターだけがバスをコントロールできるようにし、さらに、メッセージが失われたり内容が変更されないようにする手段
同期化

2016/11/18

複数のデバイスのクロック信号の周期をとるための手段

ET2016ハードウェアトラック

9

I2C通信（２）：仕様• 以下の図では、１つのバスに２つのマスターをもつマイクロコンピュータAがマイクロコンピュータBに送信する場合①A（マスター）がB（スレーブ）にアドレスを指定②A（マスター・トランスミッタ）がB（スレーブ・レシーバ）にデータを送信③A（マスター）によってデータ送信を終了

マイクロコンピュータAがマイクロコンピュータBから情報を受信する場合①A（マスター）がB（スレーブ）にアドレスを指定②B（スレーブ・トランスミッタ）がA（マスター・レシーバ）にデータを受信③A（マスター）によってデータ受信を終了

マスター・スレーブ１

スレーブ２

スレーブ１

2016/11/18

スレーブ３

スレーブ２

ET2016ハードウェアトラック

マスター・スレーブ２

10

I2C通信（３）：仕様• データの有効性
クロックが”H”の間にはSDAラインの状態は一定でなければならない。データ・ラインが”H”と”L”の間で状態を変更できるのは、SCLラインのクロックが信号が”L”のときに限られる• 「START」条件と「STOP」条件

2016/11/18

ET2016ハードウェアトラック

I2Cバスの通信手順では「START」条件および「STOP」条件という固定の状態が発生する
SCLが”H”のときSDLラインが”H”から”L”に変化する状態を「START」条件と呼ぶ
SCLが”H”のときSDLラインが”L”から”H”に変化する状態を「STOP」条件と呼ぶ「START」条件と「STOP」条件は常にマスターが生成する

11

I2C通信（４）：仕様• バイトのフォーマット

データ転送を行う場合、必ずアクノレッジが必要となる。アクノレッジのクロックはマスターが生成し、生成時トランスミッターはSDAラインを解放(“H”)する
レシーバはアクノレッジ・クロック・パルスが”H”のとき、SDLラインが”L”で安定するように設定するレシーバは、スレーブアドレスを確認できなかった場合、データ受信できなかった場合、アクノレッジ・クロック・パルスに対してSDAラインを解放する• アクノレッジ

2016/11/18

SDAラインに出力されるバイトの長さは8ビットで、一回の転送に伝達できるバイト数には制限がない。各バイトの後ろにはアクノレッジ・ビットであり、データは最上位ビット(MSB)から順に送信する

ET2016ハードウェアトラック

12

I2C通信（１）：接続例• I2C(Inter-Integrated Circuit)は周辺デバイスとのシリアル通信方式
VddMaster

Slave 1

SCL

SCL

SDA

SDA
Slave 2SCL

100kbps or 400kbps

SDA・・・••••

クロック信号(SCL)とデータ信号(SDA)の2線で通信を実施する
各スレーブがスレーブアドレスを持ち、データの中にアドレスを含む通信を開始するのは全てマスタ側でSCLを基準にデータがSDA上で転送
スレーブアドレスが一致したデバイスのみ、送受信を継続する仕組み

2016/11/18

ET2016ハードウェアトラック

13

I2C通信（２）：マスタからスレーブへ送信の場合
スレーブアドレスが7bitの時のタイミングチャート
1-7

SCL

D7-D1

D0

Slave Address

Write（0）

SDA

1-7

8

D7-D1

D0

9・・・

LSB(最下位ビット)

MSB(最上位ビット)

Start Condition

98

ACK

Write Data

・・・

ACK

Stop Condition※赤：マスタ側、青：スレーブ側• SCLがHighの間にマスタがSDAをLowとするとStart条件になる• マスタはSCLがHighの間にSDAをHighにすることでStop条件となる（それぞれ通常のデータ時はSCLがLowの時しか変化しない）• スレーブ側はデータの取り出しが完了するまでBUSYとしてSCLを強制的にLowとすることで、見かけ上クロックがなくなるので、マスタ側は次のデータ出力を待つことになる
2016/11/18

ET2016ハードウェアトラック

14I2C通信（3）：スレーブからマスタへ受信の場合
スレーブアドレスが7bitの時のタイミングチャート
1-7SCL

D7-D1

D0

Slave Address

Read（1）

SDA

91-78

D7-D1

D0・・・

LSB

MSB

Start Condition

98

ACK

Read Data・・・

ACK

Stop Condition※赤：マスタ側、青：スレーブ側• スレーブ側からのデータ入力に応じて、マスタ側はACKを自動返信する

2016/11/18

ET2016ハードウェアトラック

15

クロックストレッチ（ウエイト）• スレーブがセンサ－などの場合、マスターへの送信で待ちを要求する場合がある• この待ちは、マスターがSCLにLow出力するタイミングで、スレーブがSCLにLow出力することによりマスターに待ちを伝達する、マスター側はSCLを入力検知しHiになるまで動作待ちを行わなければならない• マスター側にウエイト検知機能がない場合、ドライバを改造してソフト待ちを入れなければならない
SCL
マスターがLow出力

スレーブがLow出力
マスターがLow検知
2016/11/18

クロック再開ET2016ハードウェアトラック

16

1.シリアルデバイスI/F
2.Ｉ２Ｃ仕様(v2.1)
3.開発環境構築（ハード）4.開発環境構築（ソフト）
5.デバイス・ドライバ内容紹介
6.各デバイス通信ソフトウェア

3.開発環境構築（ハード）2016/11/18

ET2016ハードウェアトラック

17

PCBを作成しなくても、ソフト開発は可能• 一般的な開発では、PCB作成前のソフト開発はシミュレーション開発が主流• I2Cは低クロックのデバイス制御なので、ブレッド・ボードを活用すれはPCB作成前から本格的なソフトウェア開発が可能

STM32F401 nucleo64
1500円

Arduino Uno Rev3
2940円
2016/11/18

Prototyping Shield
1100円

Arduinoはドライバをラィブラリで提供

ET2016ハードウェアトラック

I2C DEVICE18

I2C (Prototyping) Shield• Prototyping Shieldを用いて、I2Cに対応したキャラクタLCD、温度センサー、EEPROMを配置してI2Cの評価を行う• サンプルプログラムでは、温度センサーから読み取った温度を１秒単位にLCDに表示を行う。EEPROMはreadプログラムを用意• Prototyping ShieldがD14,D15ピンに対応していないため、拡張用にI2Cのインターフェイスをもつ、 401nucleo-64,446 nucleo-64が実行対象であるが、D14,15ピンに対応しているシールドを使用すればArduinoコネクタをもつすべてのボードで対応可能

対応ボード
STM32F401 nucleo-64
STM32F446 nucleo-64

2016/11/18

ET2016ハードウェアトラック

19

NucleoとI2C (Prototyping) Shieldを接続• STM32F401 NucleoとI2C (Prototyping) Shield をドッキングして、USB接続すると、ST-LINKV2と仮想ＣＯＭが使用可能となる

2016/11/18

ET2016ハードウェアトラック

20

1.シリアルデバイスI/F
2.Ｉ２Ｃ仕様(v2.1)
3.開発環境構築（ハード）4.開発環境構築（ソフト）
5.デバイス・ドライバ内容紹介
6.各デバイス通信ソフトウェア

4.開発環境構築（ソフト）2016/11/18

ET2016ハードウェアトラック

21

ソフトウェア開発環境• ソフトウェア開発環境としてTOPPERS BASE
PLATFORMV1.1 for STM32F4xxを使用• Windows上の開発環境としてオープンソースを組み合わせた環境を使用– Bash環境としてCygwinまたはMinGW等を使用– ARMコンパイラとしてGNU-ARMを使用– RTOSはTOPPERS/ASP– STM32F401 Nucleoのデバイスドライバをオープンソースで提供• 開発環境のインストール方法は「基礎セミナーの開発環境編」に記載
2016/11/18

ET2016ハードウェアトラック

22

TOPPERS BASE PLATFORM V1.1
•ASP1.9.2上に５つのレイアでプ
ラットフォームを構築BASE PLATFROM V1.1

STM32F4xx

STM32F7xx

Devicedriver

gpio

gpio

dmadma(timer)(timer)uartuarti2c

i2c

CLCD/senser

spispi

GLCD/SDcard

adc

adc

Joy stickusb OTG

usb OTG

MSC/HID

ltdc

GLCD

Base driverStandarddriver

M7F depend
driverdetailcontents

新基礎２

Application
ManualReference Manualtprtc

Clock

sdmmc

SDcard

新基礎３
Reference Manualaudio

api
middleware

File System(Opensource)
library

2016/11/18

新基礎３

fatfs

fatfs

FAT

file library

file library

C language filestdio

stdio

STDIO

STM-BSPGUI

libjpeg

JPEGlibmadMP3ET2016ハードウェアトラック

23

シールドの組み合わせで種々の開発が可能• インターフェイス2016年12月号に紹介

TOPPERSブースでデモ中
SD-Card Player

Adafruit1.8” TFTシールド

2016/11/18

ET2016ハードウェアトラック

セミナー教材用シールド

24

ターミナル画面で、Bashコマンドでビルド• ターミナル上でデバイスドライバ＋テストプログラ
ムをビルド（asp.srecができる）これを、ダウンロード後実行

ターミナル上でビルド

2016/11/18

ROMモニタにダウンロード
実行
ET2016ハードウェアトラック

25syslog文やprintfでログ表示、テストコマンド拡張• オーソドックスなデバッグ手法– UNIX等のプログラム開発と同じ• プログラム中で変数の値を表示させたり、パスの確認のために使用• テスト用のプログラムのコマンド実行
波形測定やハードテストを用意に
ソフトサポート

2016/11/18

ET2016ハードウェアトラック

26

統合開発環境に変更が可能• b-shell(bash)ベースの開発環境となる• MakefileプロジェクトはTureSTDIOで簡単にプロジェクトとして変換できるため、統合環境化が可能

2016/11/18

ET2016ハードウェアトラック27

対応ボード一覧• TOPPERS BASE PLATFORMV1.1は６つのSTMボードに対応する• Arduinoコネクタに対応して４つのシールドに対応して、評価、実験を行うことができる。（商品として発売されるボードは２つ）• USBコネクタが付いたボードはUSB-OTGに対応して、MSCやHIDの評価、実験が可能• STM32F746 Discoveryボードでは、LCD、オーディオ、SDMMC、USB-OTGに対応している▲はD15,14ピンに接続した場合
基礎２

LCDシールド
新基礎３

I2Cシールド

BLEシールドEPCシールド
開発中

USBOTGSTM32F401RE nucleo

○

○

○

○

○

×

STM32F4 Discovery○----○STM32F746 Discovery--××○○

STM32F446RE nucleo-64

○○

○

○

○

×

STM32F446ZE nucleo-144

○

○

▲×○○

STM32F746ZG nucleo-144

○

○

▲

×

○

○

2016/11/18

ET2016ハードウェアトラック

28

1.シリアルデバイスI/F
2.Ｉ２Ｃ仕様(v2.1)
3.開発環境構築（ハード）4.開発環境構築（ソフト）
5.デバイス・ドライバ内容紹介
6.各デバイス通信ソフトウェア

5.デバイス・ドライバ内容紹介

2016/11/18

ET2016ハードウェアトラック

29テストプログラムとデバイスドライバ• テストプログラム
目的：デバイスのハードウェア機能確認のためのプログラム– すべてのハード機能が評価できるように作成する– セルフテスト設定もある• デバイスドライバ
目的：アプリからデバイスを操作するためのプログラム– アプリで使用する機能をAPIに従って操作する– システム的に高品質、高速になる機能を用いて作成– 入力、出力のパラメータ検証が必要– 問題発生時、解析ができるように作成する– RTOSやハードウェアが変わっても使用できるよう考慮する
2016/11/18

ET2016ハードウェアトラック

30

I2CドライバAPI• ポートIDよりハンドラを取出し操作• 割込みを使用するが、I/F上は隠蔽する• スレーブは通常使用しないので説明しない
関数型

引数機能

i2c_init

I2C_Handler*

ID portid
I2C_Init_t* hi2c

指定ポートIDのI2Cペリフェラルを初期化、ハンドラへのポインタを返す

i2c_deinit

ER

I2C_Handler* hi2c I2Cを未初期化状態に戻す

i2c_slavewriteER

I2C_Handler* hi2c スレーブモードのデータ送
uint8_t* pData
信uint16_t Sizei2c_slavereadER

I2C_Handler* hi2c スレーブモードのデータ受
uint8_t* pData
信uint16_t Size

2016/11/18

ET2016ハードウェアトラック

31

I2CドライバAPI• デバイスにより、アドレスを指定するものとしないものがある。MemAddSizeの設定により両方のシーケンスをサポートする
関数名型

引数機能

i2c_memwriteER

I2C_Handler* hi2c
uint16_t DevAddr
uint16_t MemAddr
uint16_t MemAddSize
uint8_t* pData
uint16_t Size

マスターモードのデータ送信、
MemAddSizeにゼロを設定するとアドレス設定を行わな
いi2c_memreadER

I2C_Handler* hi2c
uint16_t DevAddr
uint16_t MemAddr
uint16_t MemAddSize
uint8_t* pData
uint16_t Size

マスターモードのデータ受信、
MemAddSizeにゼロを設定するとアドレス設定を行わない2016/11/18

ET2016ハードウェアトラック

32

I2C：マスター送信ドライバ（１）• ドライバの型はμITRON仕様に従いER型を使用している• パラメータエラーはE_PAR、状態エラーはE_OBJとしている
ER
i2c_memwrite(I2C_Handle_t *hi2c, uint16_t DevAddress, uint16_t MemAddress,uint16_t MemAddSize, uint8_t *pData, uint16_t Size){パラメータのデータ
ER ercd = E_OK;
チェック
if(pData == NULL || Size == 0)
return E_PAR;if(hi2c->Init.AddressingMode != I2C_ADDRESSINGMODE_7BIT && MemAddSize != 0)
return E_PAR;if(hi2c->status != I2C_STATUS_READY)
return E_OBJ;
if(i2c_busreadywait(hi2c, I2C_TIMEOUT_BUSY_FLAG) != E_OK)
ハンドラ毎にセマフォでreturn E_OBJ;
排他制御を設定/** 書き込みロック*/
if(hi2c->Init.semlock != 0)
wai_sem(hi2c->Init.semlock);

2016/11/18

ET2016ハードウェアトラック

33

I2C：マスター送信ドライバ（２）/** Acknowledge/PEC Position禁止*/
sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), I2C_CR1_POS);
ハンドラに通信データ
hi2c->status = I2C_STATUS_BUSY_TX;
をセットするhi2c->ErrorCode = I2C_ERROR_NONE;
割込み内で参照
hi2c->pBuffPtr = pData;hi2c->XferSize = Size;
hi2c->XferCount = Size;/* スレーブアドレスと書込みアドレスの設定 */if((ercd = i2c_masterwriteaddress(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG)) != E_OK){if(hi2c->Init.semlock != 0)
次のページのsig_sem(hi2c->Init.semlock);
スレーブアドレスとreturn ercd;サブルーチンへ}
デバイスアドレスを/*セットする* 書き込み割込み許可*/
sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), (I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN | I2C_CR2_ITERREN));
ercd = i2c_transwait(hi2c, 500);/*
割込み設定とデータの転送は* 書き込みロック解除
終了待ち
割込みサービス*/
ルーチンで（３if(hi2c->Init.semlock != 0)
sig_sem(hi2c->Init.semlock);ページ先）
排他制御解除return ercd;}2016/11/18

ET2016ハードウェアトラック

34

I2C：マスター送信ドライバ（３）• スレーブアドレスとデバイスアドレスを設定する関数として使用するi2c_mesaterwriteaddressを解説する

static ER
i2c_masterwriteaddress(I2C_Handle_t *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout){
ER ercd = E_OK;/** スタート設定と設定待ち*/
スタート状態設定
sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), I2C_CR1_START);if(i2c_sr1flagsetwait(hi2c, I2C_SR1_SB, Timeout) != E_OK){
return E_TMOUT;}/*
７ビットスレーブ* デバイスアドレス設定と設定待ち*/
アドレス設定if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT){
sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_DR), I2C_7BIT_ADD_WRITE(DevAddress));}

2016/11/18

ET2016ハードウェアトラック

35

I2C：マスター送信ドライバ（４）else{
sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_DR), I2C_10BIT_HEADWRITE(DevAddress));if((ercd = i2c_addrflagwait(hi2c, I2C_SR1_ADD10, Timeout)) != E_OK){
return ercd;}
１０ビットスレーブ/*
アドレス設定* 10ビットアドレス設定と設定待ち*/
sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_DR), I2C_10BIT_ADDRESS(DevAddress));}/** アドレスフラグ設定待ち
スレーブアドレス設定*/
終了待ち
if((ercd = i2c_addrflagwait(hi2c, I2C_SR1_ADDR, Timeout)) != E_OK){
return ercd;}/** アドレスフラグクリア*/
アドレス設定クリア
i2c_clear_addr(hi2c);/** メモリアドレス設定なしなら正常終了
デバイスアドレスを設定*/
if(MemAddSize == 0)
しない場合はここで終了
return E_OK;

2016/11/18

ET2016ハードウェアトラック

36

I2C：マスター送信ドライバ（５）• デバイスアドレスがある場合は８ビット、または、１６ビットのデバイスアドレスをセットする/** TXEフラグ設定まで待ち
送信終了待ち*/if(i2c_sr1flagsetwait(hi2c, I2C_SR1_TXE, Timeout) != E_OK){
return E_TMOUT;}/*
デバイスアドレスを設定* メモリアドレス設定と設定待ち*/
if(MemAddSize == I2C_MEMADD_SIZE_8BIT){
sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_DR), I2C_MEM_ADD_LSB(MemAddress));}else{/* 16ビットケース */sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_DR), I2C_MEM_ADD_MSB(MemAddress));
if(i2c_sr1flagsetwait(hi2c, I2C_SR1_TXE, Timeout) != E_OK){
return E_TMOUT;}
sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_DR), I2C_MEM_ADD_LSB(MemAddress));}
return E_OK;}

2016/11/18

ET2016ハードウェアトラック

37

I2C:割込みハンドラ（１）• 送信の場合は、スレーブアドレスまたはデバイスアドレス
転送終了後TXE割込みが発生し、割込み中で転送デー
タ設定を行うvoid
i2c_ev_handler(I2C_Handle_t *hi2c){
uint32_t sr1 = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_SR1));
uint32_t sr2 = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_SR2));
uint32_t cr2 = sil_rew_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2));
volatile uint32_t tmp;/*
* マスターモード
データ送信*/
サブルーチンif((sr2 & I2C_SR2_MSL) != 0){if((sr2 & I2C_SR2_TRA) != 0){/* 送信モード */if(((sr1 & I2C_SR1_TXE) != 0) && ((cr2 & I2C_CR2_ITBUFEN) != 0) && ((sr1 & I2C_SR1_BTF) == 0)){i2C_MasterTransmit_TXE(hi2c);}
else if(((sr1 & I2C_SR1_BTF) != 0) && ((cr2 & I2C_CR2_ITEVTEN) != 0)){i2c_mastertrans_BTF(hi2c);
データ送信終了処理}
サブルーチン}else{/* 受信モード */2016/11/18

ET2016ハードウェアトラック38

I2C:割込みハンドラ（２）static voidi2C_MasterTransmit_TXE(I2C_Handle_t *hi2c){/* １バイト送信 */sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_DR), (uint32_t)(*hi2c->pBuffPtr++));
hi2c->XferCount--;if(hi2c->XferCount == 0){ /* 停止 */sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2), I2C_CR2_ITBUFEN);}

送信エンプティ
割込み
１バイトづつデータ送信}
static voidi2c_mastertrans_BTF(I2C_Handle_t *hi2c)
転送終了
{
割込み
if(hi2c->XferCount != 0){ /* データ送信 */sil_wrw_mem((uint32_t *)(hi2c->base+TOFF_I2C_DR), (uint32_t)(*hi2c->pBuffPtr++));
hi2c->XferCount--;
データ送信}
フェールセーフelse{/* 送信終了 */sil_andw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR2),(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN | I2C_CR2_ITERREN));
sil_orw_mem((uint32_t *)(hi2c->base+TOFF_I2C_CR1), I2C_CR1_STOP);
hi2c->status = I2C_STATUS_READY;
if(hi2c->writecallback != NULL)
データ送信要求リセット
hi2c->writecallback(hi2c);
ストップ条件設定}}

2016/11/18

ET2016ハードウェアトラック39

1.シリアルデバイスI/F
2.Ｉ２Ｃ仕様(v2.1)
3.開発環境構築（ハード）4.開発環境構築（ソフト）
5.デバイス・ドライバ内容紹介
6.各デバイス通信ソフトウェア

6.各デバイス通信ソフトウェア

2016/11/18

ET2016ハードウェアトラック

40

デバイス通信プロトコル• I2Cは制御やデータの通信路であり、デバイス毎に通信手順やデータは異なる• ここでは、IoT関連ということで、温度センサー：
ADT7410との通信について解説する• ADT7410は14個のレジスタをもち、I2C通信を用いてレジスタアクセスが可能であるレジスタへの書込みは、1バイトアドレス指定I2C送信を使う
レジスタの読込みは、1バイトアドレス指定I2C受信を使う

2016/11/18

ET2016ハードウェアトラック

41

ADT7410レジスタアクセス• ADT7410のレジスタはEEPROMと同様に１バイトのアドレス指定、READ/WRITEでアクセス可能である• 最低限のアクセスとして、レジスタ２が状態値、レジスタ０，１がハイ、ローの温度値となる
ステータスレジスタのビット７がREADYビットとなるため、READYを待って温度を取得

2016/11/18ET2016ハードウェアトラック

42温度値の取得• 温度はレジスタ０、１から取得：２つのレジスタを合わせた16値のうち、B14-B4までが、0.0625単位の度数となる。小数点１桁の度数を取り出すには
小数点１桁の温度=

2016/11/18

レジスタ０：１×18ET2016ハードウェアトラック

×625
1000＝

112.843≒113温度センサーREADY待ち
void main_task(intptr_t exinf){
I2C_Init_t i2c_initd;
I2C_Handle_t *hi2c;
ER_UINT
ercd;
i2c_initd.ClockSpeed= 100000;i2c_initd.DutyCycle= I2C_DUTYCYCLE_16_9;i2c_initd.AddressingMode = I2C_ADDRESSINGMODE_7BIT;I2Cドライバの初期化
i2c_initd.DualAddressMode = I2C_DUALADDRESS_DISABLE;i2c_initd.GeneralCallMode = I2C_GENERALCALL_DISABLE;i2c_initd.NoStretchMode = I2C_NOSTRETCH_DISABLE;i2c_initd.OwnAddress1 = 0;i2c_initd.OwnAddress2 = 0;i2c_initd.semid= I2CTRS_SEM;
i2c_initd.semlock= I2CLOC_SEM;
レジスタ2からデータ読み取り
if((hi2c = i2c_init(I2C_PORTID, &i2c_initd)) == NULL){I2Cアドレス２指定受信
syslog_0(LOG_ERROR, "## I2C ERROR(1) ##");}do{if(i2c_memread(hi2c, (uint16_t)ADT7410_ADDR, 0x02, 1, (uint8_t*)aRxBuffer, 1)!= E_OK){
syslog_1(LOG_ERROR, "## I2C ERROR(13)[%08x] ##", hi2c->ErrorCode);
return;}ADT7410のREADY待ち
if(I2C_TransWait(hi2c, 500) != E_OK)
return;temp = aRxBuffer[0];}while((temp & 0x80) != 0);

2016/11/18

ET2016ハードウェアトラック44温度データ取得• 温度データを取出し、小数点１桁の温度データへ
while(count < 1000){if(i2c_memread(hi2c, (uint16_t)ADT7410_ADDR, 0x00, 1, (uint8_t*)aRxBuffer, 1)!= E_OK){/* I2C RECEIVE ERROR */syslog_1(LOG_ERROR, "## I2C ERROR(14)[%08x] ##", hi2c->ErrorCode);
return;}
レジスタ0を取出し、tempのb15-b8にセット
if(I2C_TransWait(hi2c, 500) != E_OK)
I2Cアドレス０指定受信
return;temp = aRxBuffer[0] << 8;if(i2c_memread(hi2c, (uint16_t)ADT7410_ADDR, 0x01, 1, (uint8_t*)aRxBuffer, 1)!= E_OK){/* I2C RECEIVE ERROR */syslog_1(LOG_ERROR, "## I2C ERROR(15)[%08x] ##", hi2c->ErrorCode);
return;}
レジスタ1を取出し、tempのb7-b4にセット
if(I2C_TransWait(hi2c, 500) != E_OK)
I2Cアドレス１指定受信return;temp += aRxBuffer[0];temp /= 13;

2016/11/18

ET2016ハードウェアトラック

45

まとめ
• シリアル通信のデバイスが入手できるようになった– 接点が少なく、小規模設計が可能• I2Cは複数デバイスをバス結合できるので、さらに優位• クロックが低速なため、DIPでも十分動作– PCBを作らなくても、ドライバソフト開発、評価が可能• TOPPERS BASE PLATFORMのような、ソフトウェアプラットフォームを活用すれば、ソースコードを参考にしながら、デバイスドライバ開発、テスト環境開発が可能
2016/11/18

ET2016ハードウェアトラック

46

参考文献

• I2Cバス仕様書 バージョン2.1
Philips Semiconductors• ATD7410 Data Sheet
ANALOG DEVICES• TOPPERS BASE PLATFORM
リファレンス・マニュアル
TOPPERSプロジェクト 教育WG

• TOPPERSハードウェア設計セミナーテキスト

2016/11/18

ET2016ハードウェアトラック

47