Shop OBEX P1 Docs P2 Docs Learn Events
Which memory model to use? — Parallax Forums

Which memory model to use?

pgbpsupgbpsu Posts: 460
edited 2012-11-16 15:04 in Propeller 1
I'm working on a Gadget Gangster Propeller Platform USB (with 64k EEPROM). I've got a C program which has some rather large (data) includes totaling 35,632 bytes. With the 64K available on my PP it seems I should have plenty of room for these data files AND a good bit of code, yet I keep getting 'hub' overflow problems.

Board Type: PPUSB
Optimizations: -Os Size
Compiler Type: C
Memory Model:
LMM - overflowed by 24260 bytes
CMM - overflowed by 15452 bytes
XMMC - overflowed by 6708 bytes
XMM-Single compiles 58,720 bytes but when executed it doesn't print anything to the console so something clearly isn't working.
XMM-SPLIT compiles to 58,720 bytes total but also doesn't display the console messages correctly (at all in fact).

Should I be using a different memory model? What can I do to reduce the code size? I've stripped out all the time functions. At this point all I'm doing is some (big) array stuff, some printing, and some pin flipping. Seems like that should fit in much less than 28K leaving the rest of the 64K for the data includes. Do I mis-understand the way the XMMC memory model works?

I'm new to C but this program doesn't seem that complicated to me yet it takes an enormous amount of space. My code is below and if anyone can help explain why I'm having so much trouble fitting this into 64Kbytes I'd be grateful.

Thanks,
Peter
/**
 * @file My_RedPine.c
 * This is the main My_RedPine program start point.
 */
#include <stdio.h>                  // standard io routines
#include <propeller.h>              // common Propeller related definitions Cog registers
//#include <time.h>                   // used for timing function
//#include <sys/time.h>               // usef for timing
//#include <stdint.h>                 // type definitions
#include "pin.h"                    // a local include - definitions not a part of the standard
                                    // libraries - this header file contains definitions of the 
                                    // PIN I/O functions - there is a corresponding pin.c file 
                                    // which must be included in your projects
//extern _Driver _SimpleSerialDriver;
//extern _Driver _FileDriver;
typedef unsigned char UCHAR;
typedef unsigned long DWORD;
typedef unsigned long UINT;
/* This is a list of all drivers we can use in the
 * program. The default _InitIO function opens stdin,
 * stdout, and stderr based on the first driver in
 * the list (the serial driver, for us)
 */
//_Driver *_driverlist[] = {
//  &_SimpleSerialDriver,
//  &_FileDriver,
//  NULL
//};

#define uint8 unsigned char


//Define all SPI Pins
#define WIFI_MISO    8     /* Define SPI SDI signal to be PIC port RC5 */
#define WIFI_MOSI    9     /* Define SPI SDO signal to be PIC port RC4 */
#define WIFI_CS     10     /* Define SPI CS signal to be PIC port RB1 */
#define WIFI_CLK    11     /* Define SPI CLK signal to be PIC port RC3 */
#define WIFI_INTR   12     /* Define WiFi interrupt line.  When high, wifi has data to transmit */
#define WIFI_RESET  13     /* Define WiFi reset line.  This line is active low */

#define BUFFER_SIZE 1400   // number of bytes in our input/output buffer
#define START_TOKEN 0x55   // start token for red pine responses

//int HUBTEXT spiByte(char display, int data_out);
int HUBTEXT spiReadWriteBytes(int count, char display);
int setupWiFiIO(void); 
int resetWiFi(void);
int lowerWiFiCS(void);
int initWiFiSPI(void);
int setSoftReset(void);
int loadSBINST1(void);
int loadSBINST2(void);
int loadSBDATA1(void);
int loadSBDATA2(void);
int readWriteFile(int infile, char display);
int removeSoftReset(void);
int waitForIrq(void);
int masterRead(unsigned short, unsigned char, unsigned char display);
int bandCommand(void);
int initCommand(void);
int queryMAC(void);
int printBuffer(int count);
int pauseMS(unsigned int);

