The Newton MessagePad 2000-series devices had a little known internal slot intended for an integrated modem card that was never made by Apple. PCMCIA WiFi cards of this era do not support modern WPA2 encryption. This site outlines a project to build a WiFi board for this never-used internal serial slot that works with modern WiFi networks.

Friday, February 27, 2015

WiFi Update

Some updates on the project:
  1. I was unhappy with the linear regulator's heat performance, so I changed to a switching module.  This increased the number of passive components a bit.  I found a nice module from TI that has an integrated inductor, so the whole thing still fits nicely.  The PCB layout is tricky for switching regulators, but I did my best to follow the guidelines in the data sheet, so I'm hopeful it will work as expected.

    Rather than making a separate breakout board to prototype the regulator, I just went ahead and ordered the PCBs for the whole project.  I'll reflow the regulator components first and test the circuit out before reflowing again to add the WiReach and additional components.

  2. Mathias suggested a buffer to translate between 3.3v and 5v signals, but this is all 3.3v logic.  I did add a buffer for another reason-- the fact that the module is powered separately from the Newton means that the Newton can be pushing 3.3v logic signals when the module is powered off.  I checked with ConnectOne and the module is tolerant to this, but it wastes power and possibly causes problems with an inconsistent state on power-up.  By using a buffer, the logic signals are kept at the same voltage level as the module itself.  I chose a buffer that has "power off protection on inputs and outputs" which means the buffer can be at Vcc=0 and still tolerate signals coming from the Newton.1
  3. I have an idea for the reset circuit.  The power regulator has a "Power Good" output that holds to ground until the power regulation hits the target voltage.   The idea is to tie this to the WiReach module's reset pin.  This should hold the module in reset until the power regulator is fully online.  This only costs one extra pull-up resistor.

    In case this strategy doesn't work, I've got an alternate setup where the Newton's extra GPIO can trigger the reset.  The GPIO is looped through the buffer, again to keep the logic at the same voltage as the WiReach supply.  A solder jumper selects which reset circuit you wish to use.  The WiReach reset pin is an open-drain, and can be pulled low by the module.  I added a 200 ohm resistor inline to limit the current should the Newton be outputting a 3.3v signal while the module is pulling down its own reset signal.
  4. Switched the test pads to just pads rather than thru-holes.  Moved them near the edge of the board so I can clip on with alligator clips to test.  Exposed the reset and MSEL signals as test pads on the back of the board as well.  These can be used to reset the module into rescue mode if necessary.
  5. Some of the routing is a little odd but I tried to keep the jumpers on the bottom layer as short as possible.  This resulted in few extra vias.  I wanted to keep the ground plane as intact as possible.
  6. I'm still paranoid about the hole locations and the physical design fitting properly, so I 3D printed another mockup to test the fit.  Seems to work well.  Hole placement is still iffy.  I'd love to know the real measurements.  Each time I tweak it a little, but never seem to be happy, so I'm finally just going with it.

So the board is off at ITEAD Studio being built, assuming it passes their error checks. update: it passed error checks and is being manufactured I also ordered two solder stencils from OSHStencils.  I also built a reflow toaster out of an old toaster oven I got for free from a garage sale.  All that's left is to get some solder paste.  I also want to build a little pick and place jig to help place the small components.

Hopefully this will all work in the end... and then there's still the antenna to figure out.
  1. The data sheet for the On Semi MC74VHCT50A is vague on exactly what "Power Down Protection Provided on Inputs and Outputs" actually means.  I did a little testing on the bench, and found that when Vcc=0 the inputs and outputs seem to work like they are Hi-Z. (I'm not sure how to verify that they are definitively Hi-Z, but I can't measure any current flowing in or out when Vcc=0) It expect it to work for this application. 

Wednesday, February 4, 2015

SSL: An Exercise for the Reader

As a diversion, I tried to compiling an SSL library for the Newton.  I settled on CyaSSL, because it is designed for constrained devices.  For example, you can define macros that conditionally compile for devices that have NO_FILESYSTEM or NO_DEV_RANDOM.  That sounds a lot like the Newton.


I got surprisingly far in compiling the library.  First you need to edit settings.h and add a section defining the compilation for the Newton, then pass this definition using "-D NEWTON" to the compiler:
    #ifdef NEWTON
        #define USER_MATH_LIB
        #define BIG_ENDIAN_ORDER
        #define SINGLE_THREADED
        #define NO_DEV_RANDOM
        #define NO_FILESYSTEM
        #define NO_STDIO_FILESYSTEM
        #define CYASSL_USER_IO
        #define NO_WRITEV
        #define SIZEOF_LONG        4
        #define SIZEOF_LONG_LONG   4
