Sign in to follow this  
Followers 0
yyrkoon

UART - Sending 3 bytes per start/stop bit sets.

25 posts in this topic

So, in case it's not already obvious. I'm very green on the subject. So if my terminology is off, please understand.

 

Anyway, I have a need to communicate via UART at 1200 baud, but I need to be able to send "packets" in the range of 2-3bytes per start / stop bit set. This is basically a UART to level converter, where the output is sent out over a bus of sorts. Where the devices connected to this bus only recognize "packets" sized 2, or 3 bytes in length.

 

It is my hope that I can use the existing hardware drivers, in Linux to do this. As bit banging this "protocol" would/ could turn into a serious hassle.

 

What I need to know however is: Is this possible ? What are the term(s) I should be searching for on the internet, as far as sending 2-3 byte "packets" ?

 

Going to add links as I go so others have reference material as well if ever needed.

 

LINKS:

 

Can Raspberry Pi reliably bit bang a 9600 baud serial and is there example code? http://raspberrypi.stackexchange.com/questions/1987/can-raspberry-pi-reliably-bit-bang-a-9600-baud-serial-and-is-there-example-code

 

Bit Bang GPIO UART from Linux Kernel https://www.ctrlinux.com/blog/?p=154

Share this post


Link to post
Share on other sites

I can't say I've ever seen a UART with 24 bits of data. I have seen 9 bit but that was the max.

 

Maybe you can use the spidev peripheral to send the data.  I had some sample code that used spidev to send data that was actually a wave form for those ws2811 leds.  

 

https://github.com/RickKimball/beaglebone/tree/master/ws2811_spi_test

 

-rick

yyrkoon likes this

Share this post


Link to post
Share on other sites

I can't say I've ever seen a UART with 24 bits of data. I have seen 9 bit but that was the max.

 

Maybe you can use the spidev peripheral to send the data.  I had some sample code that used spidev to send data that was actually a wave form for those ws2811 leds.  

 

https://github.com/RickKimball/beaglebone/tree/master/ws2811_spi_test

 

-rick

Well, I know there are devices out there that do this protocol. However, the one guy I've talked to from a company who produces some of these devices says they use a specific micro controller to bit bang 16 and 24bit serial. Sorry, but I can not get any more detailed than that( NDA ).

 

I can say the protocol is DALI( two byte ), and extended DALI(3 byte ).

 

Anyway Rick, my buddy says he read somewhere in the am335x TRM( yeah all glorious 5k pages worth of it ) that UART4 is a special UART in that not only does it do RS485 UART, but supposedly it has a variable width shift buffer. He says it's 8, 16, and pretty sure it's 24bit capable. I've browsed through the UART section of the TRM, which is around 100 pages, but found nothing specifying that. Only that the RX, and TX FIFO's are capable of up to 64bytes. BUt that's for every UART.

 

UART4 is supposed to be a different module to the rest, having something like a 16550 serial module while the others are 8250's ? I'm not exactly sure what that's supposed to imply other than UART4 is also able to use CTS and RTS lines . . .

Share this post


Link to post
Share on other sites

@@Rickta59

 

Oh, and if i did have to "invent" something by bit banging . . . I'd probably go with using the PRU's. I mean I might as well right. Seems like it would be a bit simplier than writting a UART bit bang LKM. Where the CPU would also see additional traffic, regardless if it's kernel space versus user space.

 

EDIT:

 

AH ! keep forgetting what I've found out so far. There is an MSP430 TI example project that does limited DALI. I've also found code for another micro that seems to do DALI as well. But neither one as far as I can tell use extended DALI. I do have the extended DALI specification in PDF format, but unfortunately I've been told that every company under the sun who implements their own extended DALI commands. Also have their own specification(s) for their device(s). So it's not really a specification so much as a set of guidelines.

Share this post


Link to post
Share on other sites

Another thing I found rather comical today when talking to a person I know.

 

Him: "What do you mean you can't bit-bang gpio serial from Linux user space? . . ."

 

To which I mentioned that the lowest guaranteed latency of any API call under Linux is not very deterministic at all. At best, we're talking 10's of milliseconds using an RT enabled kernel. Worse case it can be as high as 100's of milliseconds.

 

He then pulls up the ominous google search page . . .

