Browse Source

Make serial port configurable.

This change makes the choice of serial port configurable so that
wireless capability can be easily added by connecting Bluetooth modules
(such as BlueSmirf or JY-MCU) to the expansion port pins.
pull/1/head
Robert F-C 12 years ago
parent
commit
ab9d183024
  1. 7
      Marlin/Configuration.h
  2. 42
      Marlin/MarlinSerial.cpp
  3. 48
      Marlin/MarlinSerial.h

7
Marlin/Configuration.h

@ -331,6 +331,13 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th
// SF send wrong arc g-codes when using Arc Point as fillet procedure // SF send wrong arc g-codes when using Arc Point as fillet procedure
//#define SF_ARC_FIX //#define SF_ARC_FIX
// SERIAL_PORT selects which serial port should be used for communication with the host.
// This allows the use of wireless adapters (for instance) which are connected to
// non-default serial port pins.
#define SERIAL_PORT 2
#include "Configuration_adv.h" #include "Configuration_adv.h"
#include "thermistortables.h" #include "thermistortables.h"

42
Marlin/MarlinSerial.cpp

@ -28,7 +28,7 @@
// this is so I can support Attiny series and any other chip without a uart // this is so I can support Attiny series and any other chip without a uart
#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H) #if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)
#if defined(UBRRH) || defined(UBRR0H) #if UART_PRESENT(SERIAL_PORT)
ring_buffer rx_buffer = { { 0 }, 0, 0 }; ring_buffer rx_buffer = { { 0 }, 0, 0 };
#endif #endif
@ -48,18 +48,12 @@ FORCE_INLINE void store_char(unsigned char c)
//#elif defined(SIG_USART_RECV) //#elif defined(SIG_USART_RECV)
#if defined(USART0_RX_vect) #if defined(M_USARTx_RX_vect)
// fixed by Mark Sproul this is on the 644/644p // fixed by Mark Sproul this is on the 644/644p
//SIGNAL(SIG_USART_RECV) //SIGNAL(SIG_USART_RECV)
SIGNAL(USART0_RX_vect) SIGNAL(M_USARTx_RX_vect)
{ {
#if defined(UDR0) unsigned char c = M_UDRx;
unsigned char c = UDR0;
#elif defined(UDR)
unsigned char c = UDR; // atmega8, atmega32
#else
#error UDR not defined
#endif
store_char(c); store_char(c);
} }
#endif #endif
@ -76,39 +70,39 @@ MarlinSerial::MarlinSerial()
void MarlinSerial::begin(long baud) void MarlinSerial::begin(long baud)
{ {
uint16_t baud_setting; uint16_t baud_setting;
bool useU2X0 = true; bool useU2X = true;
#if F_CPU == 16000000UL #if F_CPU == 16000000UL && SERIAL_PORT == 0
// hardcoded exception for compatibility with the bootloader shipped // hardcoded exception for compatibility with the bootloader shipped
// with the Duemilanove and previous boards and the firmware on the 8U2 // with the Duemilanove and previous boards and the firmware on the 8U2
// on the Uno and Mega 2560. // on the Uno and Mega 2560.
if (baud == 57600) { if (baud == 57600) {
useU2X0 = false; useU2X = false;
} }
#endif #endif
if (useU2X0) { if (useU2X) {
UCSR0A = 1 << U2X0; M_UCSRxA = 1 << M_U2Xx;
baud_setting = (F_CPU / 4 / baud - 1) / 2; baud_setting = (F_CPU / 4 / baud - 1) / 2;
} else { } else {
UCSR0A = 0; M_UCSRxA = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2; baud_setting = (F_CPU / 8 / baud - 1) / 2;
} }
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
UBRR0H = baud_setting >> 8; M_UBRRxH = baud_setting >> 8;
UBRR0L = baud_setting; M_UBRRxL = baud_setting;
sbi(UCSR0B, RXEN0); sbi(M_UCSRxB, M_RXENx);
sbi(UCSR0B, TXEN0); sbi(M_UCSRxB, M_TXENx);
sbi(UCSR0B, RXCIE0); sbi(M_UCSRxB, M_RXCIEx);
} }
void MarlinSerial::end() void MarlinSerial::end()
{ {
cbi(UCSR0B, RXEN0); cbi(M_UCSRxB, M_RXENx);
cbi(UCSR0B, TXEN0); cbi(M_UCSRxB, M_TXENx);
cbi(UCSR0B, RXCIE0); cbi(M_UCSRxB, M_RXCIEx);
} }

