Skip to content

Commit

Permalink
Created a UART API definition in softuart.h to allow the example code…
Browse files Browse the repository at this point in the history
… to access printf() and scanf() functionality
  • Loading branch information
Roarin committed Jul 4, 2016
1 parent 0ddd377 commit bc7b0f4
Show file tree
Hide file tree
Showing 6 changed files with 324 additions and 1 deletion.
8 changes: 8 additions & 0 deletions examples/uart_main/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FX2LIBDIR=../..
BASENAME = uart_main
SOURCES=uart_main.c
DSCR_AREA=
INT2JT=
include $(FX2LIBDIR)/lib/fx2.mk
fx2_download:
../download.sh build/$(BASENAME).ihx
48 changes: 48 additions & 0 deletions examples/uart_main/uart_main.c
Original file line number Diff line number Diff line change
@@ -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 <fx2regs.h>
#include <delay.h>
#include <stdio.h>
#include <uart/api.h>
#include <uart/soft_uart.h>
#include <fx2macros.h>

//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\r\n");
}
}

void putchar(char c)
{
uart0_tx(c);
}
79 changes: 79 additions & 0 deletions include/uart/api.h
Original file line number Diff line number Diff line change
@@ -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
28 changes: 28 additions & 0 deletions include/uart/soft_uart.h
Original file line number Diff line number Diff line change
@@ -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

2 changes: 1 addition & 1 deletion lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
160 changes: 160 additions & 0 deletions lib/uart/soft_uart.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/** \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 <fx2regs.h>
#include <fx2macros.h>
#include <uart/api.h>
#include <assert.h>

/*This is set by calling the uartX_set_baud() function.*/
unsigned char load_delay;
/*Holds the value of the EA register*/
__bit ea_hold;
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
jnb _EA,set_ea_enable//Check if the EA bit is set to 1 or not
setb _ea_hold //Store the EA bit
sjmp start
set_ea_enable:
clr _ea_hold //Store the EA bit
start:
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)
delay_1$:
//1 bit is about 8.6us
djnz r1, delay_1$ //(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 )
next_bit$:
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
delay_2$:
djnz r1, delay_2$ //(3 cycles)
nop //(1 cycle )
//3 more cycles of delay
//97 cycles
djnz r0, next_bit$ //(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)
delay_3$:
djnz r1, delay_3$ //(3 cycles)
//for DJNZ , Jump for 32*3 , 96 cycles
nop //(1 cycle )
//97 cycles of delay
mov c,_ea_hold //Restore the EA register to enable or disable interrupts
mov _EA,c //(2 cycles)
__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;
}

0 comments on commit bc7b0f4

Please sign in to comment.