Him: "Well, you obviously do not know what you're talking about, because here is a guy doing exactly that on an rPI using Python . . ."

 

At which point I had to leave the conversation. As any programmer knows that first, bit-banging *anything* is going to be CPU intensive by comparison. Then the more CPU you're using, the less deterministic your code will end up being. Passed that . . . Python ? Really ?! We're talking about a serial interface that needs to be at least reasonably deterministic. At least to the point where you're able fulfill your baud rate, and then act on that data. Python for a couple of reasons is not up to that task. First, while Python *could* potentially be compiled into native code . . . Python is an interpreted language. It's going to be comparatively a lot slower than C, depending on the task, it'll use a lot more CPU doing so, and while being huge, again in comparison. Lastly, as far as scripting language performance goes . . . Python often is the worst. Even Javascript( googles V8 engine / Nodejs ) routinely gives it a beating performance wise. That, and I do not even consider Javascript / Nodejs very performant. Often times, it is fast enough, but I'd honestly never consider using it for driver code . . .

 

Granted there are a few caveats of course. Using mmap() along with /dev/mem could potentially speed things up greatly. But you're still going to be using CPU cycles to get where you want. Also while writing such an app, you'd have to be very careful which system calls you made. Something such as a single printf() call, could cripple the application. Cutting performance drastically. Threading, and Semaphores would also be out of the question. Especially on a single CPU core system such as the beaglebone black.

 

In my own case, I won't be just fulfilling my baud rate expectation with enough leg room to act on that data. There will be a multi GPIO, PWM, and MQTT system in place. That is, in addition to the "bit-bang" serial code. If, in fact I have to truly bit-bang serial at all. Using SPIDev for this purpose looks promising, thanks Rick ! Not to mention I always have a couple of PRU's to fallback on, for which they were built specifically for this sort of situation. Bit-banging. . .

 

The moral of my story here ? Simply that just because something *may* be possible. It does not mean that this *something* is a good idea.

spirilis likes this

Share this post


Link to post
Share on other sites

You're clearly deep into this, so I don't know if this fits.....

What about programming an MSP to do that protocol in real time, then have it communicate up to the Linux box as required?

As I've never heard of that 16/24 bit scheme you mentioned, I'd be absolutely no use progressing this idea further!

Cheers,

yyrkoon likes this

Share this post


Link to post
Share on other sites

Hi,

in the data sheets of some PIC uC (PIC18F13K50, for example), in the description of the EUSART synchronous mode, there is specified:

 

Start and stop bits are not used in synchronous transmissions.

Maybe it is what you are looking for?

 

Regards,

Liviu

yyrkoon likes this

Share this post


Link to post
Share on other sites

Why don't you just set up a timer interrupt and implement the fancy 16/24 bit UART using software running in the interrupt?

 

If you're using 1200baud, that's 1 bit every 833uS. On a MSP430 running at 8MHz, that's one interrupt every 6000 clock cycles (8000000/1200 = 6000). If your interrupt routine takes an average of 100 cycles to complete, you're using 1.5% of the CPU cycles for the UART (((1200 * 100) / 1000) = 0.015).

 

Recall that the original MSP430 LaunchPad shipped with the MSP430G2231 which does not have a hardware UART peripheral, so all the serial port examples for it were using a bit bang driver. It should be very trivial to look through the existing examples for software UARTs for the LaunchPad and find one you like that you should then be able to modify the bit counter to send 16 or 24 bits instead of 8.

dubnet, yyrkoon and spirilis like this

Share this post


Link to post
Share on other sites

Why don't you just set up a timer interrupt and implement the fancy 16/24 bit UART using software running in the interrupt?

 

If you're using 1200baud, that's 1 bit every 833uS. On a MSP430 running at 8MHz, that's one interrupt every 6000 clock cycles (8000000/1200 = 6000). If your interrupt routine takes an average of 100 cycles to complete, you're using 1.5% of the CPU cycles for the UART (((1200 * 100) / 1000) = 0.015).

 

Recall that the original MSP430 LaunchPad shipped with the MSP430G2231 which does not have a hardware UART peripheral, so all the serial port examples for it were using a bit bang driver. It should be very trivial to look through the existing examples for software UARTs for the LaunchPad and find one you like that you should then be able to modify the bit counter to send 16 or 24 bits instead of 8.

 

