adStar Internet Radio 테스트 (Web Radio)

[MCU]/adStar | 2013.08.18 02:59
Posted by nexp

adStar Internet Radio 테스트 (Web Radio)




adStar의 가장큰 장점은 칩내부에 16MB의 SDRAM이 내장되어 있어 대량 메모리가 필요한 곳에 아주 유용하다. 

특히 인터넷 라디오와 같이 스트림 데이터는 네트웍 상황에 따라 전송율이 변화기 때문에 메모리를 이용해 버퍼링이 필요하다. 

adStar의 SDRAM을 이용하여 버퍼링 하는 예제로 인터넷 라디오를 제작 해 보았다.


보드는 기존 이더넷(W5100), MP3(VS1053), MCU(adStar)모듈들을 재활용 할 수 있는 확장 테스트 보드를 이용했다. 이더넷은 W5100을 이용하여 고속의 이더넷 전송이 가능하도록 했다. 물론 STM32와 같은 Cortex-M3를 사용해도 되지만 버퍼링을 확실히 할수 있는 메모리를 갖추고 저렴하면서 소형인 adStar를 이용하기로 했다. 테스트 결과 최장 15분정도의 버퍼링도 가능했다.




인터넷 라디오는 ICY프로토콜을 이용한다. Shoutcast Server 에 접속하여 HTTP프로토콜을 이용해 Request를 보내면 그에 따른 응답이 오고 이후 MP3데이터를 수신할 수 있다. 예를 들어 URL (sc03.saycast.com)에 접쇽하려면 우선 DNS에 접속하여 IP와 포트번호를  알아낸다. IP 를 알아 냈다면 TCP로 접속한 후 GET 명령을 보내면 서버에서 이에 따른 응답이 온다.



Request 메시지

아래와 같이 GET메지지를 전송하면 응답 메시지가 날아온다. 사실 "GET / HTTP/1.0"  "Host : ip" 만 보내면 된다.

