2011-11-26 07:10:30 +00:00
|
|
|
/*
|
|
|
|
* external_mem.c
|
|
|
|
*
|
|
|
|
* Created on: Nov 25, 2011
|
|
|
|
* Author: Doug
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "external_mem.h"
|
2011-11-27 08:01:29 +00:00
|
|
|
#include "ports.h"
|
2011-11-26 07:10:30 +00:00
|
|
|
#include <avr/io.h>
|
|
|
|
|
2011-11-27 08:09:29 +00:00
|
|
|
#define HIGHEST_ADDRESS_LINE 20
|
2011-11-26 07:10:30 +00:00
|
|
|
|
2011-11-27 08:01:29 +00:00
|
|
|
// Allow this to be initialized more than once.
|
|
|
|
// In case we mess with the port settings,
|
|
|
|
// re-initializing ExternalMem should reset everything
|
|
|
|
// to sensible defaults.
|
2011-11-26 07:10:30 +00:00
|
|
|
void ExternalMem_Init(void)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
// Initialize the ports connected to address/data/control lines
|
|
|
|
Ports_Init();
|
2011-11-26 07:10:30 +00:00
|
|
|
|
2011-11-27 08:01:29 +00:00
|
|
|
// Configure all address lines as outputs
|
2011-12-10 21:02:21 +00:00
|
|
|
Ports_SetAddressDDR((1UL << (HIGHEST_ADDRESS_LINE + 1)) - 1);
|
2011-11-26 07:10:30 +00:00
|
|
|
|
2011-12-10 18:35:41 +00:00
|
|
|
// Set all data lines as inputs
|
|
|
|
Ports_SetDataDDR(0);
|
|
|
|
|
|
|
|
// Disable all pull-ups on the data lines. They aren't needed
|
|
|
|
// for normal operation.
|
|
|
|
Ports_DataPullups_RMW(0, 0xFFFFFFFFUL);
|
|
|
|
|
|
|
|
// Sensible defaults for address lines:
|
2011-11-27 08:01:29 +00:00
|
|
|
// Write out address zero
|
|
|
|
Ports_SetAddressOut(0);
|
2011-11-26 07:10:30 +00:00
|
|
|
|
2011-11-28 07:06:02 +00:00
|
|
|
// Control lines
|
2011-11-27 08:01:29 +00:00
|
|
|
Ports_SetCSDDR(1);
|
|
|
|
Ports_SetOEDDR(1);
|
|
|
|
Ports_SetWEDDR(1);
|
2011-11-26 07:10:30 +00:00
|
|
|
|
2011-11-27 08:01:29 +00:00
|
|
|
// Default all control lines to high (de-asserted)
|
|
|
|
ExternalMem_DeassertCS();
|
|
|
|
ExternalMem_DeassertOE();
|
|
|
|
ExternalMem_DeassertWE();
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExternalMem_SetAddress(uint32_t address)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
Ports_SetAddressOut(address);
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExternalMem_SetData(uint32_t data)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
Ports_SetDataDDR(0xFFFFFFFFUL);
|
|
|
|
Ports_SetDataOut(data);
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExternalMem_SetAddressAndData(uint32_t address, uint32_t data)
|
|
|
|
{
|
|
|
|
ExternalMem_SetAddress(address);
|
|
|
|
ExternalMem_SetData(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExternalMem_SetDataAsInput(void)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
Ports_SetDataDDR(0);
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t ExternalMem_ReadData(void)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
return Ports_ReadData();
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExternalMem_AssertCS(void)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
Ports_SetCSOut(0);
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExternalMem_DeassertCS(void)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
Ports_SetCSOut(1);
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExternalMem_AssertWE(void)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
Ports_SetWEOut(0);
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExternalMem_DeassertWE(void)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
Ports_SetWEOut(1);
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExternalMem_AssertOE(void)
|
|
|
|
{
|
2011-11-27 08:01:29 +00:00
|
|
|
Ports_SetOEOut(0);
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
2011-12-10 21:53:43 +00:00
|
|
|
void ExternalMem_DeassertOE(void)
|
|
|
|
{
|
|
|
|
Ports_SetOEOut(1);
|
|
|
|
}
|
|
|
|
|
2011-12-10 21:02:21 +00:00
|
|
|
void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len)
|
|
|
|
{
|
|
|
|
ExternalMem_AssertCS();
|
|
|
|
ExternalMem_AssertOE();
|
|
|
|
|
|
|
|
while (len--)
|
|
|
|
{
|
|
|
|
ExternalMem_SetAddress(startAddress++);
|
|
|
|
// Shouldn't need to wait here. Each clock cycle at 16 MHz is 62.5 nanoseconds, so by the time the SPI
|
|
|
|
// read has been signaled with the SPI chip, there will DEFINITELY be good data on the data bus.
|
|
|
|
// (Considering these chips will be in the 70 ns or 140 ns range, that's only a few clock cycles at most)
|
|
|
|
|
2011-12-10 21:53:43 +00:00
|
|
|
// TODO: Change the read data routines to put them in the correct order as is so I don't have to do this
|
|
|
|
// (Might shave a second or so off the read time)
|
|
|
|
uint32_t tmp = ExternalMem_ReadData();
|
|
|
|
tmp = (tmp & 0xFF) << 24 |
|
|
|
|
((tmp >> 8) & 0xFF) << 16 |
|
|
|
|
((tmp >> 16) & 0xFF) << 8 |
|
|
|
|
((tmp >> 24) & 0xFF) << 0;
|
|
|
|
*buf++ = tmp;
|
|
|
|
}
|
2011-11-26 07:10:30 +00:00
|
|
|
}
|