There are several caveats to the whole story here. What you're saying certainly intrigues the hacker / maker in me. I think cost wise, it makes more sense to use the on board PRU's. However with that said maybe short term an MSP430G2231 could be used. We will have to discuss it here internally. Our cape design has to be finalized today, but there are provisions to use either or, via on board jumpers.

 

So to all wondering about this protocol -> https://en.wikipedia.org/wiki/Digital_Addressable_Lighting_Interface I can not really put it better than that probably. However, that is the original specification, which does not include the 3 byte "command protocol". Or extended DALI. Also do keep in mind I'm not an expert, I'm still learning myself. I've just been lucky enough to be able to talk directly to a person who was involved in implementing the extended DALI spec. Unfortunately he's a project designer by trade, not a programmer . . . or EE, but he has helped fast track my learning a good deal. 

 

 

I'll keep posting more on this subject as I go on, but I may not be able to talk about some aspects of the project. As I am getting paid to do this, for a project in whole that I've agreed to an NDA on. However, I have absolutely zero qualms relaying what I found, and how I went about implementing things in general. As what I'm going to have to do, specifically, has not been "shared" yet on the internet that I've found. There are tons, and tons of devices out there that do original DALI. One from Microchip, one from Atmel( hey they're both the same company now ! ). Unfortunately they won't work for extended DALI protocols which we're trying to use a sensor that is extended DALI communications only.

 

One of the cooler aspects of this problem to be solved. Is that I only have to implement transmit. I should be able to reassemble receive bytes very easily.

Share this post


Link to post
Share on other sites

@@USWaterRockets

 

I think in fact we may end up using an MSP430 as a "uart buffer converter".

 

Here is the problem with using the PRU(s).

 

We're using roughly 31 pins from the beaglebone already. The PRUs have single cycle access to only a few pins. Let us just say 16 for PRU0 and 14 for PRU1. The actual pin count for each PRU is pretty close but maybe not 100% accurate. But for argument sake assuming I'm dead on correct. Many of the pins the PRUs have single cycle access to are already in use by our cape, or by the Beaglebone its self for things such as the on board eMMC, etc. 

 

With the above said, the PRUs *can* access every single pin, and most if not all peripheral modules on the am335x processor. However, most of these pins are connected to the PRUs via the L3 interconnect fabric. 833uS seems perfectly reasonable, in that I should still be able to access pins over the L3 interconnect quickly enough. But I'm not exactly sure of the latency that will be introduced( I'm thinking in the ~100uS range ). However I'm not sure if this latency would be deterministic enough to create a timed set of routines from. So in short term, for now, I think it's best to stick with something that's been well documented by others.

 

Because of blogposts like this: http://www.msp430launchpad.com/2010/08/half-duplex-software-uart-on-launchpad.html where the person actually describes the implementation in a very detailed way. Granted the uart speed in the code from the link here is based on SMCLK, which is not something I think is necessarily a good or even bad thing. As I know with Energia, the software timing is configurable. At least I think it is( from memory - been a few of years ). Anyway the code from the link above *seems* fairly trivial.

 

So for now I'm still feeling like I'm in over my head. However, it still feels like something I am perfectly capable of achieving with a bit of research / reading. Then later perhaps on my own I'll get to know the PRUs good enough to bit bang 1200 baud 24bit uart ? It'd definitely be a cool project to relate to both this, and the beaglebone communities in form of an exact steps blogpost, or something similar. As this, is exactly what the PRUs were designed for. Granted, this would not exactly be high speed bit-banging. But probably a good introduction for someone wanting to get experience with the PRUs.

 

I was also looking through a few of Jason Kridner's git projects I found through a google search yesterday. That somehow used the PRUs ( or so it seems ) that also has software PRU uart's built int. The project name is PRUDUINO, uses bonescript, and other software projects. However I've yet to find the actual PRU soft UART implementation . . .  too much code to wade through, for now.

Share this post


Link to post
Share on other sites

@@yyrkoon

 

Don't overthink the solution.

 

Try bit banging the protocol and see how it goes. If it solves the problem then you're done.

 

"Good enough is the enemy of perfection." 

yyrkoon likes this

