Koshianのファームを書き換えてみた

# Koshianとこの記事について
Koshianについての詳細は[mpression](http://www.m-pression.com/ja/solutions/boards/koshian)さんの商品紹介ページを見てください。本記事はKoshianを持っている、あるいは興味がある人のうち、konashi互換のファームで遊ぶだけでは満足できない人向けの内容です。

# ファームウェア開発
## 開発環境
[本家ページ](http://www.m-pression.com/ja/solutions/boards/koshian)より

* Broadcom社のBCM20737Sをチップとして利用している
* Broadcom社のWICED Smart SDKにより独自ファームが作成可能
* 同SDKはユーザ登録が必要だが、無料で利用可能
* Windows、OS X、Linux版のSDKが存在する

とのことで、1000円以下で手に入るモジュールで、ここまで環境が揃うというのはありたがい。導入方法の詳細については前回の記事[BCM20737SのOTAFU](http://qiita.com/toyoshim/items/d7c5742f32503bb86f7c)を参照の事。

## ファームウェア書き換え事情
[Getting Started (PDF)](http://www.m-pression.com/ja/c/document_library/get_file?uuid=16352244-c1d9-46a9-b0fc-326c02413c39&groupId=10157)に書かれている情報によると

1. 背面のデバッグ用端子からシリアルで書き換え（要：半田付け）
2. BLE通信を仕様したOTA(Over The Air)書き換え
3. UART端子からの書き換え

と3通りの方法がある。

### デバッグ用端子
ハンダ付けが必要。わりと狭い上に、ここをハンダ付けするとスペース的にベースボードに戻すのが難しくなるので、全力で回避したい。ラストリゾート。

### OTA
便利そう。[Getting Started (PDF)](http://www.m-pression.com/ja/c/document_library/get_file?uuid=16352244-c1d9-46a9-b0fc-326c02413c39&groupId=10157)によれば

* 書き込み済みのファームが対応していれば利用可能
* 「当モジュールは出荷時には本機能をサポートしています」との事

なので、毎回きっちりOTAの動くファームを書き込み続ければ、OTAだけでなんとか生きていける。

オリジナルのファームは公開されていないけど、OTAの口さえ出しておけば、konashi.jsのOTAFUから元に戻せるんじゃないか、という淡い期待も。

### UART
ピンは引き出されているので、ハンダ付けは回避可能。ただしUARTの端子は汎用のI/Oとしては利用できなくなる。OTAと同様、ファーム側の対応が必要。出荷時のファームではオンになっていないので、最初の書き換えは他の方法を利用する必要がある。

# 書き換えの実際
## Konashi OTAの真実
SDK付属ツールではアップデートがうまくいかない。Windowsなのでハードウェア相性問題を疑っていたが非公式のAndroid用ツールを使っても駄目。詳細は[BCM20737SのOTAFU](http://qiita.com/toyoshim/items/d7c5742f32503bb86f7c#koshian)の備考にて。

konashi.jsのOTAが実際どういう通信をしているのか調べるために、OS X上で互換OTAサービスを搭載したPeripheralを実装してみた。が、OTAサービス以外の情報を使ってデバイス確認をしているようで、konashi.jsからデバイス選択後、該当サービスにはreadもwriteも一切飛んでこなかった。公式ツールではこの互換Peripheralに対してOTAFUが最後まで流れるので、Peripheralの実装側の問題ではなさそう。

という事で、ひとまずKonashiのOTAの解析は諦める（必然的に元のファームに戻す道の確保も諦める）。

## デバッグ用端子で書き換え（残念）
![接続の様子](https://qiita-image-store.s3.amazonaws.com/0/12843/21bf7f13-f795-f3f7-702a-1f2fd9716eb5.jpeg)


```shell-session
% ./make ota_firmware_upgrade-BCM920737TAG_Q32 download UART=/dev/tty.usbserial
Linking target ELF
OK, made elf.
Call to ota_firmware_upgrade_spar_crt_setup @ 00206651
OK, made /Users/toyoshim/Documents/WICED/WICED-Smart-SDK-2.2.0/WICED-Smart-SDK/Wiced-Smart/spar/../../build/ota_firmware_upgrade-BCM920737TAG_Q32-rom-ram-Wiced-release/A_20737A1-ota_firmware_upgrade-rom-ram-spar.cgs. MD5 sum is:
05b704e9800898136da99b225a2a64e5 ../../build/ota_firmware_upgrade-BCM920737TAG_Q32-rom-ram-Wiced-release/A_20737A1-ota_firmware_upgrade-rom-ram-spar.cgs

--------------------------------------------------------------------------------
Patches start at                  0x00204568 (RAM address)
Patches end at                    0x0020537C (RAM address)
Application starts at             0x00204FD0 (RAM address)
Application ends at               0x00206650 (RAM address)

Patch size (including reused RAM)       3604 bytes
Patch size                              2664 bytes
Application size                        5760 bytes
                                      ------
Total RAM footprint                     8424 bytes (8.2kiB)
--------------------------------------------------------------------------------

Converting CGS to HEX...
Conversion complete

Creating OTA images...
Conversion complete
OTA image footprint in NV is 10266 bytes

Downloading application...
Download complete

Application running
```
で、無事にHelloという名前でBLEデバイスが見える。

# 課題とTips
## 課題
- 書き換え後のファームが安定しておらず、電源再投入すると何故か起動しない。サンプルそのままなので原因不明→デバッグ端子から書き込んでいる場合、PON時にTX/RXが結線されているとプログラミングモードに入ってしまうのが原因かも。
- オリジナルのファームに戻す方法が確立できていない。ダミーのkonashiファーム作ってkonashi.jsからOTAできれば良いのだけど。

## Tips
ファームがバグってて暴走したり、ファームの書き換えに失敗した場合には、明示的にリセットしたりリカバリーモードに入る必要があります。一度この状態になるとデバッグ端子でもファーム更新できません。僕は最初にファーム書き換えた時、手で端子抑えてたら途中でずれて書き込み失敗。リセット方法を探ってしばらく悩みました。また、PLATFORM_NVを間違った値に設定した場合にはリセットでも回復しません。

### リセット
本家の開発ボードについてるリセットボタン相当の操作を直接実施する方法です。。5個あるデバッグ用端子のうち、書き込みに使う端子は4個。真ん中の端子が未使用と思いきや、回路図によればリセット端子のようです。こいつを→Low→Highとしてやればリセットがかかります。これ、LowもHighもきっかり下げて上げないと駄目なようで……って事は、内部でPull-UpもPull-Downもされてないんでしょうか。なんか挙動不審になる原因がリセットにある気がしてならない（追記：一応、チップのデータシート見るとPull Upされているらしいですが、外からHighに上げるまではリセットかかりません）。

### リカバリーモード
こちらは本家ボードだとBOOT_ROMボタンを押しながらリセット、という操作の直接実施版のはず。内蔵EEPROMに変な書き込みをしちゃうと、リセットだけではプログラミングモードになりません。build以下にota.binと並んでlogが吐き出されるのですが、

```shell-session
1:58:44.758 Sending bytes to HW: 
4 bytes:  01 03 0C 00
21:58:44.872 ERROR: Failed to execute HCI Reset
````

こんな感じのエラーで止まってにっちもさっちもいきません。こんな時はSDAをHighに固定した状態でリセット端子を→Low→Highとすると、強制的にプログラミングモードに入るようです。koshianだと外周に出てるブレッドボード用の溝の一番左下、デバッグの電源のすぐ脇の端子です。滅多に起きない状況だから、わざわざ回路なんか組まずに手で抑えたりするかと思いますが、ショートさせないように注意が必要です。リセット後はdownloadの代わりにrecoverをmakeに渡せばOK。

```shell-session
 ./make ota_firmware_upgrade-BCM920737TAG_Q32 recover UART=/dev/tty.usbserial
Linking target ELF
OK, made elf.
Call to ota_firmware_upgrade_spar_crt_setup @ 00206651
OK, made /Users/toyoshim/Documents/WICED/WICED-Smart-SDK-2.2.0/WICED-Smart-SDK/Wiced-Smart/spar/../../build/ota_firmware_upgrade-BCM920737TAG_Q32-rom-ram-Wiced-release/A_20737A1-ota_firmware_upgrade-rom-ram-spar.cgs. MD5 sum is:
05b704e9800898136da99b225a2a64e5 ../../build/ota_firmware_upgrade-BCM920737TAG_Q32-rom-ram-Wiced-release/A_20737A1-ota_firmware_upgrade-rom-ram-spar.cgs

--------------------------------------------------------------------------------
Patches start at                  0x00204568 (RAM address)
Patches end at                    0x0020537C (RAM address)
Application starts at             0x00204FD0 (RAM address)
Application ends at               0x00206650 (RAM address)

Patch size (including reused RAM)       3604 bytes
Patch size                              2664 bytes
Application size                        5760 bytes
                                      ------
Total RAM footprint                     8424 bytes (8.2kiB)
--------------------------------------------------------------------------------

Converting CGS to HEX...
Conversion complete

Creating OTA images...
Conversion complete
OTA image footprint in NV is 10266 bytes

Recovering platform ...
Recovery complete

Application running
```