One issue is that the Newton doesn't seem to support an 8-byte integer data type.  There is one configuration in settings.h where they #undef SIZE_OF_LONG_LONG. (I assume this is if you don't have a long long datatype) When I try this, it throws an #error, so I set both SIZEOF_LONG and SIZEOF_LONG_LONG to 4 and everything seems to compile.  (Note: There is a Int64 datatype in the C++ headers, but its just a struct with two longs.)

Next you need to define a GenerateSeed() function in random.c.  I just passed rand() from the CLibrary back.  The Newton doesn't have a /dev/random or a good source of entropy that I know of.  I just wanted to get things to compile.  Randomness is important for encryption. In practice, a better source of entropy might be needed.
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
    return rand();
Next you'll find a odd casting error in internal.c in GetHandShakeHeader:

File ":src:internal.c"; Line 3136 # Error: <function argument>: implicit cast of pointer loses 'const' qualifier

The c24to32 is an inline function, and the const qualifier was getting lost for a reason I don't understand.  I manually inlined the function in the one spot where there was a problem.

In internal.h there is a buffer structure that throws the following error:
File ":cyassl:internal.h"; Line 930 # Error: 'buffer::buffer' must be a function
File ":cyassl:internal.h"; Line 931 # Fatal error: Failure of internal consistency check
odd ctor type in struct 'buffer'
The issue appears to be that the compiler does not like the struct being named the same as one of the members.  I add an underscore to the struct name.  This doesn't really affect anything else because its in a typedef and future code uses the type:
typedef struct buffer_ {
    word32 length;
    byte*  buffer;
} buffer;
Next, you need to modify dh.c to use <fp.h> for the pow() and log() functions rather than math.h (which doesn't exist in the Newton C++ Toolkit)   There is a place in dh.c for you to place this code, and a macro (USER_MATH_LIB) in the settings.h file that conditionally compiles it in.
    #include <math.h>
    #define XPOW(x,y) pow((x),(y))
    #define XLOG(x)   log((x))
    #include <fp.h>
    #define XPOW(x,y) pow((x),(y))
    #define XLOG(x)   log((x))
Finally, you need to compile the c files.  I snagged a list of the c files out of the make file (am__src_libcyassl_la_SOURCES_DIST) and made my own little makefile to call ARMCpp using the mpw tool. (mosrun would work too, but I already had an mpw makefile from another project.)  I took Demos.cp and Demos.exp from the NCT example code and modified them to call a few of the CyaSSL initialization functions.  (Otherwise the linker won't link in any of the CyaSSL stuff, since its not used anywhere) I tried to link with ARMLink...

...And... it links!  I was surprised, because I expected there to be some random assembly file or something with symbols that I missed.  The .sym file is around 386kB.  Seems like a reasonable size.

Things go wrong: Static globals

The next step in using C/C++ code in a Newton app is to make the .ntkc package using the AIFtoNTK tool... and this is where things go wrong:
### AIFtoNTK - error -  the file 'CyaSSL.sym' has a R/W global variables which is NOT supported in Newton packages.
#    You can use 'const' global variables & '*const' pointers.
Per the "NCT Programmer's Reference":
    Any global data that you reference in your C++ functions must be read-only data. You must reference this data with a constant pointer to constant data [...]
    You sometimes need to allocate memory for use in your C++ code that is like global data. Since you cannot use non-constant global data in your C++ code, you need to utilize a coordinated effort between your NewtonScript and C++ code to achieve this.
CyaSSL is pretty light on the static globals variables, but there are some sprinkled throughout.  Here are some that I found using a simple grep:
  •     sniffer.c has a bunch, but I think this can be excluded
  •     ssl.c has a mutex and a global random number generator object, and some related counters
  •     io.c has errno as a global variable
  •     des3.c has a few buffers and bytes, and a mutex
  •     ecc.c has a cache of some sort.
  •     memory.c uses globals to hold the malloc, free, and realloc functions.  These can be changed to static globals and #ifndef out the inside of CyaSSL_SetAllocators, since it won't be necessary.
  •     there may be others that I didn't find.
Not all of these get linked in, they all might not not need to be fixed.  This is more retrofitting then I care to tackle.  I'm guessing that we'd need to MakeBinary() on the NewtonScript side and access these binaries using the NCT functions for accessing NewtonScript objects.

Newton Globals

I put together a little stub function that simulates a global variable by storing a pointer in a NewtonScript frame and passing that information back and forth between the C++ code.  The prototype looks something like this:
void* NewtonGlobal(RefArg sym, long size);
You give the global a unique name and pass it as a symbol.  If the symbol does not exist, a memory block of the given size is created, the pointer is stored in the NewtonScript frame and returned.  If it does exist already, then the pointer is retrieved and returned.

With this a very ugly preprocessor macro can be used to remove the static global:
static SessionRow SessionCache[SESSION_ROWS];
#define SessionCache ((SessionRow*)NewtonGlobal(SYM(SessionCache),sizeof(SessionRow)*SESSION_ROWS))
Ugly, but it should work.  I am able to compile, link, and package the CyaSSL library as a .ntkc file.  My "test" file tries and calls a few of the CyaSSL function so that the linker will find them in the dependency tree... but in practice there may be more static globals to tackle.

Other considerations

Besides the globals issue, there needs to be some glue code that allows NewtonScript to call CyaSSL and pass data back and forth.  NIE doesn't support the traditional concept of a "socket".  On the plus side, CyaSSL has an abstracted I/O architecture.  You can define functions for input and output instead of the default socket implementation.

Also, its quite likely that there are many more compiling & linking issues hidden.  When the library is used in practice, there will be more parts of the library in the dependency tree, and we may find new errors or static globals.

An Exercise for the Reader

I think that CyaSSL is a good choice for the Newton.  If you're interested in learning more about CyaSSL, here are some good starting points:

I don't know how many places these global variables might pop up in the CyaSSL code.  Also I'm not an expert on NewtonScript/NIE Endpoints and what well designed "glue" might look like.  Could it be done? Probably.  It is more work than I want to tackle with this little digression.

While I may dabble with this a little more, I don't think I'll see it through to completion.  I invite someone else to pick up the ball run with it. You can find me on NewtonTalk if you have any questions about what I have tried up till this point.  I'm happy to help out, but given the weird encryption export laws in the USA, I don't want to post any code directly.

Monday, February 2, 2015

Initial Design of Internal WiReach WiFi Board

I have been triangulating on a final PCB design for an internal WiReach card.  I am not an EE, so the design is hobbiest-grade at best.  Here is the thinking behind some of what you see in the picture above:

1.  Board size is less than 5cm x 5cm in order to print it at iTead Studio at a reasonable cost.  10 of them on 0.8mm board should be around $15.

2.  Hole locations were determined based on trial and error.  I have a 3D printer, so I printed 6 or so iterations of the board and then checked the fit and hole locations.  If someone has better dimensions for the location of the mounting points, please let me know.

Screw size seems to be #1-72.  Length is 3/8".  Flat head.  Phillips.  Shannon from NewtonTalk was selling an original SER-001 on eBay.  I have a SER-001 too, but I've lost the screws.  Shannon was nice enough to measure the screws for me, and confirm that the head diameter is ~0.136.  This seems consistant with McMaster part number 91771A168, but I would love to find an flat undercut version of this screw.  Unfortunately, it doesn't seem to be available in this length.  At least now I can get some screws for both my SER-001 and this project!

Eagle PCB tends to want to route things across the mounting holes as plated vias.  Since these holes will need to be countersunk, I didn't want to rely on these holes.  Drilling the countersink will break the plated thru hole.  Hence a couple of extra vias are nearby to make sure there isn't an issue.

3.  I trimed down one side of the board to give a little more clearance for the microphone and power switch wires.  This isn't strictly necessary, since the wires have their own recess in the stylus assembly.  Since I don't know how/where I'm going to route the antenna yet, but I figured a little extra room wouldn't hurt.

4.  I added a 500mA PTC Fuse, since the battery leads are unfused.  While there's not going to be any external connector to short out, I figured this was a safe play.

5.  I chose the Texas Instruments REG103 regulator, mainly because I was able to get a handful cheaply on eBay and it has a shutdown input.  Also its pretty low profile and won't interfere with mainboard components. The shutdown signal will will be driven by SerPortSel3.  SerPortSel3 is normally low, keeping the regulator off.  When toggled high in software the regulator will come online and power the WiReach.  This way, the module will only be powered when in use.  This regulator can handle 500mA.  At peak, the WiReach should only use 60% of this amount.

6.  The large copper planes on the top side are for battery power, ground and 3.3v.  The intent to help cool the regulator.  I'm not sure what the thermal characteristics will be in practice.  Power and ground traces are 30 mils wide, which is more than double what the online trace width calulators say you need for 500mA.

7.  Headers for debugging give access to the power lines on one side and the communication lines on the other.  In practice, I intend to tape over the pads so that there's no possibility of a short.  (I may go a little crazy with Kapton tape just to make sure the board doens't flex into something and cause a short to the mainboard.)

8.  The ground plane on the backside is only broken by a few signal jumpers where routing couldn't be done on the top side.

My next steps are to verify the connections one more time to make sure everything is correct, and then send the board off to be made.  In the interem, I'm going to build a reflow toaster oven.