/**
 * Main program function.
 */
 
/*
double dtime()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0);
}
*/
unsigned char buffer[BUFFER_SIZE];

int main(int argc, char *argv[])
{
    
    int idx = 0;
    int j = 0;
    unsigned int t1, t2;
//    double elapsed;
    
    printf("Welcome Aboard.\n");
//    elapsed = dtime();
    setupWiFiIO();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
     
//    elapsed = dtime();
    resetWiFi();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
 
//    elapsed = dtime();
    lowerWiFiCS();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
 
//    elapsed = dtime();
    initWiFiSPI();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
 
//    elapsed = dtime();
    setSoftReset();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
 
//    elapsed = dtime();
    loadSBINST1();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
 
//    elapsed = dtime();
    loadSBINST2();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
 
//    elapsed = dtime();
    loadSBDATA1();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
 
//    elapsed = dtime();
    removeSoftReset();
    waitForIrq();    
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);

//    elapsed = dtime();
    masterRead(16,0x89,0);
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
    
//    elapsed = dtime();
    loadSBDATA2();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
    
    printf("Done with Bootload operation.\n");
//    elapsed = dtime();
    bandCommand();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
    
//    elapsed = dtime();
    masterRead(16,0x97,0);
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
    
//    elapsed = dtime();
    initCommand();
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);

//    elapsed = dtime();
    masterRead(16,0x94,0);
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
    
//    elapsed = dtime();
    qwFirmware();
    waitForIrq();    
    masterRead(16,0xFF,1);
    if (buffer[0] == 0xFF) {
        idx = (buffer[9] << 8) | buffer[8];
    } else {
        idx = buffer[0];
    }
    masterRead(idx,0xFF,0);
    printBuffer(idx);
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
    
//    elapsed = dtime();
    queryMAC();
    waitForIrq();    
    masterRead(16,0xFF,1);
    if (buffer[0] == 0xFF) {
        idx = (buffer[9] << 8) | buffer[8];
    } else {
        idx = buffer[0];
    }
    masterRead(idx,0xFF,0);
    printBuffer(idx);
//    elapsed = dtime() - elapsed;
//    printf("Elapsed time in sec: %f\n",elapsed);
    pauseMS(1000);
    return 0;
    
}

/******************************************************************************************
 * seupWiFiIO -- function to setup the pins states and directions for the WiFi device
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 ******************************************************************************************/
int setupWiFiIO(void) { 
    printf("Setting up pins.\n");
    // MISO
    pinLow(WIFI_MISO);
    pinInput(WIFI_MISO);  
    // MOSI
    pinLow(WIFI_MOSI);
    pinOutput(WIFI_MOSI);  
    // CLK
    pinHigh(WIFI_CLK);
    pinOutput(WIFI_CLK);  
    // CS
    pinOutput(WIFI_CS); 
    pinHigh(WIFI_CS);
    // INTR
    pinLow(WIFI_INTR);
    pinInput(WIFI_INTR);  
    // RESET 
    pinOutput(WIFI_RESET);  
    pinHigh(WIFI_RESET);
    
    return 1;
}

/******************************************************************************************
 * resetWiFi -- function to setup the pins states and directions for the WiFi device
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 ******************************************************************************************/
int resetWiFi(void) { 
    printf("Resetting WiFi.\n");

    // RESET 
    pinLow(WIFI_RESET);
    waitcnt(CLKFREQ/10+CNT);
    pinHigh(WIFI_RESET);
    waitcnt(CLKFREQ/10+CNT);
   
    return 1;
}

/******************************************************************************************
 * lowerWiFiCS -- lower chip select for wifi device
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 ******************************************************************************************/
int lowerWiFiCS(void) { 
    printf("Lowering WiFi CS.\n");

    // RESET 
    pinLow(WIFI_CS);
    
    return 1;
}

