Cortex-M/INFINEON2013. 12. 1. 23:00

XMC1300 EVM - Simple Embedded Web Server Test

[XMC1300 EVM] Simple Embedded Web Server Test



XMC1300과 W5200을 이용하여 TCP/IP 통신이 테스트 되었기 때문에 활용 방안으로 간단히 임베디드 웹서버응 테스트 해 보았다

XMC1300은 저렴한 MCU이지만 16Kbyte의 램과 200Kbyte의 플래시 메모리를 가지고 있기 때문에 웹페이지를 저장 할 수 있는 공간이 충분하다. 웹서버는 이러한 XMC1300의 장점을 잘 살릴 수 있는 어플리 케이션이다



XMC1300 EVM을 이용한 임베디드 웹서버 테스트 동영상





XMC1300 Embedded WebServer 테스트 소스코드

간한히 테스트 하기 위해 코드를 최대한 단순하게 작성하였다.

void ProcessTCPS(unsigned int sock)

{

    int i;

int len;

unsigned int port = MY_LISTEN_PORT;

int wait_send=0;

switch (getSn_SR(SOCK_TCPS))

{

case SOCK_ESTABLISHED:

if(m_SokStatus1==1)

{

DebugPrint("%d : Connected by %s(%u)\r\n");

m_SokStatus1 = 2;

}

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);


            U0_PutBuf(data_buf, len);


//LED 제어 처리 

            if(strstr(data_buf, "ledr_on.jpg"))

{

                for(i=0;i<(IMG_BUF_SIZE/TX_RX_MAX_BUF_SIZE);i++)

                {

    send(sock, &img_buf[i*TX_RX_MAX_BUF_SIZE], TX_RX_MAX_BUF_SIZE, 0);

                }

                

                send(sock, &img_buf[i*TX_RX_MAX_BUF_SIZE], IMG_BUF_SIZE%TX_RX_MAX_BUF_SIZE, 0);

}             

else if(strstr(data_buf, "ledr_of.jpg"))

{

                for(i=0;i<(IMG_BUF_SIZE2/TX_RX_MAX_BUF_SIZE);i++)

                {

    send(sock, &img_buf2[i*TX_RX_MAX_BUF_SIZE], TX_RX_MAX_BUF_SIZE, 0);

                }

                

                send(sock, &img_buf2[i*TX_RX_MAX_BUF_SIZE], IMG_BUF_SIZE2%TX_RX_MAX_BUF_SIZE, 0);

}

            else if(strstr(data_buf, "led_off.html"))

{

                send(sock, str_msg3, strlen(str_msg3), 0);

Led1Off();

                Led2Off();

DebugPrint("led off\r\n");

}            

            else if(strstr(data_buf, "led_on.html"))

{

                send(sock, str_msg, strlen(str_msg), 0);

Led1On();

                Led2On();


DebugPrint("led on\r\n");

}

else if(strstr(data_buf, "index.html"))

{

                send(sock, str_msg, strlen(str_msg), 0);

                DebugPrint("main\r\n");

}

            else

            {

                if(led_flag == 0)

                {

                    led_flag = 1;

                    

                send(sock, str_msg, strlen(str_msg), 0);

                DebugPrint("main\r\n");                    

                }

            }

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");

}

break;

case SOCK_CLOSE_WAIT:                          

disconnect(sock);

m_SokStatus1 = 0;

break;

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;

        

    default:

        break;

}

}




Posted by nexp

댓글을 달아 주세요

  1. 비밀댓글입니다

    2013.12.12 09:55 [ ADDR : EDIT/ DEL : REPLY ]

Cortex-M/INFINEON2013. 11. 30. 22:00

XMC1300 EVM - ADC 테스트

[XMC1300 EVM] - ADC 테스트




XMC1300은 저렴한 CORTEX-M0 코어를 가진 MCU임에도 아날로그 기능은 풍부하다. 두채널의 독립된 12비트 ADC모듈이 있고 각각 8채널 입력 가능하다. 특히 하드웨어적으로 FIR/IIR 필터가 존재 하는것이 특이하다.


XMC1300 ADC특징

- Two independent sample and hold stages with 8 analog input channels each

- Selectable result width of 8/10/12 bits

– Fast Compare Mode

– Independent result registers

– Configurable limit checking against programmable border values

– Data rate reduction through adding a selectable number of conversion results

– FIR/IIR filter with selectable coefficients




XMC1300 ADC 테스트 동영상

ADC5 에 연결되어 있는 가변저항의 전압값을 TFT LCD에 출력하는 예제




XMC1300 EVM ADC 핀맵

P2.0 -> VADC0.G0CH5


