Tuesday, January 31, 2012

Tue., Jan. 31st

Some things to do today:
  • [/] Give feedback on paper
  • [ ] Modify CTU firmware to allow server to control GPS remotely.
  • [ ] Write server-side code to massage GPS into behaving properly.
Today is the primary election day, but I forgot to vote on our county ballot measures before I left home this morning!  Oops!

Just copied the current files in Q:\ and Q:\software_v4\FEDM_ctrl_fw to the corresponding locations on Dropbox.   (in FEDM_code\q91)

Also copied the latest version of the DE3 GPS application to Dropbox, from:

  • C:\f\DE3\S3\SB+SOPC\GPS_FPGA_app\Quartus_II_Project\DE3_GPSapp
to:

  • C:\Users\Mike\Documents\My Dropbox\FAMU\COSMICi\GPS_FPGA_app\Quartus_II_Project\DE3_GPSapp
I also made a local backup of it in:

  • C:\LOCAL\GPS_FPGA_app\Quartus_II_Project\DE3_GPSapp
This is because I'm going to begin making changes to it, and the students might be able to help.

Current revision is RevA.  I'm going to make a new revision called COSMICi_DE3_GPSapp_RevC.

Let's look at the UART peripheral interface to see if we can set its baud rates.  The two UART peripheral interfaces are:

  • uart_1 (WiFi) - Baud rate 115,200; baud rate can be changed by software; include CTS/RTS.
  • uart_2 (GPS) - Baud rate 57,600; baud rate can be changed by software; CTS/RTS are not included.
IIRC, I believe uart_1 was for talking to the Wi-Fi, and uart_2 was for talking to the GPS.  Let me check.  Yes, the comments in DE3_GPSapp.v (top-level file) and GPSapp.v (main application file) make this clear.

OK, so now I need to figure out how to actually change the baud rate in software.  Let's look at the docs for the UART peripheral interface.  Was that in the Nios II Software Developer's Handbook?  Or the Embedded Design Handbook?  Hm, or the Embedded Peripherals IP User Guide?  Aha, that's it.

Here's the material on changing the baud rate:


Baud Rate Options
The UART core can implement any of the standard baud rates for RS-232 connections.
The baud rate can be configured in one of two ways:
■ Fixed rate—The baud rate is fixed at system generation time and cannot be
changed via the Avalon-MM slave port.
■ Variable rate—The baud rate can vary, based on a clock divisor value held in the
divisor register. A master peripheral changes the baud rate by writing new values
to the divisor register.
7–4 Chapter 7: UART Core
Instantiating the Core
Embedded Peripherals IP User Guide June 2011 Altera Corporation
1 The baud rate is calculated based on the clock frequency provided by the Avalon-MM
interface. Changing the system clock frequency in hardware without regenerating the
UART core hardware results in incorrect signaling.
Baud Rate (bps) Setting
The Baud Rate setting determines the default baud rate after reset. The Baud Rate
option offers standard preset values.
The baud rate value is used to calculate an appropriate clock divisor value to
implement the desired baud rate. Baud rate and divisor values are related as shown in
Equation 7–1 and Equation 7–2:
Baud Rate Can Be Changed By Software Setting
When this setting is on, the hardware includes a 16-bit divisor register at address
offset 4. The divisor register is writable, so the baud rate can be changed by writing a
new value to this register.
When this setting is off, the UART hardware does not include a divisor register. The
UART hardware implements a constant baud divisor, and the value cannot be
changed after system generation. In this case, writing to address offset 4 has no effect,
and reading from address offset 4 produces an undefined result.


This text is from pages 7-3 to 7-4.  The equations are:

  • divisor = int((clock frequency) / (baud rate) + 0.5)
  • baud rate = (clock frequency) / (divisor + 1)
Looking at table 7-4, the divisor register (16 bits) is register 4.

Let's look at the firmware, in the Nios II 9.1 IDE (legacy).  It looks like altera_avalon_uart_fd.h has support for ioctl() operations.  Looking at termios.h, it seems that there is support for setting the baud rate in the termios structure which has fields for this purpose.

Looking at the doc on page 7-10.  We need the preprocessor option -DALTERA_AVALON_UART_USE_IOCTL.  Then we use the options TIOCMGET and TIOCMSET.

Damn, the stupid legacy Nios II IDE keeps crashing whenever I try to modify the C/C++ build properties (wanted to do this to add the -D option).  Looks like I'll have to migrate this project to Eclipse.

Considering using the Micrium MicroC/OS-II embedded OS in this application.  (We probably have enough memory for it on this board.)  At least then, maybe the re-entrant versions of the STDIO routines would work properly!  And we could have proper threads (or tasks, or whatever they call 'em).

Note to self:  Pick up uC/OS-II manual from my ECE office on way home.

Ugh, getting errors from the hello-world build for uC/OS-II.  Thinking now this is maybe not worth the hassle.  Let's try again tomorrow, this time just creating a regular Eclipse project without uC/OS-II.

Tomorrow:  Need to make it a priority to try out the PADS license.

This evening I spent a little while trying to see if the central server would run on Mac OS X (Snow Leopard) on my Mac Mini at home, under Python 3.1.4.  No such luck.  Apparently, the OS X version of Tcl/Tk (TkAqua) has a restriction that the toolkit must run in the main thread, whereas presently we create a separate "guibot" thread to run GUI operations.  It will take some doing to fix this problem.  Not sure yet exactly what the best way to do it is, or if it is worth doing.  We can wait till later to fix it, or perhaps just run the server under a VM if we need to run it on a Mac.

I made a valiant effort this evening to fix the problem by enlisting the main thread into the role of the guibot thread (instead of creating a new thread to be the guibot), and improving the Worker methods so that a worker can give blocking tasks to itself without creating a deadlock situation.  However, I am still having problems; I couldn't make the main thread object callable even after adding a .__call__() attribute to it.  Not sure what's going on there.  Perhaps the main thread is not really a class object?

I should make all my threads (except the main thread) daemon threads - these don't prevent the python process from exiting.  This would allow the server to be killed by interrupting the main thread, I think, which can be done by sending it a keyboard interrupt.  I thought I tried this before though, and it didn't help for some reason?

No comments:

Post a Comment