s.takagi
2015年3月11日 11時45分
高木と申します。
お世話になっております。
Armadillo-420 SPI通信の転送バイト数について
https://armadillo.atmark-techno.com/forum/armadillo/1178
Armadill-460 SPIの16ビット転送での転送落ち
https://armadillo.atmark-techno.com/forum/armadillo/793
上記2点の質問を参考にパッチを当ててみましたが、ioctlでの8ビット以上の転送がうまく行きません。
手順とソースを下記に記しますので、解決方法がございましたらご教授頂けませんでしょうか?
踏んだ手順を下記の通りです。
1)linux-2.6.26-at23に「0001-mxc_spi-fix-over-8-byte-transfer-error.patch」をあて、カーネルをビルド。
atmark@atde3:~/linux-2.6.26-at23$ patch -p1 < ../0001-mxc_spi-fix-over-8-byte-transfer-error.patch patching file drivers/spi/mxc_spi.c atmark@atde3:~/linux-2.6.26-at23$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- && gzip -c arch/arm/boot/Image > linux.bin.gz
2)Armadilloに書き込み
atmark@atde3:~/linux-2.6.26-at23$ sudo cp ./linux.bin.gz /var/lib/tftpboot hermit> tftpdl (ArmadilloのIPアドレス) (ATDEのIPアドレス) --kernel=linux.bin.gz
ioctlのソースは下記の通りです。
static int spi_send_image(u8 *ptrImage, int numBytes) { int i; u8 *ptr; int numBlocks; u32 numFullBlocks; /* 満載のブロック数 */ u32 lastBlockSize; /* 積み残しブロックのバイト数 */ struct spi_ioc_transfer *tr = NULL; /* SPI 転送の構造体 */ for (i = 0; i < numBytes; i++){ u8 tmp = ptrImage[i]; ptrImage[i] = ptrImage[i + 1]; ptrImage[i + 1] = tmp; } numFullBlocks = numBytes / SPI_BLOCKSIZE; lastBlockSize = numBytes % SPI_BLOCKSIZE; tr = (struct spi_ioc_transfer *)malloc( sizeof(struct spi_ioc_transfer) * (numFullBlocks + 1)); // 転送ブロック(満載)を用意 ptr = ptrImage; for (i = 0; i < numFullBlocks; i++) { tr[i].tx_buf = (unsigned long)ptr; tr[i].rx_buf = (unsigned long)NULL; tr[i].len = SPI_BLOCKSIZE; tr[i].speed_hz = SPI_SPEED_HZ; tr[i].delay_usecs = SPI_DELAY_USECS; tr[i].bits_per_word = SPI_BITS; tr[i].cs_change = 0; ptr += SPI_BLOCKSIZE; } numBlocks = numFullBlocks; // 積み残し分の転送ブロックを追加(必要に応じて) if (lastBlockSize) { i = numFullBlocks; tr[i].tx_buf = (unsigned long)ptr; tr[i].rx_buf = (unsigned long)NULL; tr[i].len = lastBlockSize; tr[i].speed_hz = SPI_SPEED_HZ; tr[i].delay_usecs = SPI_DELAY_USECS; tr[i].bits_per_word = SPI_BITS; tr[i].cs_change = 0; numBlocks += 1; } // 転送ブロックの送信 int ret = ioctl(spi_fd, SPI_IOC_MESSAGE(numBlocks), tr); free(tr); if (ret < 0) { perror("error - spi send image"); return -1; } return 0; }
以上、どうぞ宜しくお願いします。
コメント
y.nakamura
中村です。
高木さんのコードをあまりよく読んでいませんが・・・
> SPIドライバ内(mxc_spi.c)にて送信できる最大サイズが8バイトと規定され、
> それ以上を上位から渡された場合は送信しないようです。
>
> ドライバ側で(無理やり)それに対応したコードを掲載します。ご参考まで。
ioctl(spi_fd, SPI_IOC_MESSAGE(numBlocks), tr);
でやるなら、mxc_spi.cに手をいれなくても8バイト以上の送信ができると思います。
ダメなのでしょうか?
mxc_spi.cを修正して8バイト以上の送信ができるようにする方法は、
ML時代に投稿したこれも参考にしてください。
http://lists.atmark-techno.com/pipermail/armadillo/2013-July/009050.html
http://lists.atmark-techno.com/pipermail/armadillo/2013-July/009059.html
--
なかむら
y.nakamura
中村です。
> 上記2点の質問を参考にパッチを当ててみましたが、ioctlでの8ビット以上の転送がうまく行きません。
どのように「うまく行かない」のかがわかりませんが・・・
(「8ビット以上」と書いてありますが「8バイト以上」の間違いですよね)
// ついでに・・・
// > Armadill-460 SPIの16ビット転送での転送落ち
// > https://armadillo.atmark-techno.com/forum/armadillo/793
// のパッチファイル
// 0001-mxc_spi-fix-over-8-byte-transfer-error.patch
のファイル名「over-8-byte」は「over-8-bit」の間違い?
>
> static int spi_send_image(u8 *ptrImage, int numBytes) > { ... > for (i = 0; i < numBytes; i++){ > u8 tmp = ptrImage[i]; > ptrImage[i] = ptrImage[i + 1]; > ptrImage[i + 1] = tmp; > } ... >
このforループの"i++"が問題ということはありませんか?
"i += 2"の間違いとか?(numBytesを偶数として)
--
なかむら
sid5323
2015年3月11日 14時39分
森本と申します。
SPIドライバ内(mxc_spi.c)にて送信できる最大サイズが8バイトと規定され、
それ以上を上位から渡された場合は送信しないようです。
ドライバ側で(無理やり)それに対応したコードを掲載します。ご参考まで。