P2.6 -> VADC0.G0CH0

P2.7 -> VADC0.G0CH1




XMC1300 ADC초기화코드

void ADC_Init()

{

        // Global ADC Initialization

WR_REG(VADC->CLC, VADC_CLC_DISR_Msk, VADC_CLC_DISR_Pos, 0);

// Wait till module clock is enabled

while((RD_REG(VADC->CLC, VADC_CLC_DISS_Msk, VADC_CLC_DISS_Pos))!= 0);


// Enable ORC; required due to erratum ADC_AI.003

WR_REG(COMPARATOR->ORCCTRL, COMPARATOR_ORCCTRL_ENORC0_Msk, COMPARATOR_ORCCTRL_ENORC0_Pos, 1);


// Initiate start up calibration

WR_REG(VADC->GLOBCFG, VADC_GLOBCFG_SUCAL_Msk, VADC_GLOBCFG_SUCAL_Pos, 1);


// Enable wait-for-read mode

WR_REG(VADC_G0->RCR[0], VADC_G_RCR_WFR_Msk, VADC_G_RCR_WFR_Pos, 1);


// Configure Scan source

// Select G1CH7 on P2.5 as input channel

WR_REG(VADC_G0->ASSEL, VADC_G_ASSEL_CHSEL5_Msk, VADC_G_ASSEL_CHSEL5_Pos, 1);

WR_REG(VADC_G0->ASMR, VADC_G_ASMR_ENGT_Msk, VADC_G_ASMR_ENGT_Pos, 1); //Enable gate

WR_REG(VADC_G0->ASMR, VADC_G_ASMR_SCAN_Msk, VADC_G_ASMR_SCAN_Pos, 1); //Enable autoscan

WR_REG(VADC_G0->ASMR, VADC_G_ASMR_LDEV_Msk, VADC_G_ASMR_LDEV_Pos, 1); //Generate a load event

    

// Arbitration

// Select normal operation

WR_REG(VADC_G0->ARBCFG, VADC_G_ARBCFG_ANONC_Msk, VADC_G_ARBCFG_ANONC_Pos, 3);

// Enable arbitration slot 1

WR_REG(VADC_G0->ARBPR, VADC_G_ARBPR_ASEN1_Msk, VADC_G_ARBPR_ASEN1_Pos, 1);


// Wait till calibration is completed

while((RD_REG(VADC_G0->ARBCFG, VADC_G_ARBCFG_CAL_Msk, VADC_G_ARBCFG_CAL_Pos))!= 0);    

}



XMC1300 ADC Read 함수

adc_result =  VADC_G0->RES[0];


// Check if new conversion result is available

if (adc_result & VADC_G_RES_VF_Msk)

{

adc_result &= VADC_G_RES_RESULT_Msk;

adc_result = (adc_result >> 2);

        

                DebugPrint("%d\r\n", adc_result);

}   




Posted by nexp

댓글을 달아 주세요

Cortex-M/INFINEON2013. 11. 24. 23:30

XMC1300 EVM - SPI 테스트 (Infineon Cortex-M0)

[XMC1300 EVM] - SPI 테스트 (Infineon Cortex-M0)


XMC 시리즈는 시리얼 통신( UART, SPI, I2S, I2C )을 동일한 블록으로 만들어 두고 모드로 선택해서 사용할수 있도록 되어 있다.

장단점이 있을것 같은데... 

장점으로 동일한 셋팅으로 사하기 때문에 소프트웨어 부담이 줄어든다. 반면 2채널 밖에 없기 때문에 여러 통신을 동시에 사용할때 어려움이 있다.



XMC1300 SPI 블록도




XMC1300 SPI 핀맵

XMC의 핀기능은 하나의 포트에 여러가지 기능을 사가능하도록 해 두었는데, 다만 기능들이 일관성이 없어 데이터시트 상에 핀의 기능을 확인할 때 주의가 필요한것 같다.


SPI 기능핀은 여러핀 리맵가능한것 처럼 되어 있지만 사실 상당히 제한적으로 설정 가능하다. 데이터시트를 자세히 보고 할당해야 한다. XMC1300 EVM 보드에서는 아래와 같이 할당 했다.

P1.0(MOSI) - USIC0_CH0.DOUT0(ALT7)


P1.1(MISO) - USIC0_CH0.DX0D


P0.8(SCLK) - USIC0_CH0.SCLKOUT(ALT6)


P1.4(SS) - USIC0_CH0.SELO0(ALT6)



SPI MISO 기능으로 사용할 수 있는 핀




XMC1300 SPI 관련 레지스터

CCR (Channel Control Register)

