Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to correctly set UART speed? #17

Open
BuddyZhang1 opened this issue Dec 29, 2016 · 2 comments
Open

How to correctly set UART speed? #17

BuddyZhang1 opened this issue Dec 29, 2016 · 2 comments

Comments

@BuddyZhang1
Copy link
Contributor

Hi, all friends:
Recently, We will release new board named "OrangePi Zero Plus2", it contains "wifi and bluetooth",
Today, A friends post issue to me, we discuss how to approve performance for Bluetooth.
At first, Bluetooth uses UART to exchange data, and then the speed of UART will affect
performance of Bluetooth.

The original mail as follow:

I was looking at the H5 SDK you posted for the Orange Pi. It has the
same problem I am experiencing with the A64 SDK.

Bluetooth has a wire speed of 3Mb/s and a throughput speed of
2.1Mb/sec. So you want to set the Bluetooth UARTs up to 3Mb/s. All of
the other vendors in Android AOSP do this. If the UART is not running
at 3MB file transfers will get overruns and performance is terrible,

Allwinner is defaulting to OSC24 as the source clock for apb2 which
clocks the UARTs. OSC24 is only able to run a UART at up to 1.5Mb/s.
To get 3Mb/s the apb2 source clock needs to be switched over to the
1.2Ghz PERIPH0x2 clock source. You can't change this in Linux because
changing it will make UART0 (the console) stop working. Instead if has
to be fixed in u-boot.

Could you ask Allwinner to fix u-boot to switch this clock source so
that 3Mb/s is possible on the UARTs? They will also need to test their
kernel drivers for TWI and UART to ensure that they work on this
1.2Ghz clock source.

From u-boot serial_spl.c...

void sunxi_serial_init(int uart_port, void *gpio_cfg, int gpio_max)
{
u32 reg, i;
u32 uart_clk;

if( (uart_port < 0) ||(uart_port > 0) )
{
return;
}

----> need to switch apb2 clock source here to periph0x2

//reset
reg = readl(CCMU_BUS_SOFT_RST_REG4);
reg &= ~(1<<(CCM_UART_PORT_OFFSET + uart_port));
writel(reg, CCMU_BUS_SOFT_RST_REG4);
for( i = 0; i < 100; i++ );
reg |= (1<<(CCM_UART_PORT_OFFSET + uart_port));
writel(reg, CCMU_BUS_SOFT_RST_REG4);
//gate
reg = readl(CCMU_BUS_CLK_GATING_REG3);
reg &= ~(1<<(CCM_UART_PORT_OFFSET + uart_port));
writel(reg, CCMU_BUS_CLK_GATING_REG3);
for( i = 0; i < 100; i++ );
reg |= (1<<(CCM_UART_PORT_OFFSET + uart_port));
writel(reg, CCMU_BUS_CLK_GATING_REG3);
//gpio
boot_set_gpio(gpio_cfg, gpio_max, 1);
//uart init
serial_ctrl_base = (serial_hw_t *)(SUNXI_UART0_BASE + uart_port *
CCM_UART_ADDR_OFFSET);

serial_ctrl_base->mcr = 0x3;
uart_clk = (24000000 + 8 * UART_BAUD)/(16 * UART_BAUD);

---> uart_clk = (1200000000 + 8 * UART_BAUD)/(16 * UART_BAUD);

serial_ctrl_base->lcr |= 0x80;
serial_ctrl_base->dlh = uart_clk>>8;
serial_ctrl_base->dll = uart_clk&0xff;
serial_ctrl_base->lcr &= ~0x80;
serial_ctrl_base->lcr = ((PARITY&0x03)<<3) | ((STOP&0x01)<<2) | (DLEN&0x03);
serial_ctrl_base->fcr = 0x7;

return;
}

BTW, all friends, what do you want to do?

@BuddyZhang1
Copy link
Contributor Author

Thank you @jonsmirl [email protected]

Mark your advice, the original mail as follow:

https://en.wikipedia.org/wiki/Bluetooth

Bluetooth 2.0 + EDR

This version of the Bluetooth Core Specification was released in 2004.
The main difference is the introduction of an Enhanced Data Rate (EDR)
for faster data transfer. The nominal rate of EDR is about 3 Mbit/s,
although the practical data transfer rate is 2.1 Mbit/s.[46] EDR uses
a combination of GFSK and Phase Shift Keying modulation (PSK) with two
variants, π/4-DQPSK and 8DPSK.[48] EDR can provide a lower power
consumption through a reduced duty cycle.


With the current code Allwinner UARTs are limited to 1.5Mb/s. Use
'stty' and try to set 3Mb/s, it will fail.

Note this impacts things like Ampak and Realtek modules, not USB BT.
USB runs at 480Mb/s.

If you do a large BT transfer - like a file transfer - trying to stick
3Mb/s data into a 1.5Mb/s serial port results in overruns. The
overruns cause packet retransmissions and everything gets a whole lot
slower.


The Allwinner hardware is capable of supporting 3Mb/s. The software
simply hasn't configured the clocks so that 3Mb/s is possible.

All of the Allwinner UARTs use the same clock source. The impact of
this is that if I use Linux to set UART1 to 3Mb/s it changes the clock
for UART0 too. UART0 is the console and the console stops working.
This clock needs to be changed before the console is active. That
means it has to be set up in u-boot.

@jonsmirl
Copy link

If your are using ARM Trusted Firmware which most people use on A64/H5, the code needs to be added there instead of in uboot SPL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants