forked from djmuhlestein/fx2lib
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create UART functions using C macros according to the api.h file.
- Loading branch information
Showing
6 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <file>" | ||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
FX2LIBDIR=../.. | ||
BASENAME = uart_main | ||
SOURCES=uart_main.c | ||
DSCR_AREA= | ||
INT2JT= | ||
include $(FX2LIBDIR)/lib/fx2.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* 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> | ||
#include <fx2types.h> | ||
#include <assert.h> | ||
|
||
//Initialize UART, call it uart0 and set the tx pin on PA1. | ||
CREATE_FAST_UART(uart0,OEB,_PB0,bmBIT0,TRUE,FALSE) | ||
CREATE_FAST_UART(uart1,OEA,_PA4,bmBIT4,TRUE,FALSE) | ||
//Used for setting the baud rate. | ||
enum uart_baud baud; | ||
|
||
void main(void) | ||
{ | ||
baud = BAUD_115200; | ||
SETCPUFREQ(CLK_48M); | ||
while (!uart0_init(baud)); | ||
while (!uart1_init(baud)); | ||
uart0_set_baud(baud); | ||
baud = BAUD_115200; | ||
uart1_set_baud(baud); | ||
while (TRUE) | ||
{ | ||
printf("Hello\r\n"); | ||
uart1_tx(0x44); | ||
} | ||
} | ||
|
||
void putchar(char c) | ||
{ | ||
uart0_tx(c); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/** \file include/uart/soft_uart.h | ||
* This file contains a MACRO for defining UART function wrappers. | ||
**/ | ||
#ifndef SOFT_UART_H | ||
#define SOFT_UART_H | ||
|
||
/** | ||
* \brief Automatically generates the function calls to allow multiple | ||
* UARTS to be created. The main parameters for the UART is the pin number | ||
* as well as the speed of the operation. These should be passed as an argument | ||
* to the macro. The load_delay element controls the speed. This is created with the | ||
* uart name. | ||
**/ | ||
#define CREATE_FAST_UART(uartname,port,pinname,bitnum,TX_BLOCKING,RX_ENABLED) \ | ||
BYTE uartname##_load_delay; \ | ||
enum uart_baud uartname##rate; \ | ||
BOOL uartname##_init(enum uart_baud rate,...) \ | ||
{ \ | ||
uartX_init(rate); \ | ||
return TRUE; \ | ||
} \ | ||
void uartname##_tx(char c) { \ | ||
__asm \ | ||
.equ _TX_PIN1,pinname \ | ||
.equ _load_delay,_##uartname##_load_delay \ | ||
__endasm; \ | ||
port = bitnum; \ | ||
uart_tx(c); \ | ||
} \ | ||
BOOL uartname##_set_baud(enum uart_baud rate) { \ | ||
uartname##rate = rate; \ | ||
switch(rate) \ | ||
{ \ | ||
case BAUD_2400: \ | ||
return FALSE; \ | ||
case BAUD_4800: \ | ||
return FALSE; \ | ||
case BAUD_9600: \ | ||
return FALSE; \ | ||
case BAUD_19200: \ | ||
uartname##_load_delay = 0xd0; \ | ||
break; \ | ||
case BAUD_38400: \ | ||
uartname##_load_delay = 0x68; \ | ||
break; \ | ||
case BAUD_57600: \ | ||
uartname##_load_delay = 0x45; \ | ||
break; \ | ||
case BAUD_115200: \ | ||
uartname##_load_delay = 0x20; \ | ||
break; \ | ||
case BAUD_ANY: \ | ||
break; \ | ||
case BAUD_FASTEST: \ | ||
uartname##_load_delay = 0x20; \ | ||
uartname##rate = BAUD_115200; \ | ||
break; \ | ||
default: \ | ||
uartname##_load_delay = 0x20; \ | ||
break; \ | ||
} \ | ||
return TRUE; \ | ||
} \ | ||
enum uart_baud uartname##_get_baud() \ | ||
{ \ | ||
return uartname##rate; \ | ||
} \ | ||
BOOL uartname##_tx_willblock() \ | ||
{ \ | ||
return TX_BLOCKING; \ | ||
} \ | ||
char uartname##_rx() \ | ||
{ \ | ||
assert(FALSE); \ | ||
return 0xFF; \ | ||
} \ | ||
BOOL uartname##_check_rx_blocking() \ | ||
{ \ | ||
return FALSE; \ | ||
} \ | ||
BYTE uartname##_check_receive_buffer() \ | ||
{ \ | ||
return FALSE; \ | ||
} \ | ||
BOOL uartname##_init(enum uart_baud rate,...); \ | ||
void uartname##_tx(char c); \ | ||
BOOL uartname##_set_baud(enum uart_baud rate); \ | ||
enum uart_baud uartname##_get_baud(); \ | ||
BOOL uartname##_tx_willblock(); \ | ||
char uartname##_rx(); \ | ||
BOOL uartname##_check_rx_blocking(); \ | ||
BYTE uartname##_check_receive_buffer(); | ||
|
||
/*Holds the value of the EA register.*/ | ||
__bit ea_hold; | ||
|
||
static inline 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. | ||
//An efficient UART bitbang routine in assembly. | ||
__asm | ||
//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 | ||
//Store the EA bit. | ||
mov _ea_hold,_EA | ||
0002$: | ||
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_PIN1 //(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) | ||
0003$: //(--) | ||
//1 bit is about 8.6us. //(--) | ||
djnz r1, 0003$ //(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 ) | ||
0004$: //(--) | ||
rrc a //(2 cycles) | ||
//The above rotates the accumulator right through the carry. //(--) | ||
//Move the carry into the port. //(--) | ||
mov _TX_PIN1, c //(2 cycles) | ||
//Now we need to add delay for the next. //(--) | ||
mov r1, _load_delay //(2 cycles) | ||
//31*3 , 93 cycles of delay. //(--) | ||
0005$: //(--) | ||
djnz r1, 0005$ //(3 cycles) | ||
nop //(1 cycle ) | ||
//3 more cycles of delay. //(--) | ||
//97 cycles. //(--) | ||
djnz r0, 0004$ //(3 cycles) | ||
setb _TX_PIN1 //(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) | ||
0006$: //(--) | ||
djnz r1, 0006$ //(3 cycles) | ||
//for DJNZ , Jump for 32*3 , 96 cycles. //(--) | ||
nop //(1 cycle ) | ||
//97 cycles of delay. //(--) | ||
//Restore the EA register to enable or disable interrupts. //(--) | ||
mov _EA, _ea_hold //(--) | ||
__endasm; | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -115,3 +115,5 @@ clean: | |
clean-all: clean | ||
$(MAKE) -C $(FX2LIBDIR)/lib clean | ||
|
||
fx2_download: | ||
../download.sh build/$(BASENAME).ihx |