Conversion of some Serial UART registers from R3 to R4

Hi - Having some trouble converting this code from an Arduino Uno R3 to an R4. It manipulates the USART Control and Status Register B to set for 9-bit operation (changes the parity bit). Looking for the equivalent calls that are compatible with the R4:

  UCSR1B = 0b10011101;
  Serial1.write(0x80);
  delay(20);
  Serial1.write(0x81);
  UCSR1B = 0b10011100;

Getting UCSR1B was not declared in this scope.

I've looked at the CPU datasheet but I am not finding what I need. Any help would be appreciated. Thanks!

A much more sensible approach would be to learn how to receive 9 bit serial data on the relevant R4 processor, since it and its peripherals have essentially no relationship to those of the Uno R3.

If you're just looking to send/receive 8 bits with parity, you might want to try out Serial1.begin(baud, SERIAL_8E1); or Serial1.begin(baud, SERIAL_8O1);

The protocol of the device I am communicating with expects the 9th parity bit to be set to 1 (mark parity) when sending the data and then set to 0 (space parity) when done; example from c#:

  Byte[] GenPoll = { 0x80, 0x81 };
  SerialPort1.Parity = Parity.Mark;
  SerialPort1.Write(GenPoll, 0, 1);   // sends  0x80 gen pol to all machines  they wake up and listen for their address OR'ed with 0x80
  Thread.Sleep(20); gives the machine time to clear responses from its buffer (prevents duplicate responses)
  SerialPort1.Write(GenPoll, 1, 1); // sends out poll to mahne with address of 1
  SerialPort1.Parity = Parity.Space;

I have been digging through the R4 code - hardwareserial, serial, serialUSB and it does not seem like it supports mark or space parity as written. Nor do I see any UART registers I can manipulate like on the R3.

The bit that it is changing in the R3 code you have is the TXB8n bit. The description says that this bit serves as the 9th bit when sending 9 bit frames.

Section 20.11.3 ATMEGA 328P datasheet.

On the R4 you have a 16 bit data register for transmissions. So when using 9 bit frames you just access the data register as a 16 bit register and stick all 9 bits in.

Section 28.2.6 Renesas RA4M1 Group User's Manual:

Thank you - that got me closer. I think the command I need looks something like this:

SCI1.TDRHL.BYTE.TDRH = 0xFE; (this will set the 9th bit to 0)

However - I am still getting error: 'SCI1' was not declared in this scope

What reference/include am I missing?

Look at the FSP manual. This thread has links to the user's manual and the FSP.

It's not going to be a command for command substitution. The UART in the Renesas chip is a whole different beast. You're going to have to figure out how to make it do what they were making that 328 do. To me it looks like you won't need any extra code at all on the new chip. Just set it for 9 bit and then set your character up in the low byte of an unsigned int and set the high byte to either 0 or 1 and then send that all at once as a 9 bit character.

When you say 'Set it for 9-bit'; I am not sure how to do that. The hardwareserial library does not support 9bit mode. So if I do a Serial1.begin(19200,SERIAL_9N1) it fails; if I attempt to update hardwareserial with a definition for SERIAL_9N1 the R4 crashes when trying to execute that line.

I've looked over the docs but I'm not very familiar with low-level manipulation of these registers. Any sample code you could share?

I'm sorry but I don't. I'm busy at the moment trying to make other stuff work on it. I'm looking at Timers and USB-Host support right now. I haven't really dug into the SCI much.

Unfortunately that's sort of where you are. And as far as I know you're in uncharted waters. Perhaps someone who's been through there before will show up eventually.

Hello, any news regarding this ?
I also would like to have 9-bit support on UNO R4 !!
Today I can only use 8bit data. Such as "Serial1.begin(9600,SERIAL_8N1)".
N/E/O works fine , but when setting for 7-bit in Serial.begin it compiles but nothing is transmitted. When trying with9-bit. I get a compilation error ...not declared in this scope.
I really think when starting with a new UNO R4, you should be able to use 5-9 bit data.
Today I use Teensy 4.0 where all this works fine (after a small edit in "hardwareSerial.h".
/

R_SCI1->TDRHL =

This is the 16 bit transfer data register. You'd write a whole 16 bit value to it where the low byte is the byte you want to send and the high byte is just your parity bit in the low bit.

It says the bits 9-15 that aren't being used should be written as 1.

I think you also need to look at the CHR bits in SMR register. They set the number of bits.

I don't know if that's enough. Like I said I haven't really looked at the SCI yet. Maybe it will get you started.

@marcdavis
You could say frame length instead of (confusing) 9-bit operation.

Start Bit:  1
Data Bits:  7 or 8
Parity Bit: Odd or Even or None
Stop Bit:   1 or 2

I think most people with low to moderate intelligence can figure out what he's talking about here.

Did you have anything to actually add to the discussion? Or did you just want to pick on people's word choices?

9bit support is a much bigger project than just adding the various smaller configuration combination working. Unless you have a working 9bit Serial class for AVR or some other chip, it means re-writing significant portions of the HardwareSerial class (and introducing incompatibilities with Stream (non-UART Serial-like interfaces.))

1 Like

So I am creeping closer to my answer; I have a conceptual example of what I need; but I am missing the correct includes from the Renesas SSP for the RA4M1. I downloaded what I think is the SSP from their site but can't find the right set of files to include. Can anyone help me move this further?

Example code:

#include "r_sci_uart.h"

/* UART control structure */
static sci_uart_instance_ctrl_t g_uart_ctrl;

void setup() {
  hardware_init();
}

void loop() {
  setNinthBit();  // Set the 9th bit
  R_SCI_UART_Write(&g_uart_ctrl, &byte, 1);
  resetNinthBit();  // Reset the 9th bit
  delay(20);
  setNinthBit();  // Set the 9th bit again if needed
  R_SCI_UART_Write(&g_uart_ctrl, &byte, 1);
  resetNinthBit();  // Reset the 9th bit
}

void hardware_init(void) {
  /* Initialize hardware here, including UART configuration for RA4M1 */

  /* Initialize UART control structure */
  R_SCI_UART_Open(&g_uart_ctrl, &g_uart_cfg);
}

void setNinthBit() {
  /* Set the 9th bit (T8) for SCI communication on RA4M1 */
  g_uart_ctrl.p_reg->SCMR |= SCI_SCIF_SCMR_T8;
}

void resetNinthBit() {
  /* Reset the 9th bit (T8) for SCI communication on RA4M1 */
  g_uart_ctrl.p_reg->SCMR &= ~SCI_SCIF_SCMR_T8;
}

Getting a variety of compile errors like: Compilation error: 'g_uart_cfg' was not declared in this scope.