Since I've got your attention, I've run into another glitch that may or may not be related. When I move the spi.read() statement into any function except the main loop it either stops working (or can't keep up with the data).
Specifically, I'm receiving data at 1 byte every 4 microseconds, so the 72 megaHz Maple processor should be able to run 288 assembly instructions before the next byte arrives. My code (in c) does at most 1) an spi.read, 2) a lookup in a 256 bit table, 3) a function that does two reassigns, then an if... switch to another reassign and a return and 4) one more conditional after the return. I don't know what this maps to in assembly but when I put in a timer it measured this cycle at 2 microseconds. I need to move the spi.read out of the main loop so I can do other functions but it stops working.
Here is all the relevant code which works fine as is. In loop I've commented out the 3 simple OPTIONS I've tired. With each I never get a successful userID. With OPTION 3, I don't think the overhead of simply going to a function is sufficient to use up my 288 cycles so maybe there is some other problem I can't think of.
Thanks in advance...
// Written by Rick Rantilla - January 2012
// with help from Nick Gammon
char sketch[] = "Maple_SPI_jan17q "; // Rick a
// rev q - clean up code - simplify calls to servos
// rev m - removed interrupts - fussing with raw2work table and getDigit() sequence
// rev k - learning interrupts - I didn't need them
// Hooked up to T&A, which sends 1500 byte bursts at 2.25 megaHz (1 byte every 4 microsec)
// 10% pass first filter, half those pass 2nd filter, then I analyze remainder for userID
// so a 256 byte buffer seems adequate
// rev f - IT WORKS! now let's find it's limits before integrating hw
// rev e - testing pin 31 (slave select)
// Rev d - corrected if raw2work loop
// experimenting with SPI mode - unsure of Slave Select/Enable
// Rev c - using HardwareSPI 2 - which is 5v tolerant
// Rev b - isn't working. Let's try as a master in example
// OK got spi.beginSlave() going
// Rev a - goal is to get basic SPI running on Maple
// then hook it to T&A and see if dropped % and junk % are better
// currently have an Arduino 2009 with SPI master connected
// also have logic analyzer connected
// global includes, variables, etc.
// Use SPI port number 2 - which is 5 volt tolerant
HardwareSPI spi(2); // Rick a - this spi is on pins 31 - 34
#include <Servo.h> // Rick A
// global variables
byte g = 0; // Rick J
byte i = 0; // Rick p
byte j = 0; // Rick p
byte k = 0; // Rick p
byte p = 0; // Rick x - I've made all counters unique and global
volatile byte c;
volatile byte cp;
volatile byte work_digit=9; // Rick n
volatile byte good_digit[255]; // Rick d - need to initialize to something besides 0
volatile boolean raw2work[] = {0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, // 0-31 Rick w
0,1,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,1,0,1,1, // 32-63
0,0,0,1,0,0,0,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 64-95
1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,1, // 96-127
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 128-159
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 160-191
1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 192-223
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 };// 224-255
// Rick x - only bytes in this table pass thru to the next step of decoding
// namely: 1,19,33,35,60,62,67,71,96,126,127,192
// Maple m - also letting in 63 to eliminate digit pairs creating false readings
int userID = 0; // Rick B
byte userDoor[255]; // Rick H - registerNewUser() uses to assign doors
int keySwitch = 26; // external key positions CW = ClockWise position
// note HardwareSPI on Maple uses pins 31, 32, 33, 34
byte SS = 31; // Maple e - test this SPI pin - Need to turn on for SPIslave to work!!!
void setup() {
pinMode (SS, INPUT); // Maple e - test SPI pins (also undocumented requirement for SPI)
// Turn on the SPI port
spi.beginSlave(MSBFIRST, SPI_MODE_2); // use this for T&A
//spi.beginSlave(MSBFIRST, SPI_MODE_0); // use this for data from Arduino simulator
//spi.begin(SPI_2_25MHZ, MSBFIRST, 0); // Maple d - if using as Master
pinMode (keySwitch, INPUT_PULLUP);
} // end setup
void loop() {
// if (digitalRead(keySwitch) == HIGH) {adultCare();} else {childCare();} // OPTION 1 - fail
// also tried using interrupts OPTION 2 - fail
// adultCare(); // with spi.read in adultCare function it stops working OPTION 3 - fail
//} // end loop
//void adultCare() {
work_digit = spi.read(); // get something on MOSI at 1 byte every 4 microsec in 1500 byte bursts
// goal is to extract 8 digit userID from each burst
if (raw2work[work_digit]>0) // Rick f - check against the valid bit map table - only about 10% should pass
{
getDigit(); // Rick x - converts only valid digits, less than half make it through this filter
// returns with a new good_digit[] at g, or with g unchanged
if (good_digit[g-8] == 0) // is it getting within range?
{
if((good_digit[g-7]==0) && (good_digit[g-6]==0) && (good_digit[g-5]==0))
{ // a valid userID starts with 4 zeroes - print the 4 least significant digits
// don't care how long this takes, I won't get another userID for a few billion cycles
userID = 1000 * good_digit[g-4] + 100 * good_digit[g-3] + 10 * good_digit[g-2] + good_digit[g-1];
SerialUSB.print("User ID = "); SerialUSB.println(userID); // debug
// do a bunch of other stuff here
} // end if good_digit(-7)
} // end if good_digit(-8)
} // end if raw2work - most of the time loop does nothing but check inpoint/outpoint
} // end adultCare()
void childCare()
{
// a completely different set of stuff that doesn't require spi.read()
} // end childCare
void getDigit() // Rick p
{
cp = c; // Rick n - store previous digit needed to distinguish a 1, 3 or 8
c = work_digit; // still the raw byte as SPI found it, but only those in raw2work lookup table
switch (c) // Rick n - each graphic bitmap has 16 bytes per digit displayed (plus 6 command digits)
// Among the digits, each digit has a unique byte (or byte pair)
// 96, 192, 62, 126 and 127 may also appear in other digits, but unique pairings finalize the selection
// So whenever I find this unique byte (pair) in a field of digits, I've got a good digit
// regardless of what else is in that digit
// I might also get what appears to be a digit in a field of commands or letters or the clock,
// but I will later throw them out unless they are immediately following 4 zeroes in a row
// Increment g only if a valid digit found
{
case 127: break; // Maple m - dispense with these in a hurry, there are a lot of them
case 126: break;
//case 192: break;
case 71:
good_digit [g++] = 0; // Rick e
break;
case 96: // original 127 remapped to 11 if cp was 0
if (cp == 192) {good_digit [g++] = 1; }// Rick t
break;
case 67:
good_digit [g++] = 2; // Rick d
break;
case 62: // original 32 remapped to 5 if cp was 0
if (cp == 127) {good_digit [g++] = 8; }// Rick t
if (cp == 126) {good_digit [g++] = 3; } // Rick t
// Note: there is a bug where sequence "43" in a valid user ID would register as "413"
// since a "4" ends in "192" and the "3" starts with "96"
// this looks like a "1" which is defined as a "96" "192"
// also "08" since "8" begins with "62" and "0" ends with "127"
// which would be "008"
// although these bytes are not part of their "unique" byte pairs
break;
case 19:
good_digit [g++] = 4; // Rick d
break;
case 33:
good_digit [g++] = 5; // Rick e
break;
case 60:
good_digit [g++] = 6; // Rick d
break;
case 1:
good_digit [g++] = 7; // Rick d
break;
case 35:
good_digit [g++] = 9; // Rick d
break;
default:
//time = micros() - time; Serial.println (time, DEC); delay(100); // debug
break;
} // end of switch
} // end of getDigit