机の裏の地獄のケーブルを配線ダクトを使って整頓する話
前々からなんとかしないとと思っていたのだが,机の裏の配線類が地獄の形相を呈していた.Mac miniを自宅に導入してからますます配線も増えてしまっていた.
机の裏の配線類をなんとかできるものがないものかと色々amazonで調べてみたりしていて,下記のようなものならばたくさん見つかったが,どうやって机の裏にマウントしようとか,机の端から端までカバーできないとか,完全にきれいにできなさそうで導入できずにいた.

山崎実業(Yamazaki) テレビ裏ケーブルボックス スマート ブラック 約W40XD15.5XH14.5cm スマート ケーブル収納 簡単開閉 4988
- 発売日: 2020/02/20
- メディア: ホーム&キッチン
しかしなんとかしたいと思っていろいろとみっちり調べてみていたところ,下記のような商品を発見した.たしかにこれこそが私の望んでいたものだった.机の裏の端から端までがカバーできて,マウントもできる.ただし価格がネックだった.

プラス Garage 配線整理 配線ダクト 80cmタイプ YY-CDCT08 白 414350
- 発売日: 2019/10/29
- メディア: オフィス用品
これを見てうーんと考えていたところ,ケーブルをまとめるようなダクトは電気配線等で普通に使われているだろうという想定し,色々と調査してみたところ,「配線ダクト」と呼ばれるものがマッチした. 様々な会社の製品が配線ダクトというワードでヒットする.配電盤や,通信線などの集約をしているところでよく用いられるもののようだ.
amazonだと送料もついてしまってやや割高になってしまっているが,東京・秋葉原の愛三電気さんで同様の製品を扱っており,1本単位から購入できる.
星和電機 カッチングダクトBDR-682 1,830円 カッチングダクト・エスシーロック
愛三電気で手頃な価格で調達できるし,今回はこれを活用して自作してみることにした.
早速仕事終わりに愛三電気に行って調達してきた.今回使うカッチングダクトは60x80の幅と高さのものを採用した.OAタップとかACアダプタとかを入れたくなった時にも対応できるくらいのサイズとしてこれをチョイス.いい感じである.
カッチングダクトと言う名の通り,スリットはニッパー等を使って簡単に切断できるようになっていて,自由にケーブルを出せるようになっている.便利.
カッチングダクトは図面が公開されていたので,これをもとに自分の机にマウントするためのアダプタを3Dプリンタを使って作る.
いい感じである.
アダプタができたら机にアダプタを付けるために穴あけをして,ネジ止めする.
ネジ止めしたアダプタにダクトを載せてみて,位置を見ていく.
机との隙間の感じとか,机とダクトの高さ関係や,まわりとの干渉がないかも確認.よさそうである.
よさそうであればダクトとマウントアダプタをネジ止めして,ごちゃごちゃだったケーブルをダクトの中に収めていく.絡まっているものはほどいて再配線.みるみるきれいになっていく.
ケーブルを出す部分はニッパで切断して出してやる.
ケーブルをあらかたダクトに入れて整頓し,上のカバーをはめる.ごちゃごちゃだったケーブルがダクト内にまとまって見違えるようにスッキリした.
これで見た目もスマートになり,ケーブルも不意に絡まったりもすることなく快適に過ごせそうである.めでたし.
ホイップアンテナ用マグネット基台を自作してみた話
ふとマグネット基台が手元に欲しくなった.真面目に買うと3000円くらいはするけど,カジュアルに使いたいだけなのでそこまでコストをかけたくない.手持ちによさげな強いマグネットがあったので,作ってみることにした.ハウジングは3Dプリンタを使ってABS樹脂で作る.
手持ちであった強いマグネット.これがないと始まらない.とても強力なので不用意に電子機器を近づけたりできない.鉄とマグネットの間に指を挟んだりしたら怪我するレベル.
私はなにか作りたいものがあったり,アイディアが生まれそうな時は,最近だいたいiPadに書いていく.iPadを導入する前はProject Paperを使っていた.オキナのProjectPaperは書き心地もよいし,罫線が丁度いい色で入っていてよい.

