{XMEGA Demo for Avrco "Userdevice"

 Written for the FM25L16B FRAM (2Kx8) 8-pin device
 Connection with SPI

 Creates a userdevice which saves and reads the data to the FRAM
}

program UserData; 

Device = xmega256A3U, VCC = 3.3; 

import SysTick, SerPortE0, SPI_C, UserPort; 


define
  // The XMegas don't provide any Oscillator fuses. 
  // So the application must setup the desired values 
  // possible OSC types: extXTAL, extClock, ext32kHz, int32Khz, int2MHz, int32MHz 
  
  OSCtype        = int32MHz, 
                   PLLmul = 6, 
                   prescB = 1, 
                   prescC = 1, 
                   overdrive; 
  
  SysTick        = 10; 
  
  StackSize      = $150, iData; 
  FrameSize      = $100, iData; 
  
  UserPort       = 2048; {2048Byte extern}             // define Mem expansion size 
  
  SerPortE0      = 38400, Stop2, Timeout; 
  TxBufferE0     = 64, iData; 
  RxBufferE0     = 8, iData; 
  
  SPIorderC      = MSB; 
  SPImodeC       = 0; 
  SPIprescC      = 2; 
  SPI_SSC        = NONE; 
  
implementation

{$UDATA}   // place vars into User Device 
var
  usrb          : byte; 
  usri          : integer; 
  usrArr        : array[0..10] of byte;
  uStr          : string[8]; 
  uRec          : record 
                    ub   : byte; 
                    uw   : word; 
                    uSt  : string[4]; 
                  end; 

{$IDATA}

// FRAM FM25L16B special Aliases and Constants
var
  FMCS[@PORTC, 4]       : bit; 
  Framstatus            : byte; 
  
alias  // Edit here for other SPI Ports and the CS line of the Fram
  FRAMCS = FMCS; 
  FRAMOutByte = SPIoutByteC; 
  FRAMInpByte = SPIInpByteC; 
  
const
  FM_WREN: byte = %00000110;//Set write enable latch 0000 0110b
  FM_WRDI: byte = %00000100;// Write disable 0000 0100b 
  FM_RDSR: byte = %00000101;// Read Status Register 0000 0101b 
  FM_WRSR: byte = %00000001;// Write Status Register 0000 0001b 
  FM_READ: byte = %00000011;// Read memory data 0000 0011b 
  FM_WRITE: byte = %00000010;// Write memory data 0000 0010b 
  
  
(* for a UserDevice import the following 3 function must be implemented *) 
userdevice UsrDevIni; 
begin
end; 

userdevice UsrDevInp(adr: word): byte; 
var
  ok    : boolean; 
  inp   : byte; 
begin
  Excl(FRAMCS); 
  FRAMOutByte(FM_READ); 
  FRAMOutByte(Hi(adr)); 
  FRAMOutByte(Lo(adr)); 
  inp:= FRAMInpByte; 
  Incl(FRAMCS); 
  return(inp); 
end; 

userdevice UsrDevOut(adr: word; outp: byte); 
var
  ok    : boolean; 
begin
// Write Enable 
  Excl(FRAMCS); 
  SPIoutByteC(FM_WREN); 
  Incl(FRAMCS); 
  
  Excl(FRAMCS); 
  FRAMOutByte(FM_WRITE); 
  FRAMOutByte(Hi(adr)); 
  FRAMOutByte(Lo(adr)); 
  FRAMOutByte(outp); 
  Incl(FRAMCS); 
end; 


// Reads the Status byte from the FRAM
function ReadFramStatus: byte; 
begin
  Excl(FRAMCS); 
  FRAMOutByte(FM_RDSR); 
  Framstatus:= FRAMInpByte; 
  Incl(FRAMCS); 
  return(Framstatus); 
end; 



begin
  Enableints($87); 
  Writeln(seroute0, 'USERDEVICE TEST'); 
  
  usrb:= 12;
  Writeln(seroute0, 'b=' + bytetostr(usrb)); 
  usrb:= 11; 
  Writeln(seroute0, 'b=' + bytetostr(usrb)); 
  usrb:= 16; 
  Writeln(seroute0, 'b=' + bytetostr(usrb)); 
  
  
  Writeln(seroute0, ReadFramStatus); 
  
  loop
    nop; 
  endloop;
end UserData.

