asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
32K Sram driver for 16F / 18F etc Pics |
Posted: Fri Feb 06, 2015 6:08 pm |
|
|
refer to this file for a schematic.
was originally tested with 18f8722 using port F and port D
using a 16.5888mhz clock
https://commons.wikimedia.org/wiki/File:SRAM32ka.pdf
The driver is semi flexible and was used to stream blocks of 16bit ADC
data into temporary storage at 2k samples per second, for later transmission to a host system - after a timed sample capture is complete.
a one second, 16it ADC capture fills one bank.
it works - but no claim to elegance is included.
suggestions for improvement welcome....
Code: |
// SRAM driver for 32k x8 fast Sram
// tested with 18F8722 using port D and F
//
// port f =control port d =data xfer Bi-Di
#use fast_io(D)
#use fast_io(F);
set_tris_d(255);
set_tris_f(0);
byte XportF =0b00011101;
unsigned int16 absmemaddr=0;
unsigned int8 membank=0;
#bit notclk=Xportf.0
#bit cntRST=Xportf.1
#bit notWEN=Xportf.2
#bit notOEN=Xportf.3
#bit notCCE=Xportf.4
#define M_CLk pin_F0
#define M_reset pin_F1
#define M_notWE pin_F2
#define M_notOE pin_F3
#define M_notCE pin_f4
// set bank 0-7 of 4096 bytes each
// autowrap occurs
void setmembank(int8 bnum){
bnum&=7; // mask all but 8 banks worth
membank=bnum; XportF &=0b00011111; // keep low order
bnum <<=5; // shift to mask back where it belongs
XportF |=bnum; // plug in new membank
output_F(xportf);
}
// the argument decides to reset within current bank
// or reset to bank 0 AND counter zero
//
#inline
void memaddRST (int1 bank_reset ){
int1 dosw;
if(0==notcce){ dosw=1; notCCE=1;} // disable sram
notclk=1; // default clock to ready to lower
delay_cycles(2); cntrst=1;
output_F(xportf); cntrst=0;
output_F(xportf);
if(dosw) notCCE=0; // re enable the mem chip if deselected
output_F(xportf); absmemaddr=0; // reset present counter
if(bank_reset) { setmembank(0); membank=0; output_F(xportf); }
}
#inline
// increment Sram address by one byte
//
void memaddinc ( void ){
output_low(M_clk); //notclk=0;
absmemaddr++; // creates a useful clock -low delay time
output_high(M_clk); // notclk=1;
// test: did we just step out of present bank ?
if (absmemaddr>4095){ // add rollover bank switch here
memaddRST (0); ++membank; setmembank(membank);
}
}
//
// spans 0 to 32767 8 blocks of 4096
// sets an arbitrary SRAM address
//
void gotoaddress( unsigned int16 w){
int8 nubank=0; memaddRST (1); // go to base 0 of bank 0
while (w>4095){ nubank++; w-=4096;}
setmembank(nubank);
while(w){
output_low(M_clk); //notclk=0;
absmemaddr++; // creates a useful clock -low delay time
output_high(M_clk); // notclk=1;
--w;
}
}
// converts negative logic of chip to positive
// chipon =1, enable chip
// =0, disable
// does not tamper with address setting etc
void mCHIPenable ( int1 chipon ){
set_tris_d(255); // insure in deflt state
if (chipon) notcce=0;
else notcce=1;
output_F(xportf);
}
//
// setup and zero mem chip
//
void setup_mem(void){
mCHIPenable(0); memaddRST(1); mCHIPenable(1);
}
// read/write is in flat space , spanning banks as absolute address
// 0 - 32767 if you just write or read consecutively
//
void writenextbyte (byte next ){
output_d(next);
set_tris_d(0); // insure in deflt state
output_low(M_notWE); delay_cycles(2); output_high(M_notWE);
set_tris_d(255); // insure in deflt state of INPUT
memaddinc();
}
void writenextWord (int16 next ){
output_d(make8(next,0));
set_tris_d(0); // insure in deflt state
output_low(M_notWE); delay_cycles(2); output_high(M_notWE);
memaddinc();
output_d(make8(next,1));
output_low(M_notWE); delay_cycles(2); output_high(M_notWE);
set_tris_d(255); // insure in deflt state of INPUT
memaddinc();
}
//
// this is serial read with bank boundary autoselect
//
byte readnextbyte(void){
byte x; //output data enable
output_low(M_notOE); delay_cycles(2); x=input_d();
output_high(M_notOE); memaddinc(); return (x);
}
int16 readnextword(void){
byte x,y; //output data enable
output_low(M_notOE); delay_cycles(2); x=input_d();
output_high(M_notOE); memaddinc();
output_low(M_notOE); delay_cycles(2); y=input_d();
output_high(M_notOE); memaddinc();
return (make16(y,x));
}
|
|
|