0

外部 RF チップとの SPI 通信をプログラミングしています。マイクロコントローラは、Microchip のモデル PIC24FJ64GA102 です。

SPIの拡張バッファ モードを使用したい。

問題: 受信バッファから受信バイトを取得します。

使用される SPI 関数:

void SPI1_get(uint8_t* data, uint16_t length) {
    uint16_t i = 0, l = length;
    uint8_t dummy;
    while (length > 0) {
        while (SPI1STATbits.SPITBF || SPI1STATbits.SPIRBF) {
            dummy = SPI1STAT;
        }
        do {
            SPI1BUF = 0xff;
        } while (SPI1STATbits.SPIRBF == 0 && --length > 0);
        do {
            while (SPI1STATbits.SRMPT == 0) {
            }
            data[i] = SPI1BUF;
            ++i;
        } while (i < l && SPI1STATbits.SRXMPT != 1);
    }
}

ここで呼び出し:

uint8_t cmd[2]; cmd[0] = length; cmd[1] = address;
SPI1_put(cmd,2); // e.g: 0x02, 0x01
SPI1_get(buf,2); // e.g: 0x05, 0x01 (received data)

通信は問題なく、オシロスコープと SPI デコード モジュールでチェックされています。SPI バス上のデータは、上記のコメントのようなものです: sent 0x02 0x01 0xff 0xff、 received0x00 0x00 0x05 0x01ですが、上記の関数は受信バッファーからデータを正しく取得しません。私はすでにフラグと割り込みをチェックする多くのコンスタレーションをテストしましたが、最終的に得られる最良の結果は次のとおりです:(0x00 0x01最後のバイトのみが正しい)。

また、コードに影響を与えない (すべきではない) 2 つの SPI 問題が記載されているエラータ シートも既に確認しました。

私は一体何を間違っているのですか?!

ここで要求されているように、SPI1_put() 関数:

void SPI1_put(uint8_t* data, uint16_t length) {
    uint16_t i = 0;
    uint8_t dummy;
    for (; i < length; ++i) {
        while (SPI1STATbits.SPITBF)
            ; // maybe change to (_SPI1BEC == 7) ?
        SPI1BUF = data[i];
        dummy = SPI1BUF; //dummy read
    }
}

[最新の編集: 2015-02-05]

そのため、今日、私はこの特定の問題にもう少し時間を費やすことができ、エラッタ シートに記載されているバグにも対処しながら、ElderBug の提案を移植することにしました。

uint8_t out_buf[128];
uint8_t in_buf[128];

void SPI1_com(uint8_t* out, uint8_t* in, uint16_t out_len, uint16_t in_len) {
    uint16_t len = out_len + in_len;
    uint16_t sent = 0, recv = 0, i = 0;
//  while (!SPI1STATbits.SRXMPT)
    sent = SPI1BUF; // empty buffer
    sent = SPI1BUF; // empty buffer
    sent = 0;
    if (out != out_buf && out != 0)
        memcpy(out_buf, out, out_len);
    while (sent < len && recv < len) {
        if (SPI1STATbits.SPIBEC != 7 && sent < len) {
            SPI1BUF = out_buf[sent++];
        }
        if (!SPI1STATbits.SRXMPT && recv < len) {
            in_buf[recv] = SPI1BUF, recv++;
        }
    }
    if (in != 0) {
        for (i = 0; i < in_len; ++i) {
            in[i] = in_buf[out_len + i];
        }
//      memcpy(in, in_buf + out_len, in_len);
    }
    for (i = 0; i < len; ++i) {
        out_buf[i] = 0xff;
        in_buf[i] = 0xff;
    }
}

このコードは基本的に機能します。私が回避できなかった例外を除いて:

通信は次のように機能します。

  • 1byte: r/w-bit+length
  • 1byte:アドレス
  • 1~127バイト:データ

したがって、スレーブ チップから 1 バイトを読み取ると、つまり 3 バイト (rw+len、アドレス、ダミーバイト) を送信すると、in_bufバッファにあるデータは 0xFF になります。ここで奇妙なことに、何も変更せずにもう 1 バイト (バス上のダミー バイトを 1 つだけ) 読み取ると、私の最初のバイトin_bufは正しいデータを取得しています。しかし、私のプログラムはまだいくつかの点でスタックしているため、これは常に機能するとは限りません。

私はここにたくさんの疑問符を残して座っています。

2番目の奇妙なこと:8バイトを読み取り、最後のバイトまでバッファ内のデータが正しい、最後のバイトが0xFFである、0x00である必要があります。え?

PS: この問題のサポートのために、Microchip にチケットを提出済みです。

4

1 に答える 1