| 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);
 }
 | 
 |  |