From 50768056674a71ae7061bdf997f6a102d370ef24 Mon Sep 17 00:00:00 2001 From: Roaming Date: Fri, 24 Jun 2016 07:40:18 +0530 Subject: [PATCH] Created a UART API definition in softuart.h to allow the example code to access printf() and scanf() functionality --- examples/uart_main/Makefile | 6 ++ examples/uart_main/download.sh | 15 ++++ examples/uart_main/uart_main.c | 48 +++++++++++ include/uart/api.h | 79 +++++++++++++++++ include/uart/soft_uart.h | 28 ++++++ lib/Makefile | 2 +- lib/uart/soft_uart.c | 152 +++++++++++++++++++++++++++++++++ 7 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 examples/uart_main/Makefile create mode 100755 examples/uart_main/download.sh create mode 100644 examples/uart_main/uart_main.c create mode 100644 include/uart/api.h create mode 100644 include/uart/soft_uart.h create mode 100644 lib/uart/soft_uart.c diff --git a/examples/uart_main/Makefile b/examples/uart_main/Makefile new file mode 100644 index 0000000..96e0cde --- /dev/null +++ b/examples/uart_main/Makefile @@ -0,0 +1,6 @@ +FX2LIBDIR=../.. +BASENAME = uart_main +SOURCES=uart_main.c +DSCR_AREA= +INT2JT= +include $(FX2LIBDIR)/lib/fx2.mk diff --git a/examples/uart_main/download.sh b/examples/uart_main/download.sh new file mode 100755 index 0000000..9f0d06b --- /dev/null +++ b/examples/uart_main/download.sh @@ -0,0 +1,15 @@ +#!/bin/bash -e + +DEVS=$(lsusb|grep -E '(2a19|16c0|04b4|1d50|fb9a|1443)' |sed 's/:.*//;s/Bus //;s/Device //;s/ /\//') + +if [ -z "$1" ]; then + echo "$0: usage: $0 " + exit 1; +fi + +for dev in $DEVS;do + echo "Downloading $1 to $dev" + /sbin/fxload -D /dev/bus/usb/$dev -t fx2lp -I $1 +done + +exit 0 diff --git a/examples/uart_main/uart_main.c b/examples/uart_main/uart_main.c new file mode 100644 index 0000000..d20b0f5 --- /dev/null +++ b/examples/uart_main/uart_main.c @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2009 Ubixum, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **/ +#include +#include +#include +#include +#include +#include + +//We need this declaration +void uart0_tx(char c); + +//Initialize UART, call it uart0 and set the tx pin on PA1 +CREATE_FAST_UART(uart0,0x82) + +//Used for setting the baud rate. +enum uart_baud baud; +void main(void) +{ + baud = BAUD_115200; + uartX_init(baud); + uartX_set_baud(baud); + SETCPUFREQ(CLK_48M); + while (TRUE) + { + printf("Hello"); + } +} + +void putchar(char c) +{ + uart0_tx(c); +} diff --git a/include/uart/api.h b/include/uart/api.h new file mode 100644 index 0000000..4f3d4c1 --- /dev/null +++ b/include/uart/api.h @@ -0,0 +1,79 @@ +/** \file include/uart/api.h + * This file is for defining a common API for accessing UARTs. + **/ + +#ifndef UART_API_H +#define UART_API_H + +#include "fx2types.h" +#include "stdarg.h" + +/** + * enum Standard available baud rates + * +**/ +enum uart_baud { BAUD_2400, BAUD_4800, BAUD_9600, BAUD_19200, BAUD_38400, BAUD_57600, BAUD_115200, BAUD_ANY, BAUD_FASTEST }; + +/** + * \brief initalizes UART. + * Returns 0 if initialization is successful. + * \param rate See uartX_set_baud() + **/ +BOOL uartX_init(enum uart_baud rate, ...); + +/** + * \brief Sets the UART baud rate to one of the allowed parameters. + * Possible Baud rates: + * \li 2400 + * \li 4800 + * \li 9600 + * \li 19200 + * \li 28800 + * \li 38400 + * \li 57600 + * \li 115200 + * Returns 0 if successful. +**/ +BOOL uartX_set_baud(enum uart_baud rate); + +/** + * \brief Returns the baud rate currently being used. +**/ +enum uart_baud uartX_get_baud(); + +/** + * \brief transmits data through UART + * \param c The character to be sent out +**/ + +void uartX_tx(char c); + +/** + * \brief Returns if the transmit is blocking or not + * 0 - Non Blocking + * 1 - Blocking +**/ + +BOOL uartX_tx_willblock(); + +/** + * \brief receives data through UART. + * Returns one byte at a time from the queue + * +**/ +char uartX_rx(); + +/** + * \brief Returns if the receive is blocking or not + * 0 - Non Blocking + * 1 - Blocking +**/ +BOOL uartX_check_rx_blocking(); + +/** + * \brief Returns count number of bytes present in the buffer + * +**/ +BYTE uartX_check_receive_buffer(); + +#endif diff --git a/include/uart/soft_uart.h b/include/uart/soft_uart.h new file mode 100644 index 0000000..10e98cb --- /dev/null +++ b/include/uart/soft_uart.h @@ -0,0 +1,28 @@ +/** \file include/uart/soft_uart.h + * This file contains a MACRO for defining UART function wrappers + **/ + +#ifndef SOFT_UART_H +#define SOFT_UART_H + + + +#define CREATE_FAST_UART(uart0,pinname) \ +__sbit __at pinname TX_PIN; \ +BOOL uart0##_init(enum uart_baud rate,...) \ +{__asm \ +.equ _TX_PIN , _PA2 \ +__endasm; \ +return TRUE; \ +} \ +void uart0##_tx(char c) { \ +uart_tx(c); \ +} + +/** + * \brief Send data out via UART +**/ +void uart_tx(char c); + +#endif + diff --git a/lib/Makefile b/lib/Makefile index 560c500..63999ad 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -15,7 +15,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA AS8051?=sdas8051 -SOURCES = serial.c i2c.c delay.c setupdat.c gpif.c eputils.c $(wildcard interrupts/*.c) +SOURCES = serial.c i2c.c delay.c setupdat.c gpif.c eputils.c $(wildcard interrupts/*.c) $(wildcard uart/*.c) FX2_OBJS = $(patsubst %.c,%.rel, $(SOURCES)) usbav.rel INCLUDES = -I../include SDCC = sdcc -mmcs51 $(SDCCFLAGS) diff --git a/lib/uart/soft_uart.c b/lib/uart/soft_uart.c new file mode 100644 index 0000000..e35cacb --- /dev/null +++ b/lib/uart/soft_uart.c @@ -0,0 +1,152 @@ +/** \file lib/uart/soft_uart.c + * This file is for defining a common API for accessing UARTs. + * Remarks By Roaring(for the FX2LP from cypress) + **/ +#include +#include +#include +#include + +/*This is set by calling the uartX_set_baud() function.*/ +unsigned char load_delay; +BOOL uartX_init(enum uart_baud rate, ...) +{ + unsigned char clk_cmp; + //Clear all bits except the CLKSPD[1:0] + clk_cmp = CPUCS & 0x18; + //If clock is currently set to 48Mhz,return TRUE + if(clk_cmp == 0x10) + return TRUE; + return FALSE; +} + + +void uart_tx(char c) +{ + //Done in ASM to improve performance. It takes only 6 + //cycles to move the data out, however a delay has been + //introduced in order to get a baud rate of 115200 + //The mask which is to be written into the pin + OEA |= 0x04; + //An efficient UART bitbang routine in assembly + __asm + //Like #define in C. Can easily be used to change the pin + //.equ _TX_PIN, _PA2 + //Disable interrupts + //This is used because timing is critical + //If the FX2 jumps into the ISR temporarily , it may cause transmit + //errors. By clearing EA, we can disable interrupts + clr _EA //(2 cycles) + //Move the data to be sent into the ACC + //The data which is to be shifted out is held in the dpl register + //We move the data into A for easy access to subsequent instructions + mov a , dpl //(2 cyles) + clr c //(1 cycle ) + //We need to send out 8 bits of data + //Load r0 with value 8 + mov r0, #0x08 //(2 cycles) + //Create the start bit + clr _TX_PIN //(2 cycles) + //Precalculated delay since 1 cycle takes 88ns + //At 12Mhz, it should be about 83.33ns + //But it appears to be about 88ns + //These numbers have been verified using an analyzer + mov r1, _load_delay //(2 cycles) + 0006$: + //1 bit is about 8.6us + djnz r1, 0006$ //(3 cycles) + //DJNZ on Rn takes 3 cycles + //NOP takes about 1 cycle + //Add 2 more cycles of delay + //97 cycles + nop //(1 cycle ) + nop //(1 cycle ) + 0001$: + rrc a //(2 cycles) + //The above rotates the accumulator right through the carry + //Move the carry into the port + mov _TX_PIN, c //(2 cycles) + //Now we need to add delay for the next + mov r1, _load_delay //(2 cycles) + //31*3 , 93 cycles of delay + 0004$: + djnz r1, 0004$ //(3 cycles) + nop //(1 cycle ) + //3 more cycles of delay + //97 cycles + djnz r0, 0001$ //(3 cycles) + setb _TX_PIN //(2 cycles) + //This is for stop bit + //We need to delay the stop bit, otherwise we may get errors. + mov r1, _load_delay //(2 cycles) + 0005$: + djnz r1, 0005$ //(3 cycles) + //for DJNZ , Jump for 32*3 , 96 cycles + nop //(1 cycle ) + //97 cycles of delay + setb _EA //(2 cycles) + //Enable back the interrupts + __endasm; +} + +BOOL uartX_set_baud(enum uart_baud rate) +{ + switch(rate) + { + case BAUD_2400: + load_delay = 0xd0; + break; + case BAUD_4800: + break; + case BAUD_9600: + break; + case BAUD_19200: + load_delay = 0xd0; + break; + case BAUD_38400: + load_delay = 0x68; + break; + case BAUD_57600: + load_delay = 0x45; + break; + case BAUD_115200: + load_delay = 0x20; + break; + case BAUD_ANY: + break; + case BAUD_FASTEST: + break; + default: + load_delay = 0x20; + break; + } + return TRUE; +} + +enum uart_baud uartX_get_baud() +{ + return BAUD_115200; +} + +BOOL uartX_tx_willblock() +{ + return TRUE; +} + +char uartX_rx() +{ + //This function should never be called + assert(FALSE); + return 0xFF; +} + +BOOL uartX_check_rx_blocking() +{ + return TRUE; +} + +BYTE uartX_check_receive_buffer() +{ + //Read not implemented.No data is present in the buffer + return 0x00; +}