MODE [3:0] rw Operating Mode


0H - USIC channel is disabled

1H - SSC (SPI) 모드로 동작

2H - ASC (SCI, UART) 모드로 동작

3H - I2S 모드로 동작

4H - I2C 모드로 동작



XMC1300 SPI 초기화 함수

void SPI0_Init(void)

{

    PORT1_Set_Mode(1,INPUT_PU);

    PORT1_Set_Mode(0,OUTPUT_PP_AF7);

    PORT0_Set_Mode(8,OUTPUT_PP_AF6);

  

//Kernel State Configuration Register - Module Enable + Bit Protection for MODEN

USIC0_CH0->KSCFG |= (1 << USIC_CH_KSCFG_MODEN_Pos) | (1 << USIC_CH_KSCFG_BPMODEN_Pos);


//Normal divider mode selected

WR_REG(USIC0_CH0->FDR, USIC_CH_FDR_DM_Msk, USIC_CH_FDR_DM_Pos, 1);

//Configuration of baud rate

WR_REG(USIC0_CH0->FDR, USIC_CH_FDR_STEP_Msk, USIC_CH_FDR_STEP_Pos, FDR_STEP);

WR_REG(USIC0_CH0->BRG, USIC_CH_BRG_PDIV_Msk, USIC_CH_BRG_PDIV_Pos, BRG_PDIV);

    

    WR_REG(USIC0_CH0->BRG, USIC_CH_BRG_SCLKOSEL_Msk, USIC_CH_BRG_SCLKOSEL_Pos, 0);    

    WR_REG(USIC0_CH0->BRG, USIC_CH_BRG_SCLKCFG_Msk, USIC_CH_BRG_SCLKCFG_Pos, 1);


//Configuration of USIC Input Stage

        //Select P1.2

WR_REG(USIC0_CH0->DX0CR, USIC_CH_DX0CR_DSEL_Msk, USIC_CH_DX0CR_DSEL_Pos, 3);

WR_REG(USIC0_CH0->DX0CR, USIC_CH_DX0CR_INSW_Msk, USIC_CH_DX0CR_INSW_Pos, 1);


//Configuration of USIC Shift Control

//Transmit/Receive MSB first is selected, Transmission Mode (TRM) = 1, Passive Data Level (PDL) = 1

WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_PDL_Msk, USIC_CH_SCTR_PDL_Pos, 1);

WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_TRM_Msk, USIC_CH_SCTR_TRM_Pos, 1);

WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_SDIR_Msk, USIC_CH_SCTR_SDIR_Pos, 1);

//Set Word Length (WLE) & Frame Length (FLE)

WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_FLE_Msk, USIC_CH_SCTR_FLE_Pos, 7);

WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_WLE_Msk, USIC_CH_SCTR_WLE_Pos, 7);


//Configuration of USIC Transmit Control/Status Register

//TBUF Data Enable (TDEN) = 1, TBUF Data Single Shot Mode (TDSSM) = 1

WR_REG(USIC0_CH0->TCSR, USIC_CH_TCSR_TDEN_Msk, USIC_CH_TCSR_TDEN_Pos, 1);

WR_REG(USIC0_CH0->TCSR, USIC_CH_TCSR_TDSSM_Msk, USIC_CH_TCSR_TDSSM_Pos, 1);


//Configuration of Protocol Control Register

WR_REG(USIC0_CH0->PCR_SSCMode, USIC_CH_PCR_SSCMode_MSLSEN_Msk,                                USIC_CH_PCR_SSCMode_MSLSEN_Pos, 1);


//Configuration of Channel Control Register

WR_REG(USIC0_CH0->CCR, USIC_CH_CCR_MODE_Msk, USIC_CH_CCR_MODE_Pos, 1);

WR_REG(USIC0_CH0->CCR, USIC_CH_CCR_AIEN_Msk, USIC_CH_CCR_AIEN_Pos, 0);


//Data Pointer & Buffer Size for Transmitter Buffer Control - DPTR = 0,  SIZE = 5

WR_REG(USIC0_CH0->TBCTR, USIC_CH_TBCTR_DPTRSIZE_Msk, USIC_CH_TBCTR_DPTRSIZE_Pos, 0x05000000);

//Data Pointer & Buffer Size for Receiver Buffer Control - DPTR = 32,  SIZE = 5

WR_REG(USIC0_CH0->RBCTR, USIC_CH_RBCTR_DPTRSIZE_Msk, USIC_CH_RBCTR_DPTRSIZE_Pos, 0x05000020);

}



XMC1300 SPI Read/Write 함수

unsigned char SPI0_WriteReadByte(unsigned char Data)

