/********************************************/
/*70V05 Dual Port RAM Configuration Code    */
/*Semaphore version                         */
/********************************************/
/*PIC32MX795F512L-80I                       */
/*PIC32MX765F512L-80I                       */
/********************************************/

#include <xc.h>
#include "MainBrain.h"

#define SRAM_FAIL         0
#define SRAM_PASS         1

int sram_test;
int sram_test_data[8192];
char SRAM_Block;
volatile uint8_t mdata_70V05;
unsigned address_70V05;

void REN70V05_Init(void)
{    
   //RD3 = /CS1
    TRISDbits.TRISD3 = 0;
    PORTDbits.RD3 = 1;
    
    //RG15 = /SEM
    TRISGbits.TRISG15 = 0;
    PORTGbits.RG15 = 1;
    
    //INT1 - INTR
    TRISEbits.TRISE8 = 1;
    
    //RA7 = M/S
    TRISAbits.TRISA7 = 0;
    
    //Slave mode to disable the BUSY logic
    PORTAbits.RA7 = 0;
    
    //BUSY - BUSYR
    //Since we are in slave mode we must pull BUSY
    //  high to allow writes to the port
    TRISEbits.TRISE9 = 0;
    PORTEbits.RE9 = 1;

    return;
}

void REN70V05_WR(unsigned address_70V05, volatile uint8_t mdata_70V05)
{        
    //save previous address
    //this fixes a hang issue
    int d = PMADDR;
    
    //Save the RD/WR Wait State Value
    int wait_m = PMMODEbits.WAITM;
    //Set new wait state = 0;
    //PMMODEbits.WAITM = 0;
    
    PMADDR = address_70V05;
    
    // /CS1 
    PORTDbits.RD3 = 0;
    
    PMDIN = mdata_70V05;
    while(PMMODEbits.BUSY == 1);

    // /CS1
    PORTDbits.RD3 = 1;
    
    //restore previous address
    PMADDR = d;

    //Restore the RD/WR Wait State Value
    PMMODEbits.WAITM = wait_m;    
       
    return;
}

void REN70V05_RD(unsigned address_70V05)
{        
    //save previous address
    //this fixes a hang issue
    int d = PMADDR;
    
    //Save the RD/WR Wait State Value
    int wait_m = PMMODEbits.WAITM;
    //Set new wait state = 0;
    //PMMODEbits.WAITM = 1;
    
    PMADDR = address_70V05;
    
    // /CS1
    PORTDbits.RD3 = 0;
        
    //dummy read
    mdata_70V05 = PMDIN;
    while(PMMODEbits.BUSY == 1);
   
    mdata_70V05 = PMDIN;
    while(PMMODEbits.BUSY == 1);

    // /CS1
    PORTDbits.RD3 = 1;
    
    //restore previous address
    PMADDR = d;
    
    //Restore the RD/WR Wait State Value
    PMMODEbits.WAITM = wait_m;    
    
    return;
}

bool CheckSemaphore(uint8_t sema)
{
    //Pull /SEMR pin low to select semaphore latch
    PORTGbits.RG15 = 0;
    
    //Write a zero to semaphore latch which requests ownership
    REN70V05_WR(sema, 0);
    
    //Now read semaphore latch to verify access
    REN70V05_RD(sema);
    
    //Release /SEMR pin
    PORTGbits.RG15 = 1;
    
    return mdata_70V05;
}

void memtest_70V05(void)
{
    int a;
    int b;
    
    //Save the RD/WR Wait State Value
    int wait_m = PMMODEbits.WAITM;
    
    //Set new wait state = 0;
    PMMODEbits.WAITM = 1;
    
    /////////////////////////////
    //SRAM write all zeros
    ////////////////////////////
    b = 0;
    //8K = 8,191 = 0x1FFF
    for(a=0;a<0x2000;a++)
    {
        PMADDR = a;
        // /CS1 
        PORTDbits.RD3 = 0;

        mdata_70V05 = b;
        PMDIN = mdata_70V05;
        while(PMMODEbits.BUSY == 1);

        // /CS1
        PORTDbits.RD3 = 1;
    }
    /////////////////////////////
    
    //SRAM read and verify 
    for(a=0;a<0x2000;a++)
    {
        PMADDR = a;
        address_70V05 = a;
        mdata_70V05 = 0;
        // /CS1
        PORTDbits.RD3 = 0;

        //dummy read
        mdata_70V05 = PMDIN;
        while(PMMODEbits.BUSY == 1);

        mdata_70V05 = PMDIN;
        while(PMMODEbits.BUSY == 1);

        //Test Fails
        if(mdata_70V05 != 0)
        {
            sram_test = SRAM_FAIL;
            sram_test_data[a] = 0;
        }
        else //Test passes
        {
            sram_test = SRAM_PASS;
            sram_test_data[a] = 1;
        }
        // /CS1
        PORTDbits.RD3 = 1;
    }

    //Restore the RD/WR Wait State Value
    PMMODEbits.WAITM = wait_m;    
    
    return;
}
