**概要 [#va21cbfb] [[DXMIO>DXMIO]]に搭載されたLPC824のペリフェラルを応用したライブラリ集です。~ GCC Developer Liteにはほとんどの各マイコンボード用にGPIOやシリアル通信に関する簡単なライブラリが含まれていますが、それ以外のペリフェラル等を活用するとなるとゼロからプログラムしなくてはなりません。その場合、プログラムコードの大半がそれらの初期化ルーチンや制御ルーチンで埋め尽くされ、1つのソースコードの編集しか許容していないGCC Developer Liteでは大きな負担となります。~ もちろんGCC Develoer Liteにこだわらなければ、その他の便利な開発環境を使用する事で、標準で提供されるペリフェラルライブラリが使えたり、複数ソースのコンパイルや編集が可能です。~ とはいえ常時複数のソースプログラムを編集するのは大変ですし、最終的には改変を行うソースプログラムは集約されて行きますので、GCC Developer Liteとしてももう少しライブラリを拡充しようと言うことで用意しました。~ なお、機能がかなり偏っていますが、 -ソース上では抽象的に記述したいが、ペリフェラルを制御する上での解釈が面倒 -コードサイズが肥大化しがちな処理ルーチン -使われていないリソースを活用 -Dynamixelの通信機能を活用 といった観点で選択しています。要望によっては拡充されたりる可能性もありますし、多勢に無勢なところで記述方法等が変わる事は十分ありますので、予めご了承ください。 **API [#ybae1454] 機能別にAPIの詳細を解説します。主なコンテンツを以下に紹介します。 -[[FreeRTOS>#uc14acff]]~ FreeRTOS関連。 -[[ディレイ>#zedbb449]]~ 正確な時間待ちや経過時間計測。できるだけ使用頻度の低いMPUのリソースを使用。 -[[CRCチェックサム>#i0bff965]]~ Dynamixel V.2プロトコルで使用されるチェックサム。 -[[内蔵フラッシュ>#k264c73f]]~ マイコンに内蔵されたフラッシュメモリの書き換え。 -[[I2C>#e900926e]]~ 外部のI2C対応デバイスとの通信。 -[[SPI>#g2fae75f]]~ 外部のSPI対応デバイスとの通信。 -[[Dynamixel V.1ホスト>#y6cc2b6f]]~ 外部のDynamixelシリーズと通信。要FreeRTOS。 -[[Dynamixel V.1クライアント>#s17315d5]]~ マイコンボード自体をDynamixelシリーズの様にクライアントとして機能。要FreeRTOS。 それ以外に処理系に依存しにくい体裁として、変数型の宣言の際は概ね以下を使用する事とします。 -int8_t -uint8_t -int16_t -uint16_t -int32_t -uint32_t ***FreeRTOS [#uc14acff] FreeRTOSをCortex-M0コア用としてコンパイル及びライブラリ化し「TARGET/FREERTOS_CM0」フォルダに収録しています。必要に応じて同梱の「FreeRTOSConfig.h」を編集してライブラリを再構築する事もできます。~ FreeRTOS自体は自信のプログラムの状態にかかわらず自由にリンクして使う事ができますので、OSが必要になった段階で適用の可否を判断したとしても影響が過大になることは少ないでしょう。~ 詳細は[[FreeRTOSのサイト>http://www.freertos.org/]]に委ねます。 ***ディレイ [#zedbb449] 正確な時間を元に時間待ちや経過時間を計測します。元となるクロックはMRT(Multi-Rate Timer)を使用しているため、各APIを定期的にコールする際は67秒以内(2147483647/32MHz)に行う必要があります。 ****Delay_us [#o27b86b3] マイクロ秒単位の時間待ちを行う。 void Delay_us (uint32_t *mydelaybuf, uint32_t us); -パラメータ --uint32_t *'''mydelaybuf''' ~API内で使用されるカウンタ情報のポインタ~ APIが初回に呼び出される際は変数は必ず0に初期化しておく必要がある --uint32_t '''us''' ~時間待ちする時間 -戻り値 ~なし~ -使用例 #html{{ <pre class="brush: c;"> #include <wl_delay.h> int main (void) { uint32_t t = 0; while (1) { Delay_us (&t, 2000); } } </pre> }} ****Delay_ms [#ye3400d5] ミリ秒単位の時間待ちを行う。 void Delay_ms (uint32_t *mydelaybuf, uint32_t ms); -パラメータ --uint32_t *'''mydelaybuf''' ~API内で使用されるカウンタ情報のポインタ~ APIが初回に呼び出される際は変数は必ず0に初期化しておく必要がある --uint32_t '''ms''' ~時間待ちする時間 -戻り値 ~なし~ -使用例 #html{{ <pre class="brush: c;"> #include <wl_delay.h> int main (void) { uint32_t t = 0; while (1) { Delay_ms (&t, 1000); } } </pre> }} ****Delay_GetTick [#ta6cc319] 本APIが始めて呼び出されてからの経過時間をミリ秒で返す。 uint32_t Delay_GetTick (uint32_t *mytickbuf); -パラメータ --uint32_t *'''mytickbuf''' ~API内で使用されるカウンタ情報のポインタ~ APIが初回に呼び出される際は変数は必ず0に初期化しておく必要がある -戻り値 ~経過時間~ -使用例 #html{{ <pre class="brush: c;"> #include <wl_delay.h> void delay (uint32_t ms) { uint32_t t = 0, target; target = Delay_GetTick (&tt) + ms; while (target > Delay_GetTick (&t)) ; } int main (void) { while (1) { delay (1000); } } </pre> }} ****Delay_csw [#rd28843e] API内の時間待ちの間に呼び出されるコールバックルーチンへのポインタを指定。~ デフォルトはNULLが指定されているため呼び出されない。 void (*Delay_csw) (void); ***CRCチェックサム [#i0bff965] X^16+X^15+X^2+1の多項式に限定した16ビット幅のチェックサムを算出します。DynamixelプロトコルV2に使用されるチェックサムを目的としているため、それ以外のCRCを算出する用途には使えません。~ なお、APIの引数に応じて内蔵ペリフェラルもしくはソフトウェアによるCRCの算出が選択されます。~ また、CRCを算出する対象データの指定方法を複数用意しているのは、長大なデータが指定された場合の無駄なループ時間を削減する事が目的ですので、通常は CRC_Write か CRC_Writes で十分です。 ****CRC_Init [#le5c5ca8] CRCの計算に必要な事前処理を行う。 void CRC_Init (void); -パラメータ ~なし -戻り値 ~なし ****CRC_SetSeed [#x02d7f5e] CRCの初期値を設定する。 void CRC_SetSeed (uint16_t *pCRC, uint16_t d); -パラメータ --uint16_t *'''pCRC''' ~CRCの計算結果を保存する変数のポインタ。~ NULLを指定するとペリフェラルを使用した計算とみなす。 --uint16_t '''d''' ~CRCの初期値~ -戻り値 ~なし ****CRC_Write [#o40f7223] 指定1バイトのCRCを算出する。 void CRC_Write (uint16_t *pCRC, uint8_t d); -パラメータ --uint16_t *'''pCRC''' ~CRCの計算結果を保存する変数のポインタ。~ NULLを指定するとペリフェラルを使用した計算とみなす。 --uint8_t '''d''' ~CRCを計算する対象データ -戻り値 ~なし ****CRC_Writes [#u4cb3db5] 指定バイト数のCRCを算出する。 void CRC_Writes (uint16_t *pCRC, uint8_t *src, uint16_t len); -パラメータ --uint16_t *'''pCRC''' ~CRCの計算結果を保存する変数のポインタ。~ NULLを指定するとペリフェラルを使用した計算とみなす。 --uint8_t *'''src''' ~CRCを計算する対象データのポインタ --uint16_t '''len''' ~CRCを計算する対象データのバイト数 -戻り値 ~なし ****CRC_Writes2 [#l6898efe] 指定バイト数のCRCを算出しながらデータをコピーする。 void CRC_Writes2 (uint16_t *pCRC, uint8_t *dest, uint8_t *src, uint16_t len); -パラメータ --uint16_t *'''pCRC''' ~CRCの計算結果を保存する変数のポインタ。~ NULLを指定するとペリフェラルを使用した計算とみなす。 --uint8_t *'''dest''' ~srcのコピー先のポインタ --uint8_t *'''src''' ~CRCを計算する対象データのポインタ --uint16_t '''len''' ~CRCを計算する対象データのバイト数 -戻り値 ~なし ****CRC_Writes3 [#sf65d945] コールバックルーチンを呼び出しながら指定バイト数のCRCを算出する。 void CRC_Writes3 (uint16_t *pCRC, uint8_t (*pf) (uint8_t), uint8_t *src, uint16_t len); -パラメータ --uint16_t *'''pCRC''' ~CRCの計算結果を保存する変数のポインタ。~ NULLを指定するとペリフェラルを使用した計算とみなす。 --uint8_t (*'''pf''') (uint8_t) ~コールバックルーチンのポインタ --uint8_t *'''src''' ~CRCを計算する対象データ --uint16_t '''len''' ~CRCを計算する対象データのバイト数 -戻り値 ~なし ****CRC_Get [#qa44eba5] 算出したCRCを取得する。~ なお、ソフトウェアによる算出を選択している場合は、本APIを使用せずとも変数にCRCが保存されている。 uint16_t CRC_Get (uint16_t *pCRC); -使用例 #html{{ <pre class="brush: c;"> #include <wl_crc.h> uint8_t data[] = {0,1,2,3,4,5,6,7,8,9}; uint16_t crc_hard (void) { CRC_SetSeed (NULL, 0); CRC_Writes (NULL, dat, sizeof (dat)); return CRC_Get (NULL); } uint16_t crc_soft (void) { uint16_t crc; CRC_SetSeed (&crc, 0); CRC_Writes (&crc, dat, sizeof (dat)); return CRC_Get (&crc); } int main (void) { CRC_Init (); crc1 (); crc2 (); } </pre> }} ***内蔵フラッシュ [#k264c73f] ****FLASH_Init [#g1e801f9] ペリフェラルの初期化。 void FLASH_Init (void); ****FLASH_Write [#q20989cf] 指定されたフラッシュのアドレスへ指定されたバイト数のデータを書き込む。~ なお、コードが書き込まれた領域を侵さないアドレスを指定しなくてはならないが、本APIではそれらを判断しないまま消去及び書き込み処理を行う。 bool FLASH_Write (uint32_t destaddr, uint8_t *dat8, uint32_t DataLengthByte); ***I2C [#e900926e] ***SPI [#g2fae75f] ***Dynamixel V.1ホスト [#y6cc2b6f] 本APIを使用する事でマイコンから直接アクチュエータが制御できます。 ****DX_OpenPort [#qc5d9135] MPUのペリフェラルを初期化し、デバイスと通信できるようにする。 TDeviceID DX_OpenPort (const TDX_UsartFunc *us, uint32_t baud); -パラメータ~ --const TDX_UsartFunc *'''us''' --uint32_t '''baud''' typedef struct { uint8_t *txbuff; uint32_t txbufflength; uint8_t *rxbuff; uint32_t rxbufflength; uint32_t (*init) (uint32_t baudrate, uint8_t *txbuf, uint16_t txl, uint8_t *rxbuf, uint16_t rxl); uint32_t (*setbaudrate) (uint32_t); uint16_t (*rx_buff) (void); void (*rx_purge) (void); int (*putsb) (const uint8_t *, int); char (*getch) (void); } TDX_UsartFunc; ****DX_ClosePort [#v55bdc69] 宣言のみで使用できない。 bool DX_ClosePort (TDeviceID dvid); ****DX_SetBaudrate [#pcf9495d] ホストのボーレートを変更する。 bool DX_SetBaudrate (TDeviceID dvid, uint32_t baud); ****DX_Active [#g2528f89] ホストの通信機能が使用できるかを判断する。 bool DX_Active (TDeviceID dvid); ****DX_SetTimeOutOffset [#e6714aa4] デバイスからの応答の待ち時間のオフセット時間を指定。 void DX_SetTimeOutOffset (TDeviceID dvid, uint32_t t); ****DX_TxPacket [#f5834acf] 任意のインストラクションパケットを送信する。~ コントロールテーブルを読み書きするAPIではサポートしていないパケットを送信する際に使用する事を目的としているため、不用意な使用は禁物。 bool DX_TxPacket (TDeviceID dvid, uint8_t id, TDXInstruction inst, uint8_t *param, uint32_t len, TDXErrCode *err); ****DX_RxPacket [#k267f5b1] ステータスパケットを受信する。~ コントロールテーブルを読み書きするAPIではサポートしていないパケットを送信した際にステータスパケットを受信する事を目的としているため、不用意な使用は禁物。 bool DX_RxPacket (TDeviceID dvid, uint8_t *rdata, uint32_t rdatasize, uint32_t *rlen, uint32_t timeout, TDXErrCode *err); ****DX_ReadBlockData [#b63fc912] bool DX_ReadBlockData (TDeviceID dvid, uint8_t id, uint16_t adr, uint8_t *rdata, uint32_t len, TDXErrCode *err); ****DX_ReadByteData [#o94606c9] 指定されたID・アドレスから1バイトの情報を読み出す。~ bool DX_ReadByteData (TDeviceID dvid, uint8_t id, uint16_t adr, uint8_t *rdata, TDXErrCode *err) { ****DX_ReadWordData [#p29180cd] 指定されたID・アドレスから2バイトの情報を読み出す。~ bool DX_ReadWordData (TDeviceID dvid, uint8_t id, uint16_t adr, uint16_t *rdata, TDXErrCode *err) { ****DX_ReadLongData [#o299bc6a] 指定されたID・アドレスから4バイトの情報を読み出す。~ bool DX_ReadLongData (TDeviceID dvid, uint8_t id, uint16_t adr, uint32_t *rdata, TDXErrCode *err) { ****DX_WriteBlockData [#e0c7f55d] bool DX_WriteBlockData (TDeviceID dvid, uint8_t id, uint16_t adr, uint8_t *dat, uint32_t len, TDXErrCode *err); ****DX_WriteByteData [#sb237648] 指定されたID・アドレスへ1バイトの情報を書き込む。~ bool DX_WriteByteData (TDeviceID dvid, uint8_t id, uint16_t adr, uint8_t dat, TDXErrCode *err) { ****DX_WriteWordData [#sac477e6] 指定されたID・アドレスへ2バイトの情報を書き込む。~ bool DX_WriteWordData (TDeviceID dvid, uint8_t id, uint16_t adr, uint16_t dat, TDXErrCode *err) { ****DX_WriteLongData [#eec903c0] 指定されたID・アドレスへ4バイトの情報を書き込む。~ bool DX_WriteLongData (TDeviceID dvid, uint8_t id, uint16_t adr, uint32_t dat, TDXErrCode *err) { ****DX_ReadSyncData [#a7e72fb2] bool DX_ReadSyncData (TDeviceID dvid, uint8_t *dat, uint32_t size, uint8_t *retdat, TDXErrCode *err); ****DX_WriteSyncData [#l1b6d662] bool DX_WriteSyncData (TDeviceID dvid, uint8_t addr, uint16_t isize, uint8_t *dat, uint32_t size, TDXErrCode *err); ****DX_Ping [#cafa9999] bool DX_Ping (TDeviceID dvid, uint8_t id, TDXErrCode *err); ****DX_Ping2 [#wdc57187] bool DX_Ping2 (TDeviceID dvid, uint32_t *num, TDXAlarmStatus *AlarmStatus, TDXErrCode *err); ****DX_Reset [#wb4237c7] bool DX_Reset (TDeviceID dvid, uint8_t id, TDXErrCode *err); ***Dynamixel V.1クライアント [#s17315d5] ****DX_Config [#sc3f2057] コントロールテーブルの定義・基本シリアル通信API・各イベントにおけるコールバックルーチンを指定し、クライアント機能の初期設定を行う。~ bool DX_Config (TDX_ConfParam *pDX_ConfParam); -パラメータ~ TDX_ConfParam *'''pDX_ConfParam'''~ typedef struct { struct { void *MemDefault; uint16_t CtrlTableSize; void (*wdt_feed) (void); void (*sys_reset) (void); uint32_t nvm_address; uint32_t nvm_size; } sys; struct { uint32_t (*us_init) (uint32_t); void (*us_deinit) (void); uint32_t (*us_setbaudrate) (uint32_t); uint16_t (*us_tx_buff) (void); uint16_t (*us_rx_buff) (void); void (*us_tx_purge) (void); void (*us_rx_purge) (void); int (*us_putsb) (const uint8_t *, int); char (*us_getc) (void); } us; struct { bool (*ValidPrevMapRange) (const void *pNewControlTable, uint8_t u_st, uint8_t u_len); bool (*ValidNextMapRange) (const void *pNewControlTable); void (*InitNVMValue) (void *pControlTable, const void *pNVMData); void (*ReadAction) (void *pCtrlTable); void (*WriteAction) (const void *pNewCtrlTable, void *pCtrlTable, bool force); } mem; } TDX_ConfParam; ****DX_ClientCommTask [#i4fc2a05] 初期設定の条件に従ってホストとの通信機能を行う。~ FreeRTOSの1つのタスクから呼び出す事。 void DX_ClientCommTask (void); ****DX_WriteMem [#td20cea0] 通信タスク以外からコントロールテーブルへアクセスする。 bool DX_WriteMem (uint8_t adr, uint8_t *data, uint8_t size); ****DX_ReadMem [#u5c70e57] 通信タスク以外からコントロールテーブルへアクセスする。 bool DX_ReadMem (uint8_t adr, uint8_t *data, uint8_t size);
(This host) = http://www.besttechnology.co.jp