From 6a5f460c6b1397b9175f532532ee80e44e07dcf5 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Mon, 22 Dec 2014 13:04:01 +0100 Subject: Expanded the cli functions and added test program for it. --- firmware/drivers/cli.c | 86 +++++++++++++++++++++++++++++------ firmware/drivers/cli.h | 8 +++- firmware/drivers/uart.c | 89 ++++++++++++++++++++++++++++-------- firmware/drivers/uart.h | 26 ++--------- firmware/test/uart/Makefile | 103 ++++++++++++++++++++++++++++++++++++++++++ firmware/test/uart/uarttest.c | 63 ++++++++++++++++++++++++++ 6 files changed, 318 insertions(+), 57 deletions(-) create mode 100644 firmware/test/uart/Makefile create mode 100644 firmware/test/uart/uarttest.c diff --git a/firmware/drivers/cli.c b/firmware/drivers/cli.c index 33c350e..db8695f 100644 --- a/firmware/drivers/cli.c +++ b/firmware/drivers/cli.c @@ -33,20 +33,32 @@ void cli_init() { - UARTInit(0, 115200); /* baud rate setting */ + uart_init(0, 115200); } +void cli_write(const char *buf, unsigned int size) +{ + uart_send(0, buf, size); +} + +int cli_read(char *buf, unsigned int size) +{ + uart_receive(0, buf, size); + return 0; +} + +/* static int cli_strlen(char *p0) { char *p = p0; while(*p) p++; - return p0 - p; + return p - p0; } - +*/ static inline void cli_write_int(int i) { if(i < 0) { - UARTSend(0, "-", 1); + uart_send(0, "-", 1); i *= -1; } @@ -60,7 +72,7 @@ static inline void cli_write_int(int i) tvaersum += res; if(tvaersum || pos == 1) { buf[0] = res + '0'; - UARTSend(0, buf, 1); + cli_write(buf, 1); } pos /= 10; } @@ -82,44 +94,46 @@ static int cli_write_format(const char *fmt, va_list ap) const char *p = fmt; while(*p) { if(*p != '%') { - buf[0] = *p; - - UARTSend(0, buf, 1); + buf[0] = *p; + cli_write(buf, 1); + if(*p == '\n') cli_write("\r", 1); // also write carrige return. } else { p++; if(!*p) { return 1; // Error: Invalid format string } - if(*p == '\n') UARTSend(0, "\n\r", 2); - if(*p == '%') UARTSend(0, "%", 1); + if(*p == '%') cli_write("%", 1); if(*p == 'd') cli_write_int(va_arg(ap, int)); if(*p == 'c') { buf[0] = va_arg(ap, int); - UARTSend(0, buf, 1); + cli_write(buf, 1); } if(*p == 'x') { char *c = va_arg(ap, char *); size_t sz = va_arg(ap, int); while(sz) { - UARTSend(0, cli_to_hex(*c), 2); + cli_write(cli_to_hex(*c), 2); c++; sz--; } } if(*p == 's') { char *str = va_arg(ap, char *); - UARTSend(0, str, cli_strlen(str)); + while(*str) { + cli_write(str, 1); + str++; + } } } p++; } // If last character wasn't a newline, print one. - if(p > fmt && *(p - 1) != '\n') UARTSend(0, "\n\r", 2); + //if(p > fmt && *(p - 1) != '\n') cli_write("\n\r", 2); return 0; } -int cli_write(const char *fmt, ...) +int cli_printf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -128,3 +142,45 @@ int cli_write(const char *fmt, ...) return 0; } + +int cli_readline(char *cmd, unsigned int size) +{ + char buf[2] = { }; + unsigned int cmdpos = 0; + int parsing = 1; + while(parsing && + cmdpos < (size - 1)) // Make sure we have room for the terminating zero. + { + cli_read(buf, 1); // read one byte + + switch(*buf) { + case '\n': + case '\r': + parsing = 0; // break out of parse loop. + break; + + case '\b': // backspace + if(cmdpos) { + cmdpos--; + cli_write("\b \b", 3); // erase last written character from echo. + continue; + } + break; + + case 27: // ignore 'ESC' sent on arrow keys. + // NOTE: Sequence ESC, '[', 'D' is left arrow. + // Sequence ESC, '[', 'C' is right arrow. + continue; + + default: + cmd[cmdpos++] = *buf; + break; + } + + // Echo + cli_write(buf, 1); // write one byte + } + cmd[cmdpos++] = '\0'; + + return cmdpos; +} diff --git a/firmware/drivers/cli.h b/firmware/drivers/cli.h index ecc373b..2605715 100644 --- a/firmware/drivers/cli.h +++ b/firmware/drivers/cli.h @@ -28,6 +28,12 @@ #define __PEDAL2METAL_CLI_H__ void cli_init(); -int cli_write(const char *fmt, ...); + +void cli_write(const char *buffer, unsigned int size); +int cli_read(char *buffer, unsigned int size); + +int cli_printf(const char *fmt, ...); + +int cli_readline(char *buf, unsigned int maxsize); #endif/*__PEDAL2METAL_CLI_H__*/ diff --git a/firmware/drivers/uart.c b/firmware/drivers/uart.c index 28a6e00..1e7960b 100644 --- a/firmware/drivers/uart.c +++ b/firmware/drivers/uart.c @@ -17,11 +17,33 @@ * notification. NXP Semiconductors also make no representation or * warranty that such application will be suitable for the specified * use without further testing or modification. -****************************************************************************/ -#include -#include //"type.h" + ****************************************************************************/ #include "uart.h" +#include +#include + +#define IER_RBR 0x01 +#define IER_THRE 0x02 +#define IER_RLS 0x04 + +#define IIR_PEND 0x01 +#define IIR_RLS 0x03 +#define IIR_RDA 0x02 +#define IIR_CTI 0x06 +#define IIR_THRE 0x01 + +#define LSR_RDR 0x01 +#define LSR_OE 0x02 +#define LSR_PE 0x04 +#define LSR_FE 0x08 +#define LSR_BI 0x10 +#define LSR_THRE 0x20 +#define LSR_TEMT 0x40 +#define LSR_RXFE 0x80 + +#define BUFSIZE 0x40 + #define TRUE 1 #define FALSE 0 @@ -40,11 +62,13 @@ volatile uint8_t UART0TxEmpty = 1, UART1TxEmpty = 1; ** VIC table ** *****************************************************************************/ -uint32_t UARTInit( uint32_t PortNum, uint32_t baudrate ) +uint32_t uart_init( uint32_t PortNum, uint32_t baudrate ) { uint32_t Fdiv; uint32_t pclkdiv, pclk; + SystemCoreClockUpdate(); + uint32_t SystemFrequency = SystemCoreClock; if ( PortNum == 0 ) @@ -77,7 +101,7 @@ uint32_t UARTInit( uint32_t PortNum, uint32_t baudrate ) LPC_UART0->DLM = Fdiv / 256; LPC_UART0->DLL = Fdiv % 256; LPC_UART0->LCR = 0x03; /* DLAB = 0 */ - LPC_UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ + LPC_UART0->FCR = 0b111; /* Enable and reset TX and RX FIFO. */ // NVIC_EnableIRQ(UART0_IRQn); @@ -135,31 +159,60 @@ uint32_t UARTInit( uint32_t PortNum, uint32_t baudrate ) ** Returned value: None ** *****************************************************************************/ -void UARTSend( uint32_t portNum, char *BufferPtr, uint32_t Length ) +void uart_send( uint32_t portNum, const char *BufferPtr, uint32_t Length ) { - if ( portNum == 0 ) - { - while ( Length != 0 ) + //unsigned int *U0LSR = (unsigned int *)0x4000C014; + + if(portNum == 0) { + while(Length != 0) { + /* THRE status, contain valid data */ + //while ( !(UART0TxEmpty & 0x01) ); + // while(((*U0LSR) & 0b100000) != 0); + while((LPC_UART0->LSR & 0b100000) == 0); + + LPC_UART0->THR = *BufferPtr; + UART0TxEmpty = 0; /* not empty in the THR until it shifts out */ + BufferPtr++; + Length--; + } + } else { + while ( Length != 0 ) { /* THRE status, contain valid data */ - //while ( !(UART0TxEmpty & 0x01) ); - LPC_UART0->THR = *BufferPtr; - UART0TxEmpty = 0; /* not empty in the THR until it shifts out */ + while ( !(UART1TxEmpty & 0x01) ); + LPC_UART1->THR = *BufferPtr; + UART1TxEmpty = 0; /* not empty in the THR until it shifts out */ BufferPtr++; Length--; - } + } } - else - { - while ( Length != 0 ) + return; +} + +void uart_receive(uint32_t portNum, char *BufferPtr, uint32_t Length) +{ + if(portNum == 0) { + while(Length != 0) { + /* THRE status, contain valid data */ + //while ( !(UART0TxEmpty & 0x01) ); + // while(((*U0LSR) & 0b100000) != 0); + while((LPC_UART0->LSR & 0b1) == 0); + + *BufferPtr = LPC_UART0->RBR; + BufferPtr++; + Length--; + } + } else { + /* + while ( Length != 0 ) { - /* THRE status, contain valid data */ while ( !(UART1TxEmpty & 0x01) ); LPC_UART1->THR = *BufferPtr; - UART1TxEmpty = 0; /* not empty in the THR until it shifts out */ + UART1TxEmpty = 0; // not empty in the THR until it shifts out BufferPtr++; Length--; } + */ } return; } diff --git a/firmware/drivers/uart.h b/firmware/drivers/uart.h index 24b8259..46e59fb 100644 --- a/firmware/drivers/uart.h +++ b/firmware/drivers/uart.h @@ -22,29 +22,9 @@ #include -#define IER_RBR 0x01 -#define IER_THRE 0x02 -#define IER_RLS 0x04 - -#define IIR_PEND 0x01 -#define IIR_RLS 0x03 -#define IIR_RDA 0x02 -#define IIR_CTI 0x06 -#define IIR_THRE 0x01 - -#define LSR_RDR 0x01 -#define LSR_OE 0x02 -#define LSR_PE 0x04 -#define LSR_FE 0x08 -#define LSR_BI 0x10 -#define LSR_THRE 0x20 -#define LSR_TEMT 0x40 -#define LSR_RXFE 0x80 - -#define BUFSIZE 0x40 - -uint32_t UARTInit( uint32_t portNum, uint32_t Baudrate ); -void UARTSend(uint32_t portNum, char *BufferPtr, uint32_t Length ); +uint32_t uart_init(uint32_t portNum, uint32_t baudrate); +void uart_send(uint32_t portNum, const char *BufferPtr, uint32_t Length); +void uart_receive(uint32_t portNum, char *BufferPtr, uint32_t Length); #endif /* end __UART_H */ /***************************************************************************** diff --git a/firmware/test/uart/Makefile b/firmware/test/uart/Makefile new file mode 100644 index 0000000..2a17077 --- /dev/null +++ b/firmware/test/uart/Makefile @@ -0,0 +1,103 @@ +#/* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +# * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +# * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +# * THE AUTHORS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +# * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. USE IT AT YOUR OWN RISK */ + +ARCH = arm-none-eabi +top_srcdir=${PWD}/../.. +LPC=${top_srcdir}/lpc17xx +DRV=${top_srcdir}/drivers +SRC=${top_srcdir}/src + +PROJ=uarttest +EXECNAME=$(PROJ).elf + +# Tool definitions +CC = $(ARCH)-gcc +LD = $(ARCH)-ld +AR = $(ARCH)-ar +AS = $(ARCH)-as +CP = $(ARCH)-objcopy +OD = $(ARCH)-objdump +SIZE = $(ARCH)-size +RM = rm +#Q = # @./quiet "$@" + +# Flags +CFLAGS = -W -Wall -Werror -O0 --std=gnu99 -fgnu89-inline -mcpu=cortex-m3 -mthumb +CFLAGS += -ffunction-sections -fdata-sections +CFLAGS += -I${DRV} -I${LPC} +ASFLAGS = +LDFLAGS = --gc-sections + +STDLIB_LDFLAGS = + +CPFLAGS = +ODFLAGS = -x --syms +PRFLAGS ?= + +# Source files +LINKER_SCRIPT = ${LPC}/LPC17xx.ld +CSRCS = \ + ${LPC}/system_LPC17xx.c \ + ${LPC}/startup_LPC17xx.c \ + ${DRV}/led.c \ + ${DRV}/cli.c \ + ${DRV}/uart.c \ + ../test.c + +CSRCS += ${PROJ}.c +ASRCS = + + +OBJS = $(CSRCS:.c=.o) $(ASRCS:.s=.o) + +.PHONY: all size clean nuke + +all: ${PROJ}.bin ${PROJ}.hex + +size: ${PROJ}.elf + @$(SIZE) $< + +%.hex: %.elf + $Q $(CP) $(CPFLAGS) -O ihex $< $*.hex + +%.bin: %.elf + $Q $(CP) $(CPFLAGS) -O binary $< $*.bin + +${PROJ}.elf: $(LINKER_SCRIPT) $(OBJS) + $Q $(LD) -Map $(@:.elf=.map) $(LDFLAGS) -T $^ -o $@ $(STDLIB_LDFLAGS) + $Q $(OD) $(ODFLAGS) $@ > $(@:.elf=.dump) + @$(SIZE) $@ + +%.o: %.c + @$(CC) -MM $< -MF $*.d -MP + $Q $(CC) -c $(CFLAGS) $< -o $@ + +%.o: %.S + $Q $(AS) $(ASFLAGS) $< -o $@ + +clean: + @-$(RM) -f *.elf + @-\ +for D in "." "**"; do \ + $(RM) -f $$D/*.o $$D/*.d $$D/*.lst $$D/*.dump $$D/*.map; \ +done + +nuke: clean + -$(RM) -f *.hex *.bin + +.PHONY : flash +#flash: $(EXECNAME) +# $(CP) -O ihex $(EXECNAME) $(PROJ).hex +# openocd -f openocd.cfg -c 'flash write_image erase $(PROJ).hex' -c 'verify_image $(PROJ).hex' -c 'reset run' +flash: $(EXECNAME) + $(CP) -O binary $(EXECNAME) $(PROJ).bin + ../../fix-lpcchecksum $(PROJ).bin + openocd -f ../../openocd.cfg \ + -c 'flash write_image erase $(PROJ).bin' \ + -c 'verify_image $(PROJ).bin' \ + -c 'reset run' + +-include $(CSRCS:.c=.d) diff --git a/firmware/test/uart/uarttest.c b/firmware/test/uart/uarttest.c new file mode 100644 index 0000000..fb6822c --- /dev/null +++ b/firmware/test/uart/uarttest.c @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * uarttest.c + * + * Sun Dec 21 20:46:19 CET 2014 + * Copyright 2014 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pedal2Metal. + * + * Pedal2Metal is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pedal2Metal is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pedal2Metal; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "../test.h" + +// For SystemCoreClock +#include + +//#include +#include +/* +volatile unsigned int temp; +static void _delay(unsigned int del) +{ + for(unsigned int i = 0; i < del; i++) temp = i; +} +*/ +int main (void) +{ + //led_init(); + + cli_init(); + + cli_printf("\rWelcome to the amazing Pedal 2 Metal version zero dot dut!\n"); + //cli_printf("clk: %d\n", SystemCoreClock); + + int cnt = 0; + while(1) { + char cmd[256]; + int sz = sizeof(cmd); + while(sz == sizeof(cmd)) { + cli_printf("# "); + sz = cli_readline(cmd, sizeof(cmd)); + } + cli_printf("\n"); + + cli_printf("command %d: '%s' (%d)\n", cnt++, cmd, sz); + //for(int i = 0; i < sz; i++) cli_printf("%c\t(%d)\n", cmd[i], (int)cmd[i]); + } +} -- cgit v1.2.3