/******************************************************************************************
 * initWiFiSPI -- function that initalized the WiFi unit to SPI:
 * sends 0x15 0x00 to the device.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int initWiFiSPI(void) { 
    printf("Setting WiFi to SPI.\n");

    int idx = 0;
    char display = 0;
    
    buffer[idx++] = 0x15;
    buffer[idx++] = 0x00;
    spiReadWriteBytes(idx,display);
    
    
    if (buffer[1] == 0x58) 
        return 1;
    else    
        return 0;
}

/******************************************************************************************
 * setSoftReset -- function that takes the unit out of soft reset; simply sends a string
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int setSoftReset(void) { 
    printf("Setting soft reset.\n");

    int result;
    int idx = 0;
    char display = 0;

    buffer[idx++] = 0x74;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x22;
    buffer[idx++] = 0x01;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    
    return spiReadWriteBytes(idx, display);
    
    
}

/******************************************************************************************
 * loadSBINST1 -- function that pulls SBINST1 data from memory and writes it to the WiFi
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int loadSBINST1(void) { 
    printf("\nLoading SBINST1.\n");

    int infile;
    int idx = 0;
    char display = 0;
    static uint8 sbinst1[] = {  //16 bytes
        #include "sbinst1"
    };

    buffer[idx++] = 0x74;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x10;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    
    spiReadWriteBytes(idx, display);

    for (idx=0; idx<sizeof(sbinst1); idx++) {
        buffer[0] = sbinst1[idx];
        spiReadWriteBytes(1, 1);
    }
    printf("\nWrote %d bytes.", idx);

/*
    if (( infile = fopen("sbinst1", "r")) == NULL ) {
        fprintf(stdout,"Unaable to open sbinst1\n");
        exit(2);
    } else {
      readWriteFile(infile, display);
    }
    fclose(infile);
*/    
    return 1;
}


/******************************************************************************************
 * loadSBINST2 -- function that pulls SBINST2 data from memory and writes it to the WiFi
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int loadSBINST2(void) { 
    printf("\nLoading SBINST2.  ");

    int infile;
    int idx = 0;
    char display = 0;
    static uint8 sbinst2[] = {  // 1008 bytes
        #include "sbinst2"  
    };

    buffer[idx++] = 0x74;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0xf0;
    buffer[idx++] = 0x03;
    buffer[idx++] = 0x10;
    buffer[idx++] = 0x40;
    buffer[idx++] = 0x01;
    buffer[idx++] = 0x02;
    
    spiReadWriteBytes(idx, display);

    for (idx=0; idx<sizeof(sbinst2); idx++) {
        buffer[0] = sbinst2[idx];
        spiReadWriteBytes(1, 1);
    }
    printf("\nWrote %d bytes.", idx);

/*
    if (( infile = fopen("sbinst2", "r")) == NULL ) {
        fprintf(stdout,"Unaable to open sbinst2\n");
        exit(2);
    } else {
      readWriteFile(infile, display);
    }
    fclose(infile);
*/
    return 1;

}

/******************************************************************************************
 * loadSDATA1 -- function that pulls SBDATA1 data from memory and writes it to the WiFi
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int loadSBDATA1(void) { 
    printf("\nLoading SBDATA1.");

    int infile;
    int idx = 0;
    char display = 0;
    static uint8 sbdata1[] = {  // 32 bytes
        #include "sbdata1"  //#include "Firmware/sbdata1"  // change to sbdata1 for size reasons PGB
    };

    buffer[idx++] = 0x74;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x20;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x31;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x20;

    spiReadWriteBytes(idx, display);
    
    for (idx=0; idx<sizeof(sbdata1); idx++) {
        buffer[0] = sbdata1[idx];
        spiReadWriteBytes(1, 1);
    }
    printf("\nWrote %d bytes.", idx);

/*
    if (( infile = fopen("sbdata1", "r")) == NULL ) {
        fprintf(stdout,"Unaable to open sbdata1\n");
        exit(2);
    } else {
      readWriteFile(infile, display);
    }

    fclose(infile);
*/
    return 1;
}

