/* ------------------------------------------------------------------------------------------------ */
/* FILE :		Demo_10-13_STM3220G_IAR.c															*/
/*																									*/
/* CONTENTS :																						*/
/*				Demo for the ST microelectronics STM3220G evaluation board							*/
/*																									*/
/*				Demo #10 - Webserver using netconn with memory base file system						*/
/*				Demo #11 - Webserver using BSD sockets with memory base file system					*/
/*				Demo #12 - Webserver using netconn with micro-SD FatFS								*/
/*				Demo #13 - Webserver using BSD sockets with micro-SD FatFS							*/
/*																									*/
/*				For demo #10 and #11:																*/
/*				*** serial port settings:															*/
/*							Baud Rate: 115200														*/
/*							Data bits:      8														*/
/*							Stop bits:      1														*/
/*							Parity:      none														*/
/*							Flow Ctrl:   none														*/
/*							Emulation:   none														*/
/*																									*/
/*				For demo #12 and #13:																*/
/*				*** serial port cannot be used														*/
/*					Because the UART shares the same pins as the SD/MMC card cage, it is not		*/
/*					possible to use the UART.  So, the demo needs to operate through semi-hosting.	*/
/*					The terminal I/O is used as it is the input/output for semi-hosting.			*/
/*					In the Debug environment, pull down the "View: tab and select "Terminal I/O".	*/
/*					Keep the default settings of the terminal I/O.									*/
/*																									*/
/*																									*/
/* Copyright (c) 2013-2014, Code-Time Technologies Inc. All rights reserved.						*/
/*																									*/
/* Code-Time Technologies retains all right, title, and interest in and to this work				*/
/*																									*/
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS							*/
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF										*/
/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL							*/
/* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR								*/
/* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,							*/
/* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR							*/
/* OTHER DEALINGS IN THE SOFTWARE.																	*/
/*																									*/
/*																									*/
/*	$Revision: 1.3 $																				*/
/*	$Date: 2014/04/28 21:32:15 $																	*/
/*																									*/
/* ------------------------------------------------------------------------------------------------ */

#if (((OS_DEMO) < 10) || ((OS_DEMO) > 13))
	#error "Wrong OS_DEMO value" 
#endif

#include "WebServer.h"

/* ------------------------------------------------ */

#define BAUDRATE			   115200				/* Serial port baud rate						*/
#define SYS_FREQ			120000000				/* Processor clock frequency					*/

#define BG_COLOR			(((0xFC>>3)<<11)|((0x39>>2)<<5)|(0x02>>3))
#define FG_COLOR			LCD_COLOR_BLACK

#define DHCP_TASK_PRIO   	(OS_PRIO_MIN-2)			/* Priority of the DHCP task					*/
#define LED_TASK_PRIO    	(OS_PRIO_MIN-1)			/* Priority of the LED flashing task			*/

#define USE_FAT_FS	(((OS_DEMO)==12)||((OS_DEMO)==13))
#define USE_SOCKET	(((OS_DEMO)==11)||((OS_DEMO)==13))
#define USE_UART	(!(USE_FATFS))

/* ------------------------------------------------ */

extern   u32_t G_IPnetDefGW;
extern   u32_t G_IPnetDefIP;
extern   u32_t G_IPnetDefNM;
extern   int   G_IPnetStatic;

USART_InitTypeDef USART_InitStructure;

#if (USE_FAT_FS)
  DIR      g_Dir;
  FATFS    g_FileSys;
#endif

/* ------------------------------------------------ */

int  GetKey(void);
void TaskLed3(void);

extern void ETH_IRQHandler(void);					/* Ethernet I/F interrupt handler				*/
extern void EXTI15_10_IRQHandler(void);				/* Ethernet I/F interrupt handler				*/
extern void SD_ProcessDMAIRQ(void);					/* micro SD I/F interrupt handler				*/
extern void SD_ProcessIRQSrc(void);					/* micro SD I/F interrupt handler				*/

/* ------------------------------------------------------------------------------------------------ */

