Slicekit COM Port GPIO Demo: code issue?

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
JasonWhiteman
Active Member
Posts: 63
Joined: Mon Jul 15, 2013 11:39 pm

Slicekit COM Port GPIO Demo: code issue?

Post by JasonWhiteman »

I'm having issues using the COM Port GPIO Demo. My next step is to take the scope and look at what's going on the line both in front and in back of the SP3220E buffer. However, the first scan through under the hood of the demo has me scratching my head.

The uart_tx function within uart_tx.xc qualifies the baud rate with the following code:

Code: Select all

if((baud_rate!=115200) && (baud_rate!= 96000) && (baud_rate!=24000) && (baud_rate!= 57600))
      {
		   printf("Incorrect baud_rate .Fail\n");
		  _Exit(1);
      }
115200 - makes sense, standard value
57600 - makes sense, standard value
However - 96000 and 24000 are suspiciously strange looking as they are 10x the standard values of 9600 and 2400

Regardless, I am having issues receiving data with both 115200 and 57600.

Seems that lowercase "c", "e", and "l" are not passing through uart_rx_impl_get_byte()

as I've modified the function to show characters:

Code: Select all

void uart_rx_get_byte_byref(chanend c, uart_rx_client_state &state,
                                   unsigned char &byte)
{
  byte = uart_rx_impl_get_byte(c, state);
  printchar(byte);
}
and never see the these characters.

Is my experience universal? Any suggestions on how to get back on track?

Regards,
Jason Whiteman


User avatar
JasonWhiteman
Active Member
Posts: 63
Joined: Mon Jul 15, 2013 11:39 pm

Post by JasonWhiteman »

Note - would help to have others with experience using the COM port demo to verify if the behavior is expected or outside of the normal experience.

At the moment, I'm using the problem with the COM port as a debug environment learning experience to attempt to pinpoint the issue.

For reference, I'm using the xTIMEcomposer IDE 12.2.0 (Build 7741), Windows environment.

Please chime in if there's a better environment to use (CMD line, beta build, etc).

I started a debug session to break on some of the lower level UART functions. Although the break seemed to work (although not where I expected to break using "run to code" -- still, break happened somewhere valid without error) -- stepping through the code threw a windows exception.

Unhandled exception at 0x004712fc in xgdb.exe: 0xC0000005: Access violation reading location 0x00000008.

In case anyone was wondering about the debugger code (x86 instructions):

Code: Select all

004712F0  ret  
004712F1  lea         esi,[esi]  
004712F4  xor         eax,eax  
004712F6  ret  
004712F7  ret  
004712F8  mov         edx,dword ptr [esp+4]  
004712FC  mov         eax,dword ptr [edx+8]  ;  <<==== exception thrown here
004712FF  test        eax,eax  
00471301  je          00471309  
00471303  cmp         byte ptr [edx+19h],0  
00471307  je          00471310  
00471309  mov         edx,dword ptr [edx+0Ch]  
And for the ultra-curious:

esp = 2684492 (dec, 0x0028F64C)
edx = 0

Memory @ ESP (0x0028F64C)

Code: Select all

