Skip to content

Instantly share code, notes, and snippets.

@mpflaga
Last active September 16, 2021 02:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mpflaga/ebe6aadd20f81de8e970 to your computer and use it in GitHub Desktop.
Save mpflaga/ebe6aadd20f81de8e970 to your computer and use it in GitHub Desktop.
Leonardo or Arduino Micro Using Serial1 to USB Serial where Serial1 supports 9 Bits
// For Leonardo or Arduino Micro Using Serial1 to USB Serial
#define TXB8 0
#define RXB8 1
char buffer[4];
#define buffer_size sizeof(buffer)/sizeof(buffer[0])
int8_t buffer_pos = 0;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
Serial1.begin(9600);
//Configure 9-bit Mode
bitSet(UCSR1C, UCSZ10);
bitSet(UCSR1C, UCSZ11);
bitSet(UCSR1B, UCSZ12);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println("Serial to mySerial demo started");
Serial.print("buffer_size = "); Serial.print(buffer_size); Serial.println("");
buffer_pos = 0;
}
void loop() {
char inByte;
while (Serial.available()) {
inByte = Serial.read();
Serial.print("inByte = "); Serial.print(inByte); Serial.println("");
Serial.print("buffer_pos = "); Serial.print(buffer_pos); Serial.println("");
while (buffer_pos >= buffer_size) {
for (int8_t i = 0; i < buffer_size - 1; i++) { // rotate buffer left if at end of buffer
buffer[i] = buffer[i + 1];
}
buffer_pos--;
}
buffer[buffer_pos++] = inByte;
Serial.print("buffer = ");
for (int8_t i = 0; i < buffer_size; i++) {
Serial.print(buffer[i]);
}
Serial.println("");
if (strstr(buffer, "cks:")) {
Serial.println("9-bit Transmit");
while(bit_is_set(UCSR1B, UDRIE1));
bitSet(UCSR1B, TXB8); //TXB8
Serial1.write((uint8_t ) 0x39); // Calculate CheckSUM
//should clear buffer and reset to pos to 0;
while(bit_is_set(UCSR1B, UDRIE1));
bitClear(UCSR1B, TXB8); //TXB8
} else {
Serial.println("Regular Transmit");
Serial1.write((uint8_t ) buffer[buffer_pos - 1]); // Calculate CheckSUM
}
}
while(Serial1.available()) {
Serial.print("Serial1 RX = "); Serial.write((uint8_t) Serial1.read()); Serial.println("");
}
}
/// Replace the core library ISR function for Hardware Serial to add Rx feature of 9th bit.
#if (0)
###if ARDUINO > 150
//...\arduino-1.5.6-r2\hardware\arduino\avr\cores\arduino\HardwareSerial.h
...
class HardwareSerial : public Stream
{
...
// Interrupt handlers - Not intended to be called externally
inline void _rx_complete_irq(void);
inline void store_char(unsigned char);
void _tx_udr_empty_irq(void);
};
...
//...\arduino-1.5.6-r2\hardware\arduino\avr\cores\arduino\HardwareSerial_private.h
...
void HardwareSerial::store_char(unsigned char c)
{
uint8_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != _rx_buffer_tail) {
_rx_buffer[_rx_buffer_head] = c;
_rx_buffer_head = i;
}
}
#define RXB8 1
#define UFE0 4
// Actual interrupt handlers //////////////////////////////////////////////////////////////
void HardwareSerial::_rx_complete_irq(void)
{
if (bit_is_clear(*_ucsra, UPE0)) {
bool UCSZ12_set = bit_is_set(*_ucsrb, RXB8);
bool UFE0_set = bit_is_set(*_ucsra, UFE0);
if (UFE0_set) {
// Frame error detected, add error message
store_char('[');
store_char('F');
store_char('E');
store_char(':');
}
if (UCSZ12_set) {
// No Parity error, add error message
store_char('[');
store_char('9');
store_char(':');
}
unsigned char c = *_udr;
store_char('c');
if (UCSZ12_set) {
// No Parity error, end error message
store_char(']');
}
if (UFE0_set) {
// Frame error detected, end error message
store_char(']');
}
} else {
// Parity error, read byte but discard it
*_udr;
};
}
...
// OR
//...\arduino-1.0.5\hardware\arduino\cores\arduino\HardwareSerial.cpp
##if ARDUINO > 100
ISR(USART1_RX_vect)
{
bool UCSZ12_set = bit_is_set(UCSR1B, RXB8);
if (bit_is_clear(UCSR1A, UPE1)) {
if (UCSZ12_set) {
store_char('[', &rx_buffer1);
store_char('9', &rx_buffer1);
}
}
if (bit_is_clear(UCSR1A, UPE1)) {
unsigned char c = UDR1;
store_char(c, &rx_buffer1);
if (UCSZ12_set) {
store_char(']', &rx_buffer1);
}
} else {
unsigned char c = UDR1;
};
}
#endif
##Below is output of the above with Serial1 Tx and Rx looped back, with a test pattern sent.
inByte = 1
buffer_pos = 4
buffer = :671
Regular Transmit
Serial1 RX = 1
inByte = 2
buffer_pos = 4
buffer = 6712
Regular Transmit
Serial1 RX = 2
inByte = 3
buffer_pos = 4
buffer = 7123
Regular Transmit
Serial1 RX = 3
inByte = 4
buffer_pos = 4
buffer = 1234
Regular Transmit
Serial1 RX = 4
inByte = 5
buffer_pos = 4
buffer = 2345
Regular Transmit
Serial1 RX = 5
inByte = c
buffer_pos = 4
buffer = 345c
Regular Transmit
inByte = k
buffer_pos = 4
buffer = 45ck
Regular Transmit
inByte = s
buffer_pos = 4
buffer = 5cks
Regular Transmit
inByte = :
buffer_pos = 4
buffer = cks:
9-bit Transmit
inByte = 6
buffer_pos = 4
buffer = ks:6
Regular Transmit
inByte = 7
buffer_pos = 4
buffer = s:67
Regular Transmit
inByte = 8
buffer_pos = 4
buffer = :678
Regular Transmit
Serial1 RX = c
Serial1 RX = k
Serial1 RX = s
Serial1 RX = [
Serial1 RX = 9
Serial1 RX = 9
Serial1 RX = ]
Serial1 RX = 6
Serial1 RX = 7
Serial1 RX = 8
inByte = 9
buffer_pos = 4
buffer = 6789
Regular Transmit
Serial1 RX = 9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment