Reading UART Rx count register on Mesa 5i25/6i25

More
03 Feb 2016 16:09 #69517 by andypugh
Probably too late now to mention that if I was writing the UART driver again, I would do it differently...

At the time I had no idea how to create unknown numbers of unknown HAL pins on-the-fly or how to concisely define the meaning of data.

However since then we added the smart-serial cards, and that required us to create pins at load-time with unknown numbers and types, and the various absolute encoder types led me to create a concise format for defining pin names. This means that all the code exists for re-use.

Nowadays I would be looking at a format like "uart_0=error%1bposition%15g" which would create a boolean pin called "hm2_5i23.0.uart.0.error" mapped to bit1 of a 16-bit packet, and the other 15 bits interpreted as a gray-code number and presented as hm2_5i23.0.uart.0.position.
I don't know how many use-cases that would cover, though. Keeping multu-byte packets in synch is the puzzle.
The following user(s) said Thank You: sirop

Please Log in or Create an account to join the conversation.

More
03 Feb 2016 16:25 - 03 Feb 2016 16:34 #69518 by PCW

So there is only one rx_addr and tx_addr per instance of PktUART?


Yes

I do not quite understand how the burst mode of PktUARTx send count register functions.
Suppose I want to send two datagrams of 10 bytes length each.
Let the datagram be: 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A .
Then I do for the first datagram:

write 0x04030201 to PktUARTx data register
write 0x08070605 to PktUARTx data register
write 0x00000A09 to PktUARTx data register
and then do the same for the second datagram .

Writing 0x0000000A to PktUARTx sendcount register sends out the first datagram.
Will writing 0x0000000A to PktUARTx sendcount register send out the second datagram?



Yes, thats how you can send bursts (they will be separated by the preset interpacket delay time )
when you write to the send count register you are writing to a 16 deep FIFO of packet byte counts
But as you surmised, multiple packets in a burst need to be "rounded up" to multiples of 32 bits
just like individual packets
Last edit: 03 Feb 2016 16:34 by PCW.
The following user(s) said Thank You: sirop

Please Log in or Create an account to join the conversation.

More
06 Feb 2016 21:35 #69712 by sirop
I have commited something more github.com/sirop/machinekit/commits/master
and tested the driver.
Send and receive work, multiple frames functionality is yet to be added.

