/*******************************************************************************
* Function Name  : STM3210B_LCD_Init
* Description    : Initializes the LCD.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void STM3210B_LCD_Init(void)
{
  /* Setups the LCD */
  LCD_Setup();

  /* Try to read new LCD controller ID 0x9320 */
  if (LCD_ReadReg(R0) == LCD_ILI9320)
  {
    LCDType = LCD_ILI9320;
  }
  else
  {
    LCDType = LCD_SPFD5408;

    /* Setups the LCD */
    LCD_Setup();

    /* Try to read new LCD controller ID 0x5408 */
    if (LCD_ReadReg(R0) != LCD_SPFD5408)
    {
      LCDType = LCD_HX8312;
      /* Setups the LCD */
      LCD_Setup();
    }
  }
}
Beispiel #2
0
/**
  * @brief  Initializes the LCD.
  * @param  None
  * @retval None
  */
void STM32303C_LCD_Init(void)
{
  __IO uint32_t lcdid = 0;
  
  /* Setups the LCD */
  LCD_Setup();

  /* Read the LCD ID */
  lcdid = LCD_ReadReg(0x00);  
  
  if (lcdid == LCD_SPFD5408)
  {
    LCDType = LCD_SPFD5408;
        /* Setups the LCD */
    LCD_Setup();
  }
  else if (lcdid == LCD_ILI9320)
  {
    LCDType = LCD_ILI9320;
    /* Setups the LCD */
    LCD_Setup();    
  }  
  else
  {
    LCDType = LCD_HX8347D;
        /* Setups the LCD */
    LCD_Setup();
  } 
    
  LCD_SetFont(&LCD_DEFAULT_FONT);
}
Beispiel #3
0
/**********主程序*******/
int  main()
{
#ifdef DEBUG
    debug();
#endif
	/* System Clocks Configuration */
	SystemInit();

	/* Enable the FSMC Clock */
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);    

	/* Configure FSMC */
	FSMC_LCD_Init();

	/* Init for LCD */
	LCD_Setup();
	EXTI_Config();
	SPI_Flash_Init();
    NVIC_Configuration();

	/*变量初始化*/
	GlobalStateFlag=0;
	MenuFlag=1;
	Pic_Addr=gImage_picture1;
	HomePage_Disp();
    /* Infinite loop */
    while (1)
    {
    }
}
/**
  * @brief  Initializes the LCD.
  * @param  None
  * @retval None
  */
