chipKIT® Development Platform

Inspired by Arduino™

Serial crash problem

Created Wed, 24 Jul 2013 21:21:27 +0000 by majenko


majenko

Wed, 24 Jul 2013 21:21:27 +0000

Here's an interesting one... Can someone confirm this for me?

Simple little sketch - original idea is feed through from one serial to another for testing a bluetooth module. Cut down to just this to find the problem:

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  Serial1.begin(9600); // <-- Comment this out and it works
  Serial.println("Channel 1 Ready");
}

void loop() {
  static unsigned long ts = millis();
  static int f = LOW;
  if (millis() - ts >= 500) {
    ts = millis();
    f = 1 - f;
    digitalWrite(13, f);
  }
  int c;
  c = Serial.read();
  if (c > 0) {
    Serial.write(c);
  }
}

Simple enough operation - echo back what you type. Flash an LED to show it's working.

With the Serial1.begin() in there the first hint of sending data to the board causes it to lock up. Or it does on my UNO32 anyway. Comment out the Serial1.begin() line, and it all works fine.

Anyone else seeing this happen with this sketch?


majenko

Wed, 24 Jul 2013 21:34:49 +0000

Narrowing it down:

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  Serial1.begin(9600); 
  Serial.println("Channel 1 Ready");
}

void loop() {
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13, LOW);
  delay(500);
}

As soon as a character arrives through serial it crashes. Either Serial or Serial1. My guess is something to do with the receive interrupt.


caroper

Wed, 24 Jul 2013 21:36:12 +0000

I use Serial pass-trough often and have never had a problem, but I have always made both ports the same BAUD rate.

I am on a long weekend break at the moment but will be home on Sunday and have an UNO32 sitting on the bench that I have been using to compare the DP32 Sketches on. I will run your code on it when I get back and post my result.

Cheers Chris


majenko

Wed, 24 Jul 2013 21:46:04 +0000

Interesting thought about the baud rates. Just tried them both on 9600 though, and it's just the same.

I'm using the latest git version btw, but the same behavior is seen using UECIDE.


majenko

Wed, 24 Jul 2013 22:25:45 +0000

Hmmm... It looks like just having Serial1.begin(9600) and a flashing LED is all that is needed. No need for Serial.begin(...).


Ian_B

Thu, 25 Jul 2013 18:50:06 +0000

Looked into it and there is a problem with the serial interrupt. In line 210 of HardwareSerial.cpp, you've got:

setIntVector(_SER0_VECTOR, isr);

Change '_SER0_VECTOR' to 'vec' and you should be good. I tested it out and it seems to work fine now. It looks like this is new to the 0715 version of mpide.

Also interesting, if you switch the order of Serial.begin() and Serial1.begin() without changing the interrupt vector, the sketch you provided works.

Thanks for finding this. We (Digilent) are looking into it now.


majenko

Thu, 25 Jul 2013 19:41:34 +0000

Well found. I've corrected it in mine, and submitted a pull request.


hvm2hvm

Wed, 31 Jul 2013 10:39:48 +0000

Thank you very much for the fix, I had the same problem on my Uno32.


ggesmundo

Sat, 03 Aug 2013 00:10:55 +0000

Thanks from me as well, worked for my DP32.


Sprigo

Fri, 20 Sep 2013 20:19:31 +0000

Phew! Finally got serial working. I was on the verge of sending the board back as defective. :oops:


labegf

Sat, 09 Nov 2013 22:00:58 +0000

