/*
 * SelfTest.c
 *
 *  Created on: Aug 6, 2013
 *      Author: jclasquin
 */

#include "driverlib\device.h"
#include "stddef.h"
#include "hunterdef.h"

uint32 DebugData[5];

BOOL MemTestInit()
{
	BOOL bReturn = TRUE;

	HWREG(PBIST_BASE + PBIST_PACT) = 1;              // Enable the PBIST internal clocks
	HWREG(PBIST_BASE + PBIST_OVER) = 9;              // override register
	if((HWREG(NVIC_PEND2) & 0x08000000) == 0x08000000) {
	    bReturn = FALSE;                             // Error - PBIST interrupt already pending. Device not reset properly.
	}
	return bReturn;
}

BOOL StartTestAndWait()
{
	HWREG(PBIST_BASE + PBIST_DLR) = 0x21C;           // Configure PBIST to run in Go/No-Go testing mode and kick off the PBIST Test

	// Wait for the PBIST test to complete by polling bit 27 of the NVIC_PEND2 register
	while((HWREG(NVIC_PEND2) & 0x08000000) != 0x08000000) {}

	// Once complete, clear bit 27 of the NVIC_UNPEND2 register
	HWREG(NVIC_UNPEND2) = 0x08000000;

	DebugData[0] = HWREG(PBIST_BASE + PBIST_FSRF0);
	DebugData[1] = HWREG(PBIST_BASE + PBIST_FSRF1);
	DebugData[2] = HWREG(PBIST_BASE + PBIST_RAMT);
	DebugData[3] = HWREG(PBIST_BASE + PBIST_FSRC0);
	DebugData[4] = HWREG(PBIST_BASE + PBIST_FSRC1);


	if ((HWREG(PBIST_BASE + PBIST_FSRF0) != 0) || (HWREG(PBIST_BASE + PBIST_FSRF1) != 0)) {
		return TRUE;                                // Return error - Test failed
	}
	else {
	  	HWREG(PBIST_BASE + PBIST_DLR) = 0x218;       // Stop the test
	   	HWREG(PBIST_BASE + PBIST_PACT) = 0;          // Disable the PBIST controller
	   	return FALSE;                                // Return no error
	}
}


uint16 RunPBist()
{
	uint16 ulReturnValue;

	if (MemTestInit() == FALSE) {
		ulReturnValue = 2;                                 // Error 2 - Failed to init
	}
	// ROM Test - All ROM areas except M3 boot ROM.  Testing that ROM caused the test to never end (stuck in while loop waiting for NVIC_PEND2)
	else {
		HWREG(PBIST_BASE + PBIST_ALGO) = 0x1F600001;       // Choose ALGO (Two Port Memories; Triple Read for ROM's) .
		HWREG(PBIST_BASE + PBIST_OVER) = 1;                // Memory Override. This forces the PBIST controller to override the value in the RINFOL and RINFOU registers..
		ulReturnValue = (StartTestAndWait() ? 4 : 0);      // Returns 0 if pass, 4 if fail
	}
	// RAM Test
	if (ulReturnValue == 0) {
		if (MemTestInit() == FALSE)
			ulReturnValue = 2;                             // Error 3 - Failed 2nd init
		else {
			HWREG(PBIST_BASE + PBIST_ALGO)   = 0x00100000; // March 13N: Single Port RAM Distributed Compare
			HWREG(PBIST_BASE + PBIST_OVER)   = 0;
			HWREG(PBIST_BASE + PBIST_RINFOL) = 0x00000000;
			HWREG(PBIST_BASE + PBIST_RINFOU) = 0x00000100; // Shared 0-7, PIE0-1, DCAN0-5, MSG0-1, L0-3, USB, but not C0-C3 because we're using those when the M3 bootloader is running
			ulReturnValue = (StartTestAndWait() ? 5 : 0);  // Returns 0 if pass, 5 if fail
		}
	}
	return ulReturnValue;
}



