296 lines
7.2 KiB
C
296 lines
7.2 KiB
C
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* INCLUDES
|
|
***************************************************************************/
|
|
|
|
#include <avr/io.h>
|
|
|
|
#include "config.h"
|
|
#include "global.h"
|
|
#include "io.h"
|
|
#include "memory.h"
|
|
|
|
|
|
/***************************************************************************
|
|
* DEFINITIONS
|
|
***************************************************************************/
|
|
|
|
/* GLOBAL: data send/receive buffer for communication with PC */
|
|
BYTE data_buffer[262];
|
|
|
|
/* indicates whether device is accessible for ECU */
|
|
static BOOL b_ecu_read_avail = false;
|
|
|
|
/* data byte used commonly in read/write and test operations */
|
|
static BYTE data_byte;
|
|
|
|
/* indexing variable for memory operations */
|
|
static UINT16 index = 0;
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
* FUNCTIONS
|
|
***************************************************************************/
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
BOOL memoryClear()
|
|
{
|
|
/* default state for eeproms is 0xFF for each byte */
|
|
data_byte = 0xFF;
|
|
|
|
for (index = 0; index < MEMORY_SIZE; ++index)
|
|
{
|
|
if (!memoryWrite(index, data_byte))
|
|
return (false);
|
|
}
|
|
|
|
return (true);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
BOOL memoryTest()
|
|
{
|
|
/* patterns testing */
|
|
data_byte = 0x00;
|
|
|
|
/* TEST1: 0x00 pattern */
|
|
for (index = 0; index < MEMORY_SIZE; ++index)
|
|
memoryWrite(index, data_byte);
|
|
|
|
for (index = 0; index < MEMORY_SIZE; ++index)
|
|
{
|
|
if (*(memoryRead(index)) != 0x00)
|
|
return (false);
|
|
}
|
|
|
|
/* TEST2: 0x55 odd and 0xAA even pattern */
|
|
for (index = 0; index < MEMORY_SIZE; ++index)
|
|
{
|
|
if ((index & 1) == 0)
|
|
data_byte = 0x55;
|
|
else
|
|
data_byte = 0xAA;
|
|
|
|
if (!memoryWrite(index, data_byte))
|
|
return (false);
|
|
}
|
|
|
|
/* read from memory for verification */
|
|
for (index = 0; index < MEMORY_SIZE; ++index)
|
|
{
|
|
data_byte = *(memoryRead(index));
|
|
|
|
if ((index & 1) == 0)
|
|
{
|
|
if (data_byte != 0x55)
|
|
return (false);
|
|
}
|
|
else
|
|
{
|
|
if (data_byte != 0xAA)
|
|
return (false);
|
|
}
|
|
}
|
|
|
|
/* TEST3: 0xAA odd and 0x55 even pattern */
|
|
for (index = 0; index < MEMORY_SIZE; ++index)
|
|
{
|
|
if ((index & 1) == 0)
|
|
data_byte = 0xAA;
|
|
else
|
|
data_byte = 0x55;
|
|
|
|
if (!memoryWrite(index, data_byte))
|
|
return (false);
|
|
}
|
|
|
|
/* read from memory for verification */
|
|
for (index = 0; index < MEMORY_SIZE; ++index)
|
|
{
|
|
data_byte = *(memoryRead(index));
|
|
|
|
if ((index & 1) == 0)
|
|
{
|
|
if (data_byte != 0xAA)
|
|
return (false);
|
|
}
|
|
else
|
|
{
|
|
if (data_byte != 0x55)
|
|
return (false);
|
|
}
|
|
}
|
|
|
|
return (true);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
BOOL memoryWrite(const UINT16 addr, const BYTE byte)
|
|
{
|
|
static BYTE vrfy_byte;
|
|
|
|
for (UINT8 retry = 0; retry < MEMORY_WRITE_RETRIES; ++retry)
|
|
{
|
|
setMemoryAccessMcuWrite();
|
|
setMemoryAddress(addr);
|
|
|
|
DATA_OUT = byte;
|
|
|
|
/* write to memory */
|
|
SET_BIT(RAMWE_PORT, RAMWE, RAMWE_ACT);
|
|
NOP_DELAY;
|
|
SET_BIT(RAMWE_PORT, RAMWE, !RAMWE_ACT);
|
|
|
|
/* read byte from memory and check wheter written byte match */
|
|
vrfy_byte = *(memoryRead(addr));
|
|
|
|
if (byte == vrfy_byte)
|
|
return (true);
|
|
}
|
|
|
|
/* if something went bad, light red led */
|
|
SET_BIT(LED_R_PORT, LED_R, LED_R_ACT);
|
|
|
|
return (false);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
BOOL memoryWriteBlock(const UINT16 addr, const UINT16 size, const BYTE* buffer)
|
|
{
|
|
for (index = 0; index < size; ++index)
|
|
{
|
|
if (!memoryWrite((addr + index), *(buffer + index)))
|
|
return (false);
|
|
}
|
|
|
|
return (true);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
BYTE* memoryRead(const UINT16 addr)
|
|
{
|
|
static BYTE byte;
|
|
|
|
setMemoryAccessMcuRead();
|
|
setMemoryAddress(addr);
|
|
|
|
byte = DATA_IN;
|
|
|
|
return (&byte);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
BYTE* memoryReadBlock(const UINT16 addr, const UINT16 size, BYTE* buffer)
|
|
{
|
|
for (index = 0; index < size; ++index)
|
|
*(buffer + index) = *(memoryRead(addr + index));
|
|
|
|
return (buffer);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
void setMemoryAccessEcuRead()
|
|
{
|
|
if (b_ecu_read_avail)
|
|
return;
|
|
|
|
SET_BIT(RAMOE_PORT, RAMOE, RAMOE_ACT);
|
|
SET_BIT(RAMWE_PORT, RAMWE, !RAMWE_ACT);
|
|
|
|
SET_BIT(ADRHI_PORT, ADRHI, !ADRHI_ACT);
|
|
SET_BIT(ADRLO_PORT, ADRLO, !ADRLO_ACT);
|
|
|
|
SET_BIT(ADRLOE_PORT, ADRLOE, !ADRLOE_ACT);
|
|
SET_BIT(ADRSOE_PORT, ADRSOE, ADRSOE_ACT);
|
|
|
|
SET_BIT(DATSOE_PORT, DATSOE, DATSOE_ACT);
|
|
SET_BIT(DATDOE_PORT, DATDOE, !DATDOE_ACT);
|
|
|
|
SET_BIT(DATDDIR_PORT, DATDDIR, DATDDIR_READ);
|
|
|
|
b_ecu_read_avail = true;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
void setMemoryAccessMcuRead()
|
|
{
|
|
b_ecu_read_avail = false;
|
|
|
|
SET_BIT(RAMOE_PORT, RAMOE, RAMOE_ACT);
|
|
SET_BIT(RAMWE_PORT, RAMWE, !RAMWE_ACT);
|
|
|
|
SET_BIT(ADRHI_PORT, ADRHI, !ADRHI_ACT);
|
|
SET_BIT(ADRLO_PORT, ADRLO, !ADRLO_ACT);
|
|
|
|
SET_BIT(ADRLOE_PORT, ADRLOE, ADRLOE_ACT);
|
|
SET_BIT(ADRSOE_PORT, ADRSOE, !ADRSOE_ACT);
|
|
|
|
SET_BIT(DATSOE_PORT, DATSOE, !DATSOE_ACT);
|
|
SET_BIT(DATDOE_PORT, DATDOE, DATDOE_ACT);
|
|
|
|
SET_BIT(DATDDIR_PORT, DATDDIR, DATDDIR_READ);
|
|
|
|
DATA_DDR = PORT_DIR_IN;
|
|
|
|
/* ensure that pull-ups are disabled */
|
|
DATA_PULLUP = (BYTE)~PORT_PULLUP_ACT;
|
|
|
|
/* wait for data propagation */
|
|
NOP_DELAY;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
void setMemoryAccessMcuWrite()
|
|
{
|
|
b_ecu_read_avail = false;
|
|
|
|
SET_BIT(RAMOE_PORT, RAMOE, !RAMOE_ACT);
|
|
SET_BIT(RAMWE_PORT, RAMWE, !RAMWE_ACT);
|
|
|
|
SET_BIT(ADRHI_PORT, ADRHI, !ADRHI_ACT);
|
|
SET_BIT(ADRLO_PORT, ADRLO, !ADRLO_ACT);
|
|
|
|
SET_BIT(ADRLOE_PORT, ADRLOE, ADRLOE_ACT);
|
|
SET_BIT(ADRSOE_PORT, ADRSOE, !ADRSOE_ACT);
|
|
|
|
SET_BIT(DATSOE_PORT, DATSOE, !DATSOE_ACT);
|
|
SET_BIT(DATDOE_PORT, DATDOE, DATDOE_ACT);
|
|
|
|
SET_BIT(DATDDIR_PORT, DATDDIR, DATDDIR_WRITE);
|
|
|
|
DATA_DDR = PORT_DIR_OUT;
|
|
|
|
/* wait for data propagation */
|
|
NOP_DELAY;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
void setMemoryAddress(const UINT16 addr)
|
|
{
|
|
/* set lo byte of address and wait for propagation before latching */
|
|
ADDRESS = addr;
|
|
SET_BIT(ADRLO_PORT, ADRLO, !ADRLO_ACT);
|
|
NOP_DELAY;
|
|
SET_BIT(ADRLO_PORT, ADRLO, ADRLO_ACT);
|
|
NOP_DELAY;
|
|
|
|
/* the same with hi byte of address */
|
|
ADDRESS = (addr >> 8);
|
|
SET_BIT(ADRHI_PORT, ADRHI, !ADRHI_ACT);
|
|
NOP_DELAY;
|
|
SET_BIT(ADRHI_PORT, ADRHI, ADRHI_ACT);
|
|
NOP_DELAY;
|
|
}
|
|
|
|
|
|
/* END */
|