diff options
Diffstat (limited to 'lib/lufa/Projects/XPLAINBridge/Lib')
| -rw-r--r-- | lib/lufa/Projects/XPLAINBridge/Lib/SoftUART.c | 156 | ||||
| -rw-r--r-- | lib/lufa/Projects/XPLAINBridge/Lib/SoftUART.h | 71 | 
2 files changed, 227 insertions, 0 deletions
| diff --git a/lib/lufa/Projects/XPLAINBridge/Lib/SoftUART.c b/lib/lufa/Projects/XPLAINBridge/Lib/SoftUART.c new file mode 100644 index 0000000000..5c0e3c8cd9 --- /dev/null +++ b/lib/lufa/Projects/XPLAINBridge/Lib/SoftUART.c @@ -0,0 +1,156 @@ +/* +             LUFA Library +     Copyright (C) Dean Camera, 2017. + +  dean [at] fourwalledcubicle [dot] com +           www.lufa-lib.org +*/ + +/* +  Copyright 2010  David Prentice (david.prentice [at] farming [dot] uk) +  Copyright 2010  Peter Danneger +  Copyright 2017  Dean Camera (dean [at] fourwalledcubicle [dot] com) + +  Permission to use, copy, modify, distribute, and sell this +  software and its documentation for any purpose is hereby granted +  without fee, provided that the above copyright notice appear in +  all copies and that both that the copyright notice and this +  permission notice and warranty disclaimer appear in supporting +  documentation, and that the name of the author not be used in +  advertising or publicity pertaining to distribution of the +  software without specific, written prior permission. + +  The author disclaims all warranties with regard to this +  software, including all implied warranties of merchantability +  and fitness.  In no event shall the author be liable for any +  special, indirect or consequential damages or any damages +  whatsoever resulting from loss of use, data or profits, whether +  in an action of contract, negligence or other tortious action, +  arising out of or in connection with the use or performance of +  this software. +*/ + +/** \file + * + *  Software UART for both data transmission and reception. This + *  code continuously monitors the ring buffers set up by the main + *  project source file and reads/writes data as it becomes available. + */ + +#include "SoftUART.h" + +/** Total number of bits remaining to be sent in the current frame */ +static uint8_t TX_BitsRemaining; + +/** Temporary data variable to hold the byte being transmitted as it is shifted out */ +static uint8_t TX_Data; + +/** Total number of bits remaining to be received in the current frame */ +static uint8_t RX_BitsRemaining; + +/** Temporary data variable to hold the byte being received as it is shifted in */ +static uint8_t RX_Data; + + +/** Initializes the software UART, ready for data transmission and reception into the global ring buffers. */ +void SoftUART_Init(void) +{ +	/* Set TX pin to output high, enable RX pull-up */ +	STXPORT |= (1 << STX); +	STXDDR  |= (1 << STX); +	SRXPORT |= (1 << SRX); + +	/* Enable INT0 for the detection of incoming start bits that signal the start of a byte */ +	EICRA  = (1 << ISC01); +	EIMSK  = (1 << INT0); + +	/* Set the transmission and reception timer compare values for the default baud rate */ +	SoftUART_SetBaud(9600); + +	/* Setup reception timer compare ISR */ +	TIMSK1 = (1 << OCIE1A); + +	/* Setup transmission timer compare ISR and start the timer */ +	TIMSK3 = (1 << OCIE3A); +	TCCR3B = ((1 << CS30) | (1 << WGM32)); +} + +/** ISR to detect the start of a bit being sent to the software UART. */ +ISR(INT0_vect, ISR_BLOCK) +{ +	/* Reset the number of reception bits remaining counter */ +	RX_BitsRemaining = 8; + +	/* Reset the bit reception timer to -(1/2) of the total bit time, so that the first data bit is +	 * sampled mid way through the total bit time, making reception more robust. +	 */ +	TCNT1 = -(OCR1A >> 1); + +	/* Check to see that the pin is still low (prevents glitches from starting a frame reception) */ +	if (!(SRXPIN & (1 << SRX))) +	{ +		/* Disable start bit detection ISR while the next byte is received */ +		EIMSK = 0; + +		/* Start the reception timer */ +		TCCR1B = ((1 << CS10) | (1 << WGM12)); +	} +} + +/** ISR to manage the reception of bits to the software UART. */ +ISR(TIMER1_COMPA_vect, ISR_BLOCK) +{ +	/* Cache the current RX pin value for later checking */ +	uint8_t SRX_Cached = (SRXPIN & (1 << SRX)); + +	/* Check if reception has finished */ +	if (RX_BitsRemaining) +	{ +		/* Shift the current received bit mask to the next bit position */ +		RX_Data >>= 1; +		RX_BitsRemaining--; + +		/* Store next bit into the received data variable */ +		if (SRX_Cached) +		  RX_Data |= (1 << 7); +	} +	else +	{ +		/* Disable the reception timer as all data has now been received, re-enable start bit detection ISR */ +		TCCR1B = 0; +		EIFR   = (1 << INTF0); +		EIMSK  = (1 << INT0); + +		/* Reception complete, store the received byte if stop bit valid */ +		if (SRX_Cached) +		  RingBuffer_Insert(&UARTtoUSB_Buffer, RX_Data); +	} +} + +/** ISR to manage the transmission of bits via the software UART. */ +ISR(TIMER3_COMPA_vect, ISR_BLOCK) +{ +	/* Check if transmission has finished */ +	if (TX_BitsRemaining) +	{ +		/* Set the TX line to the value of the next bit in the byte to send */ +		if (TX_Data & (1 << 0)) +		  STXPORT &= ~(1 << STX); +		else +		  STXPORT |=  (1 << STX); + +		/* Shift the transmission byte to move the next bit into position and decrement the bits remaining counter */ +		TX_Data >>= 1; +		TX_BitsRemaining--; +	} +	else if (!(RX_BitsRemaining) && !(RingBuffer_IsEmpty(&USBtoUART_Buffer))) +	{ +		/* Start bit - TX line low */ +		STXPORT &= ~(1 << STX); + +		/* Transmission complete, get the next byte to send (if available) */ +		TX_Data          = ~RingBuffer_Remove(&USBtoUART_Buffer); +		TX_BitsRemaining = 9; +	} +} + diff --git a/lib/lufa/Projects/XPLAINBridge/Lib/SoftUART.h b/lib/lufa/Projects/XPLAINBridge/Lib/SoftUART.h new file mode 100644 index 0000000000..b273967814 --- /dev/null +++ b/lib/lufa/Projects/XPLAINBridge/Lib/SoftUART.h @@ -0,0 +1,71 @@ +/* +             LUFA Library +     Copyright (C) Dean Camera, 2017. + +  dean [at] fourwalledcubicle [dot] com +           www.lufa-lib.org +*/ + +/* +  Copyright 2010  David Prentice (david.prentice [at] farming [dot] uk) +  Copyright 2010  Peter Danneger +  Copyright 2017  Dean Camera (dean [at] fourwalledcubicle [dot] com) + +  Permission to use, copy, modify, distribute, and sell this +  software and its documentation for any purpose is hereby granted +  without fee, provided that the above copyright notice appear in +  all copies and that both that the copyright notice and this +  permission notice and warranty disclaimer appear in supporting +  documentation, and that the name of the author not be used in +  advertising or publicity pertaining to distribution of the +  software without specific, written prior permission. + +  The author disclaims all warranties with regard to this +  software, including all implied warranties of merchantability +  and fitness.  In no event shall the author be liable for any +  special, indirect or consequential damages or any damages +  whatsoever resulting from loss of use, data or profits, whether +  in an action of contract, negligence or other tortious action, +  arising out of or in connection with the use or performance of +  this software. +*/ + +/** \file + * + *  Header file for SoftUART.c. + */ + +#ifndef _SOFT_UART_ +#define _SOFT_UART_ + +	/* Includes: */ +		#include <avr/io.h> +		#include <avr/interrupt.h> +		#include <stdbool.h> + +		#include "../XPLAINBridge.h" +		#include "Config/AppConfig.h" + +	/* Macros: */ +		#define SRX        PD0 +		#define SRXPIN     PIND +		#define SRXPORT    PORTD + +		#define STX        PD1 +		#define STXPORT    PORTD +		#define STXDDR     DDRD + +	/* Inline Functions: */ +		static inline void SoftUART_SetBaud(const uint32_t Baud) +		{ +			uint16_t BitTime = ((F_CPU / Baud) - 1); + +			OCR1A = BitTime; +			OCR3A = BitTime; +		} + +	/* Function Prototypes: */ +		void SoftUART_Init(void); + +#endif + | 