void STM32072B_LCD_Init(void)
{
  /* Configure the LCD Control pins ------------------------------------------*/
  LCD_CtrlLinesConfig();
  
  /* Configure the LCD_SPI interface -----------------------------------------*/
  LCD_SPIConfig();

  LCD_Setup();

  LCD_SetFont(&LCD_DEFAULT_FONT);
}
Beispiel #5
0
void SetupHardware(void) {

    MY_SetLedAll(true);

    MY_Setup();
    USB_Init();
    LCD_Setup();
    TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 400000));
    Serial_Init(2000000, true);

    //  noisy thing
    PORTC &= ~(1 << 6);
    DDRC |= (1 << 6);

    //  don't txen
    PORTD &= ~(1 << 4);
    PORTD |= (1 << 2);  //  pull-up
    DDRD |= (1 << 4);
}
Beispiel #6
0
/* ****************************************************************************/
int main() {
    SYSTEMConfigPerformance(FCY); // setup system to improve performance 
    init_io_ports();              // initialize I/O ports 
    LCD_Setup();                  // setup the LCD
//    dis_RES=1;
//    dis_CS=1;
//    dis_D_C=1;
//    dis_E_RD=1;
//    dis_R_W=1;
//    dis_EN=1;
//    LATE=0xFF;
    
    while(1){ // main loop 
        delay_clock(10000);
        LATDbits.LATD8=1;
        delay_clock(10000);
        LATDbits.LATD8=0;
    }
}
Beispiel #7
0
/* main work function */
void work(void) {
    unsigned short i, j;
    unsigned char mailbox_num = 0;
    volatile ProtoIOMBox * mbox;
    /* setup status */
    status_setup();
    /* setup serial console */
    usart1_setup();
    /* setup proto */
    proto_setup();
    mbox = proto_srv_dat.mailboxes[mailbox_num];
    /* setup button */
    buttons_setup();
    /* lcd setup */
    LCD_Setup();
    LCD_Clear(BLACK);
    
    for (i = 0; i < 10; i++) {
        for (j = 0; j < 10; j++) {
            LCD_Pixel(j + 10, i + 10, test.data[i * 10 + j]);
        }
    }
    LCD_Window(0, 0, 9, 9);
    LCD_RS_LOW;
    LCD_SELECT;
    for (i = 0; i < 100; i++) {
        LCD_Send(test.data[i] >> 8);
        LCD_Send(test.data[i] & 0x00ff);
    }
    LCD_Cursor(0, 0);
    LCD_DESEL;
    
    /* check status */
    check_status();
    /* send ping */
    mbox->outbox->header = 'C'; /* Command */
    mbox->outbox->size = 0x00; /* 0 for ping request */
    mbox->outbox_s = PROTO_IO_MBOX_READY; /* Box ready */
    mbox->inbox->size = 64; /* buffer len for control */
    mbox->inbox_s = PROTO_IO_MBOX_READY; /* Box ready */
    /* wait connection estabilished */
    while (status == 0);
    /* send ping message */
    proto_send_msg(mailbox_num);
    /* wait to send message */
    while (mbox->outbox_s <= PROTO_IO_MBOX_SEND);
    if (mbox->outbox_s == PROTO_IO_MBOX_COMPLETE)
        LCD_String("Con", 36, 6, 1, WHITE, GLASSY);
    else
        LCD_String("Un", 36, 6, 1, RED, GLASSY);
    /* get ping message */
    /* FIXME wtf? this not work or work parity */
    //proto_get_msg(mailbox_num);
    /* wait to get message */
    while (mbox->inbox_s <= PROTO_IO_MBOX_SEND);
    if (mbox->inbox_s == PROTO_IO_MBOX_COMPLETE) {
        LCD_String("OK", 36 + 3 * 7, 6, 1, GREEN, GLASSY);
        for (i = 0; i < mbox->inbox->size; i++)
            LCD_Char(mbox->inbox->message[i], 70 + i * 6, 6, 1, WHITE, GLASSY);
    }
    else
        LCD_String("ERR", 36 + 3 * 7, 6, 1, RED, GLASSY);
    /* infinity loop */
    while (1) {
        if (button_state.state[B_LGHT] == B_CLICK) {
            sender('+');
            button_state.state[B_LGHT] = B_RELEASE;
        }
        if (button_state.state[B_MOD] == B_CLICK) {
            sender('m');
            button_state.state[B_MOD] = B_RELEASE;
        }
        if (button_state.state[B_SET] == B_CLICK) {
            sender('-');
            button_state.state[B_SET] = B_RELEASE;
        }
        if (button_state.state[B_UP] == B_CLICK) {
            sender('<');
            button_state.state[B_UP] = B_RELEASE;
        }
        if (button_state.state[B_SU] == B_CLICK) {
            sender('p');
            button_state.state[B_SU] = B_RELEASE;
        }
        if (button_state.state[B_DWN] == B_CLICK) {
            sender('>');
            button_state.state[B_DWN] = B_RELEASE;
        }
    }
}
Beispiel #8
0
/*******************************************************************************
* Function Name  : STM3210D_LCD_Init
* Description    : Initializes the LCD.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void STM3210D_LCD_Init(void)
{
    /* Setups the LCD */
    LCD_Setup();
}
int main(void) {

	// Cache on, min flash wait, interrupts on, LED/button init, UART init
  NU32_Startup();

  // Setup LCD and create message to be sent
  LCD_Setup();
  char message[MAX_MESSAGE_LENGTH];

  // Local variables for determining and setting Timer interrupts based on FPS
	int Time1_Side = 0, N_Side = 0, PR_Side = 0, TCKPS_Side = 0;
	int Time1_Top = 0, N_Top = 0, PR_Top = 0, TCKPS_Top = 0;


	// =============================================================================================
	// Change Notification Digital Input Interrupt from PPOD
	// =============================================================================================
  CNPUEbits.CNPUE17 = 0;  						// CN17/RF4 input has no internal pull-up

  oldF = PORTF;           						// all pins of port F are inputs, by default

  __builtin_disable_interrupts(); 		// step 1: disable interrupts
  CNCONbits.ON = 1;               		// step 2: configure peripheral: turn on CN
  CNENbits.CNEN17 = 1; 								//         listen to CN17/RF4
  IPC6bits.CNIP = 3;              		// step 3: set interrupt priority
  IPC6bits.CNIS = 2;              		// step 4: set interrupt subpriority
  IFS1bits.CNIF = 0;              		// step 5: clear the interrupt flag
  IEC1bits.CNIE = 1;              		// step 6: enable the _CN interrupt
  __builtin_enable_interrupts();  		// step 7: CPU enabled for mvec interrupts



	// =============================================================================================
	// PWM and digital output for piezoelectric droplet generator
	// =============================================================================================
  OC1CONbits.OCTSEL = 1;  			 			// Select Timer3 for comparison

  T3CONbits.TCKPS = 0;     						// Timer3 prescaler N=1 (1:1)
  PR3 = 3999;              						// period = (PR3+1) * N * 12.5 ns = 20 kHz
  TMR3 = 0;                						// initial TMR3 count is 0

  OC1CONbits.OCM = 0b110; 						// PWM mode with no fault pin; other OC1CON bits are defaults
  OC1RS = 0;           								// duty cycle = OC1RS/(PR3+1) = 75%
  OC1R = 0;             							// initialize before turning OC1 on; afterward it is read-only

  T3CONbits.ON = 1;        						// turn on Timer3
  OC1CONbits.ON = 1;       						// turn on OC1

	// Set A10/A2 to digital output pins
	TRISAbits.TRISA10 = 0;							// RA10 is an output pin
	TRISAbits.TRISA2 = 0;								// RA2 is an output pin

	//-Vcc: set L1 to HIGH, L2 to LOW, PWMA to >0
	OC1RS = 4000;
	LATAbits.LATA10 = 1;
	LATAbits.LATA2 = 0;



	// =============================================================================================
	// TrackCam ExSync Trigger - Side (A3), Top (A4)
	// =============================================================================================

	// Digital output pin
	TRISAbits.TRISA3 = 0;
	TRISAbits.TRISA4 = 0;

	// Set to HIGH
	LATAbits.LATA3 = 1;
	LATAbits.LATA4 = 1;



	// =============================================================================================
	// Keep program running to look for command from master to start record procedure
	// =============================================================================================
  while(1) {

		// Get message from computer
    NU32_ReadUART1(message, MAX_MESSAGE_LENGTH);

		//Serial message: [NUMIMAGES_Side, FPS_Side, NUMIMAGES_Top, FPS_Top, PULSETIME, DELAYTIME]
		sscanf(message, "%d%*c %d%*c %d%*c %d%*c %d%*c %f", &NUMIMAGES_Side, &FPS_Side, &NUMIMAGES_Top, &FPS_Top, &PULSETIME, &DELAYTIME);		//%*c reads in comma and ignores it


		// -------------------------------------------------------------------------------------------
		// Side Camera Interrupt -  NUMIMAGES_Side Hz - Timer2
		// -------------------------------------------------------------------------------------------

		// Calculate pre-scaler based on FPS_Side
		Time1_Side = (((1.0/FPS_Side*1.0)*1e9)/12.5);
		N_Side = ceil( (Time1_Side*1.0/65535.0) );

		// Select best pre-scaler of 1, 2, 4, 8, 16, 32, 64, or 256 
		if( N_Side == 1 ) {
			N_Side = 1;
			TCKPS_Side = 0;
		}
		else if( N_Side <= 2 ) {
			N_Side = 2;
			TCKPS_Side = 1;
		}
		else if( N_Side <= 4 ) {
			N_Side = 4;
			TCKPS_Side = 2;
		}
		else if( N_Side <= 8 ) {
			N_Side = 8;
			TCKPS_Side = 3;
		}
		else if( N_Side <= 16 ) {
			N_Side = 16;
			TCKPS_Side = 4;
		}
		else if( N_Side <= 32 ) {
			N_Side = 32;
			TCKPS_Side = 5;
		}
		else if( N_Side <= 64 ) {
			N_Side = 64;
			TCKPS_Side = 6;
		}
		else {
			N_Side = 256;
			TCKPS_Side = 7;
		}

		// Calculate period register based on selected prescaler
		PR_Side = (Time1_Side / N_Side) - 1;



		__builtin_disable_interrupts(); 	// INT step 2: disable interrupts at CPU

																			// INT step 3: 	setup TMR2 to call ISR at frequency of 5 kHz
		PR2 = PR_Side;										// 							set period register to 16,000
		TMR2 = 0;													// 							initialize count to 0
		T2CONbits.TCKPS = TCKPS_Side;			// 							set prescaler to 1:1
		T2CONbits.ON = 1; 								// 							turn on Timer2
		IPC2bits.T2IP = 5; 								// INT step 4: 	priority 5
		IPC2bits.T2IS = 2; 								// 							subpriority 2
		IFS0bits.T2IF = 0; 								// INT step 5: 	clear interrupt flag
		IEC0bits.T2IE = 1; 								// INT step 6: 	enable interrupt

		__builtin_enable_interrupts(); 		// INT step 7: 	enable interrupts at CPU



		// -------------------------------------------------------------------------------------------
		// Top Camera Interrupt -  NUMIMAGES_Top Hz - Timer4
		// -------------------------------------------------------------------------------------------

		// Calculate pre-scaler based on FPS_Top
		Time1_Top = (((1.0/FPS_Top)*1e9)/12.5);
		N_Top = ceil( (Time1_Top/65535.0) );

		// Select best pre-scaler of 1, 2, 4, 8, 16, 32, 64, or 256 
		if( N_Top == 1 ) {
			N_Top = 1;
			TCKPS_Top = 0;
		}
		else if( N_Top <= 2 ) {
			N_Top = 2;
			TCKPS_Top = 1;
		}
		else if( N_Top <= 4 ) {
			N_Top = 4;
			TCKPS_Top = 2;
		}
		else if( N_Top <= 8 ) {
			N_Top = 8;
			TCKPS_Top = 3;
		}
		else if( N_Top <= 16 ) {
			N_Top = 16;
			TCKPS_Top = 4;
		}
		else if( N_Top <= 32 ) {
			N_Top = 32;
			TCKPS_Top = 5;
		}
		else if( N_Top <= 64 ) {
			N_Top = 64;
			TCKPS_Top = 6;
		}
		else {
			N_Top = 256;
			TCKPS_Top = 7;
		}

		// Calculate period register based on selected prescaler
		PR_Top = (Time1_Top / N_Top) - 1;



		__builtin_disable_interrupts(); 	// INT step 2: disable interrupts at CPU

																			// INT step 3: 	setup TMR2 to call ISR at frequency of 5 kHz
		PR4 = PR_Top; 										// 							set period register to 16,000
		TMR4 = 0;													// 							initialize count to 0
		T4CONbits.TCKPS = TCKPS_Top; 			// 							set prescaler to 1:1
		T4CONbits.ON = 1; 								// 							turn on Timer2
		IPC4bits.T4IP = 5; 								// INT step 4: 	priority 5
		IPC4bits.T4IS = 0; 								// 							subpriority 0
		IFS0bits.T4IF = 0; 								// INT step 5: 	clear interrupt flag
		IEC0bits.T4IE = 1; 								// INT step 6: 	enable interrupt

		__builtin_enable_interrupts(); 		// INT step 7: 	enable interrupts at CPU




		// Convert DELAYTIME to DelayFrames
		//DelayFrames_Side = DELAYTIME*FPS_Side;

		// Turn RecordFlag ON since we have received from master
		RecordFlag = 1;

		// Display properties on LCD
    LCD_Clear();
    LCD_Move(0,0);
		sprintf(message, "%d, %d, %d", NUMIMAGES_Side, FPS_Side, FPS_Top);
		//sprintf(message, "%d, %d, %d", PR2, N_Side, T2CONbits.TCKPS);
    LCD_WriteString(message);                     	

    LCD_Move(1,0);
		sprintf(message, "%d, %f", PULSETIME, DELAYTIME);
		//sprintf(message, "%d, %d, %d", PR4, N_Top, T4CONbits.TCKPS);
    LCD_WriteString(message);
  }

  return 0;
}
int main(void) {

	// Cache on, min flash wait, interrupts on, LED/button init, UART init
  NU32_Startup();
  LCD_Setup();

  char message[MAX_MESSAGE_LENGTH];


	// =============================================================================================
	// Change Notification Digital Input Interrupt from PPOD
	// =============================================================================================
  CNPUEbits.CNPUE17 = 0;  // CN17/RF4 input has no internal pull-up

  oldF = PORTF;           // all pins of port F are inputs, by default

  __builtin_disable_interrupts(); // step 1: disable interrupts
  CNCONbits.ON = 1;               // step 2: configure peripheral: turn on CN
  CNENbits.CNEN17 = 1; 						//         listen to CN17/RF4
  IPC6bits.CNIP = 3;              // step 3: set interrupt priority
  IPC6bits.CNIS = 2;              // step 4: set interrupt subpriority
  IFS1bits.CNIF = 0;              // step 5: clear the interrupt flag
  IEC1bits.CNIE = 1;              // step 6: enable the _CN interrupt
  __builtin_enable_interrupts();  // step 7: CPU enabled for mvec interrupts



	// =============================================================================================
	// PWM and digital output for piezoelectric droplet generator
	// =============================================================================================
  OC1CONbits.OCTSEL = 1;  			 		// Select Timer3 for comparison

  T3CONbits.TCKPS = 0;     					// Timer3 prescaler N=1 (1:1)
  PR3 = 3999;              					// period = (PR3+1) * N * 12.5 ns = 20 kHz
  TMR3 = 0;                					// initial TMR3 count is 0

  OC1CONbits.OCM = 0b110; 					// PWM mode with no fault pin; other OC1CON bits are defaults
  OC1RS = 0;           							// duty cycle = OC1RS/(PR3+1) = 75%
  OC1R = 0;             						// initialize before turning OC1 on; afterward it is read-only

  T3CONbits.ON = 1;        					// turn on Timer3
  OC1CONbits.ON = 1;       					// turn on OC1

	// Set A10/A2 to digital output pins
	TRISAbits.TRISA10 = 0;						// RA10 is an output pin
	TRISAbits.TRISA2 = 0;							// RA2 is an output pin

	//-Vcc: set L1 to HIGH, L2 to LOW, PWMA to >0
	OC1RS = 4000;
	LATAbits.LATA10 = 1;
	LATAbits.LATA2 = 0;



	// =============================================================================================
	// TrackCam ExSync Trigger
	// =============================================================================================

	// Set A3 to digital output pin
	TRISAbits.TRISA3 = 0;						// RA3 is an output pin

	//Set A3 to HIGH
	LATAbits.LATA3 = 1;



	// =============================================================================================
	// Keep program running to look for command from master to start record procedure
	// =============================================================================================
  while(1) {
		// Get message from computer
    NU32_ReadUART1(message, MAX_MESSAGE_LENGTH);

		//Serial message: [NUMIMAGES, FPS, PULSETIME, DELAYTIME]
		sscanf(message, "%d%*c %d%*c %d%*c %f", &NUMIMAGES, &FPS, &PULSETIME, &DELAYTIME);		//%*c reads in comma and ignores it

		// Convert DELAYTIME to DelayFrames
		DelayFrames = DELAYTIME*FPS;

		// Turn RecordFlag ON since we have received from master
		RecordFlag = 1;

		// Display properties on LCD
    LCD_Clear();
    LCD_Move(0,0);
		sprintf(message, "%d, %d", NUMIMAGES, FPS);
    LCD_WriteString(message);                     	

		sprintf(message, "%d, %f", PULSETIME, DELAYTIME);
    LCD_Move(1,0);
    LCD_WriteString(message);
  }

  return 0;
}
Beispiel #11
0
/**
 * \fn HMI_Setup(const THMISetup * const aHMISetup)
 * \brief Setup HMI system.
 * \param aHMIContext A pointer of HMI configuration structure
 * \return TRUE if HMI is set properly or FALSE when failed
 */
