view main.c @ 3:74e9b3baac1e

Jumbo commit to make things work. Note I have t
author Daniel O'Connor <darius@dons.net.au>
date Sun, 01 Jan 2012 11:01:13 +1030
parents 274e01fa5a4c
children 2c87e30c982d
line wrap: on
line source

#include <ctype.h>
#include <malloc.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <stdlib.h>

#include "stm32f10x.h"
#include "lcd.h"
#include "main.h"
#include "comm.h"

typedef struct {
    char		buf[40];
    volatile uint8_t	state;
    uint8_t		len;
} consbuf_t;

void Setup_HW(void);
void NVIC_Configuration(void);


/* Called every 1 / TICK_FREQ */
#define TICK_FREQ 10000
RAMFUNC void
SysTick_Handler(void) {
    static uint32_t	tick = 0;
    static int		led = 0;
    
    tick++;
    if (tick % 10000 == 0) {
	led = !led;
	if (led)
	    GPIO_SetBits(GPIOB, GPIO_Pin_5);
	else
	    GPIO_ResetBits(GPIOB, GPIO_Pin_5);
    }
    
}

consbuf_t	cmd;

RAMFUNC void
USART1_IRQHandler(void) {
    char	c;
    int		i;
    
    /* Recieved data */
    while (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
	c = USART_ReceiveData(USART1);
	    
	/* End of line? */
	if (c == '\n' || c == '\r') {
	    cmd.buf[cmd.state] = '\0';
	    fputs("\r\n", stdout);
	    cmd.len = cmd.state;
	    cmd.state = 255;
	    continue;
	}
	
	/* Ctrl-w / Ctrl-u */
	if (c == 0x17 || c == 0x15) {
	    for (i = 0; i < cmd.state; i++)
		fputs("\010\040\010", stdout);
	    cmd.state = 0;
	    continue;
	}
	    
	/* Backspace/delete */
	if (c == 0x08 || c == 0x7f) {
	    if (cmd.state > 0) {
		cmd.state--;
		fputs("\010\040\010", stdout);
	    }
	    continue;
	}
	
	/* Anything unprintable just ignore it */
	if (!isprint(c))
	    continue;

	cmd.buf[cmd.state] = tolower(c);

	/* Echo back to the user */
	comm_put(cmd.buf[cmd.state]);
	
	cmd.state++;
	/* Over flow? */
	if (cmd.state == ((sizeof(cmd.buf) / sizeof(cmd.buf[0])) - 1)) {
	    fputs("\r\nLine too long", stdout);
	    cmd.state = 0;
	    continue;
	}
    }
}


int
main(void) {
    char	buf[40];
    struct tm	nowtm;
    time_t	now;
    
    cmd.state = cmd.len = 0;
    
    /* Setup USART etc */
    Setup_HW();

    /* NVIC configuration */
    NVIC_Configuration();

    /* Setup SysTick Timer rate, also enables Systick and Systick-Interrupt */
    if (SysTick_Config(SystemCoreClock / TICK_FREQ)) {
	/* Capture error */
	comm_puts("Can't setup SysTick\r\n");
	while (1)
	    ;
    }

    /* Init LCD interface */
    LCD_init();

    /* Set stdout to unbuffered */
    setvbuf(stdout, NULL, _IONBF, 0);
    
    /* Say hello */
    fputs("\r\nHello world\r\n", stdout);
    
#define Bank1_LCD_D    ((uint32_t)0x60020000)    //disp Data ADDR
#define Bank1_LCD_C    ((uint32_t)0x60000000)    //disp Reg ADDR
    
    while (1) {
	fputs("> ", stdout);
	
	while (cmd.state != 255)
	    ;
	
	if (cmd.len > 0) {
	    if (!strncmp("gc", cmd.buf, 2)) {
		now = time(NULL);
		gmtime_r(&now, &nowtm);
		strftime(buf, sizeof(buf) - 1, "Time is %Y/%m/%d %H:%M:%S UTC", &nowtm);
		printf("Time is %s (%d)\r\n", buf, (int)now);
	    } else if (!strncmp("sc ", cmd.buf, 3)) {
		struct timeval tv;
		tv.tv_sec = atoi(cmd.buf + 3);
		tv.tv_usec = 0;
		settimeofday(&tv, NULL);
	    } else if (!strncmp("lcd", cmd.buf, 3)) {
		*(__IO uint16_t *) (Bank1_LCD_C) = 0x00;
		printf("LCD ID = %hx\r\n", *(__IO uint16_t *) (Bank1_LCD_D));
	    } else if (!strncmp("read", cmd.buf, 4)) {
		printf("PB5 = %d\r\n", GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15));
	    } else if (!strncmp("zz", cmd.buf, 2)) {
		NVIC_SystemReset();
	    } else {
		printf("Unknown command\r\n");
	    }
	}
	cmd.state = 0;
    }
}

/* Setup hardware (USART etc) */
void
Setup_HW(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    /* RTC stuff */
    /* Enable PWR and BKP clocks */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

    /* Allow access to BKP Domain */
    PWR_BackupAccessCmd(ENABLE);

    /* Reset Backup Domain
     *
     * This resets the RTC etc back to 0 so probably only useful under user command
     BKP_DeInit();
    */

    /* Enable LSE */
    RCC_LSEConfig(RCC_LSE_ON);

    /* Wait till LSE is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
	;

    /* Select LSE as RTC Clock Source */
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

    /* Enable RTC Clock */
    RCC_RTCCLKCmd(ENABLE);

    /* Wait for RTC registers synchronization */
    RTC_WaitForSynchro();

    /* Wait until last write operation on RTC registers has finished */
    RTC_WaitForLastTask();

    /* Wait until last write operation on RTC registers has finished */
    RTC_WaitForLastTask();

    /* Set RTC prescaler: set RTC period to 1sec */
    RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */

    /* Wait until last write operation on RTC registers has finished */
    RTC_WaitForLastTask();

    /* Clock setup */
    /* Enable clocks we need */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
			   RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);

    /* Port configuration */
    /* Configure USART1 TX (PA.09) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure USART1 RX (PA.10) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure PB5 as output push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* Configure PB15 as input pull-up push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* USART configuration */
    /* USART1 - 115200 8n1, no flow control TX & RX enabled */
    USART_InitStructure.USART_BaudRate = 115200;
    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;
    USART_Init(USART1, &USART_InitStructure);

    /* Enable interrupts on receive data */
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    /* Enable USART */
    USART_Cmd(USART1, ENABLE);
}

/* Configure interrupt controller */
#ifdef VECT_TAB_RAM
/* vector-offset (TBLOFF) from bottom of SRAM. defined in linker script */
extern uint32_t _isr_vectorsram_offs;
#else
extern uint32_t _isr_vectorsflash_offs;
#endif

void
NVIC_Configuration(void) {
    NVIC_InitTypeDef NVIC_InitStructure;

#ifdef VECT_TAB_RAM
    /* Set the Vector Table base location at 0x20000000+_isr_vectorsram_offs */
    NVIC_SetVectorTable(NVIC_VectTab_RAM, (uint32_t)&_isr_vectorsram_offs);
#else
    /* Set the Vector Table base location at 0x08000000+_isr_vectorsflash_offs */
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, (uint32_t)&_isr_vectorsflash_offs);
#endif

    /* Enable the USART1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}