Cannot make software serial send more than one character

ChibiOS public support forum for topics related to the Atmel AVR family of micro-controllers.

Moderators: utzig, tfAteba

carldong
Posts: 62
Joined: Wed Oct 15, 2014 6:08 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Cannot make software serial send more than one character

Postby carldong » Wed Mar 29, 2017 1:00 am

Now adding a print to SD1 causes some more funny outputs(SD1 output is fine):

Code: Select all

  while (true) {
    debug("USART1\r\n");
    chThdSleepSeconds(1);
    chprintf((BaseSequentialStream*) &SDS, "USARTS\r\n");
    chThdSleepSeconds(1);
  }


Output:

Code: Select all

UUSARTS{h0D}
USARTS{h0D}
U{h00}USARTS{h0D}
USARTS{h0D}
UUSARTS{h0D}
USARTS{h0D}
UUSARTS{h0D}


For each of the double 'U's, one 'U' prints first, then one second later, the string "USARTS\r\n" is printed. That {h00} does not repeat itself later.

carldong
Posts: 62
Joined: Wed Oct 15, 2014 6:08 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Cannot make software serial send more than one character

Postby carldong » Thu Mar 30, 2017 5:59 pm

Any ideas? I am basically stuck here. I am actually running a project deadline here, if I can't fix it soon I will use a mux on hardware side to force a second port, and I might not revisit this problem unless I am forced to use AVR 8 again.

utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Location: Brazil
Has thanked: 1 time
Been thanked: 20 times
Contact:

Re: Cannot make software serial send more than one character

Postby utzig » Thu Mar 30, 2017 6:24 pm

Please copy your latest .c/.h version somewhere. I will try later today.

carldong
Posts: 62
Joined: Wed Oct 15, 2014 6:08 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Cannot make software serial send more than one character

Postby carldong » Thu Mar 30, 2017 8:52 pm

utzig wrote:Please copy your latest .c/.h version somewhere. I will try later today.

I did not change it. Yes, I moved the usartS_init #endif statement to exclude timer initialization code, but that's it. In theory, it should have no effect on the program, but now it "sort of" works, except with those extra 'U's.

That's why I said I was stuck...

carldong
Posts: 62
Joined: Wed Oct 15, 2014 6:08 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Cannot make software serial send more than one character

Postby carldong » Thu Mar 30, 2017 10:17 pm

I retried one more time just now, and the behavior reverted to the original problem -- printing a single 'U'.

And now I recognize that:

If I plug in the TX from computer(RX on the software serial port, that is), I get the correct printouts --- except for an extra 'U' every fifth outputs.

Now I think there might be some problems in my state machine.

utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Location: Brazil
Has thanked: 1 time
Been thanked: 20 times
Contact:

Re: Cannot make software serial send more than one character

Postby utzig » Thu Mar 30, 2017 10:21 pm

If you end up solving the issue before I get started, even better! :)

carldong
Posts: 62
Joined: Wed Oct 15, 2014 6:08 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Cannot make software serial send more than one character

Postby carldong » Thu Mar 30, 2017 11:05 pm

Yep, confirmed one thing: If I turn off RX, transmission works as intended. If I turn on RX, all kinds of weird stuff happen. I definitely need to revise the state machine. Updating a common state in two ISRs might be the problem.

carldong
Posts: 62
Joined: Wed Oct 15, 2014 6:08 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Cannot make software serial send more than one character

Postby carldong » Fri Mar 31, 2017 12:12 am

Now I splitted the state machines, and RX and TX no longer conflict! So transmission is working correctly. However, now I cannot receive anything... Not sure whether it is a OS thing or my code. I am way too depleted of glucose to continue today :(

https://pastebin.com/jziyaC0r

Note that I doubled the TIMER2 clock, so for B4800, the clock should be set to 9600Hz. These are some settings:

Code: Select all

/**
 * @brief B4800 on 7372800Hz Clock
 */
const SerialConfig softserial_config = {
  UBRR(4800), /* No use, just a placeholder.*/
  USART_CHAR_SIZE_8,
  96,
  (1 << CS21) /* Divide 8.*/
};
/**
 * @brief B4800(approx) on 16000000Hz Clock
 */
const SerialConfig softserial_config = {
  UBRR(4800), /* No use, just a placeholder.*/
  USART_CHAR_SIZE_8,
  208,
  (1 << CS21) /* Divide 8.*/
};


I will probably make use of that UBRR thing after I get serial working. Here is the current symptom. For a main thread like this:

Code: Select all

  while (true) {
    debug("USART1\r\n");
    chThdSleepSeconds(1);
    chprintf((BaseSequentialStream *)&SDS, "USARTS\r\n");
    chprintf((BaseSequentialStream *)&SDS, "USARTS Press A Key > ");
    {
      char x = sdGet(&SDS);
      chprintf((BaseSequentialStream *)&SDS, "%d\r\n", x);
    }
    chThdSleepSeconds(1);
  }


USART1 works of course, and USARTS prints are perfect. However, the program doesn't read anything to `x`. For now, I can't find the reason yet. Here is a snippet of output:

Code: Select all

USARTS Press A Key > USARTS
USARTS Press A Key > USARTS
USARTS Press A Key > �����������������������������������������������������������������������������������������������������������������������������


Those garbage at the end generates once per second. Not sure where they come from(maybe Q_EMPTY?), and don't know why the period is one second instead of two. However, if I actually try to type, garbage stops appearing. After I stop, garbage shows up a second later.

I will investigate the problem slightly later.

utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Location: Brazil
Has thanked: 1 time
Been thanked: 20 times
Contact:

Re: Cannot make software serial send more than one character

Postby utzig » Fri Mar 31, 2017 12:21 am

I was able to get it working here on an ATmega1280 with your previously posted code (single state machine). I had to change the pin mapping and rolled back the config to get 4800 bps.

Code: Select all

const SerialConfig softserial_config = {
  UBRR(4800), /* No use, just a placeholder.*/
  USART_CHAR_SIZE_8,
  52,
  (1 << CS22) /* Divide 64.*/
};

I did only one change to the code:

Code: Select all

#if !defined AVR_GPT_USE_TIM2
  #error "Software serial requires AVR_GPT_USE_TIM2"
#endif

which should really be:

Code: Select all

#if !AVR_GPT_USE_TIM2
  #error "Software serial requires AVR_GPT_USE_TIM2"
#endif

I'll try reading some stuff too.

utzig
Posts: 359
Joined: Sat Jan 07, 2012 6:22 pm
Location: Brazil
Has thanked: 1 time
Been thanked: 20 times
Contact:

Re: Cannot make software serial send more than one character

Postby utzig » Fri Mar 31, 2017 1:16 am

Ok, got it to work!

You won't believe this but the problem is the ISR vector. Your where defining it like this:

Code: Select all

#define AVR_SDS_RX_VECT PCINT0_vect

But it actually is this:

Code: Select all

#define AVR_SDS_RX_VECT INT0_vect

So the MCU was resetting because there was not INT0 handler!

Also in the block where you write EICRA, etc, please change your #if from:

Code: Select all

#if defined AVR_SDS_USE_INT0

to:

Code: Select all

#if AVR_SDS_USE_INT0


Cheers,
Fabio Utzig


Return to “AVR Support”

Who is online

Users browsing this forum: No registered users and 15 guests