
相変わらず、SDカードの読み書きがPIC32MXで出来ない。ChaNさんのFatfsだけど、pic24だとすんなり動くんだけど、PIC32に移植したら動かない。というか、最初の初期化で失敗する。単にクロックを送るだけなんだけど、SDカードから反応が返ってこない。
で、ロジアナいるなーってことで、作ってみたら動いた。めずらし(苦笑)

pickit2のロジアナでSPIを見ているところ

teratermに表示させると、0と1だけど、なんとなく、データが見えてこない?(笑)ほら、地球防衛本部で、紙テープが出てきて、それを読んで、大変なことになった、なんてアレを思い出してもらうと、いいかも(^^;;;下2ビットがデータで、ちゃんと見えてる。クロック1MHzでサンプリングのはずだけど、一応数えてみるとちゃんとクロック幅は16個=16usであってると思う。
で、本題の前にはまったことの覚え書き。
1.PIC32の割り込みは、トリガではなく、ステータスフラグの場合がある
前にも受信割り込みで動かねー。とやっていたが、今回ChaNさんのライブラリが送信割り込みも使っていたので、それをPIC32に持ってきたら、やっぱり動かない。どうしても、PIC24までのトリガ(というのでいいのだろうか? 送信バッファが空になったら送信割り込み、が起きるが、割り込みルーチン内で、そのフラグをクリアすると、割り込みはそれ以降再び空になるまで起きない)に慣れているせいで、送信割り込み内でフラグをクリアしただけでリターンすると、バッファが空なので、また割り込みが起きるPIC32には、まだまだ慣れない。ということで、ここで無限ループ。。。となる。
2.MICROCHIPのライブラリは、信用してはいけない
UART2PrintString ("init 1\n");
if (_TRISB5 == 1) {
UART2PrintString ("TRISB5 chenged\n");
}
SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN5 );
UART2PrintString ("init 2\n");
if (_TRISB5 == 1) {
UART2PrintString ("TRISB5 chenged\n");
}
OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 );
UART2PrintString ("init 3\n");
if (_TRISB5 == 1) {
UART2PrintString ("TRISB5 chenged\n");
}
EnableADC10(); // Enable the ADC
UART2PrintString ("init end\n");
if (_TRISB5 == 1) {
UART2PrintString ("TRISB5 chenged\n");
}
さて、上記コード、なにやってるかわかりますよね。ADCの初期化をライブラリに任せると、ADCとは関係無いTRISまで、書き換えてくれるので、犯人捜しのコードです。
MPLABXだと、カーソル当てて右クリックで、定義に移動できるので、使う前に是非ソースをお読みになるか、ライブラリをまったくあてにしないで使わない、というのが正しい姿勢だと思います。
mPORTBSetPinsDigitalOut(BIT_5);
ConfigCNBPullups(CNB5_PULLUP_ENABLE);
上記2つのコードもそうです。同じような扱いのはずなんですが、違います。
mPORTBSetPinsDigitalOut(BIT_5);
ConfigCNBPullups(CNB5_PULLUP_ENABLE);
mPORTBSetPinsDigitalOut(BIT_6);
ConfigCNBPullups(CNB6_PULLUP_ENABLE);
なんて、ピンごとに初期化すると、うまくありません。何でかは、定義に移動して怒ってください。
3.Bootloaderは16bitコードを書けないかもしれない。
これはまだ、確証がないのですが、AN1388のbootloaderで16bitコード有効にしたアプリケーションを書き込もうとすると、verifyエラーが出ます。たぶん、32bitのアラインが崩れているところで引っかかるのでは、と思っていますが、Pcapplicationを改造しようとしたら、MFCだったかな、ライブラリが必要で、それは、VCexpressにはついてないので、コンパイルできない。というオチが待っていました。とほほ。
というわけで、あきらめて16bitやめたら、うまく使えています。
本題のロジアナコード
void usbsend(char * buf, int len) {
while (!USBUSARTIsTxTrfReady()) {
USBDeviceTasks();
CDCTxService();
}
putUSBUSART(buf, len);
}
void logiana() {
char buf[10];
int i, j, c;
UART2PrintString("\n\nlogiana start\n");
ANSELB = 0;
TRISB |= 0x00FF;
ANSELAbits.ANSA0 = 0;
ANSELAbits.ANSA1 = 0;
_LATA1 = 0;
_TRISA1 = 1;
_LATA0 = 1;
_TRISA0 = 0;
CNPUAbits.CNPUA0 = 1;
databufc = 0;
while (_RB0 == 1) {
if (_RA0 == 0) {
UART2PrintString("logiana aboat\n");
_LATA1 = 0;
return;
}
}
_LATA1 = 0;
//UART2PrintString ("logiana datain start\n");
while (1) {
while (!IFS0bits.T5IF);
IFS0bits.T5IF = 0;
databuf[databufc++] = PORTB;
if (databufc >= 1000) {
break;
}
}
UART2PrintString("logiana dataget\n");
for (i = 0; i < 1000; ++i) {
c = databuf[i];
for (j = 0; j < 8; ++j) {
if (c & 1)
buf[7 - j] = '1';
else
buf[7 - j] = '0';
c >>= 1;
}
buf[8] = '\n';
usbsend(buf, 9);
}
UART2PrintString("logiana send fin\n");
}
肝心の部分はこれだけです。大体わかりますよね、雰囲気。timer5を必要なタイミングでまわしておいてください。
何しろ40MHzで動いているのですから、この原始的タイマフラグチェック方式でも数MHzは余裕でしょう。MIPSってパイプラインがあるはずですので、分岐でどのぐらいペナルティがあるかわからないんですが、とりあえず1MHzでは動いているようです。
このテストでは、PIC32MX250F128Bを使っていますが、-O0でコードサイズ32K行きませんので、PIC32MX220F032Bでも使えそうです。バッファも1000バイトにしていますが、USBに取られるのはRAM500バイトぐらいなので、PIC32MX220F032Bでも7000サンプリングぐらいはいけそうです。
RB6等ピンが抜けているところがあるので、7000サンプリング7chか、3500サンプリング13chのロジアナが、220円のpicで出来る、、というわけ(^^)
まあ、実際には、picレギュレータ用のコンデンサが10円。電源3.3vレギュレータで100円。usbケーブル100均で100円。ポリスイッチ50円。ユニバーサル基盤にすると6,70円。220円で、安いってだまされると、ろくなもんじゃない。
ちなみに、完成品はというと、、、、
http://dx.com/p/logic-analyzer-w-dupont-lines-and-usb-cable-for-scm-black-148945
なんてのが$12足らずであります。めっちゃよさげで、安いし買おうかな、と思って調べたら、まんまピーコ品の模様。おまけに本家のファームとか焼いて、本家のアナライズソフト使うんだって。さすがに買うのは気が引ける(--;