GET sc03.saycast.com HTTP/1.0
User-Agent: GOMA mpg123/1.15.1
Host: 211.43.215.141
Accept:audio/mpeg, audio/x-mpeg, audio/mp3, audio/x-mp3, audio/mpeg3, audio/x-mpeg3, audio/mpg, audio/x-mpg, audio/x-mpegaudio, application/octet-stream, audio/mpegurl, audio/mpeg-url, audio/x-mpegurl, audio/x-scpls, audio/scpls, application/pls, application/x-scpls, */*
Icy-MetaData: 1

Connection: close




응답 메시지

"ICY 200  OK"가 전송되면 정상적으로 접속이 된것이고 이후에 MP3데이터가 출력된다. 물론 곡 정보나 전송률등의 메타데이터도 함께 전송된다.

ICY 200 OK
content-type:audio/mpeg
icy-br:128
icy-genre:뮤직카페
icy-metaint:16384
icy-name:《 М 4 Ц 》 ‥ ───‥ http://m4ucast.co.kr ⌒∇⌒γ
icy-notice1:<BR>This stream requires <a href="http://www.saycast.com/">SayRadio</a><BR>
icy-notice2:SayCast Distributed Network Audio Server/Linux v2.0.0<BR>
icy-pub:1

icy-url:http://saycast.sayclub.com/saycast/gateway/winamp?domainid=m4u




MP3데이터를 받으면 VS1053의 데이터 버퍼에 쓰면 되는데 인터넷 속도에 따라 버퍼링이 필요하기 때문에 adStar의 SDAM을 이용해 저장하고 적절한 버퍼링이 되면 출력 하도록 했다.


SDRAM에 메모리 할당

#define RINGBUFFER_SIZE (4096*1024)


//SDRAM에 버퍼 메모리 할당

m_RxBuffer.buffer = malloc(RINGBUFFER_SIZE);




수신된 internet radio MP3 데이터 처리

//수신되 데이터 링버퍼에 저장

void Copy_to_StreamBuffer(u16 len, u8 *tmp_buffer)

{

u16 i;


for ( i = 0; i < len; i++)

{

SetRingBuffer(&m_RxBuffer, tmp_buffer[i]);

}

}


//저장된 MP3 데이터 출력 함수

void Push_to_VS1053(void)

{

u32 remain_bytes;

remain_bytes = GetDataSize(&m_RxBuffer);


if(remain_bytes == 0)

{

Enable_Play = 0;

}

        else if (remain_bytes > BUFFERING_SIZE)

                // buffering

Enable_Play = 1;

}

        //데이터 출력

if (Enable_Play == 1)

{

if(IsVs1053DataReady())

{

VS_WriteData(GetRingBuffer(&m_RxBuffer));

}

}

:

}






테스트 동영상

간단한 인터넷 라디오를 제작하기 위해 우선 몇개의 인터넷 라디오 사이트를 저장해 두고 스위치를 누름에 따라 각각의 서버에 접속해 라디오를 출력하는 예제를 작성해 보았다.







 

인터넷 라디오 TCP 처리 함수

인터넷 라디오의 이더넷 처리 부분은 아래와 같이 구현이 가능하다.

void ProcessiRadio(unsigned int sock, unsigned int port)

{

int len;

u8 tmp_buffer[MAX_BUF_SIZE];

switch (getSn_SR(sock))

{

case SOCK_ESTABLISHED:

//데이터 수신 검사

if (state == -1)

{

//Request 전송

SendProbe();

state = 0;

}

else if (state == 0)

{

//HTTP Request 전송

SendRequest();

DebugPrint("\r\nSend HTTP request\r\n");


state = 1;

}

else if (state == 1)

{

//응답 메시지 분석

if (ParseReply(sock) > 0) 

{

state = 2;

}

}

else if (state == 2)

{

//MP3 데이터 버퍼링

if ((len = getSn_RX_RSR(sock)) > 0) 

{

len = recv(sock, tmp_buffer, len);

Copy_to_StreamBuffer(len, tmp_buffer);

gTotalWriteCount += len;

}

}

break;

case SOCK_CLOSE_WAIT:                          

//If the client request to close

disconnect(sock);

m_SokStatus1 = 0;

break;

case SOCK_CLOSED:

if(!m_SokStatus1)m_SokStatus1 = 1;


if (getSn_RX_RSR(sock) > 0)

{

       DebugPrint("\r\nParse_Reply2"); 

 Parse_Reply(SOCK_CLIENT);

      }

    

     close(SOCK_CLIENT);


//URL일 경우 DNS 접속

if (Need_DNS(Server_URL, strlen(Server_URL)) == 1) 

{

if (dns_query(Server_URL) != -1)

{

DebugPrint("\r\nDNS ok");


//얻어온 IP 및 포트로 접속

init_socket(sock, Config_Msg.Sip, Config_Msg.Sport);

}else 

{

DebugPrint("\r\nDNS Fail");

}

}

else

{

//IP일 경우 

init_socket(sock, Config_Msg.Sip, Config_Msg.Sport);

}

break;


    default:

        break;

}

}


 

 

결론

기존에도 인너넷 라디오를 제작해 보았지만 네트웍 상황에 따라 끊기는 현상이 발생하는데 메모리 가격 때문에 상용 제품 형태로 제작하기에는 문제가 많았다. 저렴한 가격에 메모리가 포함된 adStar를 이용하면 이러한 문제점들을 해결할 수 있을것 같다. 좀더 다듬으면 훌륭한 인터넷 라디오를 제작할 수 있을것 같다.

adStar - W5100 TCP/IP 전송 속도 테스트 (외부 메모리 제어 모드 사용)

 

 

 

adStar 도 CANTUS 와 같이 외부 메모리 제어 모드가 있다.  외부 메모리를 연결할 수 있고,  특히 W5100과 같이 고속 이더넷이 필요할 때 사용하면 편리하다. [adStar TFT-EX] 보드에는 메모리 방식의 W5100을 연결할 수 있는 커넥터가 있기 때문에 이를 테스트 해 보았다.

 

메모리 제어 기능은 PORT3, PORT4에서 설정할 수 있다.

 

 

 

adStar의 CS0 할당 번지는 0x5000 0000 이다.

기존 CANTUS 와 약간의 차이가 있는것은 메모리 번지와 제어 레지스터 번지이다. 나름의 이유가 있었겠지만 기존 코드와 호환성을 유지하기 위해 동일하게 했으면 하는 생각이 든다.

 

 

 

 

asStar W5100 초기화 코드

 

void W5100_IO_INIT()
{
 *(volatile U16*)0x80000800 = BIT10; //BANK 0 8Bit

 *R_PAF3 = 0; //SRAM interface address, data
 Cbi(*R_PAF4, GP_CFG(1) | GP_CFG(3)| GP_CFG(4)| GP_CFG(5));// nCS, nWE, nRE, ALE  

 

 

 

asStar W5100 메모리 제어 방식(INDIRECT)을 이용한 TCP/IP 전송 속도 테스트

회로적으로 간단하게 테스트 하기위해 INDIRECT방식을 이용했는데도 6Mbps 이상 나오고 있는데 DIRECT모드를 이용하면 더 빠를 수 있을것 같다. 

 

 

 

[AT90USB EVM] FTP Client 테스트 - USB메모리 스틱의 mp3파일 전송하기

 

 

이더넷을 이용하여 FTP Client 테스트를 진행했다.

AT90USB1287은 USB호스트를 지원하므로 USB메모리스틱의 파일을 읽어 FTP로 전송 가능하다.

FTP 서버 접속을 위한 이더넷 처리는 W5100에서 한다. 원격지의 임베디드 보드에서 FTP서버로 접속해 파일을 송수신 할수 있다.

 

 

 

AT90USB1287 FTP Client 테스트 동영상

FTP Server( ALFTP)에 접속해서 특정 이벤트에 따라 USB메모리 스틱의 mp3파일을 전송하는 테스트

 

 

 

 


 

FTP 서버모드로 실행

알FTP를 실행하고 서버 모드로 실행한다.

서버 디렉토리는 디폴트 디렉토리 ALFtpServer 로 설정되어 있다.

 

 

 

 

 

IP및  ID, PASS 설정
서버로 사용할 IP설정 - PC의 IP이다.

 

 

보드쪽에서는 main.h 에 설정 되어 있다.

#define FTP_SERVER_PORT     {192,168,0,7} 

 

 

ID : admin, PASS: 1234
보드쪽 펌웨어 main.c에서 아래 코드로 설정되어 있다.
 
 switch (resp)
  {
  case 220:
   //ID설정
   fsprintf(CTRL_SOCK, "USER %s\r\n", "admin");
   resp = getresp(CTRL_SOCK, 200);
   break;
   
  case 331:
   //Password
   fsprintf(CTRL_SOCK, "PASS %s\r\n", "1234");
   resp = getresp(CTRL_SOCK, 200);
   break;

 

 

 

 

 

FTP Client 접속

서버 실행하면 보드쪽에서 자동으로 FTP서버로 접속을 시도 한다.
 
! 192.168.0.104 connected
< 192.168.0.104 USER admin
> 192.168.0.104 331 Password required for admin.
< 192.168.0.104 PASS 1234
! 192.168.0.104 User 'admin' is authenticated
> 192.168.0.104 230 User admin logged in.

 

 

 

 

 

 

FTP서버로 파일 전송
보드의 스위치 1번을 누르면 USB 메모리 스틱에 있는 mp3파일을 읽어서 FTP서버로 전송한다.
  

 

 

< 192.168.0.104 PORT 192,168,0,104,15,162
> 192.168.0.104 200 Port command successful.
 
< 192.168.0.104 STOR test.mp3
> 192.168.0.104 150 Opening data connection for test.mp3.
> 192.168.0.104 226 File received ok

 

알FTP에서는 파일 전송 완료후  F5를 누르면 업데이트된 파일을 볼수 있다.

 

 

 

 

 

 

 

 

[CANTUS] W5100을 이용한 네트웍 스피커 제작

 

 

 

CANTUS-EX 보드는 하드웨어 TCP/IP를 지원하는 W5100을 BUS방식으로 제어할 수 있기 때문에 네트웍 속도가 빠르다.

이 저렴한 솔루션을 이용하여 활용할 수 있는 어플리케이션으로 네트웍 스피커를 제작해 보았다.

 

네트웍 스피커는 이더넷으로 연결되는 스피커 이기 때문에 원격지에서 원하는 음원을 송출 가능하며 많은 수의 스피커를 원하는 형태로 제어 가능하다. 인터넷 라디오나 원격방송용으로 활용하면 좋을것 같다.

 

 

 

구성도

전체적인 구성도로 보면 아래와 같다.

 

네트웍은 하드웨어 TCP/IP를 지원하는  W5100을 이용하므로 쉽게 구현할 수 있다. 음원 전송은 UDP, 멀티캐스트 방식으로 원하는 IP의 스피커로 전송가능하다. MCU는 I2S와 소프트웨어 MP3코덱을 지원하는 CANTUS를 이용하여 아주 저렴하게 네트웍으로 받은 음원을 출력할 수 있다.

 

스피커 출력은 15W출력을 가진 소형의 Class-D AMP [TPA-3110 EVM] 보드를 이용했다.

 

 

 

PC 서버 프로그램

PC용 소프트웨어는 네트웍에 연결된 스피커들의 IP를 찾고 원하는 IP에 음원을 전송하거나 제어 명령을 보낼 수 있다. 또한 네트웍 상에서 IP를 변경하거나 LCD에 메세지를 출력할 수 있다.

 

 

 

마무리

테스트용이라 스피커 위에 그냥 고정했다.  

케이스가 있으면 좋겠는데.. 아니면 스피커 속으로 들어가면 더 좋을것도 같고...

추후 아크릴로 판넬하나 만들면 좋을것 같다.

 

 

 

 

 

 

네트웍 스피커 테스트 동영상

TCP/IP 프로그램으로 네트웍상의 스피커를 검색하고 원하는 IP로 보드상의 LED를 제어 하거나  MP3파일 혹은 WAV파을 전송하여 스피커로 출력하는 테스트 동영상이다.

[STM32-SM2 EVM] W5200 이더넷 테스트 -  NET-EVM 보드



STM32를 이용하여 [NET-EVM] 보드에서 W5200 모듈을 테스트 했다.





[NET-EVM] W5100/W5200용 커넥터




STM32-SM2는 핀맵이 약간 수정되었는데.. W5200의 /RST(INT0) 핀이 3.3V로 연결되기 때문에 3.3V끊고 PA15와 0옴으로 연결해 주어야 한다.




W5200 드라이버 코드
//-----------------------------------------------------------------------------
// W5100 HAL
#define _SPI1_ENABLE     1

#define W5100_CS_PORT     GPIOB
#define W5100_CS_BIT     BIT12
#define IINCHIP_RSToff()    cbi(W5100_RST_PORT, W5100_RST_BIT) 
#define IINCHIP_RSTon()     sbi(W5100_RST_PORT, W5100_RST_BIT)

#define W5100_IO_INIT()     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);\
          GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;\
          GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;\
          GPIO_InitStructure.GPIO_Pin=BIT12;\
          GPIO_Init(GPIOB, &GPIO_InitStructure);\
          GPIO_InitStructure.GPIO_Pin=BIT15;\
          GPIO_Init(GPIOA, &GPIO_InitStructure);


#define W5100_RST_PORT     GPIOA
#define W5100_RST_BIT     BIT15

#define IINCHIP_CSoff()     cbi(W5100_CS_PORT, W5100_CS_BIT) 
#define IINCHIP_CSon()     sbi(W5100_CS_PORT, W5100_CS_BIT)

#define IINCHIP_SPI_INIT()    SPI1_Init()
#define IINCHIP_SpiSendData    SPI1_WriteReadByte
#define IINCHIP_SpiRecvData     SPI1_WriteReadByte




STM32 TCP/IP 전송 속도 테스트
최대 SPI클럭 18Mhz 인 STM32에서 전송 속도는 2Mbps정도 출력된다.

코드 옵티마이즈 후 2.5Mbps 까지 가능하다.





[AT90USB1287-EX] 이더넷 테스트 - 초간단 웹서버 만들기




AVR와 W5100을 이용하여 아주 간단한 웹서버를 만들어 보도록 하자.
웹서버는 TCP서버의 일종으로 웹브라우저에서 80번 포트로 접속하면 HTTP프로토콜에 따라 데이터를 송수신 하면 된다.

AVR 초간단 웹서버 테스트 동영상
[AT90USB1287-EX] 보드가 임베디드 웹서버로 동작하고 접속하여 보드의 LED제어하는 간단한 예제를 작성해 보았다.





먼저 접속하면 보여줄 웹페이지를 HTML 코드로 작성해서 변수로 저장해 둔다. 추후 좀더 복잡한 페이지는 USB메모리 스틱이나 SD Card에 저장할 수 있다.




const unsigned char str_http_ok[] = {"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n"};

const unsigned char str_msg[] = {"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n\
    <html><head></head><body ><DIV><p align=\"center\"><b><size=\"8\"><br>[AT90USB1287-EX] WebServer - LED Test</font></b></DIV>\
    <HR style=\"COLOR: #3366FF; BACKGROUND-COLOR: #EB9243\"></DIV><div align=\"center\"><p align=\"center\"></p></div>\
    <form name=\"form1\" method=\"get\" action=\"$LED_ON\"><p align=\"center\"><input type=\"submit\" value=\"LED ON\"  name=\"ledo\"></p></form>\
 <p><p></td></tr><tr><td><form name=\"form2\" method=\"get\" action=\"$LED_OF\"><p align=\"center\">\
    <input type=\"submit\" value=\"LED OFF\" name=\"ledn\"></p></form><p></td></tr></table></div></body></html>"};




TCP서버 처리를 위한 함수는 기존과 동일한데 HTTP프로토콜은 디폴트 80번 포트 이므로 80번포트로 소켓을 생성하고 데이터 수신되면 웹페이지를 전송해 주면 된다. 아래 코드와 같이 아주 간단하다.

void ProcessTCPS(unsigned int sock)
{
    unsigned int len;
 unsigned int port = MY_LISTEN_PORT;

 switch (getSn_SR(sock))
 {
  // Socket CLOSED일 경우     
 case SOCK_CLOSED:
  if(!m_SokStatus1)
  {
   DebugPrint("[%d] : Web Server Started.",sock);
   m_SokStatus1 = 1;
  }

  if(socket(sock, Sn_MR_TCP, DEFAULT_HTTP_PORT, 0x00) == 0)
  {
   DebugPrint("\a%d : Fail to create socket.",sock);
   m_SokStatus1 = 0;
  }
  else listen(sock);
 
  break;

case SOCK_ESTABLISHED:
  //수신데이터가 있으면
  if((len = getSn_RX_RSR(sock)) > 0)   
  {
      if (len > TX_RX_MAX_BUF_SIZE) len = TX_RX_MAX_BUF_SIZE;
      //데이터 수신
      len = recv(sock, data_buf, len);  
  
     //수신데이터 처리 -> 웹 쿼리 응답
     ProcessWebpage(sock, data_buf);    
  } 
  break;

 case SOCK_CLOSE_WAIT:                            
  //If the client request to close
  disconnect(sock);
 
  m_SokStatus1 = 0;
  break;  
  } 
}



이제 웹페이지에서 특정한 응답을 받아서 처리 하는 부분을 작성해 보자. 이번 예제에서는 웹페이지에 있는 버튼에 따라 LED를 On/Off할 수 있도록 해 보았다.

아래 코드와 같이 브라우저에서 웹페이지를 요청하면 "HTTP/1.0 200 OK" 메세지와 HTML페이지를 전송하면 된다.
  send(sock, str_http_ok, strlen(str_http_ok));
  send(sock, str_msg, strlen(str_msg));


void ProcessWebpage(unsigned sock, unsigned char *data_buf)
{
 int wait_send=0;

 //LED 제어 처리
 if(strncmp("$LED_ON", (char *)&(data_buf[5]), 7)==0)
 {     
  Led1On();
  send(sock, str_http_ok, strlen(str_http_ok));
  send(sock, str_msg, strlen(str_msg));
  DebugPrint("led on\r\n");
 }
 else if(strncmp("$LED_OF", (char *)&(data_buf[5]), 7)==0)
 {     
  Led1Off();
  PORTF = 0xFF;
  send(sock, str_http_ok, strlen(str_http_ok));
  send(sock, str_msg, strlen(str_msg));
  DebugPrint("led off\r\n");
 }
 else
 {
  send(sock, str_msg, strlen(str_msg));   
 }

 while(getSn_TX_FSR(sock)!= getIINCHIP_TxMAX(sock))
 {
  if(wait_send++ > 1500)
  {
   DebugPrint( "HTTP Response send fail");
    break;
  }
  Delay(1);
 }
 disconnect(sock);
 DebugPrint("closed\r\n");
}





[AT90USB1287-EX] 이더넷 테스트 - TCP/IP를 이용한 광센서 데이터 전송 테스트


[AT90USB1287-EX] 보드에는 하드웨어 TCP/IP 모듈인 W5100을 메모리 제어(다이렉트) 방식으로 연결할 수 있다. 
간단히 TCP/IP  동작확인 테스트를 위해 이더넷으로 LED 제어 및 ADC값을 읽어오는 예제를 테스트 해 보았다.


TCP/IP 호스트 프로그램
기존에 C#으로 작성했던 TCP예제를 그대로 사용하기로 한다.





AT90USB1287 TCP/IP 전송 테스트 동영상
보드에 연결되어 있는 LED를 제어하고 ADC값(CdS)을 읽어와 그래프로 출력하는 예제를 작성해 보았다.




[AT90USB1287-EX] TCP 서버 처리 함수
ProcessTCPS() 함수는 루프를 돌면서 이더넷으로 데이터가 전송되면 필요한 처리를 한다.
void ProcessTCPS(unsigned int sock)
{
    unsigned int len;
 unsigned char data_buf[TX_RX_MAX_BUF_SIZE];
 unsigned int port = MY_LISTEN_PORT;

 switch (getSn_SR(sock))
 {
  // Socket CLOSED일 경우      
 case SOCK_CLOSED:
   if(!m_SokStatus1)m_SokStatus1 = 1;
  
  //socket 초기화 하고
  if(socket(sock,Sn_MR_TCP, port,0x00) == 0)
  {
   DebugPrint("Fail to create socket.");
   m_SokStatus1 = 0;
  }
  else
  {
   //접속대기
   listen(sock);
  }
  break; 


 case SOCK_ESTABLISHED:
  //수신데이터가 있으면
  if((len = getSn_RX_RSR(sock)) > 0)    
  {
      if (len > TX_RX_MAX_BUF_SIZE) len = TX_RX_MAX_BUF_SIZE; 
      //데이터 수신
      en = recv(sock, data_buf, len);   
   
     //수신데이터 처리
     //send(sock, data_buf, len);    
     EthernetTest(data_buf, len);
  }  
  break;


 case SOCK_CLOSE_WAIT:                             
  //If the client request to close
  disconnect(sock);
  
  m_SokStatus1 = 0;
  break;  
 
    default:
      
        break;
 } 
}


[AT90USB1287-EX] 이더넷 데이터 수신 처리 처리 함수
//-----------------------------------------------------------------------------
//수신데이터 처리

void EthernetTest(unsigned char *pRcvBuffer, unsigned int len)
{
 unsigned int i;
 char buf[32];
 DebugPrint("Read Data[%d]\r\n", len);
 
 //Packet CMD Check
 if(pRcvBuffer[0] == 0x55)
 {
  switch(pRcvBuffer[1])
  {
   case '0':
    Led1Off();
    break;
    
   case '1':
    Led1On();
    break;
    
   case '2':
    Led2Off();
    break;
    
   case '3':
    Led2On();
    break; 
    
   case 'r':
    sprintf(buf, "%d\r\n", AdcRead(2));
    send(SOCK_TCPS, buf, strlen(buf));
    break;      
  }
 }
}
[AT90USB1287-EX] Ehternet Test - W5100 TCP/IP 루프백 테스트

[AT90USB1287-EX] 보드는 하드웨어 TCP/IP 모듈인 W5100/W5200 을 연결할 수 있여 이더넷 관련 테스트를 쉽게 진행할 수 있다.
물론 AT90USB1287-EX 보드는 ATmega128도 호환 되기 때문에 동일하게 동작 시킬 수 있다.

먼저 개발 환경 설정을 해 보면...
하드웨어 TCP/IP 스택이므로 쉽게 이더넷 구현이 가능한데, 드라이버 폴더의 wizent에서 W5100관련 w5100.c, socket.c 만 삽입하면 된다.



그리고 메인 소스코드에  아래를 인클루드 한다.
#include "w5100.h"
#include "socket.h"


다음은 네트웍 설정을 해 준다.
W5100초기화 하고 MAC 어드레스, IP, Gateway등을 설정해 준다.
#define MY_NET_MAC   {0x00, 0x08, 0xdc, 0x00, 0x00, 0x00} // MY Mac Address : 00.08.DC.00.00.00

#define MY_NET_GWIP   {192,  168, 0,    1} //Gateway     : 192.168.0.1
#define MY_SOURCEIP   {192,  168, 0,  104} //보드 IP     : 192.168.0.101
#define MY_SUBNET   {255, 255, 255,   0}


void W5100_NetInit(void)
{
 unsigned char mac[6] = MY_NET_MAC;
 unsigned char sm[4] = MY_SUBNET;
 unsigned char gwip[4] = MY_NET_GWIP;
 unsigned char m_sip[4] = MY_SOURCEIP;

 IICHIP_HAL_INIT();
 IICHIP_RESET_INIT() ;
 IICHIP_RESET();

 DebugPrint("W5100_NetInit");     

 //W5100 Chip Init
 iinchip_init();
     
 //Set MAC Address
 setSHAR(mac);

 //Set Gateway
 setGAR(gwip);

 //Set Subnet Mask
 setSUBR(sm);

 //Set My IP
 setSIPR(m_sip);
 
#ifdef __DEF_IINCHIP_INT__
 setIMR(0xEF);
#endif

 sysinit(MY_NET_MEMALLOC, MY_NET_MEMALLOC);  
}



여기까지 하고 시리얼 포트로 설정한 값을 읽을 수 있다면 하드웨어적 설정이 끝난 것이고 ping테스를 할 수 있다.




int main(void)
{
 //시스템 초기화
 SystemInit();
 
 //LED포트 초기화
 Led1Init();
 Led1On();

 Led2Init();
 Led2On();

 //UART Init
 DebugInit(BAUD_57600);
 DebugPrint("myMCU UART0 Test Program\r\n");

 //init_network();
    W5100_NetInit();
    DisplayConfig();

   while(1);
}




TCP 서버 루프백 테스트
ProcessTCPS() 함수를 main루프에서 호출하면 TCP루프백 테스트를 할 수 있다.
(좀더 자세한 사항은 다음에 진행하고 일단 이더넷 통신이 되는것을 확인 하도록 하자)
void ProcessTCPS(unsigned int sock)
{
    unsigned int len;
 unsigned char data_buf[TX_RX_MAX_BUF_SIZE];
 unsigned int port = MY_LISTEN_PORT;

 switch (getSn_SR(sock))
 {
  // Socket CLOSED일 경우     
 case SOCK_CLOSED:
   if(!m_SokStatus1)m_SokStatus1 = 1;
 
  //socket 초기화 하고
  if(socket(sock,Sn_MR_TCP, port,0x00) == 0)
  {
   DebugPrint("Fail to create socket.");
   m_SokStatus1 = 0;
  }
  else
  {
   //접속대기
   listen(sock);
  }
  break; 


 case SOCK_ESTABLISHED:
  //수신데이터가 있으면
  if((len = getSn_RX_RSR(sock)) > 0)   
  {
      if (len > TX_RX_MAX_BUF_SIZE) len = TX_RX_MAX_BUF_SIZE;
      //데이터 수신
      len = recv(sock, data_buf, len);  
  
     //수신데이터 처리-> 루프백
     send(sock, data_buf, len);    
  } 
  break;

 case SOCK_CLOSE_WAIT:                            
  //If the client request to close
  disconnect(sock);
 
  m_SokStatus1 = 0;
  break; 
 
    default:
      
        break;
 } 
}


[CANTUS-EX] 이더넷을 이용한 움직이는 이미지파일 전송 테스트


[CANTUS-EX] 보드는 저렴한 고속 이더넷 솔루션으로 제작한 보드이다. AVR가격 보다 저렴하지만 고속의 메모리제어 방식을 적용하면 고속 이더넷이 가능하다.

초기 기능 테스트를 위해 이더넷으로 GIF이미지를 전송하여 LCD에 출력하는 테스트를 진행 해 보았다.
아직 외부 메모리 부분의 속도를 고속으로 하기는 무리가 있지만, 이더넷으로 이미지 전송하는 기본 테스트는 가능하기 때문에 간단한 테스트를 해 보았다.


CANTUS 이더넷을 이용항 이미지 전송 테스트 동영상
[CANTUS-EX] 보드가 TCP서버로 동작하며 Client에서 움직이는 GIF이미지를 설정하면 이미지를 받아와 TFT-LCD에 출력하는 테스트 이다.


[STM32F4] W5100/W5200 TPC/IP Loopback 전송 속도 테스트



SPI 최대 클럭 21Mhz에서 3.5Mbps 정도 나온다.
빠르긴 한데.. 아쉬운 점은 168Mhz MCU인데 속도가 기대한 만큼은 나오지 않는것 같다.
(PIC32 CP/IP 전송 속도 테스트 결과 와 비교하면 80Mhz PIC32가 더 빠르게 나온다)

SPI클럭 설정을 좀더 자유롭게 할 수 있으면 좋을것 같은데....
SPI FIFO가 없어 그런것 같은데... DMA를 이용하면 좀더 빨라지지 않을까?

------------------------------------------------------------
[7] iInChip Send: 3.5567 Mbps(5278574 bytes, 11.3230 sec)
iInChip Recv: 3.5074 Mbps(5278574 bytes, 11.4822 sec)
------------------------------------------------------------
[8] iInChip Send: 3.5647 Mbps(5278574 bytes, 11.2975 sec)
iInChip Recv: 3.3565 Mbps(5278574 bytes, 11.9982 sec)
--------------------------------------------------------






Cortex-M4 STM32F405 의 W5200 HAL Driver 코드
//-----------------------------------------------------------------------------
// W5100 HAL
#define _SPI1_ENABLE     1

#define W5100_CS_PORT     GPIOB
#define W5100_CS_BIT     BIT12

#define W5100_RST_PORT     GPIOA
#define W5100_RST_BIT     BIT0

#define IINCHIP_RSToff()    cbi(W5100_RST_PORT, W5100_RST_BIT) 
#define IINCHIP_RSTon()     sbi(W5100_RST_PORT, W5100_RST_BIT)

#define W5100_IO_INIT()     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB, ENABLE);\
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;\
          GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;\
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;\
          GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\
          GPIO_InitStructure.GPIO_Pin=W5100_CS_BIT;\
          GPIO_Init(GPIOB, &GPIO_InitStructure);\
          GPIO_InitStructure.GPIO_Pin=W5100_RST_BIT;\
          GPIO_Init(GPIOA, &GPIO_InitStructure);


#define IINCHIP_CSoff()     cbi(W5100_CS_PORT, W5100_CS_BIT) 
#define IINCHIP_CSon()     sbi(W5100_CS_PORT, W5100_CS_BIT)

#define IINCHIP_SPI_INIT()    SPI1_Init();IINCHIP_SpiSpeed()
#define IINCHIP_SpiSendData    SPI1_WriteReadByte
#define IINCHIP_SpiRecvData    SPI1_WriteReadByte
#define IINCHIP_SpiSpeed()              SPI1_SetSpeed(SPI_SPEED_MAX)
//-----------------------------------------------------------------------------

블로그 이미지

nexp

카테고리

분류 전체보기 (1560)
[MyProject] (48)
[TI] (75)
[NXP] (51)
[ST_MICRO] (129)
[FreeScale] (31)
[MSP430] (140)
[Microchip] (131)
Cortex-M (36)
[ATMEL] (29)
[AnalogDevice] (22)
[Embedded] (2)
ARM9 (24)
[AVR] (80)
[DSP] (111)
[8051] (21)
[MCU] (50)
[INTERFACE] (213)
[AppBoard] (23)
[ROBOT] (25)
[MODULE] (129)
[SENSOR] (41)
[DATA] (21)
[FPGA] (32)
[EVB] (1)
[Proramming] (38)
[MyLog] (6)
[IDEA] (0)
[Utility] (19)
[Book] (24)
취미생활 (4)
[Link] (2)