또다시 반년만에 이어지는 글;;
이번에 다룰 내용은 하나의 SPI 버스에 여러개의 장치를 연결한 경우 인터페이싱 하는 방법에 관한 것이다. 간단한 구성을 설정하고 예를 들어 설명하는 것이 보다 직관적일 듯 하여 myGyro300SPI 3개를 동시에 연결한 경우를 예로 살펴보려 한다.
myGyro300SPI는 1축 자이로 센서이므로 서로 직교하도록 3개의 센서를 연결해 사용하려는 생각을 쉽게 할 수 있다. 아날로그 회로라면 ADC 3채널을 할당해서 쓰면 되는 것이고, SPI라면 CS만 3개 할당해서 쓰면 된다. 그렇다!. SPI 버스는 공유할 수 있으므로 하나만 가지고 같이 사용하면 된다.
2008/07/17 - SPI 버스
위 페이지의 그림을 살펴보자.
1:1 연결과 1:3 연결의 차이점은 SS 핀의 갯수 뿐이다. slave가 3개니깐 SS(Slave Select) 핀도 3개. 이걸로 끝! 정말 이걸로 끝!!
여기서 끝맺어버리면 허탈해 하실 분들도 계실듯 하니 한줄로 다 설명되는 초간단 이론이 실제로는 어떻게 구현되는지 좀 더 살펴보자.
위 파일은 myCortex-LM8962와 myGyro300SPI 3개를 연결한 회로도다.(물론 myCortex-LMx08시리즈 보드와도 똑같이 연결하면 된다) myCortex-LM8962 예제 중 spi_myGyro300SPI의 회로도와 한번 비교해 보자. 그냥 넘어가지 말고 꼭 비교해 보고 차이점을 채크해보자.
spi_myGyro300SPI에서는 CS 즉 SS핀의 구현을 SPI peripheral이 알아서 하도록 코딩했었다. myGyro300SPI에 사용된 ADIS16100 칩의 SPI는 frame width 16bit로 고정이기 때문에 이렇게 편하게 사용할 수 있는 것이다. 반면 이번 예에서와 같이 slave가 다수인 경우에는 PA3/SSI0FSS에다 모두 연결해서 사용할 수가 없다. 이 핀의 역할이 CS(Chip Select)인데 3개 칩을 모두 하나의 CS에다 연결해서 어떻게 셀랙트 하겠다는 말인가.
이 이유로 위 회로도에서는 PA3/SSI0FSS핀을 사용하는 대신 놀고있는 GPIO 3개를 이용해서 CS핀을 소프트웨어적으로 만들어 사용한다. GPIO 많이 놀고 있으므로 아무것이나 잡아 사용하면 된다. 여기서는 PB0, PB1, PB2를 각각 X, Y, Z축 센서에 할당해서 연결했다.
이제 펌웨어 코드를 살펴볼 차례. 2009/12/20 - myGyro300SPI에서 결과값 읽기 포스팅에서 사용한 코드를 그대로 가져와서 3축 버전으로 바꿔보자.
똑같은 코드 그대로 복사해서 3개 집어넣었고, 앞뒤로 PB0, PB1, PB2를 적당히 흔들어주는 코드가 들어가 있다.
위 그림을 살펴보자. ADIS16100 데이터쉬트에서 발췌한 타이밍차트이다. 1회 SPI frame을 보여주고 있다. CS핀의 상태를 눈여겨 보자. 프레임 시작 전에 H->L로 떨어지고, 프레임 끝난 후에 L->H로 올라간다. PB0가 X축의 CS이므로 X축 값을 읽기 전에 PB0에 low를 write(11라인)하고, X축 값을 다 읽은 다음에 PB0 값을 다시 원상태로 high를 write(14라인)하고 있다.
그리고 같은 작업을 모든 frame마다 반복하고 있다. CS핀의 역할은 위 타이밍차트에서 보는 것과 같이 너무나도 단순하고 명확하다. 이 단순하고 명확한 일을 GPIO를 이용해서 소프트웨어적으로 처리해 주기만 하면 되는 것이다.
위 소스코드의 Initialize() 함수 내에서 PB0, PB1, PB2를 GPIO output 타입으로 설정해야 한다는 것쯤은 이 글을 보는 분들 수준이라면 벌써 눈치 채셨을 것으로 생각하고 생략. 혹시 모르겠다면 예제와 myGyro300SPI 글 시리즈를 자세히 보지 않은 경우일듯.
좀 더 깔끔한 소스코드를 위해서 spi_myAccel3LV02 예제에서와 같이 macro function들을 이용하면 편하다. MA3_CS_ON(), MA3_CS_OFF()
이번에 살펴본 예는 myGyro300SPI 3개를 사용했기 때문에 구현하기 간단한 경우다. 예전 글에서 설명한 바와 같이 SPI에는 여러가지 모드가 있기 때문에 서로 다른 모드를 가진 칩들을 동일한 SPI 버스에 물려 사용할 때에는 모드 전환을 직접 처리해 줘야 한다. myGyro300SPI와 myAccel3LV02를 동시에 사용하려는 경우가 그런 예가 될 수 있다. 이 예에 대해서는 다음기회에 다룰 생각이다.
이번에 다룰 내용은 하나의 SPI 버스에 여러개의 장치를 연결한 경우 인터페이싱 하는 방법에 관한 것이다. 간단한 구성을 설정하고 예를 들어 설명하는 것이 보다 직관적일 듯 하여 myGyro300SPI 3개를 동시에 연결한 경우를 예로 살펴보려 한다.
myGyro300SPI는 1축 자이로 센서이므로 서로 직교하도록 3개의 센서를 연결해 사용하려는 생각을 쉽게 할 수 있다. 아날로그 회로라면 ADC 3채널을 할당해서 쓰면 되는 것이고, SPI라면 CS만 3개 할당해서 쓰면 된다. 그렇다!. SPI 버스는 공유할 수 있으므로 하나만 가지고 같이 사용하면 된다.
2008/07/17 - SPI 버스
위 페이지의 그림을 살펴보자.
- 첫번째 그림은 가장 기본적인 1:1 연결.
- 두번째 그림이 오늘 예로 사용하려고 하는 1:3 연결.
- 세번째 그림은 그냥 무시.
1:1 연결과 1:3 연결의 차이점은 SS 핀의 갯수 뿐이다. slave가 3개니깐 SS(Slave Select) 핀도 3개. 이걸로 끝! 정말 이걸로 끝!!
여기서 끝맺어버리면 허탈해 하실 분들도 계실듯 하니 한줄로 다 설명되는 초간단 이론이 실제로는 어떻게 구현되는지 좀 더 살펴보자.
위 파일은 myCortex-LM8962와 myGyro300SPI 3개를 연결한 회로도다.(물론 myCortex-LMx08시리즈 보드와도 똑같이 연결하면 된다) myCortex-LM8962 예제 중 spi_myGyro300SPI의 회로도와 한번 비교해 보자. 그냥 넘어가지 말고 꼭 비교해 보고 차이점을 채크해보자.
spi_myGyro300SPI에서는 CS 즉 SS핀의 구현을 SPI peripheral이 알아서 하도록 코딩했었다. myGyro300SPI에 사용된 ADIS16100 칩의 SPI는 frame width 16bit로 고정이기 때문에 이렇게 편하게 사용할 수 있는 것이다. 반면 이번 예에서와 같이 slave가 다수인 경우에는 PA3/SSI0FSS에다 모두 연결해서 사용할 수가 없다. 이 핀의 역할이 CS(Chip Select)인데 3개 칩을 모두 하나의 CS에다 연결해서 어떻게 셀랙트 하겠다는 말인가.
이 이유로 위 회로도에서는 PA3/SSI0FSS핀을 사용하는 대신 놀고있는 GPIO 3개를 이용해서 CS핀을 소프트웨어적으로 만들어 사용한다. GPIO 많이 놀고 있으므로 아무것이나 잡아 사용하면 된다. 여기서는 PB0, PB1, PB2를 각각 X, Y, Z축 센서에 할당해서 연결했다.
이제 펌웨어 코드를 살펴볼 차례. 2009/12/20 - myGyro300SPI에서 결과값 읽기 포스팅에서 사용한 코드를 그대로 가져와서 3축 버전으로 바꿔보자.
똑같은 코드 그대로 복사해서 3개 집어넣었고, 앞뒤로 PB0, PB1, PB2를 적당히 흔들어주는 코드가 들어가 있다.
위 그림을 살펴보자. ADIS16100 데이터쉬트에서 발췌한 타이밍차트이다. 1회 SPI frame을 보여주고 있다. CS핀의 상태를 눈여겨 보자. 프레임 시작 전에 H->L로 떨어지고, 프레임 끝난 후에 L->H로 올라간다. PB0가 X축의 CS이므로 X축 값을 읽기 전에 PB0에 low를 write(11라인)하고, X축 값을 다 읽은 다음에 PB0 값을 다시 원상태로 high를 write(14라인)하고 있다.
그리고 같은 작업을 모든 frame마다 반복하고 있다. CS핀의 역할은 위 타이밍차트에서 보는 것과 같이 너무나도 단순하고 명확하다. 이 단순하고 명확한 일을 GPIO를 이용해서 소프트웨어적으로 처리해 주기만 하면 되는 것이다.
위 소스코드의 Initialize() 함수 내에서 PB0, PB1, PB2를 GPIO output 타입으로 설정해야 한다는 것쯤은 이 글을 보는 분들 수준이라면 벌써 눈치 채셨을 것으로 생각하고 생략. 혹시 모르겠다면 예제와 myGyro300SPI 글 시리즈를 자세히 보지 않은 경우일듯.
좀 더 깔끔한 소스코드를 위해서 spi_myAccel3LV02 예제에서와 같이 macro function들을 이용하면 편하다. MA3_CS_ON(), MA3_CS_OFF()
이번에 살펴본 예는 myGyro300SPI 3개를 사용했기 때문에 구현하기 간단한 경우다. 예전 글에서 설명한 바와 같이 SPI에는 여러가지 모드가 있기 때문에 서로 다른 모드를 가진 칩들을 동일한 SPI 버스에 물려 사용할 때에는 모드 전환을 직접 처리해 줘야 한다. myGyro300SPI와 myAccel3LV02를 동시에 사용하려는 경우가 그런 예가 될 수 있다. 이 예에 대해서는 다음기회에 다룰 생각이다.