EmbeddedRelated.com
Forums

Two-wires RS485 and the driver enable problem

Started by pozzugno October 13, 2014
On 10/13/2014 11:17 AM, Don Y wrote:
> > First, you need to *know* that it is *you* that has been granted access to > the bus/resource. If this requires you to perform some analysis of the > ENTIRE MESSAGE (to verify that the "address field" is, in fact, intact!), > then you probably DON'T want to try to ride the coat-tails of the message, > directly.
It's called a checksum and can be done after the entire message is received and before a reply needs to be sent.
> As the front end of a message (including yours) is more likely to be > corrupted > (by a collision on the bus -- someone jabbering too long or too soon), you > might consider designing a packet format that has one checksum on the > address field "early" in the packet (before the payload) and another that > handles the balance of the message. > > This allows you to capture the address information and it's closely > following > checksum, verify that it is *you* that are being addressed and prepare > for your > acquisition of the bus before the message has completely arrived.
As the OP has pointed out this is of no value whatsoever. No one is trying to minimize dead time or maximize throughput. The question is about turning off the driver at the end of a transmission.
> You can also arrange to access the bus in "timeslots" referenced to some > easily recognizable event (e.g., a beacon sent by the master). So, > you do all of your timing off of that single event (see "some special > point" in the beacon, start timer, wait to transmit until "your slot").
This is not only not a solution to the problem, it is entirely pointless. The protocol is that the master sends a message to a peripheral device. When the peripheral device receives a message it responds. When the master receives a response it can send the next message.
> Note this also works if you just assume the "next slot" after the master's > message is the slot you should use (you just limit the length of the > master's > message so it fits in that fixed delay). Similarly, the master can "know" > that your reply will never exceed a fixed duration so it won't issue > another > beacon/request until that has expired.
Or the master can wait to send another message until the reply from the peripheral is complete.
> Hopefully, this makes sense. Sorry, I'm off for a pro bono day so no time > here... :-/
Actually this is poorly thought out. The problem is not with the protocol. The problem is a basic hardware limitation which makes it hard to control the driver enable at the time it is needed. Either you have no understanding of the problem or you just couldn't be bothered to actually respond about the problem at hand. -- Rick
On 10/14/2014 12:28 AM, pozzugno wrote:
> Il 13/10/2014 17:17, Don Y ha scritto: >> On 10/13/2014 4:58 AM, pozzugno wrote: > >> First, you need to *know* that it is *you* that has been granted access to >> the bus/resource. If this requires you to perform some analysis of the >> ENTIRE MESSAGE (to verify that the "address field" is, in fact, intact!), >> then you probably DON'T want to try to ride the coat-tails of the message, >> directly. >> >> As the front end of a message (including yours) is more likely to be >> corrupted >> (by a collision on the bus -- someone jabbering too long or too soon), you >> might consider designing a packet format that has one checksum on the >> address field "early" in the packet (before the payload) and another that >> handles the balance of the message. > > > > This allows you to capture the address information and it's closely > > following > > checksum, verify that it is *you* that are being addressed and prepare > > for your > > acquisition of the bus before the message has completely arrived. > > I have just one checksum at the end of the message, but the address field is at > the beginning. Anyway I look at the address field as it arrives to decide if > it's a frame for me.
Correct.
> I know the address field could be corrupted, but IMHO it's not important. If > the address field is corrupted and appear for me, but the master wanted to talk > to another node, I store the message till the end, but the checksum will be > wrong, so the frame will be discarded. If the address field is corrupted and > it doesn't appear for me, but the master really wanted to talk with me, I > discard early the message.
Also correct.
> IMHO, adding a new checksum at the beginning of the frame, only to protect the > address field, doesn't add more robustness to the final performance.
You haven't indicated how big the payload is. Or, the effort required to create the reply. In your scheme, you MUST deliver a reply as soon as the message from the master is complete (you are free to define "soon"). Verifying the address (as yours AND "intact") lets you know whether or not you have to deal with the payload AT ALL.
>> You can also arrange to access the bus in "timeslots" referenced to some >> easily recognizable event (e.g., a beacon sent by the master). So, >> you do all of your timing off of that single event (see "some special >> point" in the beacon, start timer, wait to transmit until "your slot"). >> >> Note this also works if you just assume the "next slot" after the master's >> message is the slot you should use (you just limit the length of the >> master's >> message so it fits in that fixed delay). Similarly, the master can "know" >> that your reply will never exceed a fixed duration so it won't issue >> another >> beacon/request until that has expired. >> >> Hopefully, this makes sense. Sorry, I'm off for a pro bono day so no time >> here... :-/ > > I think I'll have to think more deeply about this beacon approach. Any useful > info on the Internet?
<shrug> Probably. But, I've not gone looking for it. You might look at some of the token passing algorithms to see (Arcnet?) what they have to say by way of example. The key advantage is that it lets you set up the time at which your reply will be "required" instead of having to "watch carefully" for the end of the immediately preceding transmission (from the master). This lets you deal with bigger time intervals instead of bit-level timing. I.e., recognize the start of the beacon -- because that is usually a more repeatable "event" -- (and it's content) and then IGNORE the serial line until you know it is your timeslot to reply (you don't care what the data on the bus happens to be from the other nodes -- why even receive it?). [Unless you also want to use this scheme to allow the other nodes to be bus masters and directly deliver their messages to other nodes, instead of via the master. I.e., in time slot N, node N can send a message to ANY node (which may be a REPLY to a message sent from that other node, earlier). The master's significance is just to coordinate the timeslots. Note this is far more involved than anything discussed so far] Note that you also know when your timeslot *ends* and the next begins. So, you can turn on the driver for the entire duration REGARDLESS of how long your message is -- subject to the constraint that you know it must fit in the time allotted. And, even before you are ready to transmit! If you are sluggish getting onto the bus... <shrug> No problem. As long as you hit *your* timeslot. I.e., you can be sluggish if you know your reply is short enough to still get out in the time remaining. In other words, you can trade processing time for response time. If you have to digest a complex message from the master, just make sure your expected reply is SHORT: ACK vs. NAK instead of detailed. If you need to deliver a detailed reply, then modify your protocol so that you can get some forewarning of its impending need. E.g., a message that effectively says, "prepare the detailed reply for me" to which you acknowledge (or NOT!) your understanding of the request AND your ability to deliver it (which might require scheduling resources that aren't normally available for that). Then, later, expect to get a message asking for the actual details (that you have presumably "staged" in anticipation of this). [You can also modify the protocol so the master does this in three steps: "Prepare the details" "ACK/NAK" "Are you ready yet?" "ACK/NAK" "OK, give them to me!"] It's just another way to get stuff out of ISR's and into lower priority processing. It also lets you modify the protocol to give everyone a slot (if you have a small number of nodes) instead of having the master constantly prompting everyone (which wastes bandwidth as well as increasing the number of instances where the bus has to be handed off "per unit message exchange") Finally, it allows the master to routinely distribute information that may be pertinent to all nodes (e.g., current system time). I have no idea what your actual communications needs are (you haven't indicated an application, etc.). I offer it as an alternative approach to consider instead of the more obvious "ping-pong" of command-response that you appear to be pursuing. Only you can tell if it has merit in your case. If messages pass between nodes (via the master?) infrequently, then this wastes a lot of time on the bus -- because most timeslots will contain no information (though the corresponding node can be REQUIRED to deliver an acknowledgement if it is important for you to use that as a keepalive/verification that the node is still "up"). Of course, if the master is cyclicly *polling* each of these nodes, then even MORE time is wasted (the time for the individual solicitations and the negative acknowledgements). I use a similar scheme with Ethernet to manage multiple (~120) co-operating hosts and ensure all have "system data" that needs to be delivered periodically (the beacon is a "periodic token") as well as ensuring that the required nodes are "up". [Of course, my nodes can all chat as necessary so it isn't used to arbitrate access to the medium]
>> You should be able to get ~60 second delays. >> >> If you *know* you will always look at a value "more often" than the >> wraparound >> period, you can always *deduce* wraparound trivially: >> >> unsigned now, then; >> >> if (now < then) >> now += counter_modulus; >> >> (effectively) > > I don't think I have got your point.
Assuming the counter counts UP, the only way you can see a SMALLER value than the last one you saw was if the counter wrapped in the time between those two observations. I.e., the "real" value of the counter NOW is actually counter_modulus greater than the OBSERVED value. If you want to know how much time has transpired, it is: now + (counter_modulus - then) i.e., the time from "then" to the counter wrapping PLUS the time from the counter wrapping ("0") to "now".
> I usually use the following comparison to understand if a timer tmr has expired. > > ((uint32_t)(ticks - tmr) <= UINT32_MAX / 2) > > In this way I loose a half of the total period, but it isn't usually a big issue.
>>> With a "software" ticks counter incremented in a timer ISR, it's >>> simpler to >>> calibrate the hardware counter to trigger every 1ms or similar nice >>> values. >> >> Timer IRQ's (esp the jiffy) are a notorious source of problems. > > What do you mean with "jiffy"? Are you naming my approach as "jiffy"? I didn't > understand.
The "periodic interrupt" common in most systems is the "jiffy". <http://catb.org/~esr/jargon/html/J/jiffy.html> <http://lwn.net/Articles/549593/> There are probably better references (I'm pressed for time)
> I'm sorry, I think I completelty didn't understand what you have written :-( > I don't hope you explain again in greater details what you have written, have > you a link to study this "beacon" approach?
Ah, well... <grin> Ignore my previous reply!
>> If it hasn't been said (and, if your environment can accommodate it), you >> might want to look at a different signalling/comms technology that allows >> for a true party-line (resolving contention in hardware). > > Any suggestions?
CAN Off to another pro-bono day. (Boy do I hate mornings!)
On Monday, October 13, 2014 9:02:33 PM UTC+2, upsid...@downunder.com wrote:
> ...you can't get an interrupt, when the last bit of > the last character is actually shifted out of the Tx shift register.
Sure you can, just append N dummy TX bytes where "N" is the TX FIFO depth. But check it on the scope!! Hope that helps, Best Regards, Dave
On 10/14/2014 12:58 PM, Dave Nadler wrote:
> On Monday, October 13, 2014 9:02:33 PM UTC+2, upsid...@downunder.com wrote: >> ...you can't get an interrupt, when the last bit of >> the last character is actually shifted out of the Tx shift register. > > Sure you can, just append N dummy TX bytes where "N" is the TX FIFO depth. > > But check it on the scope!!
That is a very dangerous way to control the driver enable. Most likely the interrupt will happen when the start bit is sent which means the output will already be sending the start bit when the driver is disabled. I think you are worrying about the wrong end of the message. -- Rick
On 10/14/2014 9:09 AM, Don Y wrote:
> On 10/14/2014 12:28 AM, pozzugno wrote: > >> IMHO, adding a new checksum at the beginning of the frame, only to >> protect the >> address field, doesn't add more robustness to the final performance. > > You haven't indicated how big the payload is. Or, the effort required to > create the reply. > > In your scheme, you MUST deliver a reply as soon as the message from the > master is complete (you are free to define "soon").
Really? "MUST"??? All the respondent is required to do is respond before the master times out thinking the respondent is not replying. This timeout should be set as required by system level requirements such as throughput, etc. Don't make this as complex as the things you design.
> Verifying the address (as yours AND "intact") lets you know whether or not > you have to deal with the payload AT ALL.
Who cares?
>> I think I'll have to think more deeply about this beacon approach. >> Any useful >> info on the Internet?
The "beacon" is pointless, don't waste your time with it. It has no advantage over a simple poll/response protocol and in fact is just the same thing with more complication and no added benefit. One point you should be aware of is that your start and end characters can be compromised and the protocol has to deal with that. So consider what happens when they are munged and not recognized. Make sure your protocol is robust to those problems. -- Rick
On 10/13/2014 01:58 PM, pozzugno wrote:

> Of course, other interrupts can be triggered. What happens when > interrupt X (whatever) triggers just before the "transmit complete" > interrupt? The result is the ISR X is called, postponing the execution > of "transmit complete" ISR. The RS485 driver will be disabled with a > certain amount of delay. In the worst case, the driver could be > disabled with a delay that is the sum of the duration of all ISRs that > could trigger.
Try to reduce the time spent in other ISRs.
> > If a node on the bus is very fast and starts transmitting (the master) > or answering (one slave) immediately after receving the last byte, but > when the previous transmitting node is executing other ISRs, the final > result is a corrupted transmission. > > What is the solution? I think the only solution is to define, at the > design time, a minimum interval between the receiving of the last byte > from one node and the transmission of the first byte. This interval > could be in the range of 100 microseconds and should be calibrated on > the sum of duration of *all* ISRs of *all* nodes on the bus. It isn't a > simple calculation.
Instead of calculating, you can also build the design, and then measure how long it takes and adjust the timeout value until error rate is sufficiently low. I'm assuming that error rate > 0 is acceptable.
> > Moreover, implementing a short "software" delay in the range of some > microseconds isn't a simple task. An empty loop on a decreasing > volatile variable is a solution, but the final delay isn't simple to > calculate at the design time, and it could depend on the compiler, > compiler settings, clock frequency and so on. Use an hw timer only for > this pause?
Use a hardware timer, but it doesn't have to be just for this purpose. Often, you can still use match interrupts on a free running timer, you just have to adjust the match registers after each interrupt. I do this all the time. Keep in mind that the receiver also needs to process the incoming packet, verify checksums, and prepare a response. You can use the dead time for that.
> > How do you solve this problem?
Use a better microcontroller ?
On 10/13/2014 11:50 PM, pozzugno wrote:
> Il 13/10/2014 17:06, Don Y ha scritto:
>> No, what you are most concerned with is ensuring every ISR manages to >> terminate before it can be reinvoked. >> >> So, ISR1 can be interrupted by ISR3 which can be interrupted by ISR7 >> which can be interrupted by ISR2, etc. AS LONG AS ISR1 can't reassert >> itself while ANY instance of ISR1 is still "active". >> >> (Ditto for every ISR in the system) >> >> Even this "rule" can be bent -- if you know the worst case nesting of ISR's >> on themselves (and ensure you have adequate stack to cover that level of >> penetration) > > IMHO it's a critical approach. In order to let the immediate "transmit > complete" ISR (TXC), I have to re-enable interrupts inside all the other ISRs. > > So ISR A could be interrupted by ISR B even if I don't interested in this, just > because ISR A must be interrupted by ISR TXC.
You're stuck with this problem because you are forcing processing and timeliness constraints into the ISR's. An ISR should *only* do what it ABSOLUTELY MUST. "In and out", lickity split! Your description SUGGESTS that you are implementing your comms system in a state machine something at the RxIRQ level like (pseudocode): GetCharacter: retrieve character from comms hardware note error flags associated with this reception if any error, do some sort of error recovery/logging (or, do state specific error recovery, as appropriate) ret AwaitSoH: header = GetCharacter() if (header != Start_of_Header) diagnostic("SoH not received when anticipated") // leave RxIRQ as is; remain in the state awaiting SoH else set_RxIRQ(SoHReceived) return from interrupt // the above assumes SoH doesn't occur in a message body. If it // does, then you revisit this state occasionally as you sync up to // the data stream SoHReceived: address = GetCharacter() if (address != MyAddress) diagnostic("message APPARENTLY not intended for me") set_RxIRQ(AwaitSoH) // a simplification, for illustration else message_length = 0 // prepare for payload to follow InitializeChecksum(address) set_RxIRQ(AccumulateMessage) return from interrupt AccumulateMessage: datum = GetCharacter() buffer[message_length++] = datum UpdateChecksum(datum) if (message_length > MESSAGE_LENGTH) set_RxIRQ(AwaitChecksum) return from interrupt AwaitChecksum: checksum = GetCharacter() if (Checksum != computedChecksum) diagnostic("message failed integrity check") error else parse message (unless you've been doing this incrementally) act on message prepare result wait until master has turned off its bus driver turn on your bus driver and transmitter (or, have the scheduler do so) schedule your reply for transmission set_RxIRQ(AwaitSoH) return from interrupt [Note that you may, instead, have folded all of this into one static RxIRQ by conditionally examining a "state variable" (byte counter?) and acting accordingly: if (byte_count == 1) check if correct header else if (byte_count == 2) check if correct address else if (byte_count ... I manipulate the interrupt vector instead as each little ISR "knows" what the next ISR should be so why introduce a bunch of conditionals?] And, your TxIRQ (once the reply has been scheduled): TxIRQ: SendCharacter(buffer[message_length++]) if (message_length > MESSAGE_LENGTH) set_TxIRQ(ShutdownTx) return from interrupt ShutdownTx: wait until last character cleared transmitter (NOT holding reg)! wait until line has stabilized (bus driver) turn off bus driver set_TxIRQ(none) return from interrupt [Of course, message lengths can vary between Tx and Rx, etc] So, all of your IRQ's are lightweight. EXCEPT the "AwaitChecksum" state. There, you have to do a fair bit of processing ON THE HEELS OF the final character in the master's transmission (you could add an additional "trailer" but that's just more characters to receive and process and doesn't fundamentally change the algorithm). The delays ("wait until...") are all relatively short. Yet, not necessarily "opcode timing" short. So, you sort of have to sit around twiddling your thumbs until you think you've met the required delays (you can't make any *observations* to tell you when the time is right... when the master has turned off its bus driver, etc.) Or, throw some hardware resource at the problem (small interval timing) All of that waiting wants to be done OUTSIDE the ISR. Yet, you can't afford for it to be unbounded -- because your master no doubt expects a reply in *some* time period else a dropped message would hang all comms! (and it probably uses a lack of reply to indicate a failure of your node) I.e., there are LOWER and UPPER bounds on when you can start your reply. Too soon and you collide with the the tail end of the master's transmission; too late and you risk the end of your reply running into the master's *next* transmission. [Or, you can add a timer to the master so that it doesn't start its next transmission until it is *sure* you are finished transmitting] Likewise, all of the *processing* that isn't time critical (or, SHOULDN'T be!) wants to happen outside the ISR. If, instead, you could note the time at which a "request" from the master was sent and use that as a reference point from which to determine when you would have a CHANCE to deliver a reply ("timeslot"), then you can do all of this processing AND waiting outside of the IRQ. [If you force that time to be JUST the duration of the master's message, then you don't have any real leeway -- you have to act promptly! You're stuck with your present dilemma.] For example, assume you have a 1ms periodic interrupt (change to suit your needs). Assume you are delivering data at 9600 baud (change to suit your needs). Assume messages from the master are M characters long. [I've chosen numbers that make the math relatively easy so you don't have to dig out a calculator. Changing the values just changes the math. I.e., characters are arriving roughly at the same rate as your periodic interrupt -- though they aren't guaranteed to be in a particular phase relationship with it. (this is not a requirement of this approach, just a coincidence for the numbers I have chosen)] On a particular node, you notice a "SoH" received sometime between periodic interrupt S-1 and S (because you modify your AwaitingSoH ISR to signal an event that you can then examine -- or, let it capture the "periodic counter" *in* the ISR and post that time value as the "event"). You KNOW the master's message will not be complete until at least (S-1)+M but definitely before S+M -- because you have *designed* to this goal! Furthermore, you know that your timeslot is offset X ms from the StartOfHeader in the master's message (i.e., time ~S). You KNOW that you can't safely turn on your bus driver until S+X (because those are the rules of the protocol) but you *do* know that the master will have turned his bus driver off by then (because it is following the same rules!) So, you schedule a job that turns on your bus driver at S+X and pushes *a* reply onto the bus. *A* reply. This need not be *the* reply to the message from the master sent at time S! It may, instead, be a reply to the message sent by the master at the *previous* "time S". Or, the one before that! Instead of tail-gating the master's message and trying to reply as soon as the last character in its message has cleared the medium (or, some epsilon later), you decouple your replies from the master's requests. With the timeslot, you *know* you can send a reply EVEN IF THE MESSAGE FROM THE MASTER IS NOT FOR YOU! I.e., you dont have to check the address, decode the message, act on it AND compose your reply *now*. Likewise, other nodes know that they can send THEIR replies even when the current message is for *you* and not them! You just support some number of outstanding messages to each node (perhaps just "1" but bigger numbers are better) and tag them with a (small) sequence number -- so the master can pair replies to outstanding requests AND so you can see when the master has given up on an "old" request that you perhaps forgot to acknowledge. [E.g., you can conceivably reply to message 2 before replying to message 1 -- if that makes sense in your current execution environment. If not, then Reply2 has to wait to be scheduled until Reply1 has been sent. You are free to arrange those criteria as fits your processing capabilities. You don't HAVE TO reply to the message *now*.] Note that this can be scaled by supporting a smaller number of timeslots than there are physical nodes in the system -- the master can allow nodes (1 - Q) to use the Q timeslots following *this* message (before it issues the NEXT message) and the (Q+1 - 2Q) nodes to use the Q timeslots following the NEXT message. The point is, each node knows AHEAD OF TIME when it can reply (when it can turn on its bus driver) instead of having "very little notice" and having to react promptly. It also allows the nodes to know that communications are "fair" and "deterministic". Any node knows how long it must wait before it is *guaranteed* a chance to access the medium. (if there was no guarantee, then nodes wouldn't have been able to PREDICT when they should acquire the medium and place their messages on it) You've moved the: parse message (unless you've been doing this incrementally) act on message prepare result steps from the ISR into a lower priority task where you, presumably, have more leeway in addressing those needs (than you would in an ISR that wants to be short!). *All* of your ISRs are now short (because they just empty the receiver or stuff the transmitter and don't do any *decoding*, processing, etc.) RxIRQ: datum = GetCharacter() FIFO <- (datum,timestamp) return from interrupt Something else watches the FIFO to try to identify messages within. When it does, it knows when the message began (because of the timestamp on that datum) so it can figure out when a reply *should* be scheduled -- even though the reply might not be the reply for this message. Instead of having to deliver a response *NOW*, your protocol moves the time that you are granted to fabricate a response out of the low level "driver". You could conceivably allow different timeouts for different types of messages, etc. And, because you know when to expect a message from the master (even if it is not for you!) -- because the protocol has the master sending a message followed by Q reply timeslots -- and when, relative to that, to present your reply, the timing of the bus arbitration is decoupled from the immediacy of a particular "Rx IRQ". You're not trying to accurately time/delay "character times", "bit times" or smaller. You, instead, rely on a timebase that you already have in place. Making timing decisions in a more tolerant environment (including, potentially, the enabling and disabling of the bus driver) If you look at higher performance "packet protocols", you will tend to see this same pattern repeated. I.e., you don't send an ethernet message and expect the receiving interrupt on the destination node to prepare and deliver a reply! Nor do you expect the sending node to twiddle its thumbs awaiting that reply; nor the reply to message 1 before it sends message 2 (to you *or* some other node). You just have to agree, ahead of time (i.e., protocol specification!) how long you are willing to wait for old acknowledgements and how many you are willing to let remain outstanding at any given time. This defines the time you have to "handle" a particular message; NOT some artifically tight constraint IN an ISR. Then, "do the math" for your particular periodic interrupt rate and data rates (and message lengths, node counts, etc.) so you can ensure each node gets serviced in a timely fashion. The point isn't to maximize throughput but, rather, to be able to provide *guarantees* without overspecifying hardware or needlessly tightening constraints on the software. This turns a hard real-time approach (where missing a deadline means you simply abandon the action that you were attempting) into a softer one with more flexible deadlines (where missing a deadline doesn't render the effort "wasted" but, rather, salvageable at some possibly reduced "value", at a later time). Otherwise, you "must" reply to this message now. And, if you can't, what makes you think you will be able to the *next* time it is sent to you (i.e., as a "retry")? Your implementation is "more brittle". (what happens if some node needs an ISR for some other capability and that ISR interferes with your TIMELY processing of "this" message?) [I currently use a variation of this "over ethernet" (where it isn't necessary) in anticipation of porting the design to a wireless implementation (where folks can't all "talk at once" yet deterministic delivery is required). I.e., "bus driver" in my case is "RF transmitter"] *Think* about this sort of implementation... what it means/costs in your hardware. Put ballpark numbers on how much time it allows slaves to handle messages, etc. Decide what the impact on the devices (master?) making those requests might be: e.g., if they BLOCK until they get a request (and no other processing CAN occur on that node), then you would want to favor more prompt responses. OTOH, if you can do meaningful work while awaiting a reply, then the impact of a delayed reply is minimized. I reviewed a colleague's implementation of a product a few weeks back that had several CAN nodes collaborating on the services provided. Every message request he sent out, I asked: "What happens if you NEVER get a reply to this? What happens if the reply is delayed? Is this node effectively *stuck* in that get_reply() for the duration?" And, eventually: "Ahhhh... so that's why you are doing all this work in your ISRs that one would more safely do elsewhere -- less precious! Can't risk things catching fire while you're waiting for a reply!"
On 14/10/14 20:20, rickman wrote:
> On 10/14/2014 12:58 PM, Dave Nadler wrote: >> On Monday, October 13, 2014 9:02:33 PM UTC+2, upsid...@downunder.com >> wrote: >>> ...you can't get an interrupt, when the last bit of >>> the last character is actually shifted out of the Tx shift register. >> >> Sure you can, just append N dummy TX bytes where "N" is the TX FIFO >> depth. >> >> But check it on the scope!! > > That is a very dangerous way to control the driver enable. Most likely > the interrupt will happen when the start bit is sent which means the > output will already be sending the start bit when the driver is disabled. >
It can often work fine - at worst, the receiver sees a brief noise at the end of the telegram itself, and that is easily ignored. However, if you are worried that the "transmission complete" interrupt might be delayed too long, then clearly the same thing will apply to the final "transmit character" interrupt for your extra character. So it is a useful trick if you don't have a "transmission complete" interrupt signal, but not for the problem at hand here.
> I think you are worrying about the wrong end of the message. >
On 10/14/2014 5:35 PM, David Brown wrote:
> On 14/10/14 20:20, rickman wrote: >> On 10/14/2014 12:58 PM, Dave Nadler wrote: >>> On Monday, October 13, 2014 9:02:33 PM UTC+2, upsid...@downunder.com >>> wrote: >>>> ...you can't get an interrupt, when the last bit of >>>> the last character is actually shifted out of the Tx shift register. >>> >>> Sure you can, just append N dummy TX bytes where "N" is the TX FIFO >>> depth. >>> >>> But check it on the scope!! >> >> That is a very dangerous way to control the driver enable. Most likely >> the interrupt will happen when the start bit is sent which means the >> output will already be sending the start bit when the driver is disabled. >> > > It can often work fine - at worst, the receiver sees a brief noise at > the end of the telegram itself, and that is easily ignored. > > However, if you are worried that the "transmission complete" interrupt > might be delayed too long, then clearly the same thing will apply to the > final "transmit character" interrupt for your extra character. So it is > a useful trick if you don't have a "transmission complete" interrupt > signal, but not for the problem at hand here.
Is all of this based on the idea that the transmitter empty interrupt is not valid in some way? -- Rick