{

    //while(!(USIC0_CH0->TRBSR&BIT11));

    USIC0_CH0->IN[0] = Data;

    

    while(USIC0_CH0->TRBSR&BIT3);

    return USIC0_CH0->OUTR;  

}



Posted by nexp

댓글을 달아 주세요

Cortex-M/INFINEON2013. 11. 24. 22:00

XMC1300 EVM - UART 테스트 (Infineon Cortex-M0)

[XMC1300 EVM] - UART 테스트 (Infineon Cortex-M0)



XMC1300는 UART, SPI,I2C,I2S통신을 위한    모듈이 하나의 통합된 모듈로 2채널 존재한다

하나의 통합된 모듈이기 때문에 소프트웨어 적으로는 거의 동일하게 설정해서 사용할 수 있기 때문에 편리하다. 하지만 동시에 여러 통신 채널을 사용하는 어플리케이션에는 문제가 발생 할 수 있다



XMC1300 UART 블록도



여러 통신모듈이 레지스터를 공유하기 때문에 다소 복잡해 보인다

하지만 몇가지 레지스터만 학인하면 쉽게 UART통신이 가능하다



TDV 

bit7

Transmit Data Valid


전송버퍼 (TBUF)의 데이터 상태를 나타내는 비트로 1이면 정상 전송되었음을 나타낸다.의  can be considered as valid for




REMPTY 3 rh Receive Buffer Empty

This bit indicates whether the receive buffer is

empty.

0B The receive buffer is not empty.

1B The receive buffer is empty.




TEMPTY 11 rh Transmit Buffer Empty

This bit indicates whether the transmit buffer is

empty.

0B The transmit buffer is not empty.

1B The transmit buffer is empty.



XMC1300 UART 송수신 함수

unsigned char U0_GetByte(void)

{

    while((USIC0_CH1->TRBSR&BIT3));

    return USIC0_CH1->OUTR;

}



void U0_PutByte(unsigned char Data)

{

    while(USIC0_CH1->TCSR & BIT7); 

    USIC0_CH1->TBUF[0]  = Data;

}


Posted by nexp

댓글을 달아 주세요

Cortex-M/INFINEON2013. 11. 23. 21:46

XMC1300 EVM - 성능측정 GPIO토글 테스트

[XMC1300 EVM] - 성능측정 GPIO토글 테스트


Infineon사의 저렴한 Cortex-M0 XMC1302를 이용하여 간단히 성능 테스트를 해 보았다. 물론 요즘에 출시되는 MCU들은 각각의 용도별 특징이 있기 때문에 절대 성능을 측정하기는 무리가 있지만 기록해 두면 여러모로 쓸모는 있을것 같다.


XMC1300은 다른 Cortex시즈와 달리 GPIO 셋, 클리어, 토글레지스터가 따로 없고 OMR(Output Modification Register)레지스트라고하는 출력 상태를 변경하는 레지스터에서 토글이나 셋, 클리어 가능하다.

이렇게 레지스터가 하나로 되면 하드웨어적으로는 간단해 지지만 소프트웨어적으로는 한번의 연산이 더 필요기 때문에 코드상에서는 불리한것 같다.



XMC1300 GPIO 블록도

아래 그림은 XMC1300의 GPIO 구조도 이다.




우선 최대 32Mhz로 구동하고 GPIO출력 레지스터를 토글해 보니 1.25Mhz정도 된다. 


1.25Mhz

              while(1)

                   {

               

                       PORT0->OUT ^=  BIT13;

   \   00000036   0x6821             LDR      R1,[R4, #+0]

   \   00000038   0x4041             EORS     R1,R1,R0

   \   0000003A   0xE7FB             B        ??main_1

   \                     ??main_0:

   \   0000003C   0x40040000         DC32     0x40040000

   \   00000040   0xFFFFEFFF         DC32     0xffffefff

                  }



GPIO상태 변경 레지스터를 이용해 보면 좀더 빨라지지만 다른 MCU들의 성능 측정 결과와 비교하면 만족할 만한 수준은 아닌것 같다.

2.9Mhz

                   while(1)

                   {

                       PORT0->OMR = (0x00010001UL << 13);

   \                     ??main_1: (+1)

   \   00000038   0x6060             STR      R0,[R4, #+4]

   \   0000003A   0xE7FD             B        ??main_1

   \                     ??main_0:

   \   0000003C   0x40040000         DC32     0x40040000

   \   00000040   0xFFFFEFFF         DC32     0xffffefff

   \   00000044   0x20002000         DC32     0x20002000

                   }


Posted by nexp

댓글을 달아 주세요