I noticed one pecularity:
These lines github.com/sirop/machinekit/blob/master/.../pktuart.c#L342-L355 , now commented out:
	//count=buff;
	// Check Bit  7	 Buffer error (send idle but data in send data FIFO) read only
	/*r = hm2->llio->read(hm2->llio, hm2->pktuart.instance[inst].tx_mode_addr,
                                 &buff, sizeof(u32));
	if (r < 0){
        HM2_ERR("BSPI: hm2->llio->read failure %s\n", name);
        return r;
    }
	else {
		  if ((buff>>7) & 0x01){
			  HM2_ERR("%s send Buffer error\n", name);
			  return -TxBufferError;
		  }
    } 
where I check the 7th bit of Tx mode register after sending out my frame with
 hm2->llio->write(hm2->llio, hm2->pktuart.instance[inst].tx_fifo_count_addr,
                                 &buff, sizeof(u32)); #

The frame gets sent out, but I nevertheless get the error message about the 7th bit "send Buffer Error".
I guess it is due to my reading the 7th bit of Tx mode register too soon after sending a frame as my hardware is rather fast:
gist.github.com/sirop/47d19d9e2da3039e93cb .

I wonder if implementing the tram functions for PktUARt could be a remedy for reading/(writing ?) registers too soon/too fast.

But this is not really an issue, just curiosity..

Please Log in or Create an account to join the conversation.

More
06 Feb 2016 21:43 #69713 by sirop

However since then we added the smart-serial cards, and that required us to create pins at load-time with unknown numbers and types, and the various absolute encoder types led me to create a concise format for defining pin names. This means that all the code exists for re-use.

Nowadays I would be looking at a format like "uart_0=error%1bposition%15g" which would create a boolean pin called "hm2_5i23.0.uart.0.error" mapped to bit1 of a 16-bit packet, and the other 15 bits interpreted as a gray-code number and presented as hm2_5i23.0.uart.0.position.
I don't know how many use-cases that would cover, though. Keeping multu-byte packets in synch is the puzzle.


I neither know as for now how many use cases this would cover.
Maybe, always create mode and count register pins for each PktUART instance? I do not know.

I would ask you about tram functions - declared , but not defined for UART - if they are worth a question.

Please Log in or Create an account to join the conversation.

More
06 Feb 2016 22:46 #69714 by PCW
Looks like the regmap file is not up to date
here are the current TX mode reg defnitions:

Bit 21 FrameBuffer Has Data
Bits 20..16 Frames to send
Bits 15..8 InterFrame delay in bit times
Bit 7 Send busy
Bit 6 Drive Enable bit (enables external RS-422/485 Driver when set)
Bit 5 Drive enable Auto (Automatic external drive enable)
Bit 4 SCFIFO Error (overrun)
Bits 3..0 Drive enable delay (delay from asserting drive enable
to start of data transmit. In CLock Low periods
The following user(s) said Thank You: sirop

Please Log in or Create an account to join the conversation.

More
06 Feb 2016 22:57 #69716 by sirop

Looks like the regmap file is not up to date
here are the current TX mode reg defnitions:

Bit 7 Send busy


Yes, this makes more sense to me: if the frame is being sent right now, then the 7th bit is set
which is not an error.

Please Log in or Create an account to join the conversation.

More
06 Feb 2016 23:06 #69718 by PCW
Bit 7 is only clear when the transmit logic is completely idle

Meaning sendcount FIFO empty (no more packets to send), no data being sent, and no interframe delay running
The following user(s) said Thank You: sirop

Please Log in or Create an account to join the conversation.

More
11 Feb 2016 20:22 #70008 by sirop
Hallo.

I have 3 rather naive questions.

The simplistic scheme in my head is:
Rx buffer ( with up to 1024 bytes) -> Rx registers.

1. So if I write 0x80010000 to the PktUARTr mode register, does all the bytes in the Rx buffer ( with up to 1024 bytes)
also get cleared ?

The background is that I work now with an UART device which has a so called streaming mode.
I can not always know in advance if this streaming mode is switched on.
So if I write 0x80010000 to the PktUARTr mode register during the setup,
then any receives in process, the data FIFO and the receive count FIFO are cleared,
but if the bytes in Rx buffer remain, then it is unpredictable for me which data
the read function would deliver by reading from PktUARTr data register in the next step.

2. Are the Bits 20..16 ( Frames received) of the PktUARTr mode register incremented after the complete frame is received?
Or is it incremented when the frame is started to be received?

3. Is "Bit 7 Buffer error (RX idle but data in RX data FIFO) read only" to understand like "Rx logic active" ?

Thanks.

Please Log in or Create an account to join the conversation.

More
11 Feb 2016 21:50 - 11 Feb 2016 21:57 #70012 by PCW

Hallo.

I have 3 rather naive questions.

The simplistic scheme in my head is:
Rx buffer ( with up to 1024 bytes) -> Rx registers.

1. So if I write 0x80010000 to the PktUARTr mode register, does all the bytes in the Rx buffer ( with up to 1024 bytes)
also get cleared ?


No, the FIFO pointers get initialized


The background is that I work now with an UART device which has a so called streaming mode.
I can not always know in advance if this streaming mode is switched on.
So if I write 0x80010000 to the PktUARTr mode register during the setup,
then any receives in process, the data FIFO and the receive count FIFO are cleared,
but if the bytes in Rx buffer remain, then it is unpredictable for me which data
the read function would deliver by reading from PktUARTr data register in the next step.


This problem is basically the same with any RX UART, you need to initialize the UART and if a device is spitting
data at it during initialization you will get corrupted data (imagine setting the baud rate on your streaming UART)
If the data has periodic gaps (what the PktUART is designed for) you can just throw out bad packets assuming they
have a CRC, checksum, sync character, etc

I think the best you can do with a continuous data stream is to initialize the RX UART with RXENA false
and then set RXENA true as the last step, worst case you will get one corrupted packet

2. Are the Bits 20..16 ( Frames received) of the PktUARTr mode register incremented after the complete frame is received?
Or is it incremented when the frame is started to be received?


When done ( data received and interpacket time has passed )
(this is how you know you can read the packet/packet size)

3. Is "Bit 7 Buffer error (RX idle but data in RX data FIFO) read only" to understand like "Rx logic active" ?
Thanks.

Yes, is like the TX case not a error bit but a RX busy bit
Last edit: 11 Feb 2016 21:57 by PCW.
The following user(s) said Thank You: sirop

Please Log in or Create an account to join the conversation.

More
21 Feb 2016 21:04 #70457 by sirop
I tested as much as possible for this commit github.com/sirop/machinekit/commit/3446d...ee7211f94f1a1a2462d5
and added a test component which works with Microstrain 3DM-GX3-15 gyro.

Your advice about clearing RxEnable - in order to circumvent the problem of a device streaming data from the very beginning - helped.

We tested only with 112500 baud rate as for higher baud rates we have to solder a different converter,
we'll test with a converter for higher baud rates next week.

Some remarks/questions:

1. The send function with "burst" mode works as I show in the test component,
nevertheless I do not know if I implemented its concept corrrectly.
I have two (nested) loops:
the outer loop iterates over the frames to be sent, the inner loop writes the bytes of each frame to PktUARTx data register.
After all the bytes of a frame have been written to PktUARTx data register, their number is written to PktUARTx sendcount register.

Maybe, it were conceptually more correct to first write all the bytes of all the frames to PktUARTx data register,
and only then write the number of bytes for each frame to PktUARTx sendcount register?

2. Do I get it right that the Tx frames can only be <=255 bytes long?

3. If I, for instance, clear Rx registers with 0x80010000 command,
how much time does this change need to complete on 5i25 ?

4. If I see it right from my experiments, RCFIFO Error can also get sticky if it is a consequence of
Rx Overrun error (sticky) or Rx False Start bit error (sticky)?

Thanks.

Please Log in or Create an account to join the conversation.

Time to create page: 0.254 seconds
Powered by Kunena Forum