// KCO 2010.6.8
// main.c
#include "common.h"
#include "lcd.h"
#include "key.h"
#include "adc.h"
#include "i2c_eep.h"
#include "spi.h"
#include "timer.h"
#include "can.h"
#include "uart.h"

GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM1_TimeBaseInitStruct;

int mcnt=0;
extern EEPROM_Info eeprom;
u32 eep_addr=0;
u8  spi_tx_run=1;
extern u16 spi2_rx_data[];
extern u8 spi2_rx_idx, spi2_rx_flag;
u16 spi1_tx_data[20];
extern u16 pul1_width,pul1_period;
extern u16 pul2_width,pul2_period;
extern u16 cap1_cnt,cap2_cnt;
u16 cap1_cnt_b=0,cap2_cnt_b=0;

extern CanTxMsg TxMessage;
extern CanRxMsg RxMessage;
extern u8 can_rx_flag,can_rx_cnt;
u8 can_txd[8];

u16 adc8_data;
extern u8 rx1_flag,rx2_flag,rx3_flag;
extern u8 rx1_data,rx2_data,rx3_data;
extern u8 rx1_cnt,rx2_cnt,rx3_cnt;

u16 tx1_cnt=0,tx2_cnt=0,tx3_cnt=0;
u8 tx_flag=1;
void gpio_init(void){
    //*********************** GPIO Init *****************************
    // Enable GPIO clock and release reset
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
                         RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC,
                         ENABLE);
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA |
                         RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC,
                         DISABLE);
    // GPIO init.
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | 
       GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | 
       GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    OFF_LED1;    OFF_LED2;   OFF_LED3;   OFF_LED4;
    OFF_LED5;    OFF_LED6;   OFF_LED7;   OFF_LED8;
}
void timer1_init(void){
    //************************ Timer1 Init **************************
    // Enable Timer1 clock and release reset
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1,DISABLE);
    
    // Set timer period 100 usec
    TIM1_TimeBaseInitStruct.TIM_Prescaler = 72-1;  // 1us resolution
    TIM1_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM1_TimeBaseInitStruct.TIM_Period = 100-1;  // 100 us
    TIM1_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV2;   // for 36MHz
    TIM1_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM1,&TIM1_TimeBaseInitStruct);
    // Clear update interrupt bit
    TIM_ClearITPendingBit(TIM1,TIM_FLAG_Update);
    // Enable update interrupt
    TIM_ITConfig(TIM1,TIM_FLAG_Update,ENABLE);
    
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    // Enable timer counting
    TIM_Cmd(TIM1,ENABLE);
}

void TIM1_UP_IRQHandler(void){  // Timer1 interrupt routine
    // Clear update interrupt bit
    TIM_ClearITPendingBit(TIM1,TIM_FLAG_Update);
    check_period_flag();
    T_LED1;
}

void	key_down_proc(BYTE c){
	switch(c){
		case 0: 
            uart1_printf("uart1: tx1_cnt=%04XH\n\r",tx1_cnt++);
            uart2_printf("uart2: tx2_cnt=%04XH\n\r",tx2_cnt++);
            uart3_printf("uart3: tx3_cnt=%04XH\n\r",tx3_cnt++);
            lcd_gotoxy(0,2);
            lcd_puts("Tx UART1,2,3        ");
            lcd_gotoxy(0,3);
            lcd_puts("                    ");
 			break;
		case 1:
            uart1_printf("uart1: tx1_cnt=%04XH\n\r",tx1_cnt++);
            lcd_gotoxy(0,2);
            lcd_puts("Tx UART1            ");
            lcd_gotoxy(0,3);
            lcd_puts("                    ");
			break;
		case 2:
            uart2_printf("uart2: tx2_cnt=%04XH\n\r",tx2_cnt++);
            lcd_gotoxy(0,2);
            lcd_puts("Tx UART2            ");
            lcd_gotoxy(0,3);
            lcd_puts("                    ");
           break;
		case 3:
            uart3_printf("uart3: tx3_cnt=%04XH\n\r",tx3_cnt++);
            lcd_gotoxy(0,2);
            lcd_puts("Tx UART3            ");
            lcd_gotoxy(0,3);
            lcd_puts("                    ");
			break;
		case 4:
            tx_flag ^= 1;
            lcd_gotoxy(18,0);
            if(tx_flag) lcd_puts("TX");
            else lcd_puts("  ");
            lcd_gotoxy(0,2);
            lcd_puts("                    ");
            lcd_gotoxy(0,3);
            lcd_puts("                    ");
 			break;
		default:	
			break;
	}
}

