Jump to content

Banana Pi M2+ uart2 only works one way


Guest

Recommended Posts

Hi all,
 
First of all, a big thanks for making Armbian work, the work you guys have done is incredible. I have a BPI M2+ board and I have a problem getting the serial communication to work both ways.

I am using the latest image that is available to download on the Armbian website version 5.20, Jessie server, 3.4.112 kernel.
 
According to the board fex file (found here) the configuration for the uart2 is:

[uart2]
uart_used       = 1
uart_port       = 2
uart_type       = 4
uart_tx         = port:PA00<2><1><default><default>
uart_rx         = port:PA01<2><1><default><default>
uart_rts        = port:PA02<2><1><default><default>
uart_cts        = port:PA03<2><1><default><default>

Which in turn maps to GPIO pins 11 and 12 according to their documentation

 

My problem is that I can receive serial signals to the banana pi board from a a different source but nothing gets through the other way. In summary:
Armbian TX (Pin 13)  --> RX other device XXX - Doesn't work

Armbian RX (Pin 11) <--  TX other device  WORKS

 

The device options are the following:

root@bananapim2plus:~# stty -a -F /dev/ttyS2
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

I have tried the exact same connection setup with one of the latest ubuntu images (headless) that are available from the Banana Pi org and I can have duplex communication without any issues.

 

Finally, I used the armbianmonitor program to collect logs which may be found here

 

Thank you in advance for your help.

Link to comment
Share on other sites

Hi @zador.blood.stained,

 

Thanks for your prompt response. I did try what you suggested and the behaviour is similar.

 

As one of the signal directions seems to work fine, do you think it could be that somewhere the pin gets reconfigured and used as a different peripheral function? I am not familiar enough with the chip to start investigating this.

 

Thanks

Link to comment
Share on other sites

Hi @zador.blood.stained , 

 

I have tried that with no success, I'm afraid. Related to this, is that the ports defined for the [uart3] section of the .fex file are also present in the [gpio_para] section and that serial port (/dev/ttyS3) works like a charm. Is there a way through sysfs to check whether the offending pin 13 is misconfigured?

Link to comment
Share on other sites

According to the board fex file (found here) the configuration for the uart2 is:

 

Please keep in mind that with Banana hardware it's always the same. They release new hardware, provide some hardware descriptions (be it fex files or .dts) just to realize months later that a huge amount of stuff is just wrong. Sometimes they correct this, sometimes not.

 

I gave up a while ago. At least they made a lot of changes 3 weeks ago: https://github.com/BPI-SINOVOIP/BPI-M2P-bsp/commit/4e4b27f21457de19a9103466db493e506532059c#diff-95e358c369379367a13a1a17ce93f151

 

(you have to figure out yourself where they just took stuff from Armbian or where they changed stuff since they figured out how their own hardware works -- on a related note: Foxconn creates the specs, Steven from Xunlong does the ODM work and then SinoVoip produces the stuff and scares the customers away).

 

Further reading: http://forum.armbian.com/index.php/topic/1745-different-gpio-pin-mappings-on-bpi-m2-compared-to-orange-pis/

Link to comment
Share on other sites

Hi all,

 

I did try replacing the Armbian provided fex file with the one from the ubuntu sinovoip image where the issue is not present but the behaviour was the same. I have since used the BPI-WiringPi provided gpio binary (repository and installation instructions may be found here) to read the peripheral function of the pins right after boot and it turns out that my initial suspicions were right, the TX pin was misconfigured as an Input. After using the same tool to set it correctly, namely:

gpio mode 2 alt5

I was able to use UART2 reliably.

 

I have since created a systemd script that runs the above and installed it as a dependency of the "dev-ttyS2.device" unit file and now the problem is fixed on boot.

I know that it is not pretty, but it is a workaround. Hope this helps if anyone else needs to use UART2 until we look into it and make the workaround redundant.

Link to comment
Share on other sites

