Skip to content
isdnetworks
Go back

답은 데이터시트 각주에 있었다

무선 칩셋의 특정 레지스터를 SPI 로 읽으면 항상 0이 나왔다. 다른 레지스터는 정상인데 그것만 그렇다.

배선을 의심했고 SPI 규격을 의심했고 타이밍을 의심했는데 다른 레지스터가 잘 읽히니 그쪽일 가능성은 낮았다.

Table of contents

Open Table of contents

데이터시트를 다시 읽었다

처음에 읽었을 때는 Register Map 표만 봤는데 주소와 비트 정의가 있는 표다.

이번에는 그 장 전체를 읽었다. 표 아래에 각주가 있었다.

이 레지스터는 칩이 특정 모드일 때만 유효하다.
다른 모드에서 읽으면 0을 반환한다.

MODE_IDLE 로 전환을 안 하고 읽고 있었고 전환한 뒤 읽으니 값이 나왔다.

원인 — 표와 각주가 말하는 것

Register Map 만 보고 넘어갔기 때문에 못 봤다. 표는 무엇이 있는가를 각주는 언제 유효한가를 알려 준다.

Register Map 은 정적인 그림이라 조건이 안 보인다. 칩 상태에 따라 같은 주소가 다른 것을 뜻하거나 아예 안 읽히기도 한다.

읽는 쪽에서 보면 이 둘은 같은 무게가 아니다. 주소를 몰라서 못 읽는 일보다 조건을 몰라서 0을 읽는 일이 훨씬 찾기 어렵다.

주소가 틀리면 아무 값이나 나와서 금방 안다. 조건을 안 맞추면 그럴듯한 0이 나와서 배선부터 의심하게 된다.

코드에도 답이 있었다

더 허탈한 것이 있었다. 벤더가 준 예제 코드를 열어 봤다.

static int read_status(void)
{
    set_mode(MODE_IDLE);        /* 이 레지스터는 IDLE에서만 읽힌다 */
    return reg_read(REG_STATUS);
}

같은 파일 안 다른 함수에 set_mode 가 먼저 있고 주석까지 달려 있었다. 내가 짠 함수는 그 패턴을 안 따랐다.

예제에서 필요한 부분만 복사해 오면서 앞뒤 문맥을 뺀 것이고 reg_read 한 줄만 가져왔다.

그래서 순서를 바꿨다

새 하드웨어를 붙일 때의 순서를 다시 잡았다.

1. 동작 모드와 상태 전이도를 먼저 읽는다
2. 그다음 레지스터 맵
3. 각 레지스터의 유효 조건을 함께 적어 둔다

그리고 Datasheet 보다 예제를 먼저 여는 쪽으로 바꿨다. 같은 기능을 다루는 부분이 있으면 이미 동작하는 코드가 가장 빠른 답이다.

그 코드는 통째로 읽는다. 필요한 줄만 뽑으면 앞뒤에 있던 전제가 함께 안 온다.

이번 경우가 그랬는데 set_modereg_read 보다 앞에 있었고 그것을 안 가져오니 같은 문제가 났다.

복사할 때 주석도 같이 가져온다. 주석이 안 오면 왜 그렇게 하는지가 사라지고 다음 사람이 그 줄을 지운다.

참고 자료 — 벤더 문서의 계층

이 일을 겪고 벤더 자료를 보는 순서를 정했다.

자료담는 것언제 보나
데이터시트전기적 특성, 레지스터, 유효 조건처음, 그리고 값이 이상할 때
애플리케이션 노트실제 사용 패턴, 권장 설정설계할 때
예제 코드동작하는 순서붙일 때
에라타문서와 실제가 다른 부분문서대로 했는데 안 될 때

마지막이 특히 중요했는데 ErrataDatasheet 가 틀린 곳의 목록이다.

문서대로 했는데 안 되면 여기부터 본다. 이 칩셋에도 Errata 가 있었고 다른 레지스터 하나가 문서와 다르게 동작한다고 적혀 있었다.

나중에 그것도 겪었을 텐데 미리 봐서 피했다. 틀린 곳을 적어 둔 문서가 따로 있다는 것을 아는 것만으로 조사 한 번을 덜었다.

정리


Share this post on:

Previous Post
지표가 안 올라오면 멈춘 건가
Next Post
코드에 적힌 값이 실제 값이 아니다