void	key_up_proc(BYTE c){
	switch(c){
		case 0:
			break;
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		default:	
			break;
	}
}

BYTE	key_cnt=0;
void	key_cont_proc(BYTE c){
	switch(c){
		case 0:
            key_down_proc(c);
			break;
		case 1:
            key_down_proc(c);
			break;
		case 2:
            key_down_proc(c);
			break;
		case 3:
            key_down_proc(c);
			break;
		case 4:
			break;
		default:	
			break;
	}
}

WORD	key_code;
void	key_process(void){
WORD	i,c;
	key_code = key5_proc();
	for(i=0;i<5;i++){
	  	c = (key_code>>(2*i) )& 0x03;
		if(c == KEY_CONT) key_cont_proc(i);
		else if(c == KEY_DOWN) key_down_proc(i);
		else if(c == KEY_UP) key_up_proc(i);
	}
}

int main(void){
    /* Setup STM32 system (clock, PLL and Flash configuration) */
    SystemInit();
    
    /* Set the Vector Table base location at 0x08000000 */
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    
    gpio_init();
    timer1_init();
	lcd_init(20,4);
    key_init();
    init_adc();
    init_i2c_eep(AT24C16);  // for AT24C16
//    init_spi1();    // SPI1: master mode    
//    init_spi2();    // SPI2: slave mode
//    init_tim_cap();
//    init_can();
    init_uart(1,115200,0);    // uart1(RS232), bps, txenable
    init_uart(2,115200,0);    // uart2(RS232), bps, txenable
    init_uart(3,115200,1);    // uart3(RS485), bps, txenable

	lcd_gotoxy(0,0);
	lcd_puts("*** UART Test *** TX");
    lcd_gotoxy(0,2);
    lcd_puts("S1=Tx1/2/3,   S2=Tx1");
    lcd_gotoxy(0,3);
    lcd_puts("S2=Tx2,S3=Tx3,S4=R/S"); 
    while(1){
        if(rx1_flag){
            rx1_flag = 0;
            lcd_gotoxy(0,2);
            lcd_printf("rx1=%c(%02X)",rx1_data,rx1_data);
            lcd_gotoxy(11,2);   lcd_hex2(rx1_cnt);
            uart1_printf("uart1: Received char = %c\n\r",rx1_data);
        }
        if(rx2_flag){
            rx2_flag = 0;
            lcd_gotoxy(0,3);
            lcd_printf("rx2=%c(%02X)",rx2_data,rx2_data);
            lcd_gotoxy(14,2);   lcd_hex2(rx2_cnt);
            uart1_printf("uart2: Received char = %c\n\r",rx2_data);
        }
        if(rx3_flag){
            rx3_flag = 0;
            lcd_gotoxy(11,3);
            lcd_printf("rx3=%c(%02X)",rx3_data,rx3_data);
            lcd_gotoxy(17,2);   lcd_hex2(rx3_cnt);
            uart1_printf("uart3: Received char = %c\n\r",rx3_data);
        }

	    if(flag_1ms){
	    	flag_1ms = 0;
	    }
	    if(flag_2ms){
	    	flag_2ms = 0;
	    }
	    if(flag_10ms){
	    	flag_10ms = 0;
			key_process();
		}
	    if(flag_100ms){
	    	flag_100ms = 0;
		}
	    if(flag_300ms){
	    	flag_300ms = 0;
            mcnt++;

            ON_LED2;    adc8_data = get_adc(8); OFF_LED2;
            lcd_gotoxy(0,1);    lcd_printf("mcnt=%04X",mcnt);
            lcd_gotoxy(10,1);   lcd_printf("VR=%4d",adc8_data);

            if(tx_flag){
                ON_LED3;

                // using interrupt 
                uart1_printf("uart1: mcnt=%04XH,vr=%4d\n\r",mcnt,adc8_data);
                uart2_printf("uart2: mcnt=%04XH,vr=%4d\n\r",mcnt,adc8_data);
                uart3_printf("uart3: mcnt=%04XH,vr=%4d\n\r",mcnt,adc8_data);
/*
                // using polling 
                uart1_printf_p("uart1: mcnt=%04XH,vr=%4d\n\r",mcnt,adc8_data);
                uart2_printf_p("uart2: mcnt=%04XH,vr=%4d\n\r",mcnt,adc8_data);
                TXEN3_ENABLE;
                uart3_printf_p("uart3: mcnt=%04XH,vr=%4d\n\r",mcnt,adc8_data);
                while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);  
                TXEN3_DISABLE;
*/                
                OFF_LED3;
            }
		}
    }
}