BOOL HMI_Setup(const THMISetup * const aHMISetup) 
{
  UINT16 i = 0, j = 0;
#ifndef NO_INTERRUPT
  TTimerSetup timerCh6;
  
  timerCh6.outputCompare    = bTRUE;
  timerCh6.outputAction     = TIMER_OUTPUT_DISCONNECT;
  timerCh6.inputDetection   = TIMER_INPUT_OFF;
  timerCh6.toggleOnOverflow = bFALSE;
  timerCh6.interruptEnable  = bFALSE;
  timerCh6.pulseAccumulator = bFALSE;
  timerCh6.routine          = &HMIRoutine;
#endif
  if (aHMISetup) 
  {
    if (LCD_Setup())
    {
      HMIContext.renderMode = aHMISetup->renderMode;
      //HMIContext.idlePanelId = aHMISetup->idlePanelId;
      HMIContext.screenFrameBufferPtr = &HMIFrameBuffer[0];
      HMIContext.renderFrameBufferPtr = &HMIFrameBuffer[1];      
      for (j = 0; j < aHMISetup->frameTemplate.height; ++j)
      {
        for (i = 0; i < aHMISetup->frameTemplate.width; ++i)
        {
          HMIContext.frameTemplate.data[j][i] = aHMISetup->frameTemplate.data[j][i];
        }
      }
      HMIContext.frameTemplate.width = aHMISetup->frameTemplate.width;
      HMIContext.frameTemplate.height = aHMISetup->frameTemplate.height;
      
      HMIContext.focusedMenuItemId = 0xFF;
      HMIContext.selectedMenuItemId = 0xFF;
      
      HMIContext.idlePanelId = aHMISetup->idlePanelId;
      HMIContext.idleTimeCount = 0;
      HMIContext.maxIdleTimeCount = aHMISetup->maxIdleTimeCount;
      HMIContext.parentPanelId = 0;
      HMIContext.currentPanelId = 0;
      HMIContext.previousPanelId = 0;
      
      HMIContext.popupPtr = (THMIPopup*)0x00;
      HMIContext.maxPopupTimeCount = 10;
      HMIContext.popupTimeCount = 0;
      
      HMIContext.oldHours = 0;
      HMIContext.oldMinutes = 0;
      HMIContext.oldSeconds = 0;      

      HMIContext.hours = 0;
      HMIContext.minutes = 0;
      HMIContext.seconds = 0;
      
      HMIContext.backlight = aHMISetup->backlight;
      HMIContext.backlightChangedCallback = aHMISetup->backlightChangedCallback;
      HMIContext.contrast = aHMISetup->contrast;
      HMIContext.contrastChangedCallback = aHMISetup->contrastChangedCallback;      
#ifndef NO_INTERRUPT
      HMIRoutinePeriod = (UINT16)(48000); // 2ms
      
      Timer_Init(TIMER_Ch6, &timerCh6);
      Timer_Set(TIMER_Ch6, HMIRoutinePeriod);
      Timer_AttachRoutine(TIMER_Ch6, &HMIRoutine);
      Timer_Enable(TIMER_Ch6, bTRUE);            
#endif
      DDRK = DDRK & (DDRK_BIT0_MASK | DDRK_BIT1_MASK);
      
      UNUSED(LCD_Backlight(aHMISetup->backlight));
      UNUSED(LCD_SetContrast((UINT8)aHMISetup->contrast));
      
      return bTRUE;
    } else {
#ifndef NO_DEBUG
      DEBUG(__LINE__, ERR_LCD_SETUP);
#endif
    }
  }
  else 
  {
    DEBUG(__LINE__, ERR_INVALID_POINTER);
  }
  return bFALSE;
}
Beispiel #12
0
int_t main(void)
{
   error_t error;
   NetInterface *interface;
   OsTask *task;
   MacAddr macAddr;
#if (APP_USE_DHCP == DISABLED)
   Ipv4Addr ipv4Addr;
#endif
#if (APP_USE_SLAAC == DISABLED)
   Ipv6Addr ipv6Addr;
#endif

   //Initialize kernel
   osInitKernel();
   //Configure debug UART
   debugInit(115200);

   //Start-up message
   TRACE_INFO("\r\n");
   TRACE_INFO("**********************************\r\n");
   TRACE_INFO("*** CycloneTCP FTP Client Demo ***\r\n");
   TRACE_INFO("**********************************\r\n");
   TRACE_INFO("Copyright: 2010-2015 Oryx Embedded SARL\r\n");
   TRACE_INFO("Compiled: %s %s\r\n", __DATE__, __TIME__);
   TRACE_INFO("Target: STM32F107\r\n");
   TRACE_INFO("\r\n");

   //LED configuration
   STM_EVAL_LEDInit(LED1);
   STM_EVAL_LEDInit(LED2);
   STM_EVAL_LEDInit(LED3);
   STM_EVAL_LEDInit(LED4);

   //Clear LEDs
   STM_EVAL_LEDOff(LED1);
   STM_EVAL_LEDOff(LED2);
   STM_EVAL_LEDOff(LED3);
   STM_EVAL_LEDOff(LED4);

   //Initialize I/O expander
   IOE_Config();
   //Initialize user button
   STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO);

   //Initialize LCD display
   LCD_Setup();
   LCD_SetBackColor(Blue);
   LCD_SetTextColor(White);
   LCD_SetFont(&Font16x24);
   LCD_Clear(Blue);

   //Welcome message
   lcdSetCursor(0, 0);
   printf("FTP Client Demo\r\n");

   //TCP/IP stack initialization
   error = netInit();
   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to initialize TCP/IP stack!\r\n");
   }

   //Configure the first Ethernet interface
   interface = &netInterface[0];

   //Set interface name
   netSetInterfaceName(interface, "eth0");
   //Set host name
   netSetHostname(interface, "FTPClientDemo");
   //Select the relevant network adapter
   netSetDriver(interface, &stm32f107EthDriver);
   netSetPhyDriver(interface, &dp83848PhyDriver);
   //Set external interrupt line driver
   netSetExtIntDriver(interface, &extIntDriver);
   //Set host MAC address
   macStringToAddr(APP_MAC_ADDR, &macAddr);
   netSetMacAddr(interface, &macAddr);

   //Initialize network interface
   error = netConfigInterface(interface);
   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to configure interface %s!\r\n", interface->name);
   }

#if (IPV4_SUPPORT == ENABLED)
#if (APP_USE_DHCP == ENABLED)
   //Get default settings
   dhcpClientGetDefaultSettings(&dhcpClientSettings);
   //Set the network interface to be configured by DHCP
   dhcpClientSettings.interface = interface;
   //Disable rapid commit option
   dhcpClientSettings.rapidCommit = FALSE;

   //DHCP client initialization
   error = dhcpClientInit(&dhcpClientContext, &dhcpClientSettings);
   //Failed to initialize DHCP client?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to initialize DHCP client!\r\n");
   }

   //Start DHCP client
   error = dhcpClientStart(&dhcpClientContext);
   //Failed to start DHCP client?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to start DHCP client!\r\n");
   }
#else
   //Set IPv4 host address
   ipv4StringToAddr(APP_IPV4_HOST_ADDR, &ipv4Addr);
   ipv4SetHostAddr(interface, ipv4Addr);

   //Set subnet mask
   ipv4StringToAddr(APP_IPV4_SUBNET_MASK, &ipv4Addr);
   ipv4SetSubnetMask(interface, ipv4Addr);

   //Set default gateway
   ipv4StringToAddr(APP_IPV4_DEFAULT_GATEWAY, &ipv4Addr);
   ipv4SetDefaultGateway(interface, ipv4Addr);

   //Set primary and secondary DNS servers
   ipv4StringToAddr(APP_IPV4_PRIMARY_DNS, &ipv4Addr);
   ipv4SetDnsServer(interface, 0, ipv4Addr);
   ipv4StringToAddr(APP_IPV4_SECONDARY_DNS, &ipv4Addr);
   ipv4SetDnsServer(interface, 1, ipv4Addr);
