WIZnet Developer Forum

데이터 수신 인터럽트 사용하려면

안녕하세요 질문을 너무 많이 드려 죄송합니다 ㅠ

W7200_AN_SNMP_V111 폴더 안에 있는 5200 예제소스로
snmp 주고 받는건 확인을 했습니다.

그런데 이게 예제소스가 무한루프에서 데이터만 기다리고 있는 것이고

저는 시스템에 적용하기 위해 인터럽트를 사용하여 snmp 데이터가 수신되면
그때 처리를 데이터 처리를 하려고합니다.

nINT 핀을 사용하면 된다는것까진 알겠는데
nINT 핀을 어떻게 Low떨어뜨릴지가 문제입니다.
데이터 시트에 Interrupt 관련한 레지스터들이 있긴한데

common 레지스터---------------------
0x0015 번지의 IR,
0x0016 번지의 IMR,

0x0034 번지의 IR2,
0x0036 번지의 IMR2,

socket 레지스터 ------------------------
0x4n02 번지의 Sn_IR
0x4n2C 번지의 Sn_IMR

중 어떤 내용을 설정해주고 확인해줘야 하는지를 모르겠네요…
소켓 넘버가 무엇인지도 모르겠구요…ㅠ_ㅠ

일단 현재 소스에 인터럽트 설정은 없는 것 같은데요…
nINT 핀을 snmp 데이터 수신인터럽트로 사용하기 위해 어떻게 해줘야 하나요 ??

그리고 초기화 시점에 세팅을 해주면 되는것인지도 알려주시면 감사하겟습니다…

답변 부탁드립니다…

nINT 핀을 인터럽트로 사용하기 위해서는 MCU의 기능을 활용하셔야 합니다.

nINT 핀은 이벤트 발생시 high -> low로 떨어지게 되니 MCU에서는 falling edge를 감지하고 처리해야 하겠죠.

이 때 MCU에서도 인터럽트로 처리할지 폴링으로 처리할지를 결정하셔야 하겠죠?

소켓은 데이터를 주고 받을 수 있는 가상의 통로? 방? 정도라고 생각하시면 됩니다. 그리고 W5200은 최대 8개의 소켓을 동시에 열 수 있습니다.

그래서 소켓 넘버도 0~7까지 있구요. 인터럽트와 함께 생각해보면 각 소켓마다 통신을 하고 있으니 소켓별도 인터럽트가 발생할 수 있겠죠?

인터럽트가 발생한 후 Sn_IR(S0_IR~S7_IR까지 있겠죠?)를 확인하면 어떤 Interrupt가 발생했는지 알 수 있습니다.

안녕하세요

register에 대해 간단히 설명드리자면,
IR2는 Socket의 Interrupt가 발생했을때 알려주는 register이고
IMR는 IR2의 Mask register입니다.
즉, 서로 연결되어 있다고 보시면 됩니다.