オキナ プロジェクトペーパー B5 5ミリ方眼罫 100枚 PPB55S
- 発売日: 2017/07/20
- メディア: オフィス用品
ソフトウェアでもハードウェアでもなにか作りたいときはいつもだいたいこうやって描くことから始まる.
こうして描いてみるとだいたい作りたいもののイメージがついてくる.この脳のうちにデータに起こす.
fusion360でモデリングする.今回は上半分と下半分の2パーツからハウジングを構成して,間にケーブルを通すスリットをいれておく.2つのパーツでマグネットを固定して保持し,パーツ同士はネジ固定にする.ネジ固定にするにあたって下側のパーツにはインサートナットを熱圧入してやることにした.
モデルができたら早速作っていく.3Dプリンタにデータを食わせて積層する.
とりあえず下半分ができた.
続いて上半分も出力する.
上半分もできた.サポート材の条件がよくなくて,剥がすのが大変だった.
ハウジングパーツができたので,あとは組み上げるだけ.インサートナットを熱圧入する.
www.monotaro.com
モノタロウで買ってあったM4の廣杉計器のインサートナットをハンダゴテで熱しながら圧入していき,ある程度挿入できたら机などの平面にナットとパーツを押し当ててツライチになるようにする.
するとわりときれいに圧入できる.
ここまできたらあとはコネクタとケーブルをつけて組み上げる.ケーブルは取り回しやすい3D-2V.秋葉原の九州電気で買った.
M型接栓は安物の手持ち.
これを組み上げて
完成.使ってみるとこんな感じ.
丁度いい吸着力でいいかんじ.
吸着力はハウジング下部パーツのマグネットと底面までの高さを変えてやることで調整できるが,今回は4mmで一発成功.ちょうどよかった.
というわけでほしいと感じてから手に入るまでとても早く,手持ちの機器と部材でサクサクと作り上げることができました.めでたし.
ICOM IC-T90のバッテリ換装をしてみた話
おことわり
- 本記事で紹介する内容はわたし自身が自身の責任のもと実施した例を紹介するにすぎません.
- 本記事を参考して生じた事故,火災やその他の損害等が生じた場合でも,いかなる理由に関わらず一切の責任を負いかねます.
- 一般的な二次電池,得に高エネルギー密度であるリチウムイオンバッテリーは取り扱いを誤るとたやすく爆発・火災等を生じる危険性があります.このことに十分配慮する必要があります.
- この内容は製造元であるアイコム株式会社とは一切関係がなく,また推奨されることではありません.保証等が一切受けられなくなることをご理解ください.
- もしも参考にされる場合でも,上記のことを十分ご理解頂いた上で事故なく実施いただけることを願います.
コトの発端
しばらく前に手に入れていたIC-T90だが,付属のバッテリーが使い物にならなくなった.具体的にはチャージャーで充電しても5W送信した瞬間に電源が落ちる.また充電中にバッテリーが異常と思われるほどひどく発熱していたことがあった.このままでは爆発・火災になる恐れがあると判断してしばらく利用をやめていたが,どうにか使い続けられるようにできないかと色々思考錯誤してみていました.具体的には11Vの外部電源端子からの給電のみとして利用し,バッテリは外して運用することや,バッテリの交換を実施することでした.新規に純正バッテリを購入することも検討しましたが,バッテリの値段は安くなく,それなら11Vの外部電源から運用したほうがコスパはよさそうだ,などと考えていました.
しかしどうにも11Vの外部電源だとモビリティがよくありません.せっかくのハンディ機なのにいちいち外部電源のことを考えて用意しておく必要が出てきます.これでは使いにくいと考え,思いついたのがバッテリパックを分解・改造したバッテリの換装でした.ただ,リチウムイオンバッテリパックの改造は多くのリスクを伴うものであり幾度か考え直しましたが,保護回路付きのセルに入れ替えることである程度の安全性を担保しつつ,換装が行えないかと考えました.
早速換装
ICOMのバッテリパックです.BP-217という型番がついていて,7.4Vの1500mAhのものとなっています.
当初これを記事にする予定はなかったこともあり,分解時の写真が残っておらずに申し訳ないのですが,バッテリパックは側面の隙間にマイナスドライバ等を差し込んでこじ開けることができました.中にバッテリがいるということに注意をして,金属ではなくプラスチックのドライバを利用するなどするほうが安全でしょう.中には18500のリチウムイオンバッテリの生セルが2本,ニッケルのタブでスポット溶接されて内蔵されていました.セル外装はピンク色. タブ,電池の端子等をショートさせないよう十分注意を払いタブはニッパで切断してセルを取り出しました.セルさえ取り出し,絶縁してしまえば危険はひとまずありません.
分解時の写真が無いため,いきなり換装後の写真を紹介します.
このように,既存のバッテリパックの外装のみを再利用し,その中に新たに保護回路付きのセルを内蔵するような設計にしました.詳細を追って紹介します.
換装するバッテリとして選択したのはKEEPPOWERに18350, 1200mAhの保護回路付きのセルです. 値段も2セルで2000円未満と十分手頃です. www.amazon.co.jp
これを選ぶまでの過程はいくつかあります.要素としては下記を考えました.
1. もとのバッテリーパックの外装に内蔵できる大きさであること(絶対)
2. 内蔵した際に得られる公称電圧が7.4Vとなること(つまりバッテリパックの中で2Sのセルとして構成できること)
3. 保護回路がついていること(絶対)
4. できる限り容量が大きいものであること
5. さらなる交換・換装が可能であること
3の保護回路がついていることは絶対条件として考えていました.火災や爆発は避けたいからです.
1, 2の内容について,次のような結論を得ました.
もとのバッテリパックに入っているセルは生セルの18500セルとなっています.BP-217そのセルに最適化されたバッテリパックのサイズになっており,横幅には薄いニッケルのタブだけが収められる程度のサイズ余裕しかありません.しかし保護回路が搭載されたセルは一般の生セルよりも数mm長くなってしまいます.このことから同じサイズである18500の保護回路付きのセルはバッテリパックの外装に収めることはサイズ的余裕がないためできません.18500よりも小さいサイズとしては18490, 18350等があります.一般に電池の容量が増加すると電池自体のサイズも増加することから,4の条件を考えると18490サイズで保護回路付きのものがあり,全長がバッテリパックの外装に収められればこれを選びたいと考えるところでしたが,どうやら調べてみると18490のバッテリというのはあまり流通していないようで入手性がよくないようです.このことから今回は18350のサイズのセルを選ぶことにしました.また,このサイズにすることで5の条件である交換・換装用意になるようなしくみをバッテリパック内部に取り入れることが可能になりそうだという考えが浮かびます.
この時点で,上記のKEEPPOWERの18350保護回路付きセルはこれらの条件をすべて満たしており,さらに評判も悪くないメーカーであること,数多く利用され,実績のあるセイコーインスツルメンツの保護回路ICを利用していると謳われていることから上記を選択しています.
今回はこの5の条件である換装容易性を,通常の乾電池ボックス等で利用されているようなバネ性のあるコンタクトが利用できそうだと考えました.これは秋月電子で販売されているものを利用しました.ターミナルクリップと呼ばれているんですね. akizukidenshi.com
これら18350セル2本,上記のターミナルクリップ,その他配線類をもとのバッテリーパックの外装に収められれば求めるものができます.ここで懸念するべき点がいくつかあります.
1. リチウムイオンバッテリの特性がもともと入っているものと異なる可能性があること
2. 容量が異なること
少なくともこの点については気をつけなければなりません.いくら保護回路が入っているといえど,リチウムイオンバッテリで比較的特にリスクが有る作業が充電です.
充電はこの1, 2のことをよく考慮して実施する必要があります.リチウムイオンバッテリは一般に最大充電電流は1Cとされています.このセルは1200mAh, もとのセルは1500mAhです.この時点でIC-T90の急速充電装置およびIC-T90本体からの補助充電時の充電電流が高すぎる恐れがあるということは容易に想像できます.このことを気にかけておく必要があります.
また放電についても,もとのバッテリの放電特性が不明であることから,気にかける必要があります.しかしリチウムイオンバッテリの放電特性として低内部抵抗で比較的大電流を扱うことができることからそこまで大きな問題になることは少ないでしょう.KEEPPOWERのこのバッテリはの出力電流は最大4.1C出力の仕様であり,最大放電電流は約5A程度になります.あらかじめIC-T90のバッテリ運用時の必要電流を測定しましたが,5Aは大きく下回っていることを確認していましたので,この点についてはクリアです.
このことを忘れないようにしておき,作成後に検証することにします.
さて,長くなりましたが作成物の紹介をしていきます.購入したバッテリはこれ.ちゃんとケースもついてきて2セルで1500円くらいです.
バッテリとコンタクトするターミナルクリップをうまく固定するため,3Dプリンタで保持具を作ります.モデルはこんな感じ.
この保持具にコンタクトを接着剤で固定し,配線類のはんだ付けを行っています.配線類はバッテリから2-3A程度の電流をとっても発熱が少なくなるよう余裕を持った太さのものを使うと良いでしょう.
見ていただくとわかると思いますが,バッテリパックには制御基板が入っています.これはもともと生セルと一緒に入っていた制御基板をそのまま利用しています.制御基板からはそれぞれ充電用端子,バッテリの各セルのプラスマイナスに対して配線が伸びているので,もとの生セルと同様の配線になるように配線してあげます.要するに生セルだろうが換装後の保護回路付きセルだろうが配線は変えずに生セルだと思って配線してあげればよいです.これで制御基板側でも充電・放電電流の監視も行ってくれることでしょう.セル側にも最後の頼みの綱として保護回路があり,2重で保護されている形になります.
両側面にはエポキシ接着剤をいれて固定してしまっています.
斜めからみるとこう.バッテリを入れる前に抵抗計でバッテリのセルを入れても問題ないか(セル両端で抵抗値測定をした場合に異常に低い値を示さないか)を確認しておくと良いでしょう.
これでバッテリパック自体は構成できました.この時点で電圧を確認します.低くても5V程度から高くても8.4V程度である必要があるでしょう.リチウムイオンバッテリの終止電圧は低くてもセルあたり2.5V程度,満充電電圧はセルあたり4.2V程度ですから,これに由来します.この範囲を大きく外れていた場合はセルや回路に異常があると判断して調査を行ったほうが良いかもしれません.
さて,電圧の正常性が確認できたら充電電流を測定してみます.今回は急速充電クレードルBC-139を利用して測定を行いました.電流計,電圧計をかましてセル状態を監視しながら充電をしてみます.最大充電電流は1Cですから,1.2Aを超えていた場合は即座に充電を中止する心構えをしておきます.
測定中の画像が下記です.クレードルの端子にはワニ口クリップをはさみ充電・測定系につなぎます.クレードルの下にはスイッチがついており,このスイッチが押されていると充電を開始しますから,これを押して計測します.はじめは手で押して様子を見て,問題なさそうならマスキングテープで押しっぱなしにして充電完了まで監視します.
測定の結果,終止電圧付近から充電を始めた場合でも,充電電流は最大0.8A程度で,1Aをこえることはありませんでした.このことから約0.66C程度で充電をしている事になりますが,これは1Cを大きく下回っていること,一般に充電電流は0.5C-1Cの間で行うことが多いことから,0.66C充電は問題ないものと判断しました.実際危険はあまりないでしょう.
充電は無事完了し,充電クレードル側でも充電完了を示す緑色のランプが点灯し充電電流が0Aになり充電が終了しました. 充電が無事成功したといえるでしょう.
換装後充電したバッテリパックで送信・受信ともにテストを行いましたが5W送信も問題なく行え,電池本体や周辺回路からの発熱もほぼありませんでした.それより5W送信すると本体の発熱が大きいです.
ちなみに充電中であっても電池本体・回路からの発熱はほぼありません.それより充電クレードル本体の発熱がひどいです.
というわけで無事バッテリの換装ができ,ハンディ機として継続して利用することができるようになりました.1500mhAから1200mhAに容量が減っていることから,多少運用時間は短くなることは想定されますが,その場合はセル自体が交換できるようになっていますので,同様の18350保護回路付きセルをケースに入れて持ち運び,交換してあげるような運用もできます.これで使いやすくなりました.めでたし.
まとめ
STM32 HAL タイマ割り込みの基礎の基礎
おことわり・前提
- STM32CubeIDEを使った話をします.
- あくまで自分用のメモという目的が主.
- 逐次updateしたり追記したりがあるかもしれません.
本題
- タイマ割り込みを使えるようにする.
- CubeMXで利用したいタイマを有効にする.
- プリスケーラ,カウンタを適切に計算してセット.
- 基本的にtimer clock sourceはinternal clockならAPB系がつかわれるが,どの系でくるかはdatasheet要確認.
- auto preloadをenableにしておくと楽.
- overしたときのcnt resetを自動でやってくれる.
- overしたときのcnt resetを自動でやってくれる.
- タイマ割り込みをenableにする.
- 忘れるとハマる.
- 忘れるとハマる.
- どこかで
HAL_TIM_Base_Start_IT(&htimx);
をcallしてtimer interruptをenableにする.
コードを見ていく
./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) { uint32_t tmpsmcr; /* Check the parameters */ assert_param(IS_TIM_INSTANCE(htim->Instance)); /* Enable the TIM Update interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE); /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) { __HAL_TIM_ENABLE(htim); } /* Return function status */ return HAL_OK; }
- 基本的に
main.cpp
のstatic void MX_TIMx_Init(void)
あたりの最後で呼び出せばいいと思う.- もちろんmain関数の頭らへん(
MX_TIM3_Init()
が呼ばれたあと)で呼んでももちろん動くはず. - ex.
- もちろんmain関数の頭らへん(
/** * @brief TIM3 Initialization Function * @param None * @retval None */ static void MX_TIM3_Init(void) { /* USER CODE BEGIN TIM3_Init 0 */ /* USER CODE END TIM3_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM3_Init 1 */ /* USER CODE END TIM3_Init 1 */ htim3.Instance = TIM3; htim3.Init.Prescaler = 39999; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 199; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim3) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM3_Init 2 */ HAL_TIM_Base_Start_IT(&htim3); /* USER CODE END TIM3_Init 2 */ }
main.cpp
にcallbackを書く- 複数あるときでも引数で渡される
&htimx
を見て比較して分岐する. ./Core/Src/main.cpp
- 複数あるときでも引数で渡される
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if(htim == &htim3) HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_0); if(htim == &htim14) printf("htim14 callback!\r\n"); }
- 大まかな流れと実装.
./Core/Src/stm32f0xx_it.c
- それぞれの割り込みハンドラがここにいる.
- タイマの割り込みハンドラは共通の
HAL_TIM_IRQHandler(&htimx)
をcallする.
/** * @brief This function handles TIM3 global interrupt. */ void TIM3_IRQHandler(void) { /* USER CODE BEGIN TIM3_IRQn 0 */ /* USER CODE END TIM3_IRQn 0 */ HAL_TIM_IRQHandler(&htim3); /* USER CODE BEGIN TIM3_IRQn 1 */ /* USER CODE END TIM3_IRQn 1 */ }
./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c
HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
は共通のタイマハンドラ.- ここでタイマの各種イベントに応じてcallback先を選んでいる.
- タイマの時間切れ(elasped)の場合update eventとなり,タイマ共通の
HAL_TIM_PeriodElapsedCallback(htim)
がcallされるが,htimはそれぞれのIRQHandlerで引数として渡したタイマのオブジェクト(address)が入っているのでhtimを見ることでどのタイマによって発生したイベントかを判断できる.
/** * @} */ /** @defgroup TIM_Exported_Functions_Group7 TIM IRQ handler management * @brief TIM IRQ handler management * @verbatim ============================================================================== ##### IRQ handler management ##### ============================================================================== [..] This section provides Timer IRQ handler function. @endverbatim * @{ */ /** * @brief This function handles TIM interrupts requests. * @param htim TIM handle * @retval None */ void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim) { ...(snip)... /* TIM Update event */ if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET) { if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET) { __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) htim->PeriodElapsedCallback(htim); #else HAL_TIM_PeriodElapsedCallback(htim); #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ } } ...(snip)... }
STM32でSWCLK, SWDIOをGPIO Outputにして書き込めずにハマる
STM32 HAL GPIOの基礎の基礎
おことわり・前提
- STM32CubeIDEを使った話をします.
- あくまで自分用のメモという目的が主.
- 逐次updateしたり追記したりがあるかもしれません.
本題
- tips: GPIOのlabelはただのエイリアス.
./Core/Inc/main.h
#define LCD_RS_Pin GPIO_PIN_6 #define LCD_RS_GPIO_Port GPIOA
- エイリアスの先はちゃんとdriverのheaderで定義されている.なのでlabelをつけたからといって
GPIOA
やGPIO_PIN_X
などで指定できなくなるというわけではない../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h
...(snip)... /* Exported constants --------------------------------------------------------*/ /** @defgroup GPIO_Exported_Constants GPIO Exported Constants * @{ */ /** @defgroup GPIO_pins GPIO pins * @{ */ #define GPIO_PIN_0 ((uint16_t)0x0001U) /* Pin 0 selected */ #define GPIO_PIN_1 ((uint16_t)0x0002U) /* Pin 1 selected */ #define GPIO_PIN_2 ((uint16_t)0x0004U) /* Pin 2 selected */ #define GPIO_PIN_3 ((uint16_t)0x0008U) /* Pin 3 selected */ #define GPIO_PIN_4 ((uint16_t)0x0010U) /* Pin 4 selected */ #define GPIO_PIN_5 ((uint16_t)0x0020U) /* Pin 5 selected */ #define GPIO_PIN_6 ((uint16_t)0x0040U) /* Pin 6 selected */ #define GPIO_PIN_7 ((uint16_t)0x0080U) /* Pin 7 selected */ #define GPIO_PIN_8 ((uint16_t)0x0100U) /* Pin 8 selected */ #define GPIO_PIN_9 ((uint16_t)0x0200U) /* Pin 9 selected */ #define GPIO_PIN_10 ((uint16_t)0x0400U) /* Pin 10 selected */ #define GPIO_PIN_11 ((uint16_t)0x0800U) /* Pin 11 selected */ #define GPIO_PIN_12 ((uint16_t)0x1000U) /* Pin 12 selected */ #define GPIO_PIN_13 ((uint16_t)0x2000U) /* Pin 13 selected */ #define GPIO_PIN_14 ((uint16_t)0x4000U) /* Pin 14 selected */ #define GPIO_PIN_15 ((uint16_t)0x8000U) /* Pin 15 selected */ #define GPIO_PIN_All ((uint16_t)0xFFFFU) /* All pins selected */ ...(snip)...