Robot C 3.5X Migration Issues

I’m not sure what to call this thread, but this is good enough. I have been working on a project for most of the summer off and on to provide an alternate method of communicating with the Cortex. I do intend to document the project and post the sample code as soon as I get it robust enough. The project uses XBee parts and the Cortex Serial port.

I got a rudimentary communications working both String based and Binary Based Thanks to a lot of help from James Pearman. I recently upgraded to Robot C 3.51 while supporting a BEST tournament, and afterward found my code no longer works. As so much time > 3weeks had passed since I had it working I quickly came to believe the upgrade was part of the culprit. After downgrading my laptop to 3.08 and the master firmware to 3.21 with a little fiddling I got the code to work again. I am very frustrated with the need for wait statements in Robot C to make an assignment ‘stick’ but more on that when I can build a simple example. Right now it appears some fundamental things have changed with the way Robot C presents the serial port. After ensuring my code was working well under 3.08 i.e. I was transmitting packets of data in both directions 1/sec with no bad packets being received, I copied the code to a PC with Robot C 3.54 ( Since I noticed the problem in 3.51 I went ahead and upgraded to 3.54 out this weekend) and I found the code did not work. I get neither transmission or reception on the Cortex. it acts like its transmitting (I can see the LEDs on my XBee board light up) but I get no (intelligible) data in or out of the Cortex. But when I re-load the 3,21 firmware and the Code on the Cortex (and handset) it works again.

I did notice a compiler warning which might explain the issues with the Rx on the Cortex, but doesn’t seem immediately to point to the problems on the Tx side.

The Errors are below, and I’ll post my code please excuse the roughness this is not ready for prime time, but is the basis for which I’m heading the project example to be.

From the debugger:
File “stringOrBinary.c” compiled on Nov 04 2012 14:41:39
Warning:Truncation of constant value ‘-1’ to ‘unsigned char’ variable range
Warning:Meaningless comparision between ‘unsigned’ value and ‘negative constant’ [L]

The lines of relevant code are here:

