기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.
저희 타겟보드가 OMAP3530 EVM 을 Reference해서 만들었습니다.
소스는 Open Source 및 TI 에서 공급 받은 것으로 Linux Version이 현재 Linux-2.6.22-18을 사용을 하고 있습니다.
그런데, EVM에서 사용하던 터치스크린의 Interuppt가 GPIO_175를 GPIO_181로 변경을 해서 사용합니다.
그래서 PAD Configuration의 해당 Pin에 대한 Register에 GPIO Mode로 설정하여 사용을 했습니다.
ptr = (u32 *)(&CONTROL_PADCONF_MCSPI2_CS0); /* for TSC2007 PENIRQ */
*ptr |= (u32)(IO_PAD_WAKEUPENABLE |
IO_PAD_OFFPULLUDENABLE | /* Pull up enable */
IO_PAD_OFFOUTENABLE | /* Input enable */
IO_PAD_OFFENABLE |
IO_PAD_INPUTENABLE |
IO_PAD_PULLUDENABLE |
IO_PAD_MUXMODE4);
이렇게 사용하던걸 PAD config 함수를 사용하여 기타 GPIO Mode 함수를 만들었습니다.
여기서 궁금한 것이 기존의 OMAP3530 EVM Board에서 사용하던 GPIO_175에 해당 하는 MUXMODE설정이
보이지 않는 다는 것이지요! mux.c를 봐도 잘 모르겠구요.
OMAP3 EVM의 GPIO 175에 대한 Interrupt mode 설정을 어떻게 이루어 지는지?
혹시 알고 계시다면 조언 부탁드립니다.
우선, OMAP3530에 대한 Datasheet가 잘 안구해지네요.. :) TI 쪽에 가봐도 Electrical Spec만 기술된 문서만 나오네요.
따라서, 몇가지 가능성만 간단하게 말씀 드리겠습니다.
1. GPIO_175 번이 Mux Mode를 지원하지 않을 경우
-> S3C 계열 프로세서의 경우 이런 경우가 가끔 발생합니다. 이 경우, Mux Mode 자체가 없기 때문에,
보이지 않을 경우에는 인터럽트 모드를 지원하는 핀으로 변경을 하셔야 할 듯 싶습니다.
2. GPIO_175번이 Mux Mode를 지원하지만, 소스코드 상에서 구현이 되지 않았을 경우
-> 이 경우도 리눅스 커널에서 상당히 많이 발생을 합니다. 첨부해 주신 소스를 봤을 때, 해상 소스는 핀 셋팅을 하는 것
같은데, 이것을 참고로 데이터시트를 보고, 직접 구현을 해주시면 됩니다.
하지만, 여기서 몇가지 문제점이 발생 합니다.
ptr = (u32 *)(&CONTROL_PADCONF_MCSPI2_CS0); /* for TSC2007 PENIRQ */
*ptr |= (u32)(IO_PAD_WAKEUPENABLE |
IO_PAD_OFFPULLUDENABLE | /* Pull up enable */
IO_PAD_OFFOUTENABLE | /* Input enable */
IO_PAD_OFFENABLE |
IO_PAD_INPUTENABLE |
IO_PAD_PULLUDENABLE |
IO_PAD_MUXMODE4);
제가 위에 붉은 색 친 부분은 실제 레지스터의 주소가 와야 하는 부분인데, 문제는 리눅스 상에서 이 주소체계가
가상 메모리 주소 체계라는 점 입니다.
따라서 실제 데이터 시트의 레지스터 주소와 리눅스 상의 주소가 틀릴 수가 있습니다.
OMAP 커널은 안써보고, S3C 계열을 써본 경험에서 말씀드리자면 리눅스의 경우 레지스터에 직접 읽기 및 쓰기를 구현하기 위해 raw_writel(물리주소, 값) 또는 val = raw_readl(물리주소) 함수를 제공 합니다.
만약 OMAP 커널에 해당 함수를 지원한다면, 해피하게 다음과 같이 구현해 주시면 됩니다.
raw_writel( GPIO_175_MUX 레지스터 가상 주소 , IO_PAD_WAKEUPENABLE |
IO_PAD_OFFPULLUDENABLE | /* Pull up enable */
IO_PAD_OFFOUTENABLE | /* Input enable */
IO_PAD_OFFENABLE |
IO_PAD_INPUTENABLE |
IO_PAD_PULLUDENABLE |
IO_PAD_MUXMODE4);
물리 주소를 가상 주소로 매핑해주는 함수의 경우 보통 직접 작성하셔야 합니다. (간단한 옵섿값 계산 정도)
하지만, 리눅스 커널의 경우 보통 물리-가상 주소 매핑 함수는 커널마다 기본적으로 제공하고 있으니 해당 소스코드를
잘 찾아보시기 바랍니다.
예를 들면 (int32)val(가상주소 저장 변수) = phy_to_virt(물리주소) 와 같은 형식의 함수가 있겠죠. :)
리눅스에서는 이렇게 변환된 주소를 앞서 기술한 raw_writel 함수를 이용하여 사용하시면 됩니다.