int main(void)
{
int  ii;											/* General purpose								*/
int  LastWait;										/* Last elapse time (to update display)			*/
int  Prio = 0;										/* Priority of the timer tick interrupt			*/
int *TimerBase;										/* Systick timer registers base address			*/
char TimeMsg[] = "    DHCP in 5s.     ";			/* Message line to refresh every seconds		*/
int  WaitTime;										/* Elapsed time waiting for key pressed			*/

/* ------------------------------------------------ */
/* Processor clock set-up							*/
/* Is called at start-up in ASM file				*/
//	SystemInit();

/* ------------------------------------------------ */
/* 	Start the RTOS									*/

	OSstart();

/* ------------------------------------------------ */
/* UART set-up										*/

  #if (USE_UART)
	USART_InitStructure.USART_BaudRate            = BAUDRATE;
	USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits            = USART_StopBits_1;
	USART_InitStructure.USART_Parity              = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;

	STM_EVAL_COMInit(COM1, &USART_InitStructure);
  #endif

	setvbuf(stdin,  NULL, _IONBF, 0);				/* By default, IAR library flush the I/O		*/
	setvbuf(stdout, NULL, _IONBF, 0);				/* buffer when full or when new-line			*/

	puts("\n\n");

/* ------------------------------------------------ */
/* LCD set-up										*/

	STM322xG_LCD_Init();
	LCD_Clear(BG_COLOR);
	LCD_SetColors(FG_COLOR, BG_COLOR);

	DISPLAY(Line0, "    Abassi Demo     ");

/* ------------------------------------------------ */
/* LEDs & push button set-up						*/

	STM_EVAL_LEDInit(MY_LED_0);
	STM_EVAL_LEDInit(MY_LED_1);
	STM_EVAL_LEDInit(MY_LED_2);
	STM_EVAL_LEDInit(MY_LED_3);

	if (IOE_Config() != IOE_OK) {
		DISPLAY(Line4, (uint8_t *)"IO Expander FAILED ");
		DISPLAY(Line5, (uint8_t *)" Please Reset the  ");
		DISPLAY(Line6, (uint8_t *)"   board and start ");
		DISPLAY(Line7, (uint8_t *)"    again          ");
		while(1);
	}

	STM_EVAL_PBInit(MY_BUTTON_0, BUTTON_MODE_GPIO);
	STM_EVAL_PBInit(MY_BUTTON_1, BUTTON_MODE_GPIO);
	STM_EVAL_PBInit(MY_BUTTON_2,    BUTTON_MODE_GPIO);

/* ------------------------------------------------ */
/* Start Abassi										*/

	OSstart();

/* ------------------------------------------------ */
/* SysTick Set-up									*/

	TimerBase = (int *)0xE000E000;
	((volatile int *)0xE000Ed20)[0] = (((volatile int *)0xE000Ed20)[0] & 0x1FFFFFFF)
	                                |   ((Prio & 7) << 29);
	TimerBase[5] = (((SYS_FREQ/100000) * OS_TIMER_US)/10)-1;
	TimerBase[4] = 0x7;								/* internal clock / int & enable				*/

/* ------------------------------------------------ */
/* Attach the interrupt handlers					*/

	OSisrInstall(-1, TIMtick);						/* Install the OS timer tick function			*/
	OSisrInstall(61, ETH_IRQHandler);				/* Install the Ethernet interrupt				*/
	OSisrInstall(40, EXTI15_10_IRQHandler);			/* Install the I/O pin on Ethernet interrupt	*/

/* ------------------------------------------------ */
/* micro SD file system mounting					*/

  #if (USE_FAT_FS)
	OSisrInstall(49, SD_ProcessIRQSrc);				/* Install the micro SD interrupt				*/
	OSisrInstall(59, SD_ProcessDMAIRQ);				/* Install the micro SD DMA interrupt			*/

	if (FR_OK != f_mount(&g_FileSys, "0", 1)) {
		DISPLAY(Line5, "Cannot mount volume ");
		DISPLAY(Line6, "  on the micro SD   ");
		DISPLAY(Line8, "      Make sure     ");
		DISPLAY(Line9, " JP22 is not fitted ");
		for(;;);
	}

	if (FR_OK != f_opendir(&g_Dir, "/")) {
		DISPLAY(Line5, "Cannot mount volume ");
		DISPLAY(Line6, "  on the micro SD   ");
		DISPLAY(Line8, "      Make sure     ");
		DISPLAY(Line9, " JP22 is not fitted ");
		for(;;);
	}
 #endif

	OSeint(1);

/* ------------------------------------------------ */
/* Allow user selection static or dynamic address	*/

	DISPLAY(Line1, "  lwIP  Webserver   ");
  #if (USE_SOCKET)
	DISPLAY(Line2, "  with BSD sockets  ");
  #else
	DISPLAY(Line2, "    with netconn    ");
  #endif
  #if (USE_FAT_FS)
	DISPLAY(Line3, "  using uSD FAT FS  ");
  #else
	DISPLAY(Line3, "   using memory FS  ");
  #endif
	DISPLAY(Line5, "Will use DHCP unless");
	DISPLAY(Line6, "key pressed on UART ");
	DISPLAY(Line7, " switch / joystick  ");
	DISPLAY(Line9, &TimeMsg[0]);

/* ------------------------------------------------ */
/* Default static Addresses & Mask					*/

	NetAddr_Init();

/* ------------------------------------------------ */
/* UART prompt and key pressed check				*/

	WaitTime = G_OStimCnt;
	LastWait = -1;
	do {
		ii = (1000*(G_OStimCnt-WaitTime))
		   / OS_TICK_PER_SEC;
		if (LastWait != (5999-ii)/1000) {
			LastWait = (5999-ii)/1000;
		  #if (USE_UART)
			printf("\r\r\r\r%d s", LastWait);
		  #endif
		 	TimeMsg[12] = '0'+LastWait;
			LCD_DisplayStringLine(Line9, (uint8_t*)&TimeMsg[0]);
		}
		G_IPnetStatic = GetKey()					/* Check if user pressed a key					*/
		              | (0 != STM_EVAL_PBGetState(MY_BUTTON_0))
		              | (0 == STM_EVAL_PBGetState(MY_BUTTON_1))
		              | (0 == STM_EVAL_PBGetState(MY_BUTTON_2))
		              | (0 != IOE_JoyStickGetState());
	} while((ii < 5000)								/* Check for 5 seconds							*/
	  &&    (G_IPnetStatic == 0));					/* Or until a key is pressed					*/
  #if (USE_UART)
	printf("\r                             \n");	/* Erase the remaining time from UART screen	*/
  #endif

	LCD_ClearLine(Line1);
	LCD_LINE(Line2, "  lwIP  Webserver   ");
  #if (USE_SOCKET)
	LCD_LINE(Line3, "  with BSD sockets  ");
  #else
	LCD_LINE(Line3, "    with netconn    ");
  #endif
  #if (USE_FAT_FS)
	LCD_LINE(Line4, "  using uSD FAT FS  ");
  #else
	LCD_LINE(Line4, "  using memory FS   ");
  #endif
	LCD_ClearLine(Line5);
	LCD_ClearLine(Line6);
	LCD_ClearLine(Line7);
	LCD_ClearLine(Line9);

/* ------------------------------------------------ */
/* EMAC & lwIP initialization						*/

	ETH_BSP_Config();
	LwIP_Init();
	http_server_init();

/* ------------------------------------------------ */
/* DHCP task creation								*/

	if (G_IPnetStatic == 0) {
		TSKcreate("DHCP Client", DHCP_TASK_PRIO, 1024, LwIP_DHCP_task, 1);
	}

	TSKcreate("LED 3", LED_TASK_PRIO, 1024, TaskLed3, 1);

  #if ((OX_EVENTS) != 0)
	EVTwait(3, 0, -1);								/* Wait for Ethernet & file system to be ready	*/
  #endif

	MTXlock(G_OSmutex, -1);
	puts("The Webserver is ready");
	MTXunlock(G_OSmutex);

	for( ;; ) {
		TSKselfSusp();
	}
}

