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関連
女子美コラボ
その他
※プロデューサミーティング中
作り方使い方資料
イベント関連
作品記事
体験記事
ライブラリ
ツール
その他・過去ファイル
まとめておくとそのうち修正されたりされなかったりするんじゃないかという期待を込めて立てました。
サイズ縮小の要望
いまのライブラリで生成されるROMイメージファイルは無駄にでかいので、改善していただきたい。
『クルミの研究』 の投稿に改善案として修正したものを添付しています。
GR-SAKURA ライブラリ V2 と同様に bitbucket 等でリポジトリを公開して pull req とかできるようなってると良いですね。
いつの間にか V1.10 に更新されてたのですが、
gr_common/include/RLduino78.h:
#define RLDUINO78_VERSION 0x0108 //!< RLduino78ライブラリのバージョン情報
なんかバージョン情報が戻ってますね。
…ということは GR-KURUMI_TSUBAME_E010 もか。
失礼しました。analogWriteの修正兼ねて、次のバージョンで修正します。ご指摘、解決策ありがとうございました_o_
明後日なことを聞くかもしれないですが、GR-KURUMIのRL78は、オンボードのフルカラーLEDへのanalogWriteで、ハードウェアPWMを再割り当てできるんでしょうか? フルカラーシリアルLED使ってる時に、ソフトウェアPWMが正しく動作しないのが、少々、不便。
analogWrite() 修正案
void analogWrite(uint8_t u8Pin, int s16Value) { uint8_t u8Timer; unsigned short u16Duty; FUNC_MUTEX_LOCK; if (u8Pin < NUM_DIGITAL_PINS) { { s16Value = min(max(s16Value, PWM_MIN), PWM_MAX); u8Timer = g_au8TimerPinTable[u8Pin]; if (u8Timer == NOT_ON_TIMER) { /////////////////////// // PWM未対応ピンの場合 /////////////////////// _pinMode(u8Pin, OUTPUT); // 出力モードに設定 if (s16Value < (PWM_MAX / 2)) { _digitalWrite(u8Pin, LOW); } else { _digitalWrite(u8Pin, HIGH); } } else if((u8Timer & 0xF0) == SWPWM_PIN){ /////////////////////// // Software PWM対応ピンの場合 /////////////////////// #if defined(REL_GR_KURUMI) int i; _startTAU0(TIMER_CLOCK); if( g_u8AnalogWriteAvailableTable[u8Pin] == false ){ _pinMode(u8Pin, OUTPUT); // 初期時のみ出力モードを設定 g_u8AnalogWriteAvailableTable[u8Pin] = true; } g_u8SwPwmValue[u8Timer & 0x0F] = s16Value; // SoftwarePWMの設定 if (!(TE0.te0 & 0x0040)) { // No pin uses Software PWM _startTimerChannel( SW_PWM_TIMER, 0x0001, SWPWM_MIN, false, true ); } #endif } else { /////////////////////// // PWM対応ピンの場合 /////////////////////// _startTAU0(TIMER_CLOCK); if (!(TE0.te0 & 0x0001)) { // Masterチャネルの設定 TT0.tt0 |= 0x0001; // タイマ停止 TMR00.tmr00 = PWM_MASTER_MODE; // 動作モードの設定 TDR00.tdr00 = g_u16TDR00; // PWM出力の周期の設定 TO0.to0 &= ~0x0001; // タイマ出力の設定 TOE0.toe0 &= ~0x0001; // タイマ出力許可の設定 // マスタチャネルのタイマ動作許可 TS0.ts0 |= 0x00001; } u16Duty = (unsigned short)(((unsigned long)s16Value * (g_u16TDR00 + 1)) / PWM_MAX); if(g_u8AnalogWriteAvailableTable[u8Pin] == false){ _pinMode(u8Pin, OUTPUT); // 出力モードに設定 _digitalWrite(u8Pin, LOW); // Slaveチャネルの設定 _startTimerChannel(u8Timer, PWM_SLAVE_MODE, u16Duty, true, false); g_u8AnalogWriteAvailableTable[u8Pin] = true; } else { _modifyTimerPeriodic(u8Timer, u16Duty); } } } } FUNC_MUTEX_UNLOCK; }
static void _softwarePWM(void) { for (int i = 0; i< NUM_SWPWM_PINS; i++) { uint8_t u8Pin = g_au8SwPmwNumToPinTable[i]; if (g_u8AnalogWriteAvailableTable[u8Pin]) { if (g_u16SwPwmTicksCount == g_u8SwPwmValue[i]) { _swpwmDigitalWrite(u8Pin, LOW); } else if (g_u16SwPwmTicksCount == PWM_MIN) { _swpwmDigitalWrite(u8Pin, HIGH); } } } if (++g_u16SwPwmTicksCount >= PWM_MAX) { g_u16SwPwmTicksCount = PWM_MIN; }; }
同一のピンに対し analogWrite() と digitalWrite() を交互に行うテスト
/*GR-KURUMI Sketch Template Version: V1.10*/ #include <Arduino.h> int PIN = 3; // 5 6 9 10 11 void setup() { } void loop() { int count; for (int i = 0; i <= 255; i++) { analogWrite(PIN, i); delay(10); } delay(1000); count = 0; pinMode(PIN, OUTPUT); for (int i = 255; i >= 0; i--) { unsigned long start = millis(); while ((millis() - start) < 10) { int value = (count += int(long(i) * i / 255)) >= 255; if (value) { count -= 255; } digitalWrite(PIN, value); } } delay(1000); count = 0; pinMode(PIN, OUTPUT); for (int i = 0; i <= 255; i++) { unsigned long start = millis(); while ((millis() - start) < 10) { int value = (count += int(long(i) * i / 255)) >= 255; if (value) { count -= 255; } digitalWrite(PIN, value); } } delay(1000); count = 0; for (int i = 255; i >= 0; i--) { analogWrite(PIN, i); delay(10); } delay(1000); }
analogWrite() の元クロックが、 gr_common/include/RLduino78_mcu_depend.h:
/* PWM setting. */ //#define PWM_MASTER_CLOCK (32000000) #define PWM_MASTER_CLOCK (1000000) #if PWM_MASTER_CLOCK == 32000000 #define PWM_MASTER_MODE (0x0801) // CK0を選択 #define PWM_SLAVE_MODE (0x0409) #elif PWM_MASTER_CLOCK == 1000000 #define PWM_MASTER_MODE (0x8801) // CK1を選択 #define PWM_SLAVE_MODE (0x8409) #endif #define PWM_DEFAULT_FREQ (490) // 490Hz #define PWM_TDR00 (PWM_MASTER_CLOCK / PWM_DEFAULT_FREQ - 1)
32MHz じゃなくて 1MHz になってるのはなんか理由があるんでしょうか?
デフォの 490Hz で使う分には問題ないのですが、 0/255~255/255 の解像度を保ったまゝで analogWriteFrequency() で周波数を変更するには上限が 490Hz の 8倍 位までとなってしまい音声再生なんかで使いたい用途にはスペック不足な感じなんですけど。
pulseIn() がコンパイラの出力に依存する内容だったので、インラインアセンブラを使い、コンパイラの出力に依存しないようするテスト
static bool pulseInWait( volatile uint8_t* Px, uint8_t u8Bit, uint8_t u8StateMask, unsigned long* u32TimeoutCycles ) { bool ret; #if 0 const unsigned char u16PulseInWaitCycles = 30; while ((*Px & u8Bit) == u8StateMask) { if (*u32TimeoutCycles >= u16PulseInWaitCycles) { *u32TimeoutCycles -= u16PulseInWaitCycles; } else { ret = true; break; } } ret = false; #else __asm __volatile( " clrb %0 \n" " movw de, %1 \n" " mov a, %2 \n" " mov b, a \n" " mov a, %3 \n" " mov c, a \n" " movw hl, %4 \n" "1: \n" " mov a, [de] ;1 \n" " and a, b ;1 \n" " cmp a, c ;1 \n" " bnz $2f ;2/4 \n" " movw ax, [hl] ;1 \n" " subw ax, #PulseInWaitCycles ;1 \n" " movw [hl], ax ;1 \n" " movw ax, [hl+2] ;1 \n" " sknc ;1 \n" " subw ax, #1 ;1 \n" " movw [hl+2], ax ;1 \n" " bnc $1b ;2/4 \n" " .equiv PulseInWaitCycles, 1+1+1+2+1+1+1+1+1+1+1+4 \n" " oneb %0 \n" "2: \n" :"=&r"(ret) :"r"(Px), "r"(u8Bit), "r"(u8StateMask), "r"(u32TimeoutCycles) :"ax", "bc", "de", "hl" ); #endif return ret; } static bool pulseInCount( volatile uint8_t* Px, uint8_t u8Bit, uint8_t u8StateMask, unsigned long u32TimeoutCycles, unsigned long* u32PulseCycles ) { bool ret; #if 0 const unsigned long u16PulseInCountCycles = 35; *u32PulseCycles = 0; while ((*Px & u8Bit) == u8StateMask) { if (u32TimeoutCycles >= u16PulseInCountCycles) { u32TimeoutCycles -= u16PulseInCountCycles; } else { ret = true; break; } *u32PulseCycles += u16PulseInCountCycles; } ret = false; #else __asm __volatile( " clrb %0 \n" " movw de, %1 \n" " mov a, %2 \n" " mov b, a \n" " mov a, %3 \n" " mov c, a \n" " movw hl, %5 \n" " movw ax, PulseInWaitCycles/2+PulseInCountCycles/2 \n" " movw [hl], ax \n" " clrw ax \n" " movw [hl+2], ax \n" " br $2f \n" "1: \n" " movw ax, [hl] ;1 \n" " addw ax, #PulseInCountCycles ;1 \n" " movw [hl], ax ;1 \n" " movw ax, [hl+2] ;1 \n" " sknc ;1 \n" " incw ax ;1 \n" " movw [hl+2], ax ;1 \n" "2: \n" " mov a, [de] ;1 \n" " and a, b ;1 \n" " cmp a, c ;1 \n" " bnz $3f ;2/4 \n" " movw ax, %4+0 ;1 \n" " subw ax, #PulseInCountCycles ;1 \n" " movw %4+0, ax ;1 \n" " movw ax, %4+2 ;1 \n" " sknc ;1 \n" " subw ax, #1 ;1 \n" " movw %4+2, ax ;1 \n" " bnc $1b ;2/4 \n" " .equiv PulseInCountCycles, 1+1+1+1+1+1+1+1+1+1+2+1+1+1+1+1+1+1+4 \n" " oneb %0 \n" "3: \n" :"=&r"(ret) :"r"(Px), "r"(u8Bit), "r"(u8StateMask), "r"(u32TimeoutCycles), "r"(u32PulseCycles) :"ax", "bc", "de", "hl" ); #endif return ret; } unsigned long pulseIn(uint8_t u8Pin, uint8_t u8Value, unsigned long u32Timeout) { uint8_t u8Port, u8Bit, u8StateMask; volatile uint8_t *Px; unsigned long u32TimeoutCycles; unsigned long u32PulseCycles; unsigned long u32PulseLength; bool timeOut; FUNC_MUTEX_LOCK; if (u8Pin < NUM_DIGITAL_PINS) { u8Port = g_au8DigitalPortTable[u8Pin]; u8Bit = g_au8DigitalPinMaskTable[u8Pin]; u8StateMask = (u8Value ? u8Bit : 0); if (u8Port != NOT_A_PIN) { Px = getPortInputRegisterAddr(u8Port); u32TimeoutCycles = microsecondsToClockCycles(u32Timeout); timeOut = pulseInWait(Px, u8Bit, u8StateMask, &u32TimeoutCycles); if (!timeOut) { timeOut = pulseInWait(Px, u8Bit, u8StateMask ^ u8Bit, &u32TimeoutCycles); if (!timeOut) { timeOut = pulseInCount(Px, u8Bit, u8StateMask, u32TimeoutCycles, &u32PulseCycles); } } if (timeOut) { u32PulseLength = 0; } else { u32PulseLength = clockCyclesToMicroseconds(u32PulseCycles); } } } FUNC_MUTEX_UNLOCK; return u32PulseLength; }
digipontaさん、
GR-KURUMIのRL78は、オンボードのフルカラーLEDへのanalogWriteで、ハードウェアPWMを再割り当てできるんでしょうか?
オンボードのフルカラー LED は結線されてる RL78/G13 の端子がそれぞれ
となっており、この中でハードウェア PWM で使えそうなのは赤の TO02 のみですが、TO02 はいまのところ 5番ピンのハードウェア PWM に専用的に割り当ててるのでライブラリそのまゝではダメですね。 もちろん、ライブラリを修正すれば対応も可能ですが、フルカラー LED の赤のみ対応というのもあんま面白くない気がします。シリアル LED へのアクセス方法を改めてオンボードのフルカラー LED も PWM 動作する用工夫する方が良い気がしますが。
V1.11 確認、
gr_common/include/RLduino78.h の
#define interrupts() asm("EI;")
と
#define noInterrupts() asm("DI;")
をそれぞれ
#define interrupts() __asm __volatile("EI;")
#define noInterrupts() __asm __volatile("DI;")
にしていただきたい。
gr_common/RLduino78/libraries/Servo/Servo.h の
int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH
を
int16_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH int16_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH
も同様。
V1.11 の gr_common/RLduino78/cores/RLduino78_RTC.cpp の中の static void _rtc_set_constant_period_interrupt_time(RTC_CONSTANT_PERIOD_TIME ct) のコメントが間違っているので修正してください。
/** * 定周期期間を設定します。 * * @param[in] ct 定周期期間を指定します。 * RTC_CONSTANT_PERIOD_TIME_NONE: 定周期割り込み機能を使用しない * RTC_CONSTANT_PERIOD_TIME_HALFSECOND: 0.5秒に1度(秒カウントアップに同期) * RTC_CONSTANT_PERIOD_TIME_1SECOND: 1秒に1度(秒カウントアップと同時) * RTC_CONSTANT_PERIOD_TIME_1MINUTE: 1分に1度(毎分00秒) * RTC_CONSTANT_PERIOD_TIME_1HOUR: 1時間に1度(毎時00分00秒) * RTC_CONSTANT_PERIOD_TIME_1DAY: 1日に1度(毎日00時00分00秒) * RTC_CONSTANT_PERIOD_TIME_1MONTH: 1月に1度(毎月1日午前00時00分00秒) * * @retval 0:定周期期間の設定に失敗しました。 * @retval 1:定周期期間の設定に成功しました。 * * @attention なし ***************************************************************************/ static void _rtc_set_constant_period_interrupt_time(RTC_CONSTANT_PERIOD_TIME ct)
attachCyclicHandler() で呼ばれる関数が millis() がオーバーフローする付近で動作がおかしくなることの確認用スケッチ
#include <RLduino78.h> int led_red = 22; int led_green = 23; int led_blue = 24; // 呼ばれる度にオンボードのLEDを // 赤→緑→黄→青→マゼンダ→シアン→白→(赤に戻る) void timerFunc(unsigned long) { static int n = 1; analogWrite(led_red, n & 1 ? 255 - 20 : 255); analogWrite(led_green, n & 2 ? 255 - 20 : 255); analogWrite(led_blue, n & 4 ? 255 - 20 : 255); n = n % 7 + 1; } void setup() { // millis() の内部値をオーバーフローちょい手前に設定する noInterrupts(); extern volatile unsigned long g_u32timer_millis; g_u32timer_millis = 4294962000UL; interrupts(); attachCyclicHandler(0, timerFunc, 1000); } void loop() { }
赤→緑→黄→青→(謎の点滅)→(以下正常)
attachCyclicHandler() 等修正案
gr_common/RLduino78/cores/RLduino78_basic.cpp:
// 周期起動ハンドラ関数テーブル #if 0 static fITInterruptFunc_t g_afCyclicHandler[MAX_CYCLIC_HANDLER] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; static uint32_t g_au32CyclicTime[MAX_CYCLIC_HANDLER] = { 0, 0, 0, 0, 0, 0, 0, 0}; static uint32_t g_au32CyclicHandlerPerformTime[MAX_CYCLIC_HANDLER] = { 0, 0, 0, 0, 0, 0, 0, 0}; #else static struct { fITInterruptFunc_t afCyclicHandler; uint32_t au32CyclicTime; uint32_t au32RemainTime; uint32_t au32LastTime; } g_CyclicHandlerTable[MAX_CYCLIC_HANDLER] = { {NULL, 0, 0, 0}, }; #endif
void attachCyclicHandler(uint8_t u8HandlerNumber, void (*fFunction)(unsigned long u32Milles), uint32_t u32CyclicTime) { FUNC_MUTEX_LOCK; #if 0 if (u8HandlerNumber < MAX_CYCLIC_HANDLER) { g_afCyclicHandler[u8HandlerNumber] = fFunction; g_au32CyclicTime[u8HandlerNumber] = u32CyclicTime; g_au32CyclicHandlerPerformTime[u8HandlerNumber] = g_u32timer_millis + u32CyclicTime; } #else if (u8HandlerNumber < MAX_CYCLIC_HANDLER) { detachCyclicHandler(u8HandlerNumber); g_CyclicHandlerTable[u8HandlerNumber].au32CyclicTime = u32CyclicTime; g_CyclicHandlerTable[u8HandlerNumber].au32RemainTime = u32CyclicTime; g_CyclicHandlerTable[u8HandlerNumber].au32LastTime = millis(); g_CyclicHandlerTable[u8HandlerNumber].afCyclicHandler = fFunction; } #endif FUNC_MUTEX_UNLOCK; }
void detachCyclicHandler(uint8_t u8HandlerNumber) { FUNC_MUTEX_LOCK; if (u8HandlerNumber < MAX_CYCLIC_HANDLER) { #if 0 g_afCyclicHandler[u8HandlerNumber] = NULL; g_au32CyclicTime[u8HandlerNumber] = 0; g_au32CyclicHandlerPerformTime[u8HandlerNumber] = 0; #else g_CyclicHandlerTable[u8HandlerNumber].afCyclicHandler = NULL; g_CyclicHandlerTable[u8HandlerNumber].au32CyclicTime = 0; g_CyclicHandlerTable[u8HandlerNumber].au32RemainTime = 0; g_CyclicHandlerTable[u8HandlerNumber].au32LastTime = 0; #endif } FUNC_MUTEX_UNLOCK; }
void execCyclicHandler() { int i; for (i = 0; i < MAX_CYCLIC_HANDLER; i++) { #if 0 if (g_afCyclicHandler[i] != NULL) { if (g_u32timer_millis >= g_au32CyclicHandlerPerformTime[i]) { g_au32CyclicHandlerPerformTime[i] = g_au32CyclicTime[i] + g_u32timer_millis; (*g_afCyclicHandler[i])(g_u32timer_millis); } } #else if (g_CyclicHandlerTable[i].afCyclicHandler != NULL) { unsigned long currentTime = millis(); unsigned long elapsedTime = currentTime - g_CyclicHandlerTable[i].au32LastTime; g_CyclicHandlerTable[i].au32LastTime = currentTime; bool exec = g_CyclicHandlerTable[i].au32RemainTime <= elapsedTime; g_CyclicHandlerTable[i].au32RemainTime -= elapsedTime; if (exec) { g_CyclicHandlerTable[i].au32RemainTime += g_CyclicHandlerTable[i].au32CyclicTime; g_CyclicHandlerTable[i].afCyclicHandler(currentTime); } } #endif } }
gr_common/RLduino78/cores/RLduino78_basic.cpp のなかの micros() で割り込みを止めずに g_u32timer_millis を参照していたので修正
else { // ミリ秒 x 1000; m = millis() * 1000; }
2年ちょっと前の GR-KURUMI プロデューサーミーティングの最後の回で配られた資料『GR-KURUMI 最終報告』というので KURUMI のライブラリは Arduino に対して大して処理性能で差が出せず少し残念というのがあり、ちょっと v1.11 で digtalWrite() と digitalRead() の処理速度がどんなもんだか測ってみた。
digitalWrite() 処理速度測定スケッチ
pin2 の出力をオシロにつなぎ、どれくらいの速度でオン/オフできるか測定する
#include <RLduino78.h> void setup() { pinMode(2, OUTPUT); } void loop() { digitalWrite(2, HIGH); digitalWrite(2, LOW); digitalWrite(2, HIGH); digitalWrite(2, LOW); digitalWrite(2, HIGH); digitalWrite(2, LOW); digitalWrite(2, HIGH); digitalWrite(2, LOW); digitalWrite(2, HIGH); digitalWrite(2, LOW); }
digitalRead() 処理速度測定スケッチ
pin2 の出力をオシロにつなぎ、pin2 の出力が HIGH になってる期間(digitalWrite() 1回+digitalRead() 11回分の時間)を測定し、digitalRead() 1回分の処理時間を求める
#include <RLduino78.h> void setup() { pinMode(2, OUTPUT); pinMode(3, INPUT); } void loop() { digitalWrite(2, HIGH); digitalRead(3); digitalRead(3); digitalRead(3); digitalRead(3); digitalRead(3); digitalRead(3); digitalRead(3); digitalRead(3); digitalRead(3); digitalRead(3); digitalRead(3); digitalWrite(2, LOW); }
以上の測定方法で、件の資料によると Arduino の digitalWrite() が 3.9μ秒、digitalRead() が 5.4μ秒とのこと。
GR-KURUMI ライブラリ v1.11 digitalWrite() 測定
digitalWrite() 1回あたり 約4.1μ秒
digitalRead() 測定
digitalRead() 1回あたり (約54.0-約4.1)/11 ≒ 約4.5μ秒
確かに Arduino とほゞ変わらない速度で、差別化できていないカンジ。
そんなわけで、digitalWrite() と digitalRead() の高速化を図ってみたのだった。
digitalWrite() 測定
digitalWrite() 1回あたり 約2.2μ秒
digitalRead() 1回あたり (約16.0-約2.2)/11 ≒ 約1.3μ秒
まあちょっとは高速化できたのだけど、まだ差別化というのには遠い気がする。
そんなわけで、digitalWrite() と diitalRead() を置き換えるマクロ、fastDigitalWrite() と fastDigitalRead() を作成してみた。
使い方は digitalWrite() や digitalRead() と大して変わらないが、関数でなくマクロで実装されており、ポート・レジスタの内容を書き換える/読み出すのみの内容であり、digitalWrite() にあった入力プルアップ抵抗を許可する機能はない。
先の digitalWrite() と digitalRead() の処理速度測定スケッチを fastDigitalWrite() と fastDigitalRead() 用に書き換えると、それぞれ次のとおりとなる。
#include <RLduino78.h> #include <fastio.h> void setup() { pinMode(2, OUTPUT); } void loop() { fastDigitalWrite(2, HIGH); fastDigitalWrite(2, LOW); fastDigitalWrite(2, HIGH); fastDigitalWrite(2, LOW); fastDigitalWrite(2, HIGH); fastDigitalWrite(2, LOW); fastDigitalWrite(2, HIGH); fastDigitalWrite(2, LOW); fastDigitalWrite(2, HIGH); fastDigitalWrite(2, LOW); }
#include <RLduino78.h> #include <fastio.h> void setup() { pinMode(2, OUTPUT); pinMode(3, INPUT); } void loop() { fastDigitalWrite(2, HIGH); fastDigitalRead(3); fastDigitalRead(3); fastDigitalRead(3); fastDigitalRead(3); fastDigitalRead(3); fastDigitalRead(3); fastDigitalRead(3); fastDigitalRead(3); fastDigitalRead(3); fastDigitalRead(3); fastDigitalRead(3); fastDigitalWrite(2, LOW); }
fastDigitalWrite() 測定
fastDigitalWrite() 1回あたり 約0.0625μ秒
fastDigitalRead() 測定
fastDigitalRead() 1回あたり (約1.44-約0.0625)/11 ≒ 約0.125μ秒
まあ Arduino に対しては差別化できたかな。
一応まとめ
Fujitaさん、ご検討いただき誠にありがとうございます。固定ピンを操作するには非常に有効ですね。
今度はanalogReadを早くしたいですね。
fastDigitalWrite() と fastDigitalRead() が引数に変数を使うとコンパイルエラーになるので修正中ですが、デジタルI/Oの高速化は要望として聞いたことがないし(そもそもライブラリ全般についての要望自体少ない)需要があるのかわからんところが辛いところですね。
ライブラリの修正・改良は、
以上の作業が複合したものと思いますが、1. は当然行われるべきものとしても、2. や 3. については作業者個人の考えのみでは独善的なものにもなりうるため、他者の意見等には耳を傾けたいものです。
今んとこ予定(と一部作業中)の内容一覧
タイミングが厳しかったら、直接レジスタを叩けばいいか!と思っていましたが、汎用性を確保しつつ、高速なら需要は有ると思う。
直接レジスタを叩く発想ができる人からはライブラリ改善の要望は出ず、そうでない人は「こういうもんかな」で納得するのでやはり要望とかは出てこないのかなという気はしますね。
fastDigitalWrite() と fastDigitalRead() の引数に変数を使用するとコンパイルエラーとなっていたので修正。
pinMode() と digitalWrite() の実装で疑問
現在の pinMode() の実装で、
となっており、INPUT と INPUTPULLUP でポート入力モード・レジスタ(PIMx)の設定を変えてる意図がわからん。等しく CMOS入力バッファではダメなんだろうか?
また、digitalWrite() の実装で、ポート・モード・レジスタ(PMxx)の該当ビットがセットされてる(= 入力モード。INPUT か INPUT_PULLUP に設定されている)ピンに対しての動作として、
という実装となっており、pinMode() の実装と対称となっていないのだけど、何か意図があってのものなのだろーか?
fastio.h 不具合修正と fastDigitalWrite() コードサイズ改善と fastDigitalRead() の高速化。
HardwareSerial::flush() の動作が正確でない。
#include <RLduino78.h> void setup() { Serial.begin(9600); Serial.print("0123456789"); Serial.flush(); Serial.end(); } void loop() { }
↑を実行すると、
012345678
までしか出力されない。 それへの修正。
Fujitaさん、いつもありがとうございます。