I am having the same problem with UART2 on an Orange Pi+2 using the latest stable legacy version of Armbian (Armbian_5.20_Orangepiplus_Debian_jessie_3.4.112_desktop). It will receive, but it won't transmit.

 

Convolu is correct; pin PA0 is misconfigured. In the fex file, PA0 has the following attributes:

 

$ bin2fex /boot/script.bin | grep PA00
jtag_ms = port:PA00<3><default><default><default>
uart_tx = port:PA00<2><1><default><default>
gpio_pin_6 = port:PA00<1><default><default><0>
But, according to sunxi-pio, it's an input pin:

 

$ sudo sunxi-pio -m print | grep -E "^PA[0-4]<.*"
PA0<0><0><0><0>
PA1<2><1><1>
PA2<2><1><1>
PA3<2><1><1>
PA4<2><1><1>
Resetting the pin to match the settings of PA1 makes it work correctly as UART2_TX:

 

$ sudo sunxi-pio -m PA0'<2><1><1>'
$ sudo sunxi-pio -m print | grep -E "^PA[0-4]<.*"
PA0<2><1><1>
PA1<2><1><1>
PA2<2><1><1>
PA3<2><1><1>
PA4<2><1><1>
To expand on how Convolu got this to persist using systemd, here's what I did:

 

1. Create a service file in /etc/systemd/system using a text editor (must be run as root). Here's what my file looks like:

 

$ cat /etc/systemd/system/pinA0_reconfigure.service 
[Unit]
Description=Re-configure PinA0 as I/O for UART2_TX etc.

[Service]
Type=oneshot
ExecStart=/usr/bin/sunxi-pio -m PA0'<2><1><1>'

[Install]
WantedBy=dev-ttyS2.device
2. Enable and start the service:

 

$ systemctl enable pinA0_reconfigure.service
created symlink from /etc/systemd/system/dev-ttyS2.device.wants/pinA0_reconfigure.service to /etc/systemd/system/pinA0_reconfigure.service.
$ systemctl start pinA0_reconfigure.service
Link to comment
Share on other sites

Has anybody resolved this problem?

I found only such solution.