Share this post


Link to post
Share on other sites

@@yyrkoon

 

Don't overthink the solution.

 

Try bit banging the protocol and see how it goes. If it solves the problem then you're done.

 

"Good enough is the enemy of perfection." 

Hi Zeke,

 

The problem is not whether to bit-bang or not. The question is how. The project we're using involves Linux, and a bunch of software all tied together with much of it being "busy". So it's not something that could done reliably or even should be done in user space. I'm not even convinced that it would be wise to do this in kernel space. As is would also use CPU time.

 

So we're talking some sort of external processor( a pure hardware solution ). As it stands I'm pretty sure I'm simply going to make a uart bit conversion buffer with a 2553. Linux interface will be dead simple, with nothing extra to write driver wise. It'll be connected to the harware UART pins on the G2553. Dead simple RS232 connection to UART4.

 

The only thing I'm not 100% sure of right now, is *if* I need to use specific pins for my software UART. Last night I was thinking it had everythign setup fine, but this morning I was reading an article where someone said that you need a capture pin ? I figured GPIO interrupts would be fine, and maybe it is ? For receive that is. TX should not present a problem.

Share this post


Link to post
Share on other sites

Hi Zeke,

 

The problem is not whether to bit-bang or not. The question is how. The project we're using involves Linux, and a bunch of software all tied together with much of it being "busy". So it's not something that could done reliably or even should be done in user space. I'm not even convinced that it would be wise to do this in kernel space. As is would also use CPU time.

 

So we're talking some sort of external processor( a pure hardware solution ). As it stands I'm pretty sure I'm simply going to make a uart bit conversion buffer with a 2553. Linux interface will be dead simple, with nothing extra to write driver wise. It'll be connected to the harware UART pins on the G2553. Dead simple RS232 connection to UART4.

 

The only thing I'm not 100% sure of right now, is *if* I need to use specific pins for my software UART. Last night I was thinking it had everythign setup fine, but this morning I was reading an article where someone said that you need a capture pin ? I figured GPIO interrupts would be fine, and maybe it is ? For receive that is. TX should not present a problem.

The idea is to have the RX pin just happen to be one of the pins with a Timer_A association capable of doing capture, preferably a TA0.1 or TA0.2 or TA1.1 or TA1.2 type of thing.  Not sure if it would work with TA0.0 or TA1.0.  Then you can use the timer to capture the moment of transition for that pin which should assist in detecting pulses.

 

I've never written a software UART myself so I'm not sure what all is involved, but that one little piece I do know.  It might also be beneficial to have the TX pin going to another TA0.[1+] or TA1.[1+] pin too for output but I'm not 100% sure.

yyrkoon likes this

Share this post


Link to post
Share on other sites

@@spirilis

 

Hmm the datasheet is the only place to find that information ?

yep-

(Page 3, Device Pinout)

post-15991-0-40599600-1478288837_thumb.png

See how (in the 20-pin variant) pin 9 says "P2.1/TA1.1" ... Timer_A1 CCR#1 is its alternate function (with P2SEL |= BIT1, P2SEL2 &= ~BIT1)

 

Also P2DIR needs configuring (P2DIR &= ~BIT1) to make it an input (CCI):

(page 51, Port 2 schematics)

post-15991-0-74884100-1478288973_thumb.png

yyrkoon likes this

Share this post


Link to post
Share on other sites

yep-

(Page 3, Device Pinout)

attachicon.gifg2553_pinouts.png

See how (in the 20-pin variant) pin 9 says "P2.1/TA1.1" ... Timer_A1 CCR#1 is its alternate function (with P2SEL |= BIT1, P2SEL2 &= ~BIT1)

 

Also P2DIR needs configuring (P2DIR &= ~BIT1) to make it an input (CCI):

(page 51, Port 2 schematics)

attachicon.gifg2553_port2cfgtable.png

As luck would have it. Wulf already designed the board with the two P1 TA.x pins in mind, Intentionally ? I don't know . . . but going back to what you mentioned either about TXD. From what I've read, one does not need this functionality for TXD. I'm not sure the person I read this from said why, but I figured since we have full control of TXD already ( not arbitrary like RXD per se ), one would not need this functionality. But hey . . . I'm newb . . . Seriously.

 