/******************************************************************************************
 * loadSDATA2 -- function that pulls SBDATA2 data from memory and writes it to the WiFi
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int loadSBDATA2(void) { 
    printf("\nLoading SBDATA2.\n");

    int infile;
    int idx = 0;
    char display = 0;
    static uint8 sbdata2[] = {  // 34576 bytes
        #include "sbdata2"  //#include "Firmware/sbdata2"  // change to sbdata1 for size reasons PGB
    };
    
    for (idx=0; idx<sizeof(sbdata2); idx++) {
        printf("%d\t",sbdata2[idx]);
    }

/*
    buffer[idx++] = 0x74;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x10;
    buffer[idx++] = 0x87;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0xF8;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x02;
  
    spiReadWriteBytes(idx, display);

    for (idx=0; idx<sizeof(sbdata2); idx++) {
        buffer[0] = sbdata2[idx];
        spiReadWriteBytes(1, 1);
    }
    printf("\nWrote %d bytes.", idx);
*/
/*
    if (( infile = fopen("sbdata2", "r")) == NULL ) {
        fprintf(stdout,"Unaable to open sbdata2\n");
        exit(2);
    } else {
      readWriteFile(infile, display);
    }

    fclose(infile);
*/
    return 1;
}

/******************************************************************************************
 * readWriteFile -- function that pulls chars one-by-one from currently open file and 
 * feeds them to the RedPine
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int readWriteFile(int infile, char display) { 
    int idx=0;
    unsigned char rxByte;
    unsigned char txByte;
    
    while (fread(&rxByte, 1, sizeof(rxByte), infile) != NULL) {
        if (rxByte == 120) {//ascii x {
            txByte = 0;
            idx++;
        }
        
        if (rxByte > 47 && rxByte < 58) { // limit this to valid 0-9 chars
            txByte = txByte << 4;
            txByte = txByte | (rxByte - 48);
        }
        
        if (rxByte > 96 && rxByte < 103) { //limit this to valid A-F chars
            txByte = txByte << 4;
            txByte = txByte | (rxByte - 97 + 10);
        }
        
        if (rxByte == 10) { // ascii 10 (\n) send this byte
            buffer[0] = txByte;
            spiReadWriteBytes(1, display);
        }
    }
    
    fprintf(stdout,"Read %d bytes from infile and sent them to RedPine. \n", idx);
        
    return 1;
}

/******************************************************************************************
 * removeSoftRest -- function that removes soft reset
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int removeSoftReset(void) { 
    printf("\nRemoving Soft Reset\n");

    int idx = 0;
    char display = 0;

    buffer[idx++] = 0x74;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x22;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;

    spiReadWriteBytes(idx, display);

    return 1;
}

/******************************************************************************************
 * masterRead -- function that sets up a master read (send 0x5C, 0x00, numReads), then 
 * waits for start token (0x55), then reads the specified number of bytes.  
 *
 * Paramterers
 *   bytesToRead -- number of bytes to read
 *   token       -- token to scan for
 *   display     -- display bytes read back 1=YES; OTHER=NO
 * 
 * Returns 
 *   1 on success
 ******************************************************************************************/
int masterRead(unsigned short bytesToRead, unsigned char token, unsigned char display) { 
    printf("Time for Master Read.\n");

    int idx = 0; 
    
    buffer[idx++] = 0x5C;
    buffer[idx++] = 0x00;
    buffer[idx++] = ((bytesToRead & 0x00FF)>>0);
    buffer[idx++] = ((bytesToRead & 0xFF00)>>8);
    spiReadWriteBytes(idx, display);

    buffer[0] = 0x00; 
    spiReadWriteBytes(1, 0);
    while (buffer[0] != START_TOKEN) {
        spiReadWriteBytes(1, 0);
        pauseMS(10);
    } 
    printf("\nFound start token (0x55).  Now reading %d bytes.", bytesToRead);
    
    // read in all the bytes.  
       spiReadWriteBytes(bytesToRead, 0);
    
    // now print them to the console
    if (display == 1) {  
        for (idx=0; idx<bytesToRead; idx++) {
            printf("\n%d\t%02x", idx, buffer[idx]);
            if (buffer[idx] == token)
              printf(" FOUND ");
        }
    }
    printf("\n");

    return 1;
}

/******************************************************************************************
 * bandCommand -- function that sets up the band for this unit
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int bandCommand(void) { 
    printf("Setting band to: 2.4Ghz\n");

    int idx = 0;
    char display = 0;

    buffer[idx++] = 0x7c;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x10;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x02;
    buffer[idx++] = 0x18;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x00;
       spiReadWriteBytes(idx, display);
    
    printf("Sending payload\n");
    idx = 0;
    buffer[idx++] = 0x7c;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    spiReadWriteBytes(idx, display);

    return 1;
}

/******************************************************************************************
 * qwFirmware -- function that request the firmware version
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int qwFirmware(void) { 
    printf("Requesting firmware version\n");

    int idx = 0;
    char display = 0;

    buffer[idx++] = 0x7c;
    buffer[idx++] = 0x02;
    buffer[idx++] = 0x10;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x02;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x02;
    buffer[idx++] = 0x00;
       spiReadWriteBytes(idx, display);
    
    printf("Sending payload\n");
    idx = 0;
    buffer[idx++] = 0x7c;
    buffer[idx++] = 0x02;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x0d;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
       spiReadWriteBytes(idx, display);
    
    
    return 1;
}

/******************************************************************************************
 * queryMAC -- function that queries the MAC address of current module
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int queryMAC(void) { 
    printf("Requesting MAC address.\n");

    int idx = 0;
    char display = 0;

    buffer[idx++] = 0x7c;
    buffer[idx++] = 0x02;
    buffer[idx++] = 0x10;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x02;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x02;
    buffer[idx++] = 0x00;
    spiReadWriteBytes(idx, display);
    
    printf("Sending payload\n");
    idx = 0;
    buffer[idx++] = 0x7c;
    buffer[idx++] = 0x02;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x0f;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    spiReadWriteBytes(idx, display);
    
    return 1;
}

/******************************************************************************************
 * initCommand -- function that ssends the init command
 * of bytes.  
 *
 * Paramterers
 *   none
 * 
 * Returns 
 *   1 on success
 *   0 on failure
 ******************************************************************************************/
int initCommand(void) { 
    printf("Sending init command.\n");

    int idx = 0;
    char display = 0;
    

    buffer[idx++] = 0x7c;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x10;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x10;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x00;
    buffer[idx++] = 0x04;
    buffer[idx++] = 0x00;
       spiReadWriteBytes(idx, display);
    
    
    return 1;
}

/******************************************************************************************
 * printBuffer(int count) -- function that prints contents of buffer
 *
 * Paramterers
 *   count - number of bytes to print
 * 
 * Returns 
 *   1 on success
 ******************************************************************************************/
int printBuffer(int count) {
    int idx;
    
    for (idx=0; idx<count; idx++) {
        printf("\n%d\t%02x", idx, buffer[idx]);
        if (32<buffer[idx] && buffer[idx]<123) {
            printf("\t%c",buffer[idx]);
        }
     }
    printf("\n");
    return 1;
}

/******************************************************************************************
 * pauseMS -- function to pause give number of milliseconds
 *
 * Paramterers
 *   milliseconds to pause
 * 
 * Returns 
 *   1 on success
 ******************************************************************************************/
int pauseMS(unsigned int ms) {

    waitcnt(CLKFREQ/1000*ms+CNT);
       
    return 1;
}

/******************************************************************************************
 * waitForIrq -- wait here until WIFI_INTR line alerts.  
 *
 * Paramterers
 *    none
 * 
 * Returns 
 *   1 on success
 ******************************************************************************************/
