HCS12 Tx problem:

Pertaining to the HCS12 Tx problem post of yesterday, thanks to all who have reverted, but I've become completely stuck. If I attempt to send two chars by calling SendMIDI twice, nothing comes out. Hardware is fine, and a simple polled output routine works OK. Plenty of stack space, arrays and variables are all correctly declared and initialised, can't see anything else that could cause a problem.

I'm attempting to trace through the IRQ using polled serial writes to another COM port, it confirms that the ISR is triggering but I think the trace writes might be messing up the timing and the result may not be trustworthy. If anyone can see anything obviously wrong in the following, it would be appreciated. TIA

int SendMIDI (char c) { char d ; d = SCI1SR1 ; // SCI status register if ((d & TDRE) != 0) /* register is free, send immediately */ { SCI1DRL = c ; return 0 ; }

/* Transmitter is busy, queue data */ DisableInts ; mobuf[midoxi++] = c ; if (midoxi > 89) midoxi = 0 ; // wrap buffer round SCI1CR2 |= TIE ; // Data queued, enable Tx interrupt EnableInts ; return 1 ; }

// MIDI send interrupt handler. #pragma interrupt_handler MIDI_handler

void MIDI_handler(void) { char c, d ; c = SCI1SR1 ; // SIO status reg

if ((c & TDRE) == 0) return ; // buffer hasn't cleared yet, have to wait

// Here the Tx buffer is empty. if (midoxi == midoxo) return ; // No queued data

SCI1DRL = mobuf[midoxo++] ; send next queued byte & wrap buffer index if (midoxo > 89) midoxo = 0 ;

if (midoxo == midoxi) SCI1CR2 &= (~TIE) ; // buffer cleared, Mask Tx IRQ }

Reply to
Bruce Varley
Loading thread data ...

Hi Bruce,

[Disclaimer: I d> Pertaining to the HCS12 Tx problem post of yesterday, thanks to all who have

So, IRQ is not being turned on... or, never being acknowledged.

Why not just stub the routine(s) to push values into memory that you can examine at your leisure/debugger? Why drag another hardware device into the mess...?

Where do you set up the TDRE *interrupt*? You've pushed the data into the holding register but I don't see where you've told the device to interrupt you on completion?

You could reduce the size of this critical region by moving some of these operations out of it (esp if all I/O goes through these functions)

Does this handle *all* SIO interrupts?

Where did you clear the IRQ?

Odd size for a buffer! :>

Presumably, nothing else can be dicking around with the FIFO? (critical region)

Note that this has the side-effect of reading CR2 (does doing so have any side-effects of its own -- esp wrt the IRQ?)

Reply to
Don Y

You may be getting the following race condition:

  • Send the first character, all good
  • Call SendMIDI with the second character, transmitter is still working * queue up the second character * transmitter empties * turn on tx interrupt to no effect.

In my paranoia, I would go with the following sequence:

  • turn off interrupts
  • capture the status of the serial port
  • if tx empty and queue empty, * load byte * AND turn on the TX empty interrupt
  • otherwise * shove the byte in the buffer
  • turn on interrupts

You turn off interrupts and then capture the serial port status because that makes sure that the ISR doesn't mess with things before you get a chance at it.

You check that both the TX is empty and the queue empty because if you just check the TX and it went empty between turning off interrupts and capturing the serial port status, you'll shove a byte in out of order.

You turn the TX empty interrupt on when you put a byte in there so that you ALWAYS capture the TX empty event (this is unimportant if the interrupt is level-triggered on the TX empty state, but hugely important if the interrupt is edge-triggered on the TX-going-empty event: it differs from processor to processor, I'm assuming the latter).

You wait until you're altogether completely done before turning on interrupts because you don't want anything _else_ bad to happen.

HTH

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.