2013-04-09 2 views
6

이 문제가 소프트웨어 관련 하드웨어보다 많을지라도 도움을 얻을 수 있기를 바랍니다. 프리 스케일 P1021 프로세서 (ppc, e500v2 코어)를 기반으로하는 맞춤형 보드에서 작업하고 있습니다. 외부 PCB가 연결되고 SPI로 구성 될 수 있습니다. 이 외부 PCB의 사양은 전이중 모드에서 2 바이트 명령을 예상하며 마지막 바이트 만 MISO에서 데이터를 다시 전송하는 데 사용됩니다.Spidev는 ioctl을 사용하여 동시에 쓰거나 읽지 않습니다.

현재이 장치를 테스트하기 위해 일부 소프트웨어를 준비하고 있습니다. 그래서 나는 잘 알려진 spi_test 프로그램으로 시작했다.

[email protected]:~# ./spi_test -D /dev/spidev32766.3 
spi mode: 0 
bits per word: 8 
max speed: 500000 Hz (500 KHz) 

00 00 00 00 00 00 
00 00 00 00 00 00 
00 00 00 00 00 00 
00 00 00 00 00 00 
00 00 00 00 00 00 
00 00 00 00 00 00 
00 00 
[email protected]:~# 

Pic1

신호는 클럭 (608)을 도시하며 전반 데이터 만이있는 것으로 보인다. 루프백으로 조사하고 테스트하기로 결정했습니다. MOSI-MISO 루프를 shorcutting하여 rx 버퍼로 데이터를 되돌려 놓습니다. 결과 :

[email protected]:~# ./spi_test -D /dev/spidev32766.3 
spi mode: 0 
bits per word: 8 
max speed: 500000 Hz (500 KHz) 

FF FF FF FF FF FF 
40 00 00 00 00 95 
FF FF FF FF FF FF 
FF FF FF FF FF FF 
FF FF FF FF FF FF 
DE AD BE EF BA AD 
F0 0D 
[email protected]:~# 

Pic2

이 신호는 전체 전보 어떤 이유로 반복된다 (왜 몰라) 알 수있다. 그러나 프로그램은 수신 된 데이터를 콘솔에 올바르게 표시하므로 spi_test가 예상 한 것처럼 나타날 수 있습니다.

#ifdef ORIG 
    uint8_t tx[] = { 
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
     0x40, 0x00, 0x00, 0x00, 0x00, 0x95, 
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
     0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 
     0xF0, 0x0D, 
    }; 
#else 
    uint8_t tx[] = { 
     0xAA, 0x81, 
    }; 
#endif 

를하지만 기대하지 않았다으로 32 비트가 이동됩니다

내가 2 바이트까지이 프로그램에 전송됩니다 패턴을 조작 또한 같은 (내가 목표로 요청 된 명령 형식을 시뮬레이션) 처음 2 바이트 동안 MOSI는 tx []에서 두 바이트를 제공하고 나머지 두 바이트는 0/0입니다.

[email protected]:~# ./spi_test_2bytes -D /dev/spidev32766.3 
spi mode: 0 
bits per word: 8 
max speed: 500000 Hz (500 KHz) 

00 00 
[email protected]:~# 

Pic3

내가 데이터를 MISO 않음 MOSI 루프백 경우에도 수신 (콘솔 출력은 여전히 ​​동일한 수신 "00"이다) : 여기 콘솔 출력 결과 신호이다

Pic4

나는 모든 매개 변수와 비트 주위에 재생 및 반이중을 사용하는 테스트 프로그램을 변경하기로 결정 (전송 전용) 모드 :

#ifdef ORIG 
    uint8_t tx[] = { 
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
     0x40, 0x00, 0x00, 0x00, 0x00, 0x95, 
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
     0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 
     0xF0, 0x0D, 
    }; 
#else 
    uint8_t tx[] = { 
     0xAA, 0x81, 
    }; 