48
Marlin/MarlinSerial.h

@ -23,6 +23,44 @@
#define MarlinSerial_h #define MarlinSerial_h
#include "Marlin.h" #include "Marlin.h"
#if !defined(SERIAL_PORT)
#error SERIAL_PORT not set
#endif
// The presence of the UBRRH register is used to detect a UART.
#define UART_PRESENT(port) ((port == 0 && (defined(UBRRH) || defined(UBRR0H))) || \
(port == 1 && defined(UBRR1H)) || (port == 2 && defined(UBRR2H)) || \
(port == 3 && defined(UBRR3H)))
// These are macros to build serial port register names for the selected SERIAL_PORT (C preprocessor
// requires two levels of indirection to expand macro values properly)
#define SERIAL_REGNAME(registerbase,number,suffix) SERIAL_REGNAME_INTERNAL(registerbase,number,suffix)
#define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix
// Registers used by MarlinSerial class (these are expanded
// depending on selected serial port
#define M_UCSRxA SERIAL_REGNAME(UCSR,SERIAL_PORT,A) // defines M_UCSRxA to be UCSRxA where x is the serial port number
#define M_UCSRxB SERIAL_REGNAME(UCSR,SERIAL_PORT,B)
#define M_RXENx SERIAL_REGNAME(RXEN,SERIAL_PORT,)
#define M_TXENx SERIAL_REGNAME(TXEN,SERIAL_PORT,)
#define M_RXCIEx SERIAL_REGNAME(RXCIE,SERIAL_PORT,)
#define M_UDREx SERIAL_REGNAME(UDRE,SERIAL_PORT,)
#if SERIAL_PORT == 0 && !defined(UDR0)
#if defined(UDR)
#define M_UDRx UDR // atmega8, atmega32
#else
#error UDR not defined
#endif
#else
#define M_UDRx SERIAL_REGNAME(UDR,SERIAL_PORT,)
#endif
#define M_UBRRxH SERIAL_REGNAME(UBRR,SERIAL_PORT,H)
#define M_UBRRxL SERIAL_REGNAME(UBRR,SERIAL_PORT,L)
#define M_RXCx SERIAL_REGNAME(RXC,SERIAL_PORT,)
#define M_USARTx_RX_vect SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect)
#define M_U2Xx SERIAL_REGNAME(U2X,SERIAL_PORT,)
#define DEC 10 #define DEC 10
#define HEX 16 #define HEX 16
@ -46,7 +84,7 @@ struct ring_buffer
int tail; int tail;
}; };
#if defined(UBRRH) || defined(UBRR0H) #if UART_PRESENT(SERIAL_PORT)
extern ring_buffer rx_buffer; extern ring_buffer rx_buffer;
#endif #endif
@ -68,17 +106,17 @@ class MarlinSerial //: public Stream
FORCE_INLINE void write(uint8_t c) FORCE_INLINE void write(uint8_t c)
{ {
while (!((UCSR0A) & (1 << UDRE0))) while (!((M_UCSRxA) & (1 << M_UDREx)))
; ;
UDR0 = c; M_UDRx = c;
} }
FORCE_INLINE void checkRx(void) FORCE_INLINE void checkRx(void)
{ {
if((UCSR0A & (1<<RXC0)) != 0) { if((M_UCSRxA & (1<<M_RXCx)) != 0) {
unsigned char c = UDR0; unsigned char c = M_UDRx;
int i = (unsigned int)(rx_buffer.head + 1) % RX_BUFFER_SIZE; int i = (unsigned int)(rx_buffer.head + 1) % RX_BUFFER_SIZE;
// if we should be storing the received character into the location // if we should be storing the received character into the location

Loading…
Cancel
Save