I have a pipe organ controller project that I inherited that mixes 9 and and 8 bit data. It was originally written for 8051. The coms are half duplex RS485. The protocol is sort of a corruption of MIDI. There are 128 bits on each input board connected to a shift register for 16 bytes of storage per board. There can be up to 15 input boards. The organs I work with typically have 5 or 6 input boards. So what happens is that when a board is scanned the data is sent to the remote listeners by sending in 9 bit mode the sequence 0x19x where x is the number of the board. After the ID byte 16 data bytes follow which are the shift register data. This sort of maps into into a bastardized MIDI channel but at high speed as the baud-rate is 500000. This sequence repeats every .025 seconds Which I think is 25 milliseconds. The data transfer happens in the first 5 milliseconds and the other 20 milliseconds are used for processing time. (Playback record, user interface etc.) There is a 0x1C0 sync mark sent after the 0x19F marker which contains multiplexed output data to the listeners in the pipe chamber. Each rank of pipes (61 to 98 notes) has a processor working simultaneously. It is not unusual to have a polyphony of 25 or 30 which gives the pipe organ it's unique sound. (there are other codes sent with the 9th bit set that are used for data setup, checksums, etc. The lengths of the data that follow are fixed.)
In the 8 bit world of AVR this works great. One enters 9 bit mode then when the 0x19x is received it then goes into 8 bit mode and saves the data in a 256 byte array. With a simple 'Arduino' I can convert this data to MIDI or other note event data, with a xor on a second buffer. In the Arduino IDE it is possible to set the UART registers with code to set the serial data to 8 or 9 bits with an assignment. Due to the limitations on the Mega138 'Arduino' I have taken to bit banging the transmission side of this protocol as there is only one serial port, which I use for a backchannel to a terminal program or the user interface. I also bit bang the shift register as the SPI bus is used for the SD card.
I have been studying up on 9 bit mode on the Stm32F4 series (which is the processor I want to be a listener slave on this network.) What I am not sure about is how one switches the reads from 9 to 8 bits. The data lengths are fixed, so I would like to use DMA for the transfer of the 16 bytes. So the system would send a request to read one 9 bit data word, then wait for the callback. The callback would then send a request to read the 8 data bytes.
Question is, that if one is using HAL as the underlying layer how does one reset the data between 8 and 9 data bits. The online forum traffic on this is unclear, most wanting to use the multiprocessor address mode.
I could of course connect the STM32F4 directly to the Shift registers which are also RS484 buffered. The chip used is a MAX490 which has two half duplex channels one for transmit and one for receive. There are 3 of these chips on a master board. In reading the data sheet, it looks like a level shifter is needed as the wire can be as much as 12 volts on the pair side, with the Max490 logic side at 5V. If I connect the STM32F4 as a listener on the RS485 bus I only need one level shifter.
Mix 9 and 8 bit data on UART
Re: Mix 9 and 8 bit data on UART
My guess will be you need to change the WordLength fields in the uart handle (UART_HandleTypeDef )
But don't know if this will work on the fly.
Code: Select all
huart->Init.WordLength = databits;
Re: Mix 9 and 8 bit data on UART
From the muddled discussion in the other groups this is the wrong approach due to the way DMA works. The system expects to fit 9 bits into two bytes, but the registers are 4 bytes. Timing is what is the critical path here. That one has in effect 1 frame between the 9 bit data and the 8 bit data. So that in effect all data seen by the hardware is in reality 9 bits.
I am thinking that I am just going to have to connect the hardware and see what happens. Ideally I would not like to change the timing on the 8 bit AVR side. There are a few cycles from the end of the 9 bit data and the loop initialization of the 16 bytes of 8 bit data. Since the source data is bit banged there is a window for each byte. based on polling the overflow on 8 bit timers.
When I first started this project, I thought all the data was 8 bits and calculated the appropriate baud rate. Surprisingly it worked and I still have capture files. When I went to re construct the data I found that the middle bits were missing or stuck together, with no way to recover them. On the other hand the 8 bit patterns should fit into the 9 bits without data loss, although the start/stop bits may be an issue. The 9th bit may be able to be programmed as a mark or space parity, which do not seem to be used much these days.
Recently I found some old paper tape that was 7 bits even parity. One can simply read it by looking at it
I am thinking that I am just going to have to connect the hardware and see what happens. Ideally I would not like to change the timing on the 8 bit AVR side. There are a few cycles from the end of the 9 bit data and the loop initialization of the 16 bytes of 8 bit data. Since the source data is bit banged there is a window for each byte. based on polling the overflow on 8 bit timers.
When I first started this project, I thought all the data was 8 bits and calculated the appropriate baud rate. Surprisingly it worked and I still have capture files. When I went to re construct the data I found that the middle bits were missing or stuck together, with no way to recover them. On the other hand the 8 bit patterns should fit into the 9 bits without data loss, although the start/stop bits may be an issue. The 9th bit may be able to be programmed as a mark or space parity, which do not seem to be used much these days.
Recently I found some old paper tape that was 7 bits even parity. One can simply read it by looking at it
Re: Mix 9 and 8 bit data on UART
Right, forgot you want use DMA
Honestly, don't know how to handle your use case.

Honestly, don't know how to handle your use case.
Re: Mix 9 and 8 bit data on UART
well, not explored here, is it quite possible to copy say 2 bytes (dma buffer) into the 4 bytes (the register) or vice versa to solve the problem? i'd have thought in addition that uart serial is mostly below 1 mbps and it shouldn't have much impact given the low speed requirements? e.g. it may be possible to simply update the registers (i.e. s/w no dma) and still be in time, after all it is a uart?
i remember a last time while i play with uart on stm32f103 there seem to be some limits on word sizes, bauds ranges etc compared to more generic e.g. ft2232 specialized hardware, not sure about f4 though. it seemed to me 8N1 or for that matter 8E1 etc are the more common supported line disciplines. 9 bits seem there not sure about anything else.
if it is connecting to SPI there is another hack though. i'd think just not frequently explored. i think timers can trigger dma. and it may be possible to emulate SPI in one direction e.g. input capture mode. in that way the timer triggered dma may be used to read a stream of data say from a pin. it turns out timer triggered dma is quite useful
i used timer triggered dma in this logic analyzer, but i did not use input capture mode, in this case i simply use the timer as a clock to trigger dma to read in a data stream from gpio 8 pins. i think the concept is very useful. i did that little project to explore 'parallel data' reading, so that is feasible and it could possibly be used for quite common parallel data scenarios
viewtopic.php?f=10&t=116
i remember a last time while i play with uart on stm32f103 there seem to be some limits on word sizes, bauds ranges etc compared to more generic e.g. ft2232 specialized hardware, not sure about f4 though. it seemed to me 8N1 or for that matter 8E1 etc are the more common supported line disciplines. 9 bits seem there not sure about anything else.
if it is connecting to SPI there is another hack though. i'd think just not frequently explored. i think timers can trigger dma. and it may be possible to emulate SPI in one direction e.g. input capture mode. in that way the timer triggered dma may be used to read a stream of data say from a pin. it turns out timer triggered dma is quite useful
i used timer triggered dma in this logic analyzer, but i did not use input capture mode, in this case i simply use the timer as a clock to trigger dma to read in a data stream from gpio 8 pins. i think the concept is very useful. i did that little project to explore 'parallel data' reading, so that is feasible and it could possibly be used for quite common parallel data scenarios
viewtopic.php?f=10&t=116