#endif
#endif

#if (IPV6_SUPPORT == ENABLED)
#if (APP_USE_SLAAC == ENABLED)
   //Get default settings
   slaacGetDefaultSettings(&slaacSettings);
   //Set the network interface to be configured
   slaacSettings.interface = interface;

   //SLAAC initialization
   error = slaacInit(&slaacContext, &slaacSettings);
   //Failed to initialize SLAAC?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to initialize SLAAC!\r\n");
   }

   //Start IPv6 address autoconfiguration process
   error = slaacStart(&slaacContext);
   //Failed to start SLAAC process?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to start SLAAC!\r\n");
   }
#else
   //Set link-local address
   ipv6StringToAddr(APP_IPV6_LINK_LOCAL_ADDR, &ipv6Addr);
   ipv6SetLinkLocalAddr(interface, &ipv6Addr);

   //Set IPv6 prefix
   ipv6StringToAddr(APP_IPV6_PREFIX, &ipv6Addr);
   ipv6SetPrefix(interface, &ipv6Addr, APP_IPV6_PREFIX_LENGTH);

   //Set global address
   ipv6StringToAddr(APP_IPV6_GLOBAL_ADDR, &ipv6Addr);
   ipv6SetGlobalAddr(interface, &ipv6Addr);

   //Set router
   ipv6StringToAddr(APP_IPV6_ROUTER, &ipv6Addr);
   ipv6SetRouter(interface, &ipv6Addr);

   //Set primary and secondary DNS servers
   ipv6StringToAddr(APP_IPV6_PRIMARY_DNS, &ipv6Addr);
   ipv6SetDnsServer(interface, 0, &ipv6Addr);
   ipv6StringToAddr(APP_IPV6_SECONDARY_DNS, &ipv6Addr);
   ipv6SetDnsServer(interface, 1, &ipv6Addr);
#endif
#endif

   //Create user task
   task = osCreateTask("User Task", userTask, NULL, 500, 1);
   //Failed to create the task?
   if(task == OS_INVALID_HANDLE)
   {
      //Debug message
      TRACE_ERROR("Failed to create task!\r\n");
   }

   //Create a task to blink the LED
   task = osCreateTask("Blink", blinkTask, NULL, 500, 1);
   //Failed to create the task?
   if(task == OS_INVALID_HANDLE)
   {
      //Debug message
      TRACE_ERROR("Failed to create task!\r\n");
   }

   //Start the execution of tasks
   osStartKernel();

   //This function should never return
   return 0;
}