int waitForIrq(void) {

    printf("\nWaiting for interrupt from WiFi");
    while ( pinGet(WIFI_INTR) == 0) {
      printf(".");
      pauseMS(10);
    }
    printf("\nInterrupt found.\n");
    
    return 1;
}

/******************************************************************************************
 * spiReadWriteBytes -- write count bytes from buffer putting received bytes back into 
 *  buffer; once all bytes have been read/written it will print the contents depending on
 *  value of display argument  
 *
 * Paramterers
 *   count -- number of bytes to read/write
 *   diplay -- print contents of buffer when finished 1=YES; ELSE=NO
 * 
 * Returns 
 *   returns number of bytes written/read
 ******************************************************************************************/
int HUBTEXT spiReadWriteBytes(int count, char display) {
    unsigned char  dataOut;
    int  idx;
    
    for (idx=0; idx<count; idx++) {
        dataOut = buffer[idx];
        buffer[idx] = 0;

        // bit 0
        pinLow(WIFI_CLK);
        pinSet(WIFI_MOSI, dataOut >> 7);
        buffer[idx] = (buffer[idx] <<  1) | pinGet(WIFI_MISO);
        pinHigh(WIFI_CLK);

        // bit 1
        pinLow(WIFI_CLK);
        pinSet(WIFI_MOSI, dataOut >> 6);
        buffer[idx] = (buffer[idx] <<  1) | pinGet(WIFI_MISO);
        pinHigh(WIFI_CLK);

        // bit 2
        pinLow(WIFI_CLK);
        pinSet(WIFI_MOSI, dataOut >> 5);
        buffer[idx] = (buffer[idx] <<  1) | pinGet(WIFI_MISO);
        pinHigh(WIFI_CLK);

        // bit 3
        pinLow(WIFI_CLK);
        pinSet(WIFI_MOSI, dataOut >> 4);
        buffer[idx] = (buffer[idx] <<  1) | pinGet(WIFI_MISO);
        pinHigh(WIFI_CLK);

        // bit 4
        pinLow(WIFI_CLK);
        pinSet(WIFI_MOSI, dataOut >> 3);
        buffer[idx] = (buffer[idx] <<  1) | pinGet(WIFI_MISO);
        pinHigh(WIFI_CLK);

        // bit 5
        pinLow(WIFI_CLK);
        pinSet(WIFI_MOSI, dataOut >> 2);
        buffer[idx] = (buffer[idx] <<  1) | pinGet(WIFI_MISO);
        pinHigh(WIFI_CLK);

        // bit 6
        pinLow(WIFI_CLK);
        pinSet(WIFI_MOSI, dataOut >> 1);
        buffer[idx] = (buffer[idx] <<  1) | pinGet(WIFI_MISO);
        pinHigh(WIFI_CLK);

        // bit 7
        pinLow(WIFI_CLK);
        pinSet(WIFI_MOSI, dataOut);
        buffer[idx] = (buffer[idx] <<  1) | pinGet(WIFI_MISO);
        pinHigh(WIFI_CLK);
    }

    //clear clock and MOSI to low on exit
    pinLow(WIFI_CLK);
    pinLow(WIFI_MOSI);

    if (display == 1) {
        for (idx=0; idx<count; idx++) {
            printf("%d\t%02x\n", idx, buffer[idx]);
        }
    }
    return idx;

}

