Mix 9 and 8 bit data on UART
Posted: Wed Mar 04, 2020 8:40 am
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.
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.