view main.c @ 2:274e01fa5a4c

- Do console IO with RX IRQs. - Init tick counter (unused anyway). - Handle C-u and C-w. - Rejig NVIC setup for less duplication.
author Daniel O'Connor <darius@dons.net.au>
date Sat, 08 Oct 2011 20:35:34 +1030
parents c59513fd84fb
children 74e9b3baac1e
line wrap: on
line source

#include <ctype.h>
#include <stdio.h>
#include <stdint.h>
#include "stm32f10x.h"
#include "main.h"
#include "comm.h"

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

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

/* Called every millisecond */
RAMFUNC void
SysTick_Handler(void) {
    static uint32_t	tick = 0;
   
    tick++;
}

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) {
    cmd.state = cmd.len = 0;
    
    /* Setup USART etc */
    Setup_HW();

    /* NVIC configuration */
    NVIC_Configuration();

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

    setvbuf(stdout, NULL, _IONBF, 0);
    
    /* Say hello */
    fputs("\r\nHello world\r\n", stdout);
    
    while (1) {
	fputs("> ", stdout);
	
	while (cmd.state != 255)
	    ;
	
	if (cmd.len > 0)
	    printf("Got command '%s'\r\n", cmd.buf);
	cmd.state = 0;
    }
}

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

    /* Enable USART1, GPIOA, GPIOD and AFIO clocks */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOD
			   | RCC_APB2Periph_AFIO, ENABLE);
    /* Enable USART2 clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    /* DMA1 clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

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

    /* Init UART1 - 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;

    /* Configure USART1 */
    USART_Init(USART1, &USART_InitStructure);

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

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