//-------------------------------------------------
//          TestSuite: Stability Shared external 
//-------------------------------------------------

#include "lcd.h"
#include "util.h"
#include "os_core.h"
#include "os_scheduler.h"
#include "os_memory.h"

#include <avr/interrupt.h>
#include <string.h>

PROGRAM(1, AUTOSTART) {
	os_enterCriticalSection();

	uint16_t avg_Alloc_int = 0;
	uint16_t avg_Free_int = 0;
	uint16_t avg_Alloc_ext = 0;
	uint16_t avg_Free_ext = 0;

	uint16_t avg_DirectWrite_int = 0;
	uint16_t avg_DirectRead_int = 0;
	uint16_t avg_DirectWrite_ext = 0;
	uint16_t avg_DirectRead_ext = 0;


	uint16_t i;
	uint16_t j;
	for (i = 0; i < 100; i++) {

		uint16_t startTime;
		uint16_t endTime;

		// Zeitmessung Alloc intHeap
		startTime = getSystemTime();
		MemAddr addr = os_malloc(intHeap, 100);
		endTime = getSystemTime();	
		avg_Alloc_int += (endTime - startTime);

		// Zeitmessung Free intHeap
		startTime = getSystemTime();
		os_free(intHeap, addr);
		endTime = getSystemTime();
		avg_Free_int += (endTime - startTime);

		// Zeitmessung extHeap
		startTime = getSystemTime();
		addr = os_malloc(extHeap, 100);
		endTime = getSystemTime();
		avg_Alloc_ext += (endTime - startTime);

		// Zeitmessung Free intHeap
		startTime = getSystemTime();
		os_free(extHeap, addr);
		endTime = getSystemTime();
		avg_Free_ext += (endTime - startTime);


		// Zeitmessung DirectWrite intSRAM
		startTime = getSystemTime();
		for(j = 0; j < 50; j++)
			intSRAM->write(intSRAM->use.start + j, 'E');

		endTime = getSystemTime();
		avg_DirectWrite_int += (endTime - startTime);

		// Zeitmessung DirectWrite intSRAM
		startTime = getSystemTime();
		for(j = 0; j < 50; j++)
			intSRAM->read(intSRAM->use.start + j);

		endTime = getSystemTime();
		avg_DirectRead_int += (endTime - startTime);

		// Zeitmessung DirectWrite extSRAM
		startTime = getSystemTime();
		for(j = 0; j < 50; j++)
			extSRAM->write(extSRAM->use.start + j, 'E');

		endTime = getSystemTime();
		avg_DirectWrite_ext += (endTime - startTime);

		// Zeitmessung DirectRead extSRAM
		startTime = getSystemTime();
		for(j = 0; j < 50; j++)
			extSRAM->read(extSRAM->use.start + j);

		endTime = getSystemTime();
		avg_DirectRead_ext += (endTime - startTime);

		}

		lcd_clear();
		
		// Ausgabe Alloc
		lcd_line1();
		lcd_writeProgString(PSTR("Alloc Int:"));
		lcd_writeDec(avg_Alloc_int / 100);

		lcd_line2();
		lcd_writeProgString(PSTR("Alloc Ext:"));
		lcd_writeDec(avg_Alloc_ext / 100);

		delayMs(2000);
		lcd_clear();


		// Ausgabe Free
		lcd_line1();
		lcd_writeProgString(PSTR("Free Int:"));
		lcd_writeDec(avg_Free_int / 100);

		lcd_line2();
		lcd_writeProgString(PSTR("Free Ext:"));
		lcd_writeDec(avg_Free_ext / 100);

		delayMs(2000);
		lcd_clear();


		// Ausgabe Write
		lcd_line1();
		lcd_writeProgString(PSTR("Write Int:"));
		lcd_writeDec(avg_DirectWrite_int / 100);

		lcd_line2();
		lcd_writeProgString(PSTR("Write Ext:"));
		lcd_writeDec(avg_DirectWrite_ext / 100);

		delayMs(2000);
		lcd_clear();


		// Ausgabe Read
		lcd_line1();
		lcd_writeProgString(PSTR("Read Int:"));
		lcd_writeDec(avg_DirectRead_int / 100);

		lcd_line2();
		lcd_writeProgString(PSTR("Read Ext:"));
		lcd_writeDec(avg_DirectRead_ext / 100);

		delayMs(2000);
		lcd_clear();


		os_leaveCriticalSection();
}