task serialPortAscii () {
char cProcessing[INPUT_STRING_SIZE]; // create input buffer
char incomingChar = -1; // Rx data flag
int nCounter = 0; // How Many Chars Rx
bool receiving = false; // keep track of Rx loop vs idle loop

//Clear out existing array data
memset(cProcessing, 0, sizeof(cProcessing));

// need to start infinite loop
while (true) {
// poll for input
incomingChar = getChar(uartTwo);
//
if ( (incomingChar != -1) && (nCounter < INPUT_STRING_SIZE) ) {
// we have a valid data item

It appears to me that getChar now returns an unsigned char vs. a char as it did before. I need to do more digging but would appreciate help in where to look and how to code alternatives.

The Full code for the Cortex and Arduino are posted in zip files below, Be warned this is a work in progress and exposes why I don’t write S/W for a living. And I couldn’t have done the cool stuff without help from Mr Pearman who provided the excellent example of Unions.

The Arduino I use is a Mega 2560 which has multiple H/W UARTs, The serial Comms currently are facilitated by XBee H/W and I spent a lot of time ensuring the XBees work as a simple wireless point to point serial interface. I know they can do a lot more, but for now until I get the robot code working well I am using them in the simplest mode. They do not seem to be the problem, and if you wanted to reproduce my efforts you should be able to hook the serial port of the Cortex to the Arduino directly wore to wire as they are supposedly both 5v tolerant. Indeed I did this several times during the summer to rule out the XBee from some of the issues I found.

In Summary I would like to get the serial port I/F to the Cortex working again in 3.5x like it did in 3.08 or at least understand what I need to change in my code so I can keep this project going in 3.5x and beyond.

Cheers Kb

[ATTACH]6889[/ATTACH]

[ATTACH]6890[/ATTACH]
AdditionalBinaryTesting.zip (3.59 KB)
BinaryWirelessExtendedTesting.zip (4.56 KB)

getChar returns short, always did.

intrinsic short getChar(const TUARTs nPort)  asm(opcdSystemFunctions, byte(sysFuncSerialGetChar),

You code compiles under 3.51 for me with no errors.

make incomingChar a short and it will compile under 3.54 (well, actually i did not test that, i tried 3.53beta4 from last week).


short incomingChar = -1; // Rx data flag

yes thanks I can see that now, I guess I need to learn the difference between a short and a char. I was quite easily misled that ‘getchar’ would return a ‘char’.

I’ll try with that change but I’m pretty sure something else is going on that I haven’t found yet.

Thanks for your help.

Cheers - Kb

Let me look properly later. There were changes to UARTS, port2 is normally initialized as LCD now where before it was not unless specifically set that way, I though it was changed so that if used as another port then it would be unassigned.

Also, regarding waits, are you using bXmitComplete anywhere, I don’t see it with a quick look but it should be used after transmitting a character.

Thanks,
I was using bXmitComplete but wasn’t sure what it would do so commented it out.

I found the change to short had no effect. I get no RX on my Arduino and I get no Rx on my Cortex where it worked fine under 3.08

I also found the link I posted to the VexNet Upgrade utility does not work on the desktop I loaded 3.54 on I had to load the firmware from my laptop using the utility in the Easy C directory. Interesting since I rarely use Easy C anymore, but I’m glad I have kept current with it.

What a twisted web.

I’ll keep digging as well. I’m feeling like something significant changed in treatment of serial ports. If CMU hard coded some behavior I will be pretty disappointed.
It’ll be a sad day if the compiler provider locks us into using uarts for specific purposes even if we haven’t bought the required hardware.

Cheers Kb

Well the quick test of leaving the Cortex master firmware at 3.2.3 and reverting the code to Robot C 3.08 (I had to load the RobotC firmware but not the Vex firmware). I found I could not transfer files from 3.08 with the 3.54 firmware loaded, but loading the 3.08 robotC firmware fixed this problem, and the Joystick which had been updated to 3.2.3 worked as well.

here’s the results of VEX S/W inspection:

Communications Link: COM Port ‘COM11’ to VEXNET Joystick

Standard Firmware File Names:

VEXNET Joystick: .\Firmware\JOY_V3_21.BIN
VEX Cortex Master CPU Firmware: .\Firmware\CORTEX_V3_21.BIN
VEX Cortex CPU Firmware: .\Firmware\VEX_Cortex_0912.hex

VEXnet Joystick Integrity:

Firmware Version: 3.23 Newer Version (needed is 3.21)
Battery Voltage: 4.7V Poor (<6.1V)
Calibrated: No
Joystick State: Powering Up

Cortex Master CPU Integrity: Value Status

Firmware Version: 3.23 Newer Version (needed is 3.21)
Main Battery: 7.0V Good (>6.5V)
Backup Battery: 0.0V Poor (<8.0V)
Team Name: “00ROBOTC” Default. Not Assigned

Cortex User CPU Integrity: Value Status

Firmware Version: 9.12 Up to Date
Program Type: Standalone Wi-Fi Not valid for competition use

After loading the program under 3.08, bidirectional serial comms worked as before.

Cheers Kb

Looks like the serial ports are screwed up in 3.51 and later, I had some old code that also crashes, I will let CMU know. As I never use the serial ports it’s not something I test in beta releases, oh well.

Edit:

Ok, here’s what’s going on. uart2 is probably sending data to uart1 now, it’s a bug. This is the enum from the header file.

typedef enum short
{
  UART0         = 0,
  UART1         = 1,
  UART2         = 2,
  UART3         = 3,

  uartOne       = 0,
  uartTwo       = 1,
  uartThree     = 2,
} TUARTs;

If I use uartOne then the data goes to the system debug port. If I use “1” (uartTwo) then data goes to UART1 on the cortex.

So for now, in your code either do a global replace on uartTwo with uartThree or plug the xbee into port 1 and turn off the LCD display in “motors & sensors” setup.

Well thanks for the insight. I’m sure it’ll get resolved. Have you tried the LCD does it work? I’ll need to try that. If they work perhaps there’s a workaround until things get resolved.

Cheers Kb

See below, I just edited it.

Ah, Well I just tried the LCD sample code, When I plug the LCD into UART 2 and set the pragma for UART 2 then it works although I needed to power cycle after trying it in UART 1.
The motor & sensor setup is all messed up though. I’ll see if I can get the workaround you suggested to work.

Thanks again - Kb

Well I can use Uart2 with the XBee by changing all my assignments to Uart3 as you indicated. So that’s cool. Unfortunately I can’t get the LCD to work with the XBee. For some reason, I could get the LCD demo program to work when plugged into UART2 by assigning the LCD to UART1 or UART2 in the motors and sensors setup (but I had to do some manual tweaking of the pragmas to get the pragmas to stay , they kept disappearing.

So for now I would suppose anyone using an LCD could use UART2 But it looks as though UART1 is non functional.

Again thanks for your help. I will continue to work in 3.08 for the short term as I have some plans for the LCD displays when conducting long running tests.

Cheers Kb

I don’t see a problem with the LCD, I can assign it to UART1 or UART2 and use the other port for user communications. The LCD used to have a problem in 3.50 but we resolved that for 3.51.

I guess I may have caused the confusion myself. I am used to using the motors and sensors setup and only seeing one pragma added when I defined the LCD whether it was assigned to UART 1 or 2 what is happening is when I select from the menu LCD UART1, I get a pragma inserted in my code, If I select LCD for UART2 but set UART1 to not assigned I get nothing (the pragma is removed) however at least one time I tried to manually insert the Pragma for Uart2 into my code compiled and D/L, I observed the demo code to work.
After your note I went back and observed similar behavior. It is very frustrating trying to get the Pragma line to appear correctly & stay, I was thinking perhaps incorrectly but I was thinking this was a problem with the ‘menu’ item and not the compiler so I started copying out the Pragma lines when I could get them to appear and manually inserting them & compiling.

I was able to get the LCD to work in either port, but I could not get the second Uart port to work. - I am reminded of a discussion in the forums where a team was trying to use 2 LCD’s and they would not work. I wonder if this behavior is related to that in anyway. I had thought in that case that because CMU assigns a label of uartVEXLCD without giving the user the ability to change it. That there was some double defining going on, but perhaps there is something more fundamental going on with the serial ports which may have been around for a while. I’m pretty sure I had both ports working at one point or another this summer, but I’m not positive. I’ll need to go back to 3.08 and see if I can get the LCD to work at the same time as the XBee.

I don’t know if the Robot and Sensors setup menu issues are related to the header file disconnect you pointed out, but I thought I’d point it out. In v 3.08 any selection of LCD to UART inserted the appropriate pragmas in the start of the file, In 3.54 If I try to define 2 LCDs one in each uart, I only see the definition for UART1 in the code, but If I assign UART 2 to Unassigned or User code it does show up that way, but when I set UART1 unassigned and UART2 to the LCD I did get a pragma inserted (none) wierd…

Cheers Kb

So a few things to note:

  1. The TUARTs Typedef is wrong in 3.54. We’ll fix this for the next release but feel free to make the change yourself. It should look like this (note - if you make this change, verify that when 3.55 is released that everything still works).
typedef enum short
{
  UART0         = 0,
  UART1         = 1,
  UART2         = 2,
  UART3         = 3,

  uartOne       = 1,  //Was 0
  uartTwo       = 2,  //Was 1
  uartThree     = 3,  //Was 2
} TUARTs;
  1. What’s happening with “uartOne” is that ROBOTC exposes the messaging going between the Master/Slave with the Internal UART (EDIT: sorry, I refer to this as an SPI since it’s kind of used as one) link on UART0 (index 0) - uartOne was also set to index 0, so this is why you may have locked up your Cortex trying to write to that port.

  2. The default for the Cortex is nothing connected to UART1 and VEX LCD connected to UART2 - this is for curriculum/end user simplicity that they can use the VEX LCD commands without having to configure it each time in every program. If you set the Motors and Sensor Setup to ROBOTC’s default settings, it will not generate Pragma code for that port. If you want to move the VEX LCD, you’ll need to disable it (uartNotUsed) and then configure it on UART1.

Hope this helps!

Kevin

Some more thoughts and background on what you observed.

I don’t know real numbers but I would guess that the majority of users never use the serial ports. Those that do, lets say 10% of cortex owners, probably only ever use the VEX LCD. The default port for the LCD is UART2, students want to plug in the LCD and just expect it to work without any configuration, I’m sure it cuts down on a lot of tech support by not having to tell students to first configure UART2 as the LCD port in motors & setup. The assembly display is very useful in ROBOTC, if we look at the beginning of the main task for a new file without any code this is what you see.

task main()
//
//Code segment: main(); Task: 0
// 
0000: 614000                   StopAllMotors()                    
0003: 6732000000000100         configureSerialPort(UART0, uartSystemCommPort)
000B: 6732000100000000         configureSerialPort(UART1, uartNotUsed)
0013: 6732000200000300         configureSerialPort(UART2, uartVEXLCD)
001B: 676701001C               ClearSensors(in1..I2C_8)           
0020: 676D01000A               ClearMotors(port1..port10)         
{
}
0025: 614000                   StopAllMotors()                    
0028: 7B                       Return()                            // main()
0000: 7B                       Return()                            // _main__()

Notice the configureSerialPort calls, UART2 is configured as the LCD port by default, a #pragma statement is not needed in this case. Also note that UART0 is configured to be the system communications port, this is a real uart on the STM32 which is used to communicate with the master processor (it’s not SPI as Tim said, that exists also but is not UART0). The system comms port is used to download your program to the processor and is the path for debug commands and status back through the master processor to the ROBOTC IDE.

Now lets look at the code if UART1 is set as the VEX LCD in the motors & sensors dialog box.

#pragma config(UART_Usage, UART1, uartVEXLCD, baudRate19200, IOPins, None, None)
#pragma config(UART_Usage, UART2, uartNotUsed, baudRate4800, IOPins, None, None)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main()
//
//Code segment: main(); Task: 0
// 
0000: 614000                   StopAllMotors()                    
0003: 6732000000000100         configureSerialPort(UART0, uartSystemCommPort)
000B: 6732000100000300         configureSerialPort(UART1, uartVEXLCD)
0013: 6732000200000000         configureSerialPort(UART2, uartNotUsed)
001B: 676701001C               ClearSensors(in1..I2C_8)           
0020: 676D01000A               ClearMotors(port1..port10)         
{
}
0025: 614000                   StopAllMotors()                    
0028: 7B                       Return()                            // main()
0000: 7B                       Return()                            // _main__()

Two #pragma statements are created, the first tells the compiler to configure UART1 as the VEX LCD, the second tells the compiler that UART2 is now unassigned.

The file Tim is referring to is RobotCIntrinsics.c, you could edit this file but I would advise against that as you may forget or reinstall ROBOTC and wonder why everything stopped working again. As an alternative I would define the UART you want to use at the top of your code, this gives a single place to change which port you use for the xbee communications.


#define  MyUart    UART2

or I suppose just switch over to using UART2 rather than uartTwo.

Awesome! Thanks!
Changing to UART2 works, and it’s probably the best thing for me. I’m not sure why there are multiple ways to identify the ports, but I’m glad one of them works.

Thanks again for all your help explaining and coming up with a resolution. I will study the assembler view and your notes there, I’m sure there is a wealth of information to be mined If I could understand the lingo better.

Anyway I’ll be able to upgrade to 3.54 and keep working on this project.

I understand the concept behind a default port for the VEX LCD, but I sure wish it was clearer that UART2 is always configured by default for LCD.
And I wonder why UART2? was there something ‘reserved’ about UART1? or was it so the plugs for LCD and I2C would be side by side? < just a trivia question I’m sure>

Thanks for all the insights.

Cheers - Kb