PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 05, 2009 2:08 pm |
|
|
There is a hardware SPI driver for x16 mode in the CCS drivers directory:
Quote: | c:\Program Files\picc\Drivers\9356spi_x16.c |
In case you need a software SPI driver for x16 mode, here is one.
Even though the hardware SPI pins are used below as the default pins,
this really is a software driver, and you can choose other pins.
Code: |
//////////////////////////////////////////////////////////////
// Library for a MicroChip 93LC56B (x16 org)
//
// init_ext_eeprom(); Call before the other functions are used.
//
// write_ext_eeprom(a, d); Write the byte d to the address a.
//
// d = read_ext_eeprom(a); Read the byte d from the address a.
//
// The main program may define eeprom_select, eeprom_di,
// eeprom_do and eeprom_clk to override the defaults below.
//
//////////////////////////////////////////////////////////////
#ifndef EEPROM_SELECT
#define EEPROM_SELECT PIN_B0
#define EEPROM_DI PIN_C5
#define EEPROM_DO PIN_C4
#define EEPROM_CLK PIN_C3
#endif
#define EEPROM_ADDRESS byte
#define EEPROM_SIZE 128 // 16-bit Words
//-----------------------------------------------
void init_ext_eeprom()
{
byte cmd[2];
byte i;
output_low(EEPROM_DI);
output_low(EEPROM_CLK);
output_low(EEPROM_SELECT);
// Load the opcode and address for an EWEN instruction
// into a 2-byte array.
cmd[0]=0x80; // Address bit A6 = 1.
// Start bit = 1, Opcode = 0,0, and Address bit A7 = 1.
cmd[1]=0x9;
// Shift the 2 byte array left by 4 bits, so it becomes 0x9800.
// This is the bit pattern shown in Figure 3-5 (EWEN Timing)
// of the 93LC56A/B data sheet. It consists of the Start bit,
// EWEN opcode, and address. The address is only 7 bits.
for(i=1; i <= 4;++i)
shift_left(cmd,2,0);
// We use 11 clock pulses to send the Start bit, Opcode and Address.
output_high(EEPROM_SELECT);
for(i=1; i <= 11; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd,2,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_low(EEPROM_DI);
output_low(EEPROM_SELECT);
}
//----------------------------------------------------
void write_ext_eeprom(EEPROM_ADDRESS address, long data)
{
byte cmd[4];
byte i;
// Fill a 4-byte array with the Start bit, WRITE opcode,
// address, and 16 bits of data. This is 27 bits, total.
cmd[0] = (int8)(data); // Get LSB of 'data'
cmd[1] = make8(data, 1); // Get MSB of 'data'
cmd[2] = address;
cmd[3] = 0x5; // Start bit = 1, and Opcode = 0,1
// Shift the 4-byte array left by 5 bits.
// This will left-justify the bits in the array.
for(i=1; i <= 5;++i)
shift_left(cmd,4,0);
// Send the 11 bits of header information, and the 16 bits of
// data to the EEPROM. This requires 27 clocks.
output_high(EEPROM_SELECT);
for(i=1; i <= 27; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd,4,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_low(EEPROM_DI);
output_low(EEPROM_SELECT);
delay_ms(11);
}
//----------------------------------------------------
long read_ext_eeprom(EEPROM_ADDRESS address)
{
byte cmd[4];
byte i;
long data;
// Setup an array with the READ opcode and the address.
// Fill in the unused bits with zeros. These will be
// shifted out while we are shifting in the data from
// the EEPROM.
cmd[0]=0;
cmd[1]=0;
cmd[2]=address; // 8-bit address (top bit = 0)
cmd[3]=0x6; // Start bit and READ opcode
// Shift the 4-byte array left by 5 bits,
// so that it's left justified in the array.
for(i=0; i < 5; ++i)
shift_left(cmd,4,0);
// Send out 27 clocks to the EEPROM. The first 11 clocks
// will be the Start bit, Opcode (2 bits), and address (8 bits).
// The next 16 clocks will bring in the data from the EEPROM.
output_high(EEPROM_SELECT);
for(i=1; i <= 27; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd,4,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
if(i > 11) // Clocks 12 through 27 bring in the data.
shift_left(&data, 2, input(EEPROM_DO));
}
output_low(EEPROM_SELECT);
return(data);
} |
|
|