From ea484eb3c407aae781abb6fdea35364367f7ab76 Mon Sep 17 00:00:00 2001 From: bela Date: Thu, 22 Mar 2001 09:35:51 +0000 Subject: [PATCH] Initial release git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@700 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- device/examples/serialcomm/windows/serial.cpp | 149 +++++++++++++ device/examples/serialcomm/windows/serial.h | 27 +++ .../serialcomm/windows/test_serialcomm.cpp | 36 ++++ device/include/at89x051.h | 65 ++++++ device/lib/ser_ir_cts_rts.c | 200 ++++++++++++++++++ 5 files changed, 477 insertions(+) create mode 100755 device/examples/serialcomm/windows/serial.cpp create mode 100755 device/examples/serialcomm/windows/serial.h create mode 100755 device/examples/serialcomm/windows/test_serialcomm.cpp create mode 100755 device/include/at89x051.h create mode 100755 device/lib/ser_ir_cts_rts.c diff --git a/device/examples/serialcomm/windows/serial.cpp b/device/examples/serialcomm/windows/serial.cpp new file mode 100755 index 00000000..7b319af4 --- /dev/null +++ b/device/examples/serialcomm/windows/serial.cpp @@ -0,0 +1,149 @@ +// Elementary functions for for serial communication for Visual C / MFC +// Bela Torok / bela.torok@kssg.ch, March 2001 + +// This version is using the CTS/RTS protocol only, with 8 databits + no parity. +// This file was tested with ser_ir_cts_rts.c (in device/lib) + +// Todo: Imporve the function SerialInit to support communication with no_protocol & XON/XOFF protocol, +// 7 databits, even & odd parity, 1, 1.5 & 2 stopbits, etc... + +#include +#include + +//#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // serial.cpp : Defines the entry point for the console application. + +//#include "stdafx.h" +#include + +#include "serial.h" + +// Flow control flags + +#define FC_DTRDSR 0x01 +#define FC_RTSCTS 0x02 +#define FC_XONXOFF 0x04 + +// ascii definitions + +#define ASCII_BEL 0x07 +#define ASCII_BS 0x08 +#define ASCII_LF 0x0A +#define ASCII_CR 0x0D +#define ASCII_XON 0x11 +#define ASCII_XOFF 0x13 + + // variables used with the com port + BOOL bPortReady; + DCB dcb; + COMMTIMEOUTS CommTimeouts; + BOOL bWriteRC; + BOOL bReadRC; + DWORD iBytesWritten; + DWORD iBytesRead; + +HANDLE SerialInit(char *ComPortName, int BaudRate) +{ + HANDLE hCom; + + hCom = CreateFile(ComPortName, + GENERIC_READ | GENERIC_WRITE, + 0, // exclusive access + NULL, // no security + OPEN_EXISTING, + 0, // no overlapped I/O + NULL); // null template + + bPortReady = SetupComm(hCom, 2, 128); // set buffer sizes + + + bPortReady = GetCommState(hCom, &dcb); + dcb.BaudRate = BaudRate; + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; +// dcb.Parity = EVENPARITY; + dcb.StopBits = ONESTOPBIT; + dcb.fAbortOnError = TRUE; + + // set XON/XOFF + dcb.fOutX = FALSE; // XON/XOFF off for transmit + dcb.fInX = FALSE; // XON/XOFF off for receive + // set RTSCTS + dcb.fOutxCtsFlow = TRUE; // turn on CTS flow control + dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; // + // set DSRDTR + dcb.fOutxDsrFlow = FALSE; // turn on DSR flow control + dcb.fDtrControl = DTR_CONTROL_ENABLE; // +// dcb.fDtrControl = DTR_CONTROL_DISABLE; // +// dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; // + + bPortReady = SetCommState(hCom, &dcb); + + // Communication timeouts are optional + + bPortReady = GetCommTimeouts (hCom, &CommTimeouts); + + CommTimeouts.ReadIntervalTimeout = 5000; + CommTimeouts.ReadTotalTimeoutConstant = 5000; + CommTimeouts.ReadTotalTimeoutMultiplier = 1000; + CommTimeouts.WriteTotalTimeoutConstant = 5000; + CommTimeouts.WriteTotalTimeoutMultiplier = 1000; + + bPortReady = SetCommTimeouts (hCom, &CommTimeouts); + + return hCom; +} + +char SerialGetc(HANDLE *hCom) +{ + char rxchar; + BOOL bReadRC; + static DWORD iBytesRead; + + bReadRC = ReadFile(*hCom, &rxchar, 1, &iBytesRead, NULL); + + return rxchar; +} + +void SerialPutc(HANDLE *hCom, char txchar) +{ + BOOL bWriteRC; + static DWORD iBytesWritten; + + bWriteRC = WriteFile(*hCom, &txchar, 1, &iBytesWritten,NULL); +} + +char* SerialGets(HANDLE *hCom) +{ + static char rxstring[256]; + char c; + int pos = 0; + + while(pos <= 255) { + c = SerialGetc(hCom); + if(c == '\r') continue; // discard carriage return + rxstring[pos++] = c; + if(c == '\n') break; + } + rxstring[pos] = 0; + + return rxstring; +} + +void SerialPuts(HANDLE *hCom, char *txstring) +{ + BOOL bWriteRC; + static DWORD iBytesWritten; + + bWriteRC = WriteFile(*hCom, txstring, strlen(txstring), &iBytesWritten,NULL); + +} + +void sleep( int _wait) +{ + clock_t goal; + goal = clock() + _wait; + while( goal > clock() ); +} + diff --git a/device/examples/serialcomm/windows/serial.h b/device/examples/serialcomm/windows/serial.h new file mode 100755 index 00000000..dffeb2f1 --- /dev/null +++ b/device/examples/serialcomm/windows/serial.h @@ -0,0 +1,27 @@ +// Flow control flags + +#define FC_DTRDSR 0x01 +#define FC_RTSCTS 0x02 +#define FC_XONXOFF 0x04 + +// ascii definitions + +#define ASCII_BEL 0x07 +#define ASCII_BS 0x08 +#define ASCII_LF 0x0A +#define ASCII_CR 0x0D +#define ASCII_XON 0x11 +#define ASCII_XOFF 0x13 + + +HANDLE SerialInit(char*, int); + +char SerialGetc(HANDLE*); + +void SerialPutc(HANDLE*, char); + +char* SerialGets(HANDLE*); + +void SerialPuts(HANDLE*, char*); + +void sleep(int); diff --git a/device/examples/serialcomm/windows/test_serialcomm.cpp b/device/examples/serialcomm/windows/test_serialcomm.cpp new file mode 100755 index 00000000..fd0fc953 --- /dev/null +++ b/device/examples/serialcomm/windows/test_serialcomm.cpp @@ -0,0 +1,36 @@ +// Test program for serial communication. Visual C / MFC Version +// Bela Torok / bela.torok@kssg.ch, March 2001 + +#include // Defines the entry point for the console application. + +#include +#include + +#include "serial.h" + +int main(int argc, char* argv[]) +{ + + HANDLE hComPort; + + int ComPortNumber = 1; + + hComPort = SerialInit("com1", 1200); // 1200 Baud + + if( hComPort == 0) { + printf("\n\nError initializing %s!\n", "com1"); + exit(1); + } + + // write string to RS232 + SerialPuts(&hComPort, "\nInitialize\n"); +// sleep(5000); + + // read string from RS232 + printf("\nString received: %s\n", SerialGets(&hComPort)); + + CloseHandle(hComPort); + + return 0; +} + diff --git a/device/include/at89x051.h b/device/include/at89x051.h new file mode 100755 index 00000000..ec297611 --- /dev/null +++ b/device/include/at89x051.h @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------- + Register Declarations for Atmel AT89C1051, AT89C2051 and AT89C4051 Processors + + Written By - Bela Torok (august 2000) + bela.torokt@kssg.ch + based on 8051.h (8051.h must be in mcs51 subdirectory) + + KEIL C compatible definitions are included + + This program 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, or (at your option) any + later version. + + This program 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 this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#include <8051.h> /* load difinitions for the 8051 core */ + +#ifdef REG8051_H +#undef REG8051_H +#endif + +#ifndef AT89Cx051_H +#define AT89Cx051_H + +/* remove non existing registers */ + +#ifdef P0 /* P0 is defined in */ +#undef P0 /* AT89Cx051 has no P0 */ +#undef P0_0 /* undefine bit addressable registers in P0 */ +#undef P0_1 +#undef P0_2 +#undef P0_3 +#undef P0_4 +#undef P0_5 +#undef P0_6 +#undef P0_7 +#endif + +#ifdef P2 /* P2 is defined in */ +#undef P2 /* AT89Cx051 has no P2 */ +#undef P2_0 /* undefine bit addressable registers in P2 */ +#undef P2_1 +#undef P2_2 +#undef P2_3 +#undef P2_4 +#undef P2_5 +#undef P2_6 +#undef P2_7 +#endif + +#endif + diff --git a/device/lib/ser_ir_cts_rts.c b/device/lib/ser_ir_cts_rts.c new file mode 100755 index 00000000..9be6d720 --- /dev/null +++ b/device/lib/ser_ir_cts_rts.c @@ -0,0 +1,200 @@ +/*------------------------------------------------------------------------- + ser_ir.c - source file for serial routines + + Written By - Josef Wolf (1999) + + Revisions: + 1.0 Bela Torok Jul. 2000 + RTS / CTS protocol added + + This program 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, or (at your option) any + later version. + + This program 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 this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! + +-------------------------------------------------------------------------*/ + +/* This file implements a serial interrupt handler and its supporting +* routines. Compared with the existing serial.c and _ser.c it has +* following advantages: +* - You can specify arbitrary buffer sizes (umm, up to 255 bytes), +* so it can run on devices with _little_ memory like at89cx051. +* - It won't overwrite characters which already are stored in the +* receive-/transmit-buffer. +* - It checks receiver first to minimize probability for overruns +* in the serial receiver. +*/ + +/* BUG: those definitions (and the #include) should be set dynamically +* (while linking or at runtime) to make this file a _real_ library. +*/ + +/* RTS/CTS protocol howto: + + + Shematic of cable for RTS/CTS protocol (B. Torok - Jun. 2000) + +<- DB9 female connector -><- RS232 driver/receiver -><- 8051 system -> + connect to PC e.g. MAX232 + + RS232 TTL + level level + + DCD DTR + Pin1---Pin4 + Transmitters/Receivers + RXD + Pin2-----------------------------<<<-------------------TXD + + TXD + Pin3----------------------------->>>-------------------RXD + + GND + Pin5---------------------------------------------------GND + + DSR CTS + Pin6---Pin8----------------------<<<-------------------CTS (see #define CTS) + + RTS + Pin7----------------------------->>>-------------------RTS (see #define RTS) +*/ + + +#include <8051.h> +#include "ser_ir.h" + +#define TXBUFLEN 3 +#define RXBUFLEN 18 // The minimum rx buffer size for safe communications + // is 17. (The UART in the PC has a 16-byte FIFO.) +// TXBUFLEN & RXBUFLEN can be highher if rxbuf[] and txbuf[] is in xdata, max size is limited to 256! + +#define THRESHOLD 16 +#define ENABLE 0 +#define DISABLE 1 + +#define CTS P3_6 // CTS & RTS can be assigned to any free pins +#define RTS P3_7 + +static unsigned char rxbuf[RXBUFLEN], txbuf[TXBUFLEN]; +static unsigned char rxcnt, txcnt, rxpos, txpos; +static unsigned char busy; + +void ser_init() +{ + ES = 0; + rxcnt = txcnt = rxpos = txpos = 0; // init buffers + busy = 0; + SCON = 0x50; // mode 1 - 8-bit UART + PCON |= 0x80; // SMOD = 1; + TMOD &= 0x0f; // use timer 1 + TMOD |= 0x20; +// TL1 = TH1 = 256 - 104; // 600bps with 12 MHz crystal +// TL1 = TH1 = 256 - 52; // 1200bps with 12 MHz crystal +// TL1 = TH1 = 256 - 26; // 2400bps with 12 MHz crystal + TL1 = TH1 = 256 - 13; // 4800bps with 12 MHz crystal + + TR1 = 1; // Enable timer 1 + ES = 1; + + CTS = ENABLE; +} + +void ser_handler(void) interrupt 4 +{ + if (RI) { + RI = 0; + /* don't overwrite chars already in buffer */ + if(rxcnt < RXBUFLEN) rxbuf [(rxpos + rxcnt++) % RXBUFLEN] = SBUF; + if(rxcnt >= (RXBUFLEN - THRESHOLD)) CTS = DISABLE; + } + + if (TI) { + TI = 0; + if (busy = txcnt) { /* Assignment, _not_ comparison! */ + txcnt--; + SBUF = txbuf[txpos++]; + if(txpos >= TXBUFLEN) txpos = 0; + } + } +} + +void ser_putc(unsigned char c) +{ + while(txcnt >= TXBUFLEN); // wait for room in buffer + + while(RTS == DISABLE); + + ES = 0; + if (busy) { + txbuf[(txpos + txcnt++) % TXBUFLEN] = c; + } else { + SBUF = c; + busy = 1; + } + ES = 1; +} + +unsigned char ser_getc(void) +{ + unsigned char c; + + while (!rxcnt) { // wait for a character + CTS = ENABLE; + } + + ES = 0; + rxcnt--; + c = rxbuf[rxpos++]; + if (rxpos >= RXBUFLEN) rxpos = 0; + ES = 1; + return (c); +} + +#pragma SAVE +#pragma NOINDUCTION +void ser_puts(unsigned char *s) +{ + unsigned char c; + while (c= *s++) { + if (c == LF) ser_putc(CR); + ser_putc (c); + } +} +#pragma RESTORE + +void ser_gets(unsigned char *s, unsigned char len) +{ + unsigned char pos, c; + + pos = 0; + while (pos <= len) { + c = ser_getc(); + if (c == CR) continue; // discard CR's + s[pos++] = c; + if (c == LF) break; // NL terminates + } + s[pos] = '\0'; // terminate string +} + +unsigned char ser_can_xmt(void) +{ + return TXBUFLEN - txcnt; +} + +unsigned char ser_can_rcv(void) +{ + return rxcnt; +} \ No newline at end of file -- 2.39.5