/* ------------------------------------------------------------------------------------------------ */

void TaskLed3(void)
{
	for( ;; ) {
		STM_EVAL_LEDToggle(MY_LED_3);
		TSKsleep(OS_MS_TO_TICK(250));
	}
}

/* ------------------------------------------------------------------------------------------------ */

void IdleTask(void)
{
	for(;;) {
		 __ASM(" wfi");
	}
}

/* ------------------------------------------------------------------------------------------------ */

void TIMcallBack(void)
{
	return;
}

#if (USE_UART)
/* ------------------------------------------------------------------------------------------------ */
/*																									*/
/* UART functions needed by the Peripheral library to access the UART								*/
/*																									*/
/* ------------------------------------------------------------------------------------------------ */

size_t __write(int Handle, const unsigned char * Buf, size_t Bufsize)
{
size_t nChars = 0;

	for ( ; Bufsize > 0; --Bufsize) {
		if (*Buf == '\n') {
			while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TXE) == RESET);
			USART_SendData(EVAL_COM1, '\r');
		}
		while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TXE) == RESET);
		USART_SendData(EVAL_COM1, * Buf++);
		++nChars;
	}
	return(nChars);
}

/* ------------------------------------------------------------------------------------------------ */

size_t __read(int handle, unsigned char * buffer, size_t size)
{
int nChar;

	nChar = 1;
	while (!(EVAL_COM1->SR & USART_FLAG_RXNE));
	*buffer = USART_ReceiveData(EVAL_COM1);
	if (*buffer == '\b') {
		putchar('\b');
		putchar(' ');
	}
	if (*buffer == '\r') {
		*buffer = '\n';
	}
	putchar(*buffer);
	if (*buffer == 0x04) {
		buffer[1] = '\n';
		nChar = 2;
	}
	return(nChar);
}

/* ------------------------------------------------------------------------------------------------ */

int GetKey(void)
{
int RetVal;

	RetVal = 0;
	if(EVAL_COM1->SR & USART_FLAG_RXNE) {
		RetVal = 0xFF & USART_ReceiveData(EVAL_COM1);
	}

	return(RetVal);
}
#endif

/* EOF */
