view main.c @ 9:be0a1ac64d97

- Add ellipse drawing. - Factor out stripe drawing to a function. - Rename LCD functions to match other code. - Add filled circles. - Rotate coords for landsacpe.
author Daniel O'Connor <darius@dons.net.au>
date Sun, 05 Feb 2012 16:41:42 +1030
parents 58d76cf522ff
children 093bc0c3b1cc
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 "comm.h"
#include "delay.h"
#include "flash.h"
#include "hw.h"
#include "lcd.h"
#include "main.h"
#include "touch.h"

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

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;
    
    /* Init hardware - configure IO ports and external peripherals */
    hw_init();

    /* 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)
	    ;
    }

    /* Set stdout to unbuffered */
    setvbuf(stdout, NULL, _IONBF, 0);
    
    /* Say hello */
    fputs("\r\n\r\n\r\nHello world\r\n", stdout);
    
    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("read", cmd.buf, 4)) {
		printf("PB5 = %d\r\n", GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15));
	    } else if (!strncmp("touch", cmd.buf, 5)) {
		uint16_t	x, y, z1, z2;
		float		t, t2;
		for (int i = 0; i < 10; i++) {
		    tp_getcoords(&x, &y, &z1, &z2, &t, &t2);
		    printf("X = %5d Y = %5d Z1 = %5d Z2 = %5d T = %7.2f T2 = %7.2f\r\n", x, y, z1, z2, t, t2);
		}
	    } else if (!strncmp("fl", cmd.buf, 2)) {
		uint8_t status;
		char *flstattbl[] = {
		    "BUSY",
		    "WEL",
		    "BP0",
		    "BP1",
		    "BP2",
		    "BP3",
		    "AAI",
		    "BPL"
		};
		
		printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", flashreadid());
		status = flashreadstatus();

		fputs("Status = ", stdout);
		for (unsigned int i = 0; i < sizeof(flstattbl) / sizeof(flstattbl[0]); i++)
		    if (status & 1 << i) {
			fputs(flstattbl[i], stdout);
			fputs(" ", stdout);
		    }
		printf("(0x%02x)\r\n", status);

		flashwritestatus(0x00);
		
		status = flashreadstatus();

		fputs("Status = ", stdout);
		for (unsigned int i = 0; i < sizeof(flstattbl) / sizeof(flstattbl[0]); i++)
		    if (status & 1 << i) {
			fputs(flstattbl[i], stdout);
			fputs(" ", stdout);
		    }
		printf("(0x%02x)\r\n", status);
	    } else if (!strncmp("pwm ", cmd.buf, 4)) {
		lcd_setpwm(atoi(cmd.buf + 4));
	    } else if (!strncmp("timing", cmd.buf, 6)) {
		fputs("Timing..\r\n", stdout);
		delay(10000);
		fputs("Done\r\n", stdout);
	    } else if (!strncmp("circ ", cmd.buf, 5)) {
		uint16_t	x, y, r, c;
		char		col;
		
		if (sscanf(cmd.buf, "circ %hu %hu %hu %c", &x, &y, &r, &col) != 4) {
		    printf("Unable to parse circ args\r\n");
		    goto out;
		}

		col = toupper(col);
		if (col == 'R')
		    c = LCD_RED;
		else if (col == 'G')
		    c = LCD_GREEN;
		else if (col == 'B')
		    c = LCD_BLUE;
		else if (col == 'L')
		    c = LCD_BLACK;
		else
		    c = LCD_WHITE;
		lcd_circle(x, y, r, c);
	    } else if (!strncmp("zz", cmd.buf, 2)) {
		NVIC_SystemReset();
	    } else {
		printf("Unknown command\r\n");
	    }
	}
      out:
	cmd.state = 0;
    }
}

/* 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);
}