BCM2835ライブラリ その5 [Raspberry Pi]
BCM2835ライブラリの日本語解説の続き。今日はこのライブラリで使える関数にどんなものがあるかざっくり見る。
ライブラリの初期化を同じプロセスから2度したらどうなるか、あるいはあるプロセスがライブラリを初期化して、閉じる前に別のプロセスが初期化するとどうなるか、などは確認してないが、使うときはその辺りを確認してから(あるいはソースを見て)のほうがいいかもしれない。
GPIOを使いたいだけなら、これらの関数を呼ぶ必要はないはずである。
また、ピンやモード、マスクの指定にはRaspberry Piの機種に依存しない定数が定義されているので、それを使うべきである。
1バイトをやりとりする関数と複数バイトをバッファ経由でやりとりする関数があるが、spiの規格では単一バイトを複数回送るのとは意味が違うからである。コマンドに複数バイトを使うデバイスをつないだときは、バッファ経由の関数を使わないといけない。
3 利用可能な関数
ここで紹介されている関数をざっくりみる。定義済み定数は直接見るのと変わらないのでここではとりあげないけど、使える関数が頭に入ったあとに一通り眺めておいたほうがいい。3.1 初期化
int bcm2835_init (void); int bcm2835_close (void); void bcm2835_set_debug (uint8_t debug); unsigned int bcm2835_version (void);ライブラリの初期化と解放。デバグというのは引数に1を渡すと物理メモリへのアクセスをやめてアクセスがあったら情報をプリントするというもの。これは初期化の前に呼ばないといけない。
ライブラリの初期化を同じプロセスから2度したらどうなるか、あるいはあるプロセスがライブラリを初期化して、閉じる前に別のプロセスが初期化するとどうなるか、などは確認してないが、使うときはその辺りを確認してから(あるいはソースを見て)のほうがいいかもしれない。
3.2 低レベルのレジスタアクセス
uint32_t *bcm2835_regbase (uint8_t regbase); uint32_t bcm2835_peri_read (volatile uint32_t *paddr); uint32_t bcm2835_peri_read_nb (volatile uint32_t *paddr); void bcm2835_peri_write (volatile uint32_t *paddr, uint32_t value); void bcm2835_peri_write_nb (volatile uint32_t *paddr, uint32_t value); void bcm2835_peri_set_bits (volatile uint32_t *paddr, uint32_t value, uint32_t mask);やることは名前から想像できる。nbのついた関数はno barrierで、つまり排他制御をしない、ということらしい。逆にnbのない関数は排他的にメモリアクセスする、ということで別スレッドや別プロセスが物理メモリ領域をアクセスする可能性がある場合にはnbなしを使え、ということだろう。
GPIOを使いたいだけなら、これらの関数を呼ぶ必要はないはずである。
3.3 GPIOレジスタアクセス
void bcm2835_gpio_fsel (uint8_t pin, uint8_t mode); void bcm2835_gpio_set (uint8_t pin); void bcm2835_gpio_clr (uint8_t pin); void bcm2835_gpio_set_multi (uint32_t mask); void bcm2835_gpio_clr_multi (uint32_t mask); uint8_t bcm2835_gpio_lev (uint8_t pin); uint8_t bcm2835_gpio_eds (uint8_t pin); void bcm2835_gpio_set_eds (uint8_t pin); void bcm2835_gpio_ren (uint8_t pin); void bcm2835_gpio_clr_ren (uint8_t pin); void bcm2835_gpio_fen (uint8_t pin); void bcm2835_gpio_clr_fen (uint8_t pin); void bcm2835_gpio_hen (uint8_t pin); void bcm2835_gpio_clr_hen (uint8_t pin); void bcm2835_gpio_len (uint8_t pin); void bcm2835_gpio_clr_len (uint8_t pin); void bcm2835_gpio_aren (uint8_t pin); void bcm2835_gpio_clr_aren (uint8_t pin); void bcm2835_gpio_afen (uint8_t pin); void bcm2835_gpio_clr_afen (uint8_t pin); void bcm2835_gpio_pud (uint8_t pud); void bcm2835_gpio_pudclk (uint8_t pin, uint8_t on); uint32_t bcm2835_gpio_pad (uint8_t group); void bcm2835_gpio_set_pad (uint8_t group, uint32_t control); void bcm2835_delay (unsigned int millis); void bcm2835_delayMicroseconds (uint64_t micros); void bcm2835_gpio_write (uint8_t pin, uint8_t on); void bcm2835_gpio_write_multi (uint32_t mask, uint8_t on); void bcm2835_gpio_write_mask (uint32_t value, uint32_t mask); void bcm2835_gpio_set_pud (uint8_t pin, uint8_t pud);名前だけではわかりにくいのを簡単に解説すると
- fselはFunction Selectでピンに対して入出力、あるいはALT機能を設定する
- levはlevelでピンの状態を読む
- ピンのプルアップ、プルダウンを指定する
- edsのついた関数は指定したピンにイベントが発生したるかどうかチェックする
- イベントというのは変化があったかどうかで、hen、len、ren、fenがそれぞれHIGH、LOW、0→1エッジ、1→0エッジである
- afenのついた関数はAsynchronous Falling Edge Detect Enableの略らしい。1→0のエッジを検出するとイベントが発生するが、システムクロックでサンプルするのではないので、短いパルスでも検出できると書いてある
- arenはAsynchronous Rising Edge Detect Enableでafenのエッジが逆
また、ピンやモード、マスクの指定にはRaspberry Piの機種に依存しない定数が定義されているので、それを使うべきである。
3.4 SPI
void bcm2835_spi_begin (void); void bcm2835_spi_end (void); void bcm2835_spi_setBitOrder (uint8_t order); void bcm2835_spi_setClockDivider (uint16_t divider); void bcm2835_spi_setDataMode (uint8_t mode); void bcm2835_spi_chipSelect (uint8_t cs); void bcm2835_spi_setChipSelectPolarity (uint8_t cs, uint8_t active); uint8_t bcm2835_spi_transfer (uint8_t value); void bcm2835_spi_transfernb (char *tbuf, char *rbuf, uint32_t len); void bcm2835_spi_transfern (char *buf, uint32_t len); void bcm2835_spi_writenb (char *buf, uint32_t len);beginでピンがSPI用に、つまりALT0に設定される。transferというのがSPIの仕様に従ってチップセレクトを指定してMOSIにデータを乗せてMISOのデータを読み込む、という一連の動作をする。あとは読んで字の如し。
1バイトをやりとりする関数と複数バイトをバッファ経由でやりとりする関数があるが、spiの規格では単一バイトを複数回送るのとは意味が違うからである。コマンドに複数バイトを使うデバイスをつないだときは、バッファ経由の関数を使わないといけない。
3.5 I2C
void bcm2835_i2c_begin (void); void bcm2835_i2c_end (void); void bcm2835_i2c_setSlaveAddress (uint8_t addr); void bcm2835_i2c_setClockDivider (uint16_t divider); void bcm2835_i2c_set_baudrate (uint32_t baudrate); uint8_t bcm2835_i2c_write (const char *buf, uint32_t len); uint8_t bcm2835_i2c_read (char *buf, uint32_t len); uint8_t bcm2835_i2c_read_register_rs (char *regaddr, char *buf, uint32_t len); uint8_t bcm2835_i2c_write_read_rs (char *cmds, uint32_t cmds_len, char *buf, uint32_t buf_len);I2Cについても考え方は同じ。
3.6 システムタイマアクセス
uint64_t bcm2835_st_read (void); void bcm2835_st_delay (uint64_t offset_micros, uint64_t micros);まんま。
3.7 PWM
void bcm2835_pwm_set_clock (uint32_t divisor); void bcm2835_pwm_set_mode (uint8_t channel, uint8_t markspace, uint8_t enabled); void bcm2835_pwm_set_range (uint8_t channel, uint32_t range); void bcm2835_pwm_set_data (uint8_t channel, uint32_t data);PWM関数を使う前に
void bcm2835_gpio_fsel (uint8_t pin, uint8_t mode);を使ってALT機能を設定しておく必要がある。あとはmodeでenabledを立てればパルスが出る。
2015-08-30 20:27
nice!(0)
コメント(0)
トラックバック(0)
コメント 0