1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

UART receive ISR receives 1st 2 bytes twice

Discussion in 'Embedded' started by galapogos, Oct 31, 2006.

  1. galapogos

    galapogos Guest

    Hi,

    I'm trying to read data from a smart card via a Toshiba 16bit MCU's
    UART interface set at a slow 4+K baudrate. My receive ISR however seems
    to pull out the 1st 2 bytes of the transmission from the receive buffer
    twice. i.e., when the smart card sends 0x1, 0x2, 0x3, ..., 0xa, My
    receive ISR will receive 0x1, 0x2, 0x1, 0x2, 0x3, ...,0xa. I've checked
    the I/O line with a logic analyzer and the smart card isn't resending
    the 1st 2 bytes. I've checked the bit period on both the MCU and smart
    card and they both agree(i.e. similar baudrate) so it's not a
    synchronization problem either.

    Does anyone know what might be causing it? My receive ISR is simple,
    and currently does no error checking:
    ISR() {
    fifo[i++] = receivebuffer
    }

    I've tried putting in breakpoints when when i == 2 in the ISR, and
    indeed the receivebuffer is 0x1 rather than 0x3, so the ISR seems to be
    doing its job just fine, except the receivebuffer doesn't seem to have
    the right data.

    Any ideas? Thanks!
     
    galapogos, Oct 31, 2006
    #1
    1. Advertisements

  2. galapogos

    Ico Guest

    Is reading the 'receivebuffer' register enough ? Maybe your UART needs
    special treatment to tell it you have read the buffer so at can clear
    the interrupt ?
     
    Ico, Oct 31, 2006
    #2
    1. Advertisements

  3. galapogos

    galapogos Guest

    Thanks, I'll check the datasheet to see if there's any info on that,
    but I doubt that's the case, because it's always only the 1st 2 byte
    that gets repeated just once, before getting the rest in the sequence.

    Another thing I forgot to mention is that the receive buffer is shared
    with the tx buffer, but the rx buffer is double buffered, i.e. there's
    an rxbuff1 and an rxbuff2. Information gets buffered into rxbuff1, and
    then moved to rxbuff2, and only rxbuff2 is accessible to the user.
     
    galapogos, Oct 31, 2006
    #3
  4. galapogos

    Ico Guest

    Just another idea: are you using memory mapped buffers? Does your
    compiler know it's not allowed to do any optimization with that
    variable, eg, declared it volatile ?
     
    Ico, Oct 31, 2006
    #4
  5. Step back a bit, and think "How does the INT routine 'know' it is the
    first bytes" ?
    What makes that different from other bytes, and why should it _stop_
    doing this ?

    Create your own test data stream, and try that ?

    -jg
     
    Jim Granville, Oct 31, 2006
    #5
  6. galapogos

    Arlet Guest

    It could be a race condition in the copy code. Can you show how it's
    implemented ?
     
    Arlet, Oct 31, 2006
    #6
  7. galapogos

    galapogos Guest

    The copy in my isr is simply:

    fifo[Tail++] = (unsigned char) SC0BUF;
    Tail &= BUFLEN - 1;

    where fifois my circular buffer for receives, SC0BUF is the hardware
    receive buffer and Tail is the tail of the circular buffer where I push
    data in, and BUFLEN is the length of the circular buffer(power of 2).
    The first line copies data while the 2nd line handles buffer index
    wraparound. fifo is memset to all 0s at initialization.

    Anyway, I discovered that when I connect my smart card before program
    execution, I don't get the repeated bytes problem, but when I run it to
    a breakpoint right before resetting the smart card(and getting back
    some ack data from the smart card) and THEN connect the smart card
    before continuing the program, then I get the problem. Wonder why that
    would be the case.
     
    galapogos, Nov 1, 2006
    #7
  8. galapogos

    galapogos Guest

    That's what I'm wondering too. How does the isr know, when actually the
    logic analyzer shows no such repeat? And, why does it only happen when
    the smart card is plugged in right before the transmission begins? I've
    thought about creating my own test data stream so I can isolate it
    without relying on smart card transmissions, but how would I create the
    test data stream to send it to the UART though? Wouldn't I need some
    external device with another UART to do so?
     
    galapogos, Nov 1, 2006
    #8
  9. galapogos

    galapogos Guest

    Hi,
    I'm not sure what you mean by memory mapped buffers. My circular buffer
    is simply declared as an "unsigned char volatile fifo[buflen]", so yup
    it's volatile and hence not optimized. My head and tail indices are
    also volatile.
     
    galapogos, Nov 1, 2006
    #9
  10. Does this uC have any comms error flags ?
    [things covering errors like False start bits, framing error etc ? ),
    Yes, just another of the PCB you are working on, with small test code ?

    -jg
     
    Jim Granville, Nov 1, 2006
    #10
  11. galapogos

    galapogos Guest

    The mcu does have parity, framing and overrun error flags, but for the
    purpose of testing, i'm currently not checking these. The baudrate I'm
    using is so slow(~5000bps) that such errors would be very unlikely, and
    the waveform I'm seeing on my logic analyzer seems to confirm this.

    Unfortunately I only have 1 prototype pcb and 1 mcu emulator.
    Interfacing it with another board will require me to make another pcb
    and obtain another emulator from the vendor, which is pretty
    inconvenient.
     
    galapogos, Nov 1, 2006
    #11
  12. But when you insert the card while the software is running, all sorts of
    rubbisch might be received due to contact bounce, producing framing, overrun
    and parity errors. So the first two interrupts might well be caused by this.
    The solution is that right before you start issueing commands to the card,
    you clear the receiver status and empty the fifo first. Do this before each
    command sent or only the first time you detect a card (you do have a card
    detection signal, do you?).

    Meindert
     
    Meindert Sprang, Nov 1, 2006
    #12
  13. galapogos

    Arlet Guest

    Perhaps you can indicate the ISR activity by toggling a GPIO pin, and
    see how the timing relates to the actual serial data being received on
    your logic analyser.
     
    Arlet, Nov 1, 2006
    #13
  14. galapogos

    galapogos Guest

    That's exactly what I'm doing. I toggle 2 GPIO pin in my ISRs(rx and
    tx) so I can tell how many bytes are being received and transmitted.
    But it isn't that easy to trigger on the right transfers on the logic
    analyzer.
     
    galapogos, Nov 1, 2006
    #14
  15. galapogos

    galapogos Guest

    I think you might be right. Currently I'm not doing any card detection
    since I'm not sure how to do that. If I just leave card inserted or
    insert it before the start of the program, all is fine. On the
    insertion though I do notice some activity on the various pins on my
    logic analyzer, which probably indicates some contact bounce.
     
    galapogos, Nov 1, 2006
    #15
  16. You bet you have contact bounce during insertion!
    Any decent cardholder has a "card-loaded" contact. Read this contact and
    when it closes or opens (whatever indicates the card is present, wait
    another 50ms to make sure no contact bounces anymore. Then clear the fifo,
    reset any error status in the UART and only then you start sending commands
    to the card.

    Meindert
     
    Meindert Sprang, Nov 1, 2006
    #16
  17. galapogos

    Arlet Guest

    A trick that I often use is to generate a trigger in software. Since
    you only have a problem with Rx, you could use 1 GPIO pin to indicate
    an Rx interrupt, and the other one to create a trigger signal that is
    only toggled when the ISR detects the first character of a message, or
    when you detect the duplicate bytes, or something like that.
     
    Arlet, Nov 1, 2006
    #17
  18. galapogos

    James Beck Guest

    I think the error flags may be a part of your problem.
    Some UARTS need the error bits cleared before the next byte comes in or
    strange things happen. Like the interrupt isn't cleared and the ISR
    gets called again and again until the bits get cleared by you or,
    possibly, the next byte coming in.

    Jim
     
    James Beck, Nov 1, 2006
    #18
  19. galapogos

    galapogos Guest

    Well, actually I'm using a ghetto smart card reader. Basically I took a
    usb smart card reader, ripped out the pcb, desoldered the wires, and
    soldered on my own connnection to my own dev board.

    I don't recall any "card-loaded" contact on the iso7816-3 specs. There
    are only 8 pins - Vcc, GND, I/O, RST, CLK, VPP(not used) and 2
    RFU(reserve for future use), and in this case the RFUs are the USB
    D+/D- signals.
     
    galapogos, Nov 1, 2006
    #19
  20. galapogos

    galapogos Guest

    Oh and I forgot to mention, I'm using a smart card module in sim form
    factor and taping it onto the contact points on the pcb's sim holder,
    so there's no "card bounce" per se. The bounce is probably happening on
    the connector side, which is some generic connector/pin that I soldered
    onto both the smart card side and my dev board side.
     
    galapogos, Nov 1, 2006
    #20
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.