EDIT:

 

D'oh! Those were the hardware UART pins heh. SO looks like I need P1.5 for RXD.

Share this post


Link to post
Share on other sites

As luck would have it. Wulf already designed the board with the two P1 TA.x pins in mind, Intentionally ? I don't know . . . but going back to what you mentioned either about TXD. From what I've read, one does not need this functionality for TXD. I'm not sure the person I read this from said why, but I figured since we have full control of TXD already ( not arbitrary like RXD per se ), one would not need this functionality. But hey . . . I'm newb . . . Seriously.

yeah, I can imagine you don't need the timer for output, since the CPU can time its execution as needed based on interrupts or polling a timer and just manually flip the GPIO.

yyrkoon likes this

Share this post


Link to post
Share on other sites

So this is one case were Rei Vilo's Launchpad pic fails. But I use it almost exclusively for everything else.

Share this post


Link to post
Share on other sites

 

D'oh again ! I was looking in the MSP430x2xx Family use;s guide . . . About as terse reading as the beaglebone's am335x's TRM, but only 1/10th the size( in pages ).

 

So probably as everyone can see, I'm a bit flustered at the moment. I'm still a bit confused, and Wulf is trying ot finalize his schematic while I'm having to change stuff as I figure it out . . .and I'm still not 100% sure this whole deal will even work. It should, but I was also sure that talking directly from the beaglebone's uart to the DALI level converter was going to work too . . .

Share this post


Link to post
Share on other sites

So, I found an appnote from Microchip that has a very good explanation from a programmers standpoint. Honestly I could care less about the electrical characteristics . . . so long as I can figure out what I need to know. Link: http://ww1.microchip.com/downloads/en/AppNotes/01465A.pdf

 

Starting on page 4 it shows what a DALI packet should look like. Extended DALI, is exactly the same. Except the data byte would be 0x0h(always) with an additional third byte at the end.

 

I've up until now misunderstood the protocol. Which is why it would have been better to talk with an Engineer instead of a Designer. First it's Manchester encoding. Which means bit's are formed by rising or falling edge signals within a bit frame. Second, there are two stop bits at the end of transmission, not one. Which from a programmers standpoint is about the same thing. The signal just need to be high for two bit frames in a row is all. Instead of just one.

 

The rest I understood, as far as what each bit's purpose was. etc.

 

More on all this later . . . I need to work out in my head how and if this will change things. On the surface to me, this seems that because of the encoding, it's very close to, but deceptively different from standard UART. Encoding according to the appnote seems to fairly trivial. Decoding on the other hand seems a good bit more complex.

Share this post


Link to post
Share on other sites

For Manchester decoding (not on micro controllers, on other equipment), I've measured the time distance between consecutive edges. If the distance is half of the bit length, the last bit is repeated, if the distance is the bit length, the last bit is inverted.

If you use in interrupt to detect the falling edge and to start a timer, and as you know the first (start) bit is a zero, detecting the next bits shouldn't be to difficult.

yyrkoon likes this

Share this post


Link to post
Share on other sites

For Manchester decoding (not on micro controllers, on other equipment), I've measured the time distance between consecutive edges. If the distance is half of the bit length, the last bit is repeated, if the distance is the bit length, the last bit is inverted.

If you use in interrupt to detect the falling edge and to start a timer, and as you know the first (start) bit is a zero, detecting the next bits shouldn't be to difficult.

I get what you're saying, but at the same time I don't. E.G. What you're saying makes perfect sense to me in English, but working it out into code in my head . . . will take some doing ;)

Share this post


Link to post
Share on other sites

makes perfect sense to me in English

Strange, I was thinking the English is my week point... :D

What I tried to say is, if you look the diagram at page 4 in the Microchips AN, you'll see that every time the bit value changes (0->1 or 1->0) you don't have a transition at the end of bit, but if the bit repeats, you have a transition in the middle of the bit (the active one) and one transition at the end of bit.

But looking now to the same diagram, I see now that if you can detect the start edge (first H->L transition), there are maybe better criteria to decode the bits.

yyrkoon likes this

Share this post


Link to post
Share on other sites

For now, this project is on hold, and may not continue. After I've spent some time researching this protocol, we've come to the conclusion that there has to be a better way.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0