Comments

  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-16 08:40
    pgbpsu wrote: »
    XMM-Single compiles 58,720 bytes but when executed it doesn't print anything to the console so something clearly isn't working.
    XMM-SPLIT compiles to 58,720 bytes total but also doesn't display the console messages correctly (at all in fact).
    Neither of these memory models will work with the EEPROM cache driver or even the SD cache driver. You're limited with both of those to putting code in external memory, not data. That means you're stuck with the XMMC memory model which puts code in external memory and all data in hub memory. If you try the SD cache driver instead of the EEPROM cache driver your program will probably fit. However, it won't run very fast from the SD card. The best solution to external memory is using SPI or better yet SQI flash. You might want to consider the new DNA boards.
  • pgbpsupgbpsu Posts: 460
    edited 2012-11-16 08:55
    Hi Dave-

    Thanks for responding. If I'm stuck with XMMC that's fine with me. At the moment I'm not concerned about speed. However I am stuck with my Gadget Gangster platform. Can you explain a bit more about this memory model? Do I have the 64Kbytes of the EEPROM available for code and the 32K HUB ram available for data? I assume this
        static uint8 sbdata2[] = {  // 34576 bytes
            #include "sbdata2"  //#include "Firmware/sbdata2"  // change to sbdata1 for size reasons PGB
        };
    
    
    would be treated as data. Is that correct? Is there a way to force that to be stored with code, because clearly that's too large to fit in HUB?

    I actually tried to use some code posted by Dr. Acula that would allow me to put my large data (sbinst1,2, sbdata1,2) on an SD card and read them in. They are firmware instructions need for the wifi module I'm working with. I only need them at boot-up. That kinda-sorta works. I was able to open the files, read them one at a time, write them to my device and move on but it quit working so I went back to trying to fit everything into memory. I don't know what failed, but it made the card un-readable and I couldn't get it working again. I reformatted the SD card put the files on it again and had more trouble. So I went back to this. Is there any chance of getting this code and these file to fit without resorting to the SD card?

    Thanks,
    Peter
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-16 09:08
    You have a little less than 64k for code since a loader program containing the EEPROM cache driver has to reside at the start of the EEPROM. The rest of the EEPROM is available for your code. I'm not sure exactly how much is left but jazzed may be able to tell us since he wrote the EEPROM cache driver. Also, since this is a cache driver it uses some of hub memory for its cache so you won't have all of the 32k of hub memory to use for your data. I think the cache size is currently set to 8k so about 32k-8k=24k is available for your data. It's actually a little less than that because the cache driver also uses a mailbox to talk to the COG running your code.
  • jazzedjazzed Posts: 11,803
    edited 2012-11-16 10:35
    I've run XMMC EEPROM programs that were 54KB in a 64KB EEPROM.
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-16 10:43
    jazzed wrote: »
    I've run XMMC EEPROM programs that were 54KB in a 64KB EEPROM.
    The problem is there is currently no way to run CMM code from external memory so it might be better to just use CMM rather than XMMC from EEPROM.
  • pgbpsupgbpsu Posts: 460
    edited 2012-11-16 12:41
    I appreciate all the feedback, but I'm afraid I don't follow. It sounds like I've got 54KB to work with. My includes take up about 35KB and hopefully the other stuff will fit in the remainder, but how can I tell what portion of my program gets stored as data and what part gets stored as code? And is there a way to force portions of the code to live in a specific place?

    Is there any hope that an array containing 34576 bytes can fit on the board I have (Gadget Gangster Propeller Platform 64Kb EEPROM).

    Thanks,
    Peter
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-16 12:46
    pgbpsu wrote: »
    I appreciate all the feedback, but I'm afraid I don't follow. It sounds like I've got 54KB to work with. My includes take up about 35KB and hopefully the other stuff will fit in the remainder, but how can I tell what portion of my program gets stored as data and what part gets stored as code? And is there a way to force portions of the code to live in a specific place?

    Is there any hope that an array containing 34576 bytes can fit on the board I have (Gadget Gangster Propeller Platform 64Kb EEPROM).

    Thanks,
    Peter
    I'm afraid that to use an array that large you'll have to use a board that supports external RAM. Jazzed has an SDRAM board that will plug into your Propeller Platform board that has 32mb of SDRAM.
  • jazzedjazzed Posts: 11,803
    edited 2012-11-16 12:49
    Actually, I think there is a way to force a user initialized array into code space. I can't promise anything right now though as I'm tied up with other pressing issues.
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-16 12:52
    jazzed wrote: »
    Actually, I think there is a way to force a user initialized array into code space. I can't promise anything right now though as I'm tied up with other pressing issues.
    Yes, that would be a good option if your data is static.
  • pgbpsupgbpsu Posts: 460
    edited 2012-11-16 12:53
    Dave-

    I'd forgotten all about this board. But turns out I have one of the earliest ones he made. I'm checking it now to see if I've got pin conflicts. The next question is how to target that with SimpleIDE.
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-16 12:58
    pgbpsu wrote: »
    Dave-

    I'd forgotten all about this board. But turns out I have one of the earliest ones he made. I'm checking it now to see if I've got pin conflicts. The next question is how to target that with SimpleIDE.
    I think there is a board configuration called "SDRAM" that should work.
  • pgbpsupgbpsu Posts: 460
    edited 2012-11-16 13:25
    Hi Dave-

    I've got some hardware issues to solve to make these two boards get along. My wifi board competes with the SDRAM module for pins. I see the board configuration you referenced in SIDE. Do I need to do anything further (additions to the code) to get my program to recognize the SDRAM?
  • jazzedjazzed Posts: 11,803
    edited 2012-11-16 13:30
    This demonstrates how to force a read-only text array into code (.text segment) for XMMC mode.

    Why would we want to do this?

    Simple, there are many apps that need static data such as video games and other graphics oriented programs. This allows us to 1) quickly access read-only data without using up hub memory, 2) the data can be huge if necessary, and 3) accessing XMMC .text segment data is much faster than accessing a comparable external .data segment memory.

    /**
     * @file CodeArray.c
     * This is the main CodeArray program start point.
     */
    #include <propeller.h>
    
    
    __attribute__((section(".text")))
    const char array[] = "Hello there. This is an array that lives in code!";
    
    
    /**
     * Main program function.
     */
    int main(void)
    {
        char marray[100];
        memcpy(marray, array, sizeof(array));
        puts(marray);
        return 0;
    }
    
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-16 13:42
    jazzed wrote: »
    This demonstrates how to force a read-only text array into code (.text segment) for XMMC mode.

    Why would we want to do this?

    Simple, there are many apps that need static data such as video games and other graphics oriented programs. This allows us to 1) quickly access read-only data without using up hub memory, 2) the data can be huge if necessary, and 3) accessing XMMC .text segment data is much faster than accessing a comparable external .data segment memory.

    /**
     * @file CodeArray.c
     * This is the main CodeArray program start point.
     */
    #include <propeller.h>
    
    
    __attribute__((section(".text")))
    const char array[] = "Hello there. This is an array that lives in code!";
    
    
    /**
     * Main program function.
     */
    int main(void)
    {
        puts(array);
        return 0;
    }
    
    This will work but you may have to be careful of how you access this data in code space. I think memcpy has been made to understand external addresses but I don't think you can access these as normal C variables. You probably need to memcpy data from the external array to a buffer in hub memory before manipulating it with normal C code.
  • jazzedjazzed Posts: 11,803
    edited 2012-11-16 13:47
    David Betz wrote: »
    This will work but you may have to be careful of how you access this data in code space. I think memcpy has been made to understand external addresses but I don't think you can access these as normal C variables. You probably need to memcpy data from the external array to a buffer in hub memory before manipulating it with normal C code.

    You're right in the case of XMMC.

    Updated example.
    /**
     * @file CodeArray.c
     * This is the main CodeArray program start point.
     */
    #include <propeller.h>
    
    
    __attribute__((section(".text")))
    const char array[] = "Hello there. This is an array that lives in code!";
    
    
    /**
     * Main program function.
     */
    int main(void)
    {
        char marray[100];
        memcpy(marray, array, sizeof(array));
        puts(marray);
        return 0;
    }
    
  • pgbpsupgbpsu Posts: 460
    edited 2012-11-16 15:04
    Hi Steve and David-

    I wasn't able to get the SDRAM working. I think it was hardware/pin conflicts or pull-up/pull-down conflicts. However, the code Jazzed post for forcing things into text seems to work. Thanks so much.

    Have a great weekend.
    Peter
Sign In or Register to comment.