본문 바로가기
개발/Embedded

[I2C] 라즈베리파이와 EEPROM의 I2C 통신 (i2cset)

by jungcow 2024. 1. 29.

1. 개요

라즈베리파이와 EEPROM간의 I2C 통신 방법을 간략히 살펴보고 문제 해결에 초점을 맞추어 글을 이어나가려 한다.

환경

 

24FC512T-I/OT Microchip Technology | Mouser

팩토리 팩 수량 - 일반적으로 공장에서 선적되는 패키지 크기 (참고: 제조업체는 사전 통지 없이 패키지 크기를 변경할 수 있습니다.) 대량 생산 고객이 “팩토리 팩 수량”을 다양하게 주문하면

www.mouser.kr

2. I2C 통신 활성화

sudo raspi-config

위 명령어를 통해 라즈베리파이의 설정 화면으로 들어간다. 이후 아래의  글을 따라서 i2c 설정 및 연결 확인 작업을 수행한다.

https://m.blog.naver.com/chgy2131/221922893758

 

라즈베리파이 I2C 사용방법

라즈베리 I2C 기능에는 치명적일 수 있는 문제가 있습니다!! 해당 글 최하단 참고. I2C 기능이 필요하...

blog.naver.com

 

만약 위 블로그에서와 같이 i2cdetect 명령어로 주소 번호가 뜨지 않는다거나 하는 오류가 발생하면 다음을 확인해보면 좋다.
  • eeprom이 정상적으로 납땜이 되었는가.
  • eeprom과 라즈베리파이간의 와이어 연결이 정상적으로 되었는가.

나의 경우, eeprom이 납땜이 정상적으로 되어 있지 않아 i2cdetect 가 정상적으로 수행되지 않았던 적이 있다.  또한 sda 라인과 scl 라인을 엇갈리게 연결했을 때도 이런 문제가 발생했었다. 이런 확인하기 어려운 것들은 여러개의 eeprom을 가지고 비교 검증을 수행해보면 좋을 것 같다.

 

 

설정이 완료된 후 아래의 명령어를 쳐보자.

ls /dev/i2c*

위 명령어로 i2c-0이나 i2c-1 이라는 결과가 나왔다면, 뒤에 있는 숫자가 아래의 명령어와 -y 뒤에 붙을 숫자가 된다. 이 숫자는 bus를 의미한다고 나와 있다. 위 블로그에서는 1이 나와서 명령어와 -y 옵션 이후 1을 붙여주고 있다.

 

3. 16-bit addressing 의 문제

내가 사용하고 있는 EEPROM은 2바이트 어드레싱을 사용하고 있다. 즉 메모리의 주소가 2바이트로 표현되어 총 2^16의 바이트를 저장할 수 있는 구조이다.

 

이것이 왜 문제가 되냐... 바로 i2cset과 i2cget의 설명을 보면 1byte 주소체계를 사용하고 있는 장치에 맞게 명령어가 구성되어 있다는 것이다.

 

i2cset의 파라미터 구조는 다음과 같다.

i2cset -y <bus> <device address> <register address> <value>
# ex) i2cset -y 0 0x50 0x00 0x00

  • bus: 0
  • device address: 0x50
  • register address: 0x00
  • value: 0x00

이와 같이 볼 수 있다.

하지만 내가 원하는 것은 register address가 2 bytes, 즉 16-bit addressing을 함과 동시에 데이터를 쓰고 싶은 것이다. 따라서 아래와 같이 코드를 적어보면,

i2cset -y 0 0x50 0x00 0x00 0x78

위와 같은 오류가 발생한다. <value>뒤에 하나의 인자를 더 넣어 오류가 발생한 건데, 이를 해결하여 16-bit addressing을 i2cset 명령어에 어떻게 적용시키는지 살펴보도록 하자.

 

4. 해결 과정

i2c 통신에서의 데이터 값

먼저 위에서 봤던 예시를 다시 가져와보자.

i2cset -y <bus> <device address> <register address> <value>
# ex) i2cset -y 0 0x50 0x00 0x00

위와 같이 device address 이후에 오는 값에 대해 register address와 value라는 의미를 넣긴 했지만, 사실 register address와 value 모두 I2C 통신 입장에선 하나의 Data이다.

 

즉 데이터를 여러개 보낸다면, 이 장치는 첫번째 데이터는 register address로 해석하고, 두번째 값부터는 value로 해석한다는 뜻이다.

 

여기서 나의 16-bit addressing을 수행하는 EEPROM의 경우엔 어떻게 해석할까?

 

첫번째 값은 high-order address로, 두번째 값은 low-order address로 해석하고, 세번째 값부터는 이 두 바이트로 이루어진 주소에 쓰려는 값으로 해석하게 된다.

 

따라서 8bit addressing을 하던지 16-bit addressing 을 하던지간에 각각에 맞는 데이터 개수를 인자로 넣으면 된다는 것이다.

위 오류의 해결과정

그럼 위 실행에선 필요한 바이트 수만큼 넣어줬는데 왜 오류가 발생했는가? i2cset에선 `i` 라는 모드를 이용해서 여러개의 데이터들을 한번에 보낼 수 있다. 따라서 다음과 같이 고칠 수 있다.

i2cset -y 0 0x50 0x00 0x00 0x78 i

  • 0: bus
  • 0x50: eeprom이 연결되어 있는 주소
  • 0x00: high-order address
  • 0x00: low-order address
  • 0x78: 0x0000에 write하려는 데이터 값
  • i: block data 전송 모드.

5. 결론

사실 위에서는 i2cset 명령어가 1byte addressing에 더 적합하게 파라미터가 구성되어 있다고 언급했었는데, 그건 사용자 입장에서고 실제 i2c 통신 입장에선 장치 주소 이후에 오는 값들은 모두 데이터라고 인식할 뿐이다.

 

따라서 i2cset에 16-bit addressing을 사용하기 위해선 단순히 여러개의 값을 추가로 더 보내기만 하면 되는 문제였다. 값을 여러개 보내야 할 필요성을 느꼈다면, i2cset의 모드 중 여러 바이트열을 보낼 수 있는 모드가 있는지를 살펴봤으면 바로 문제 해결이 됐을 것이다.

 

i2cset 뿐만 아니라 i2cget에서도 16-bit addressing에서 오는 문제가 있었는데, 이는 EEPROM에 실질적으로 수행한 내용과 이것의 결과, 그리고 오류들을 적어놓을 때 같이 기록하려 한다.

 

 

'개발 > Embedded' 카테고리의 다른 글

[I2C] 라즈베리파이와 EEPROM의 I2C 통신 (i2cget)  (0) 2024.02.06