Please, confirm the correct file to edit: Is the file below? [color=#0000FF]mpide-0023-windows-20130715\hardware\pic32\cores\pic32\HardwareSerial.c line 210???[/color]

I'm confused, because I've already modified it and my Serial1 continues freezing my code.

thanks


majenko

Fri, 15 Nov 2013 15:25:26 +0000

That should be .cpp, not .c :P

This is my entire begin function from HardwareSerial.cpp:

void HardwareSerial::begin(unsigned long baudRate)
{
    p32_regset *    ipc;    //interrupt priority control register set
    int             irq_shift;

    /* Initialize the receive buffer.
    */
    purge();

#if defined(__PIC32MX1XX__) || defined(__PIC32MX2XX__)
    /* Map the UART TX to the appropriate pin.
    */
    mapPps(pinTx, ppsTx);

    /* Map the UART RX to the appropriate pin.
    */
    mapPps(pinRx, ppsRx);
#endif

    setIntVector(vec, isr);

    /* Set the interrupt privilege level and sub-privilege level
    */
    setIntPriority(vec, ipl, spl);

    /* Clear the interrupt flags, and set the interrupt enables for the
    ** interrupts used by this UART.
    */
    ifs->clr = bit_rx + bit_tx + bit_err;   //clear all interrupt flags

    iec->clr = bit_rx + bit_tx + bit_err;   //disable all interrupts
    iec->set = bit_rx;                      //enable rx interrupts

    /* Initialize the UART itself.
    **  http://www.chipkit.org/forum/viewtopic.php?f=7&t=213&p=948#p948
    ** Use high baud rate divisor for bauds over LOW_HIGH_BAUD_SPLIT
    */
    uart->uxSta.reg = 0;
    if (baudRate < LOW_HIGH_BAUD_SPLIT)
    {
        uart->uxBrg.reg    = ((__PIC32_pbClk / 16 / baudRate) - 1);      // calculate actual BAUD generate value.
        uart->uxMode.reg = (1 << _UARTMODE_ON);                          // enable UART module
    }
    else
    {
        uart->uxBrg.reg    = ((__PIC32_pbClk / 4 / baudRate) - 1);       // calculate actual BAUD generate value.
        uart->uxMode.reg = (1 << _UARTMODE_ON) | (1 << _UARTMODE_BRGH);  // enable UART module
    }
    uart->uxSta.reg  = (1 << _UARTSTA_UTXEN) + (1 << _UARTSTA_URXEN);    // enable transmitter and receiver
}

kaaasap

Thu, 05 Dec 2013 20:42:42 +0000

After finding this I think I know why I am having trouble with UART2 on uC32.

I did the rewrite and still not reading....


ChristopheDupriez

Thu, 05 Dec 2013 23:24:54 +0000

This looks to me to be the problem I submitted some time ago: http://www.chipkit.net/forum/viewtopic.php?f=17&t=2584 and that you helped me to solve! It is time to put the latest MPIDE build in G.A.!

Keep on the good work Majenko!

Christophe


kaaasap

Fri, 06 Dec 2013 13:21:22 +0000

Is it possible that since "_SER1_VECTOR" is also on lines 789, 979, and 981 it could be causing UART2RX to not work?


majenko

Fri, 06 Dec 2013 13:35:58 +0000

No, those are used specifically in conjunction with the Serial1 object for configuring the object with the right values for that port. The _SER1* entries are the second serial port (_SER0* being the first), and are related to the physical port in the Board_Defs.h file for your board:

#define _SER1_BASE      _UART2_BASE_ADDRESS
#define _SER1_IRQ       _UART2_ERR_IRQ
#define _SER1_VECTOR    _UART_2_VECTOR
#define _SER1_IPL_ISR   _UART2_IPL_ISR
#define _SER1_IPL       _UART2_IPL_IPC
#define _SER1_SPL       _UART2_SPL_IPC

majenko

Fri, 06 Dec 2013 13:39:50 +0000

This little snippet works on my Uno32 to pass through serial in both directions:

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
  if (Serial.available()) {
    Serial1.write(Serial.read());
  }
  if (Serial1.available()) {
    Serial.write(Serial1.read());
  }
}

drpap

Thu, 12 Dec 2013 13:14:35 +0000

Wow- I am so glad I found this thread. I have been using a Max board on a project with an autonomous boat for over 2 years now and using the new mpide version coincided with a major code re-write. I spend (wasted is more like it) the last week trying to figure out the problem and recently narrowed it down to the Serial port I/O.

Special thanks to majenko for identifying the issue.

I can confirm the 'fix' worked for me as well on a Max32 using both Serial & Serial1.

This is a pretty serious issue, it may be enough of a reason for an updated mpide?


kaaasap

Fri, 13 Dec 2013 12:57:29 +0000

Had to re-download mpide. Then did fix. All my projects are working and so is Serial1 RX pin. Must have messed something else up on my own. Thank you majenko.


mitchjp

Wed, 08 Jan 2014 00:30:33 +0000

On the verge of breaking something... why isn't my serial 1, 2, 3 working ahhhhrhrhghhg.

Changed the HardwareSerial and voila! Works like a charm.

For what it's worth my Serial would work fine, just not the other three (using a max32).

Thanks guys I wish I had read this 2 hours ago!


majenko

Wed, 08 Jan 2014 01:05:27 +0000

It's a bit of a pain this bug. I just wish I could hack into the computer of everyone in the world that runs MPIDE and patch their systems for them... ;)

Glad it's working for you.


mitchjp

Wed, 08 Jan 2014 23:31:12 +0000

I have something else which is a bit odd happening which might be related.

In the beginning of my code when I use Serial.println('Hello') it prints 'Hello' into the serial, as expected.

However, anytime I use Serial.println after I have referenced Serial1, it starts to print some digits into Serial as opposed to text. The digits aren't the ASCII code equivalent, either.

Anyone had this problem?


majenko

Thu, 09 Jan 2014 00:07:21 +0000

Nope, doesn't ring a bell. This code works fine for me:

void setup() {
	Serial.begin(9600);
	Serial1.begin(9600);
	Serial.println("Hello");
}

void loop() {	
}

Armego25

Wed, 15 Jan 2014 15:25:22 +0000

Please help me, the code in Uno32 not work I installed MPIDE 20131118


Armego25

Wed, 15 Jan 2014 15:29:04 +0000