0x0028F64C  c9 cb 4f 00 00 00 00 00 00 00 00  ÉËO........
0x0028F657  00 0c f7 28 00 02 00 00 00 00 00  ..÷(.......
Debugging the debugger is out of scope for my project.

I'll update the thread as I go -- but it looks like I'm going to have to attack this with hardware tools (my first instinct) as I know my Tektronix is a reasonably solid debug platform.

I've also considered the Xmos Realtime Scope - but the learning curve appeared to be a bit beyond the utility at the moment.

Thanks to the experts for reviewing and hopefully applying open-source / open-hardware concepts to a debug session is helpful to others down the line.

Regards,
Jason Whiteman
User avatar
JasonWhiteman
Active Member
Posts: 63
Joined: Mon Jul 15, 2013 11:39 pm

Post by JasonWhiteman »

Taking a look at what's working vs. what's not working, I noticed that characters that work have an odd number of binary 1's and the characters that do not pas have an even number of binary 1's. Numbers are in binary.

Code: Select all

Characters Work                     Characters get "eaten"
a	1100001		c	1100011
b	1100010		e	1100101
d	1100100		f	1100110
g	1100111		i	1101001
h	1101000		j	1101010
k	1101011		l	1101100
m	1101101		o	1101111
n	1101110		q	1110001
p	1110000		r	1110010
s	1110011		t	1110100
u	1110101		w	1110111
v	1110110		x	1111000
y	1111001		A	1000001
z	1111010		B	1000010
C	1000011		D	1000100
E	1000101		G	1000111
F	1000110		H	1001000
I	1001001		K	1001011
J	1001010		M	1001101
L	1001100		N	1001110
O	1001111		P	1010000
Q	1010001		S	1010011
R	1010010		U	1010101
T	1010100		V	1010110
W	1010111		Y	1011001
X	1011000		Z	1011010
I also checked single high bit characters ("@" = 1000000b) can pass. "A" with 2 high characters (even #) does not pass.

Conclusion: must be a parity issue (I thought it was off ?? Bonehead assumption detected)

... Search for "parity"

Found:

Code: Select all

on stdcore[CORE_NUM] : uart_rx(p_rx, rx_buffer, ARRAY_SIZE(rx_buffer), BAUD_RATE, 8, UART_TX_PARITY_EVEN, 1, c_chanRX);
I must have failed to "RTFM" this one. Hopefully when I go back and review the documentation there will be a glaring direction that I missed.

... and in real-time as I type this message:

Pull up PuTTY settings, change parity to even, return to serial console

"ABCDEFG" ... echo works (anything I type).

">cmd" works

in console mode "help" works

Final conclusion: NOT A CODE ISSUE

As a regression test for "documentation issue?"

1. Check the GPIO COM Port Quickstart Guide

"Configure the host terminal console program as follows: 115200 baud, 8 bit character length, even parity, 1 stop bit, no hardware flow control. The Transmit End-of-Line character should be set to "

Bold/underline not in original document - but the key setup info is there.

Conclusion: documenation was sufficient. Perhaps since "N81" is such a standard starting point (at least in my previous serial port dealings) - "idiot proofing" the docs a little more with more flash around the "even parity" would help the next fast reader.

... time for me to close a ticket.

Regards,
Jason Whiteman
User avatar
JasonWhiteman
Active Member
Posts: 63
Joined: Mon Jul 15, 2013 11:39 pm

Post by JasonWhiteman »

... and just to finalize my COM port GPIO demo comments (for now)

NO - there's no code problem causing the serial port problems under 115200 and 57600 baud rates. However, there are a few code issues I noticed along the way.

Issue 1: Check for incorrect baud rates

The baud rate checks appear to have a typo.

File: uart_tx.xc original code

Code: Select all

 if((baud_rate!=115200) && (baud_rate!= 96000) && (baud_rate!=24000) && (baud_rate!= 57600))
      {
		   printf("Incorrect baud_rate .Fail\n");
		  _Exit(1);
      }
Notice baud_rate!=96000 and baud_rate!=24000

Should be:

Code: Select all

 if((baud_rate!=115200) && (baud_rate!= 9600) && (baud_rate!=2400) && (baud_rate!= 57600))
      {
		   printf("Incorrect baud_rate .Fail\n");
		  _Exit(1);
      }
Issue 2: "setled" and "clearled" have AND/OR logic swapped

The XC code has "&" where "|" should be and vice-versa

File: main.xc original code

Code: Select all

									case SET_LED_1: //Read port Value and Set LED 1 ON
										p_led:>data;
										data=data | 0xE;
										p_led<:data;
										break;

									case CLEAR_LED_1://Read port Value and Set LED 1 OFF
										p_led:>data;
										p_led<:data&0x1;
										break;

									case SET_LED_2: //Read port Value and Set LED 2 ON
										p_led:>data;
										p_led<:data | 0xD;
										break;

									case CLEAR_LED_2: //Read port Value and Set LED 2 OFF
										p_led:>data;
										p_led<:data&0x2;

										break;

									case SET_LED_3: //Read port Value and Set LED 3 ON
										p_led:>data;
										p_led<:data | 0xB;
										break;

									case CLEAR_LED_3: //Read port Value and Set LED 3 OFF
										p_led:>data;
										p_led<:data&0x4;
										break;

									case SET_LED_4: //Read port Value and Set LED 4 ON
										p_led:>data;
										p_led<:data | 0x7;
										break;

									case CLEAR_LED_4: //Read port Value and Set LED 4 OFF
										p_led:>data;
										p_led<:data&0x8;

										break;

Should be:

Code: Select all

									case SET_LED_1: //Read port Value and Set LED 1 ON
										p_led:>data;
										data=data & 0xE;
										p_led<:data;
										break;

									case CLEAR_LED_1://Read port Value and Set LED 1 OFF
										p_led:>data;
										p_led<:data|0x1;
										break;

									case SET_LED_2: //Read port Value and Set LED 2 ON
										p_led:>data;
										p_led<:data & 0xD;
										break;

									case CLEAR_LED_2: //Read port Value and Set LED 2 OFF
										p_led:>data;
										p_led<:data|0x2;

										break;

									case SET_LED_3: //Read port Value and Set LED 3 ON
										p_led:>data;
										p_led<:data & 0xB;
										break;

									case CLEAR_LED_3: //Read port Value and Set LED 3 OFF
										p_led:>data;
										p_led<:data|0x4;
										break;

									case SET_LED_4: //Read port Value and Set LED 4 ON
										p_led:>data;
										p_led<:data & 0x7;
										break;

									case CLEAR_LED_4: //Read port Value and Set LED 4 OFF
										p_led:>data;
										p_led<:data|0x8;

										break;
Regards,
Jason Whiteman
User avatar
tescott
Junior Member
Posts: 7
Joined: Thu Jul 18, 2013 1:17 pm

Post by tescott »

Heh. I ran into the parity issue myself... so you are not alone. I assumed 'none' when it was 'even'. Doh! :P

--tim
User avatar
JasonWhiteman
Active Member
Posts: 63
Joined: Mon Jul 15, 2013 11:39 pm

Post by JasonWhiteman »

Thanks for chiming in on sharing the parity mis-step. I do think there is an opportunity to make an improvement to the messaging around the "even-parity-ness" of this code. Once getting past this issue, however, there are also true errors with the code that skew intent vs. code.

"setled" commands that do not turn LEDs on, "clearled" commands that do not turn LEDs off, and those funny baud rates of 96000 and 24000.

Of course without the errors - I wouldn't have learned as much.

However, there's a point in my debugging when I read some tagline about XMOS providing an environment where solutions could be created in weeks as opposed to ... some longer period of time (months). Phrases like that tend to hit you differently when you're watching the tools (debugger) halt on an instruction somewhere other than where you instructed it to, then crash with a read from a nul pointer (the debugger code itself referencing a nul pointer, not my XMOS), and provide something other than "plug and play" performance from pre-canned tutorial code. Thankfully, user error has helped restore some confidence.

I really do want to help XMOS build better bridges to a positive experience with their hardware, environment, customer support, etc.

Looking forward to broadcasting success stories as I march along the design path.

Regards,
Jason Whiteman