file linux-sun8i/sun8i/drivers/pinctrl/pinctrl-sunxi.c:

 471 static int sunxi_pinconf_set(struct pinctrl_dev *pctldev,
 472                  unsigned pin,
 473                  unsigned long config)
 474 {
 475     struct sunxi_pinctrl  *pctl = pinctrl_dev_get_drvdata(pctldev);
 476     struct sunxi_pin_bank *bank = sunxi_pin_to_bank(pctl, pin);
 477     unsigned int  pin_bias;
 478     void __iomem        *reg;
 479     u32                  val;
 480     u32                  mask;
 481     u16                  dlevel;
 482     u16                  data;
 483     u16                  func;
 484     u16                  pull;
 485 
 486     pin_reset_bias(&pin_bias, pin);
 487     if (IS_ERR_OR_NULL(bank)) {
 488         pr_debug("invalid pin number [%d] to set pinconf\n", pin);
 489         return -EINVAL;
 490     }
 491     switch (SUNXI_PINCFG_UNPACK_TYPE(config)) {
 492     case SUNXI_PINCFG_TYPE_DRV:
 493         if (strcmp(pin_get_name(pctl->pctl_dev, pin),"PA0")==0)
 494             break;
 495         dlevel = SUNXI_PINCFG_UNPACK_VALUE(config);
 496         val = pinctrl_readl_reg(bank->membase + sunxi_dlevel_reg(pin_bias));
 497         mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(pin_bias);
 498         val=(val & ~mask) | (dlevel << sunxi_dlevel_offset(pin_bias));
 499         reg=bank->membase + sunxi_dlevel_reg(pin_bias);
 500         pinctrl_write_reg(val,reg);
 501         pr_debug("sunxi pconf set pin [%s] drive strength to [LEVEL%d]\n",
 502                  pin_get_name(pctl->pctl_dev, pin), dlevel);
 503         break;   
 504     case SUNXI_PINCFG_TYPE_PUD:
 505         if (strcmp(pin_get_name(pctl->pctl_dev, pin),"PA0")==0)
 506             break;
 507         pull = SUNXI_PINCFG_UNPACK_VALUE(config);
 508         val = pinctrl_readl_reg(bank->membase + sunxi_pull_reg(pin_bias));
 509         mask = PULL_PINS_MASK << sunxi_pull_offset(pin_bias);
 510         val=(val & ~mask) | (pull << sunxi_pull_offset(pin_bias));
 511         reg=bank->membase + sunxi_pull_reg(pin_bias);
 512         pinctrl_write_reg(val,reg);
 513         pr_debug("sunxi pconf set pin [%s] pull to [%d]\n",
 514                 pin_get_name(pctl->pctl_dev, pin), pull);
 515         break;  
 516     case SUNXI_PINCFG_TYPE_DAT:
 517         if (strcmp(pin_get_name(pctl->pctl_dev, pin),"PA0")==0)
 518             break;
 519         data = SUNXI_PINCFG_UNPACK_VALUE(config);
 520         val = pinctrl_readl_reg(bank->membase + sunxi_data_reg(pin_bias));
 521         mask = DATA_PINS_MASK << sunxi_data_offset(pin_bias);
 522         val=(val & ~mask) | (data << sunxi_data_offset(pin_bias));
 523         reg=bank->membase + sunxi_data_reg(pin_bias);
 524         pinctrl_write_reg(val,reg);
 525         pr_debug("sunxi pconf set pin [%s] data to [%d]\n",
 526                 pin_get_name(pctl->pctl_dev, pin), data);
 527         break;  
 528     case SUNXI_PINCFG_TYPE_FUNC:
 529         if (strcmp(pin_get_name(pctl->pctl_dev, pin),"PA0")==0)
 530             break;
 531         func = SUNXI_PINCFG_UNPACK_VALUE(config);
 532         val = pinctrl_readl_reg(bank->membase + sunxi_mux_reg(pin_bias));
 533         mask = MUX_PINS_MASK << sunxi_mux_offset(pin_bias);
 534         val=(val & ~mask) | (func << sunxi_mux_offset(pin_bias));
 535         reg=bank->membase + sunxi_mux_reg(pin_bias);
 536         pinctrl_write_reg(val,reg);
 537         pr_debug("sunxi pconf set pin [%s] func to [%d]\n",
 538                  pin_get_name(pctl->pctl_dev, pin), func);
 539 
 540         printk(KERN_INFO"dima sunxi pconf set pin [%s] func to [%d]\n",
 541                  pin_get_name(pctl->pctl_dev, pin), func);
 542 
 543         break;
 544     default:
 545         pr_debug("invalid sunxi pconf type for set\n");
 546         return -EINVAL;
 547     }
 548     return 0;
 549 }

I add   if (strcmp(pin_get_name(pctl->pctl_dev, pin),"PA0")==0) break;
 

Link to comment
Share on other sites

To resolve this problem enough in fex config file on mm2_para change sdc_detmode from 1 to 3.

   764 [mmc2_para]
   765 sdc_used          = 1
~  766 sdc_detmode       = 3
   767 sdc_buswidth      = 8
   768 sdc_clk           = port:PC05<3><1><2><default>
   769 sdc_cmd           = port:PC06<3><1><2><default>
   770 sdc_d0            = port:PC08<3><1><2><default>
   771 sdc_d1            = port:PC09<3><1><2><default>
   772 sdc_d2            = port:PC10<3><1><2><default>
   773 sdc_d3            = port:PC11<3><1><2><default>
   774 sdc_d4            = port:PC12<3><1><2><default>
   775 sdc_d5            = port:PC13<3><1><2><default>
   776 sdc_d6            = port:PC14<3><1><2><default>
   777 sdc_d7            = port:PC15<3><1><2><default>
   778 emmc_rst          = port:PC16<3><1><2><default>



Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines