GR-SAKURA
GR-KURUMI
GR-COTTON
GR-CITRUS
GR-PEACH
GR-KAEDE
GR-ADZUKI
GR-LYCHEE
GR-ROSE
GR-MANGO(*)
SNShield
Web Compiler
IDE for GR
TOPPERS関連
女子美コラボ
その他
※プロデューサミーティング中
作り方使い方資料
イベント関連
作品記事
体験記事
ライブラリ
ツール
その他・過去ファイル
RL78/G13用ライブラリに対して、次版のV2.02にSoftwareSerialを入れようと考えています。FTDI USBシリアル変換モジュールを用いて4800, 9600, 57600, 115200bpsでの動作確認を行いました。ソースは以下の通りです。
GR-ADZUKIでは、USB通信用(pin0, pin1)、Wire(pin7, pin8)、モーター(pin9, pin10)でシリアルがつぶれてしまい、ESP8266やXBee等を使ったリモート制御がやりづらい状況でした。SoftwareSerialによって、これを解決したいという理由です。
なお、Arduino(AVR)ではピンチェンジ割り込みというほぼ全端子に外部割り込みが使える機能があるので、ArduinoではSoftwareSerialはほぼ全端子に使えますが、RL78/G13ではそんな機能がないため、シリアルの受信開始用に使用できるピンは外部割り込みがアサインされたpin2(INT0), pin3(INT1)だけとなります。送信はいずれのピンでも大丈夫です。
9月初旬にV-upを考えていますので、何かご意見、コメントありましたらよろしくお願いいたします。
pins_arduino.hも変更してます。
以下、サンプルです。
#include <Arduino.h>#include <SoftwareSerial.h>SoftwareSerial mySerial(2, 3); // RX, TXvoid setup() { // Open serial communications and wait for port to open: Serial.begin(115200); // set the data rate for the SoftwareSerial port mySerial.begin(115200);}void loop() { // run over and over#if 0 mySerial.println("Hello, world?"); delay(100);#else if (mySerial.available()) { Serial.write(mySerial.read()); } if (Serial.available()) { mySerial.write(Serial.read()); }#endif}
SoftwareSerial.cpp の 時間待ち部分
void _delay_loop_2(uint16_t __count) { // todo: need to implement assemble at 9 cycles volatile uint16_t count = __count; while(count != 0) count--; }
を GCC for Renesas 4.9.2.201701-GNURL78 を使用して web コンパイラでの makefile 通りのコンパイルオプションでコンパイルすると
Disassembly of section .text._Z13_delay_loop_2t: 00000000 <__Z13_delay_loop_2t>: 0: 20 02 subw sp, #2 00000002 <.LBB83>: 2: a8 06 movw ax, [sp+6] 00000004 <.L20>: 4: b8 00 movw [sp+0], ax 6: 44 00 00 cmpw ax, #0 9: 61 f8 sknz b: ec 00 00 00 br !!0 <__Z13_delay_loop_2t> f: a8 00 movw ax, [sp+0] 11: b1 decw ax 12: ec 00 00 00 br !!0 <__Z13_delay_loop_2t> 00000016 <.L21>: 16: 10 02 addw sp, #2 18: d7 ret
コメントにある通り 1 ループ 9 サイクルのコードが出力されますが、精度は粗く、コンパイル条件が変わると出力コードの内容も保証できないので
void _delay_loop_2(uint16_t __count) { __asm __volatile( " movw ax, %0 \n" " cmpw ax, #0 \n" " bz $9f \n" "0: \n" " subw ax, #1 \n" " bnz $0 \n" "9: \n" : : "r"(__count) : "ax" ); }
等とした方が良いと思います。1 ループ 5 サイクルとなるので、遅延時間を計算している箇所も
// Precalculate the various delays, in number of 5-cycle delays uint16_t bit_delay = (F_CPU / speed) / 5;
等と変更する必要があります。
ループの分岐先が間違ってたので訂正
void _delay_loop_2(uint16_t __count) { __asm __volatile( " movw ax, %0 \n" " cmpw ax, #0 \n" " bz $9f \n" "0: \n" " subw ax, #1 \n" " bnz $0b \n" "9: \n" : : "r"(__count) : "ax" ); }
ローカルラベルに 0 は一時期の GNURL78 で使用できない不具合があったことを思い出したので更に修正
void _delay_loop_2(uint16_t __count) { __asm __volatile( " movw ax, %0 \n" " cmpw ax, #0 \n" " bz $9f \n" "1: \n" " subw ax, #1 \n" " bnz $1b \n" "9: \n" : : "r"(__count) : "ax" ); }
_delay_loop_2() の 呼び出し ~ 復帰 のコスト等を考えると
// Precalculate the various delays, in number of 5-cycle delays uint16_t bit_delay = (F_CPU / speed) / 5 - 2;
くらいの調整を加味しても良いかも。
Fujitaさん、ありがとうございます!ESP8266との通信に成功しました。アセンブルで精度を上げられたのがでかいです!
アクセスポイントへの接続後のIP取得まででき、milkcocoaサービスへのデータアップまでいけました。ちょっとデータのアップが遅いため、途中でデータ化けが起きている可能性はありそうですが、微調整次第な気はします。以下、bit_delay値はTXをオシロを見つつ、8ビット単位で計算して115,200 Hzに近くなるように(-5)を入れてます。
uint16_t bit_delay = (F_CPU / speed) / 5 - 5;
ーーーーーーーーーーーーーーーーーーーーー
wait...Milkcocoa SDK demo
Connecting to WARPSTAR-1153D8FW Version:to station okJoin AP successIP: +CIFSR:STAIP,"192.168.0.9"+CIFSR:STAMAC,"18:fe:34:ef:08:e2"single okmilkcocoa on sucesssConnecting to MQTT... MQTT Connected!onpush28
ーーーーーーーーーーーーーーーーーーーーーー
以下、変更したソースです。
コードを見る限りでは SoftwareSerial::recv() や SoftwareSerial::write(uint8_t) に改善の余地がありますが
> ダメでしたので、そのままアップさせていただいてます。
というのはやり方としおかしいのでは?
問題を認識していて解決する方向に向かわないというのはSDカードでの音切れの際でもそうでしたが。
> コードを見る限りでは SoftwareSerial::recv() や SoftwareSerial::write(uint8_t) に改善の余地がありますが
おっと、既出か。
https://japan.renesasrulz.com/gr_user_forum_japanese/f/gr-adzuki/4493/softwareserial/24056#24056
SoftwareSerial::recv() と SoftwareSerial::write(uint8) が GNURL78 のアレな部分も相まってどう見ても精度が出る訳ないコードとなっているので、インラインアセンブラでも使うべきと思います。