2011-01-22 04:34 PM
STM32 - Serial Comms with 9 bit data PLUS parity - How to go about it..
2011-05-17 05:22 AM
You said the following
S-D-D-D-D-D-D-D-D-I-P-Z-Z. where: S= Start Bit D= 8 data Bits I = Write/Read Bit command P= Parity done by Hardware/Soft Z = Stop Bit.( two ) I’ve used RS-232 for at least 30 years. The thing I don’t understand in the above is your “I�? bit. There are two data lines one for data going each direction. Data direction, as such, is never transmitted. Indeed, data can be going both directions at once. I explain this in http://www.hmtown.com/fifo.htm along with usage hints. Unless you are using existing hardware that demands two stop bits use one. Enable parity if the other party to your transmission demands it. The “most standard�? use of RS-232 is 10-bit frames. One start bit, 8 data bits and one stop bit. You might be interested to know that “RS�? is short for “Recommended Standard.�? Nine data bits? I only found this in the docs related to multiple receivers with only one device waking up after receiving its specific address. Hint on Fractional baud rate generation - use all the bits in USART_BRR like this: Baud rate = PCLK / USART_BRR. No messy fractions.2011-05-17 05:22 AM
USART3->DR is 16-bits wide, so all 9-bits go in with a single write.
While not familiar with 9-bit, the following should be sufficient to initialize it. You might need to tweak for your specific board/chip configuration. /* Enable GPIOB clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* Enable USART3 clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); /* Configure USART3 Tx (PB.10) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure USART3 Rx (PB.11) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_9b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_Odd; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* Configure USART3 */ USART_Init(USART3, &USART_InitStructure); /* Enable the USART3 */ USART_Cmd(USART3, ENABLE);2011-05-17 05:22 AM
Live and learn. Thank you clive1 for making me revisit RM0008 and 9-bit data.
To the OP: From RM0008: USART_CR1 Bit 12 M: word length. This bit determines the word length. It is set or cleared by software. 0: 1 Start bit, 8 Data bits, n Stop bit 1: 1 Start bit, 9 Data bits, 1 Stop bit Please note that 9 data bits forces one stop bit. USART_DR only the low 9 bits are meaningful. I don’t think clive1 was suggesting that one could perform RS-232 with >9 data bits. From RM0008: When transmitting with the parity enabled (PCE bit set to 1 in the USART_CR1 register), the value written in the MSB (bit 7 or bit 8 depending on the data length) has no effect because it is replaced by the parity. When receiving with the parity enabled, the value read in the MSB bit is the received parity bit. The OP should note that enabled parity preempts 9-bit data transfers.2011-05-17 05:22 AM
''Nine data bits? I only found this in the docs related to multiple receivers with only one device waking up after receiving its specific address.''
Yes, that is exactly the point of the 9th bit: it's not really a data bit; it's a control bit to distinguish between address and data bytes... If you've ever used an automatic vending machine, your purchase almost certainly relied upon this!
2011-05-17 05:22 AM
Hi.. Thanks for your replies.
CLive1, Thanks for your example. I know I had been configuring the USART peripheral correctly because I am seeing the correct effect to my configuration inputs. There is however still no joy from the STM32's hardware, while itcan
andis
being done on an ATMEGA 168/328 on my desk. ISR Code is very simple on this 8 bit controller: 1) load whether 9th bit is high or low 2) load my 8 bit data 3) wait till transmission is complete 4) clear TXC flag. the result is exactly as mentioned in my pattern description above. of course, the hardware has been previously initialized with the following parameters: assync, odd, 1 stop bit, 9bit. You might see somewhat odd that I mentioned 2 stop bits in my pattern config, however with just 1 stop bit, I am seeing the length of 2 stop bits on my scope. Back to STM32: RM00008: pg701: USART CR1: Bit 12 M: Word length - at 9 bits,@PICguy.. it does not mention that only 1 stop bit can be achieved. Bit 10 PCE: Parity control - at the 9 bit setting (1) , the parity check bit is automatically inserted at 9th place. But .....the 9th bit parity from PCE is exactly where I want to insert my control bit I. In my working example on the Atmega, my parity is coming after the 9th bit I control bit, and therefore, the hardware parity is taking in consideration my 9th bit direct input. This is as the protocol requests. As the title of my post says: what I'd like to get is a 9 bit byte ( yes can be done in STM32) ... but PLUS parity .... which STM32's hardware is not letting me achieve.. as seen in Table 179 - Frame Formats, in RM00008, pg 682, bottom 2 rows. On my scope, in total, I am seeing a 13 bit pattern, as this protocol requests, and on the Atmega working example, this is fully done in hardware. However, I cannot yet replicate this on the STM32's uart in HW. Loosing faith and, I'm seeing no other way out, but to regretfully switch to another brand, and loose all the precious effort done till now to migrate to STM32, and no need to mention.. very disappointed. Any help is really appreciated.2011-05-17 05:22 AM
Don't know if its possible, bit I will try it as a last chance.
I'll try to use USART in synchronous mode ( so that no start bit is issued ) ( the clock signal output will be left unused ). Therefore I'll try 2x 8 bit writes concatenated, while taking care to manipulate the data written to ->DR, to achieve all the 13 bits needed, including the start and stop bits. Now to see if 5 bit mode ( very old ) is supported. If yes, I can do 8 bit + 5 bit = 13 bit hardware, without resorting to bit-banging, which is reallynot
desired.2011-05-17 05:22 AM
Or you could use the SPI bus, and just use the 16-bit shift register to send any pattern of start/data/parity/stop you want.
Then again it seem odd that a display device would be so asinine as to use a protocol that 95% of the UART's out there wouldn't be able to support it. The ATMEGA being an outlier not the norm, try connecting it to your PC.2011-05-17 05:22 AM
''however with just 1 stop bit, I am seeing the length of 2 stop bits on my scope''
Note that a stop bit is indistinguishable from a line idle state! Specifying ''2 stops bits'' is equivalent to saying ''at least 2 bit-times idle between bytes''''As the title of my post says: what I'd like to get is a 9 bit byte ( yes can be done in STM32) ... but PLUS parity'' Looks like the STM32 only supports either 9-bit byte or parity - but not both? I beleive that the 9-bit protocol originated with the 8051 - as its Multiprocessor Mode - and that did not support parity. So it looks rather like your protocol relies specifically upon the particular features of the AVR, and is not likely to be supported by any other microcontroller!''Loosing faith and, I'm seeing no other way out, but to regretfully switch to another brand, and loose all the precious effort done till now to migrate to STM32'' Note that the TI (formerly Luminary) Cortex-M3 does not support 9-bit at all...
2011-05-17 05:22 AM
digi-picavr:''this display gadget that works with serial at 9O1.''
What display gadget? How about a link to its datasheet?Clive1:''it seem odd that a display device would be so asinine as to use a protocol that 95% of the UART's out there wouldn't be able to support it.'' Indeed!