Nope, doesn't ring a bell. This code works fine for me:

void setup() {
Serial.begin(9600);
Serial1.begin(9600);
Serial.println("Hello");
}
void loop() {	
}

Please help me, the code not work on Uno32. I installed MPIDE 20131118


Armego25

Wed, 15 Jan 2014 18:03:25 +0000

Please help me I did all in the topic and the Uart2 Not work fine in Uno32...


majenko

Thu, 16 Jan 2014 15:22:56 +0000

Just download the latest version of MPIDE, or use UECIDE - both work perfectly. If it still doesn't work then you either have a faulty board or (more likely) your code is wrong. Confirm it fails with the bare minimum sketch above.


Armego25

Fri, 17 Jan 2014 12:07:27 +0000

Just download the latest version of MPIDE, or use UECIDE - both work perfectly. If it still doesn't work then you either have a faulty board or (more likely) your code is wrong. Confirm it fails with the bare minimum sketch above.

Majenko thank you for you answer. but the problem is that when I send data by Uart1 to Uart2 not working and when reset the Uno32 the print the same data so "serial 0 Ready" mi stech is:

int data;
 
void setup()
{
  Serial1.begin(9600);
  Serial.begin(9600);
  Serial.println("Serial 0 Ready!");
  Serial1.println("Serial 1 Ready!");
  
}
 
void loop()
{
  delay(1000);
  Serial.println("Serial 0 Ready!");
  if(Serial.available()>0)
  {
    Serial1.print("Serial 0 Sent: ");
    while(Serial.available()>0)
    {
      data=Serial.read();
      Serial1.write(data);
    }
    Serial1.println();
    }
   delay(1000);
   Serial1.println("Serial 1 Ready!");
  if(Serial1.available()>0)
  {
    Serial.print("Serial 1 Sent: ");
    while(Serial1.available()>0)
    {
      data=Serial1.read();
      Serial.write(data);
    }
    Serial.println();
  }
}

Please excuse me bad english


majenko

Fri, 17 Jan 2014 13:40:41 +0000

Works fine on UECIDE, which uses the core direct from the latest MPIDE. However, you really really really don't want those delay(1000)s in there as that really messes with the reception.

Try this modified code:

int data;
 
void setup()
{
  Serial1.begin(9600);
  Serial.begin(9600);
  Serial.println("Serial 0 Ready!");
  Serial1.println("Serial 1 Ready!");
 
}
 
void loop()
{
//  delay(1000);
//  Serial.println("Serial 0 Ready!");
  if(Serial.available()>0)
  {
    Serial1.print("Serial 0 Sent: ");
    while(Serial.available()>0)
    {
      data=Serial.read();
      Serial1.write(data);
    }
    Serial1.println();
    }
//   delay(1000);
//   Serial1.println("Serial 1 Ready!");
  if(Serial1.available()>0)
  {
    Serial.print("Serial 1 Sent: ");
    while(Serial1.available()>0)
    {
      data=Serial1.read();
      Serial.write(data);
    }
    Serial.println();
  }
}

It's exactly the same but with the Ready! messages and the delays commented out.


Armego25

Fri, 17 Jan 2014 21:52:14 +0000

Majenko. how do you conection of uart2 in Uno32.


majenko

Fri, 17 Jan 2014 22:02:30 +0000

I tickle the pins with my finger :P

If I need real serial I use a USB->TTL adapter - I have a handful here. Just plug it into pins 39 and 40 and bob's your uncle.


Armego25

Fri, 17 Jan 2014 22:19:58 +0000

[attachment=0]Resul.jpg[/attachment]> Majenko. how do you conection of uart2 in Uno32.

on both ports write the same "Serial 0 Ready!" UART2 and should write "Serial 1 Ready". I am using QP-USB-RS232 converter UDB9 coupled with a circuit containing a Max232 coupling.


majenko

Fri, 17 Jan 2014 22:21:30 +0000

Then my guess is you're connecting it to pins 0 and 1, not pins 39 and 40?


Armego25

Fri, 17 Jan 2014 23:16:58 +0000

Then my guess is you're connecting it to pins 0 and 1, not pins 39 and 40?

Thank you very much... You resolver my problem I been conecting bad. I conected in pins 0 and 1. by this not work good .


majenko

Fri, 17 Jan 2014 23:58:03 +0000

Pins 0 and 1 work like on an Arduino - they are connected to the same UART as the FT232 chip which drives the USB connection.

If you want to have pins 0 and 1 separate then you need a board that doesn't use the FT232 chip but instead uses the internal USB peripheral of the PIC32 chip. trouble is most of those don't have the standard Arduino-style footprint. The closest is probably the WF32 that has two USB device connections - one on an FT232 connected to pins 0 and 1, and another that is directly linked to the internal USB. If you don't mind the layout then one of the Fubarino boards may be better - especially the Fubarino SD (695 version). That has 6 UART connections (not sure about how they're mapped, if they're all available) plus the direct USB connection.