nINT는 다음과 같이 발생합니다.(예를 들어 Socket 1의 interrupt를 사용하고자한다면)

  1. S1_IMR의 bit 중 interrupt로 사용하고자 하는 bit를 '1’로 세팅합니다.
  2. IMR의 bit 1을 '1’로 세팅합니다.(0x20)
  3. S1_IR의 값이 한비트라고 '1’되는지 확인합니다.
  4. S1_IR이 발생하면 IR2의 bit 1이 '1’로 세팅됩니다.->S1_IMR과 S1_IR의 같은 위치의 bit가 '1’인경우에만 발생한다.
  5. nINT는 Low로 변경됩니다.
  6. S1_IR을 Clear되면('0’으로 변경되면) -> IR2의 bit1은 ‘0’ -> nINT는 High

nINT를 사용하고 싶으시다면, IMR의 bit에서 원하시는 Socket을 '1’로 세팅해 놓으셔야합니다^^

thanks,
irinakim

CPU에서 nINT핀으로 Low입력될때 인터럽트 걸리는 것은 확인했습니다
인터럽트 레지스터를 폴링으로 확인했을때 RECV 비트가 셋되는 것은 확인이 됩니다.

그런데 nINT핀이 LOW안떨어지네요…
nINT핀이 LOW로 떨어지게 하는 레지스터 세팅이 궁금해요…

소켓 3번으로 데이터 수신 되었을때 nINT 핀을 LOW 떨어뜨리려면
어떤 레지스터를 어떤 순서로 (순서가 관계가 있다면) 세팅을 해줘야 할까요 ??

아 대댓글 달고보니 답변이 하나 더 있었네요
답변 감사드립니다
그런데 2,3번 항목은 MCU 펌웨어에서 체크해줘야 하나요 ?
아니면 자동으로 체크가 된다는 말인가요 ? (자동으로 되는거죠 ???)

  1. S1_IR의 값이 한비트라고 '1’되는지 확인합니다.
  2. S1_IR이 발생하면 IR2의 bit 1이 '1’로 세팅됩니다.

wiz config 함수 마지막 부분에서 아래와 같이 세팅했었는데요


[color=#FF0040]setIMR2(0x80); //0x0016 register
[/color]printf("\n\rgetIMR2 = 0x%02x",getIMR2()); [color=#4040FF]//print : getIMR2 = 0x80
[/color]
[color=#FF0040]setSn_IMR(3, Sn_IR_RECV); //0x4n2c //RECV bit set
[/color]printf("\n\rgetSn_IMR = 0x%02x",getSn_IMR(3));

(예제) 소스에서 소켓 3번을 써서 3번으로 세팅한건데
MIB 브라우저에서 보드로 리퀘스트 송신해도 nINT가 Low 로 잡히지가 않네요…
응답은 잘 가구요;;

W5200 Data sheet 19 page 내용입니다.

IMR(Interrupt Mask Register)[R/W][0x0016][0x00]
IMR (Interrupt Mask Register)는 Interrupt를 Mask하기 위해 사용한다. 각 Interrupt Mask Bit는
Interrupt Register2 (IR2)의 Bit와 같다. Interrupt Mask Bit가 set되어있다면, IR2의 해당 Bit가 set되었을
때 Interrupt가 발생 할 것이다. 만약 IMR이 ‘0’으로 set되어 있다면, IR2의 해당 Bit가 set되더라도
Interrupt는 발생하지 않는다

결국 IR2 레지스터에 의해서 실제로 인터럽트가 발생하지만 IMR에 SET 되어 있지 않으면 인터럽트가 발생하지 않는다는 내용입니다.

시작은 IMR Register를 Set하는 것이겠죠? ^^


^^;;;

IMR Register 수신 인터럽트 set 하셨네요… 흠… 왜 안될까요?.. 저도 한번 해봐야겠네요.

IMR(0x0016), Sn_IMR(0x4n2c) 세팅한 상태에서

무한 루프내에서

            if( getSn_IR(SOCK_SNMP))	
	{
		printf("\n\r Interrupt bit Set, Sn_IR = 0x%02x", getSn_IR(SOCK_SNMP)); 
		[color=#40BF40]// printf : Interrupt bit Set, Sn_IR = 0x04

[/color]

	}
	if(getIR2()){
			printf("\n\r Interrupt bit Set, IR2 = 0x%02x", getIR2());  [color=#40BF00]//printf: Interrupt bit Set, IR2 = 0x08

[/color] setSn_IR(SOCK_SNMP, 0x04);
}

위의 두가지 레지스터를 체크해보면
확실히 MIB 브라우저에서 메세지를 보내면 딱 저 두 부분에서 브레이크가 걸립니다
setSn_IR(SOCK_SNMP, 0x04); --> 이거 해주면 풀리구요, 안해주면 무한 브레이크…;;

원래대로라면 이 상태에서 nINT가 LOW가 되는게 맞는거죠 ??
스코프로 찍어봐도 LOW가 안되는데…

SOCK_SNMP 는 예제 소스에 3번으로 되있길래 걍 놔뒀습니다
상태 레지스터 체크했떠니 소켓 3번만 UDP 상태더라구요 ~ (그러므로 소켓 번호는 3번이 맞는것 같습니다…)

[quote=“naemaum4u”]wiz config 함수 마지막 부분에서 아래와 같이 세팅했었는데요


[color=#FF0040]setIMR2(0x80); //0x0016 register
[/color]printf("\n\rgetIMR2 = 0x%02x",getIMR2()); [color=#4040FF]//print : getIMR2 = 0x80
[/color]
[color=#FF0040]setSn_IMR(3, Sn_IR_RECV); //0x4n2c //RECV bit set
[/color]printf("\n\rgetSn_IMR = 0x%02x",getSn_IMR(3));

(예제) 소스에서 소켓 3번을 써서 3번으로 세팅한건데
MIB 브라우저에서 보드로 리퀘스트 송신해도 nINT가 Low 로 잡히지가 않네요…
응답은 잘 가구요;;[/quote]

[b]-> IMR을 쓰셔야합니다.
Socket 3을 쓰신다면, IMR의 bit 3가 '1’되어있어야하며. Sn_IMR의 bit 3 도 '1’로 되어있어야합니다.

[/b]

아…
죄송합니다…

0x08을 0x80으로 써놓고 ㅠㅠ
정말 죄송하고 감사합니다.
덕분에 잘 되네요 ^^;;

[quote=“naemaum4u”]IMR(0x0016), Sn_IMR(0x4n2c) 세팅한 상태에서

무한 루프내에서

            if( getSn_IR(SOCK_SNMP))	
	{
		printf("\n\r Interrupt bit Set, Sn_IR = 0x%02x", getSn_IR(SOCK_SNMP)); 
		[color=#40BF40]// printf : Interrupt bit Set, Sn_IR = 0x04

[/color]

	}
	if(getIR2()){
			printf("\n\r Interrupt bit Set, IR2 = 0x%02x", getIR2());  [color=#40BF00]//printf: Interrupt bit Set, IR2 = 0x08

[/color] setSn_IR(SOCK_SNMP, 0x04);
}

위의 두가지 레지스터를 체크해보면
확실히 MIB 브라우저에서 메세지를 보내면 딱 저 두 부분에서 브레이크가 걸립니다
setSn_IR(SOCK_SNMP, 0x04); --> 이거 해주면 풀리구요, 안해주면 무한 브레이크…;;

원래대로라면 이 상태에서 nINT가 LOW가 되는게 맞는거죠 ??
스코프로 찍어봐도 LOW가 안되는데…

SOCK_SNMP 는 예제 소스에 3번으로 되있길래 걍 놔뒀습니다
상태 레지스터 체크했떠니 소켓 3번만 UDP 상태더라구요 ~ (그러므로 소켓 번호는 3번이 맞는것 같습니다…)[/quote]

setSn_IR에 '1’을 write하면 Clear가 되면서 nINT는 high로 변경됩니다. 마지막 부분에 setSn_IR을 clear하기 전에 delay를 줘야할 것같습니다.
IMR의 bit 4와 Sn_IMR의 bit 4의 값은 '1’로 세팅이 되어있는건가요?

잘된다니 다행입니다.

문제가 생기시면 포럼에 글 남겨주세요~

thanks,
irirna kim :slight_smile:

축하해요~ ^^

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.