#endif 
    uint8_t rx[ARRAY_SIZE(tx)] = {0, }; 
    struct spi_ioc_transfer tr = { 
     .tx_buf = (unsigned long)tx, 
#ifdef ORIG  
     .rx_buf = (unsigned long)rx, 
#else 
     .rx_buf = 0, 
#endif 

이것은 컴파일 된 것으로 실행 된 것으로 예상됩니다. SPI_CLK는 16 비트에 대해 16 사이클을 반복하며 MOSI는 예상대로 데이터를 제공합니다. Cosole 출력에는 수신 된 데이터를 표시하지 않고 신호가 예상 같다 :

[email protected]:~# ./spi_test_2bytes -D /dev/spidev32766.3 
spi mode: 0 
bits per word: 8 
max speed: 500000 Hz (500 KHz) 

00 00 
[email protected]:~# 

Pic5

Pic6

실제로 대신 2 바이트 전이중 전송을하는 I는 다음에 N 바이트의 전송을 저 보인다 N 바이트 수신.

  1. 이유를 0xAA, 0x81 등 및 × 00, × 00가 전송 :

    사실은 두 가지 질문이 있습니다?

  2. 원래 코드가 rx 버퍼에서 데이터를 다시 가져올 수있는 이유는 무엇입니까 (루프백 사용). 그러나 2 바이트로 줄이면 데이터가 수신되지 않습니까?
+0

후 다른 이미지와이 질문에 대해 그들에게 링크를 추가 - 더 높은 대표 사용자가 다음 오늘을 확인합니다 그들에게 –

+0

을 포함하는 답변을 편집 할 수 있습니다 spidev은 SPI_MASTER_HALF_DUPLEX 플래그로 컴파일 된 경우 enabled로 설정하면 spi 장치가 반이중으로 설정됩니다. – stede

+0

SPI_MASTER_HALF_DUPLEX이 (가) 설정되지 않았습니다. – stede

답변

1

글쎄, 압도적 인 게시물입니다. 방금 일부를 읽었으며 최근에 Linux에서 SPI를 사용했습니다. 그러나 언급 된대로 https://www.kernel.org/doc/Documentation/spi/spidev 비동기 읽기/쓰기는 사용자 공간에서 사용할 수 없습니다. AFAIK 읽기/쓰기는 fcntl을 감싸는 래퍼 일뿐입니다. 따라서 비동기 I/O를 구현하려면 자체 커널 모듈을 작성해야합니다.

+0

이 답변은 틀린 것 같습니다. https://www.kernel.org/doc/Documentation/spi/spidev 기사에서는 특별히 "ioctl() 요청 사용, 전이중 전송 ... 사용할 수 있음"이라고 말합니다. 그리고 spi-test (예 : https://github.com/KnCMiner/spi-test/blob/master/spi-test.c#L97)는 해당 ioctl()을 사용합니다. –

0

나는 이것이 매우 오래된 스레드라는 것을 알고 있지만 OpenWRT를 실행하는 RT5350에서 spidev를 사용해 왔습니다. 나는 너와 똑같은 결과를 얻고있다. 나는 전이중 전송을 할 수 없다. RT5350 데이터 시트를 읽으면 하드웨어가 반이중 SPI 전송 만 수행 할 수있는 것처럼 보입니다. 각 전송은 쓰기 (MOSI의 출력 바이트, 아무 것도 읽지 않음) 또는 읽기 (MOSI의 출력 0, MISO 읽기)입니다.

P1021 칩에 대한 데이터 시트를 가져올 수 없지만 하드웨어의 SPI가 유사한 방식으로 구현되었다고 말하면 결과가 비슷하다는 점을 고려해보십시오.

이것은 커널 모듈이 대답이 아니라는 것을 의미합니다 (ioctl SPI_IOC_MESSAGE는 결국 결국 spi_async()를 호출합니다). 전이중 SPI를 수행하는 유일한 방법은 소프트웨어에서 GPIO를 사용하는 것입니다.

RT5350 참조 : http://forum.vocore.io/viewtopic.php?f=3&t=72#p233

관련 문제