#ifdef CONFIG_TOOLCHAIN_IAR
#pragma inline
#endif
static void INLINE_KEYWORD busWriteNegate(void) { IO0SET = (unsigned long)0x10000000; }

#ifdef CONFIG_TOOLCHAIN_IAR
#pragma inline
#endif
static void INLINE_KEYWORD busWriteAssert(void) { IO0CLR = (unsigned long)0x10000000; }

#ifdef CONFIG_TOOLCHAIN_IAR
#pragma inline
#endif
static void INLINE_KEYWORD busReadNegate(void) { IO0SET = (unsigned long)0x20000000; }

#ifdef CONFIG_TOOLCHAIN_IAR
#pragma inline
#endif
static void INLINE_KEYWORD busReadAssert(void) { IO0CLR = (unsigned long)0x20000000; }

#ifdef CONFIG_TOOLCHAIN_IAR
#pragma inline
#endif
static void INLINE_KEYWORD busCsNegate(void) { IO0SET = (unsigned long)0x40000000; }

#ifdef CONFIG_TOOLCHAIN_IAR
#pragma inline
#endif
static void INLINE_KEYWORD busCsAssert(void) { IO0CLR = (unsigned long)0x40000000; }

#ifdef CONFIG_TOOLCHAIN_IAR
#pragma inline
#endif
static void INLINE_KEYWORD busNegateAll(void) { IO0SET = (unsigned long)0x70000000; }


// only drive the bus when writing to save power
static void busWrite(unsigned char writeAddr, unsigned char writeData)
{
  unsigned long iopinMask;
  unsigned long iodirSave;

  iopinMask  = (unsigned long)((writeData << 8) & 0x0000ff00);
  iopinMask |= (unsigned long)((writeAddr << 4) & 0x00000070);

  // drive the data and address bus
  iodirSave = IO0DIR;
  IO0DIR = (iodirSave | 0x0000ff70);

  IO0SET = iopinMask;
  IO0CLR = ((~iopinMask) & 0x0000ff70);

  ssiDelay(); // let the data settle
  ssiDelay(); // let the data settle

  // assert CS_N, then WE_N
  busCsAssert();
  ssiDelay();

  busWriteAssert();
  ssiDelay();
  ssiDelay();


  busWriteNegate();
  ssiDelay(); // let the data settle 
  
  busCsNegate();
  ssiDelay(); // let the data settle 

  // stop driving the data bus
  IODIR = iodirSave;
}

static unsigned char busRead(unsigned char readAddr)
{
  unsigned long iopinMask;
  unsigned long iopinState;
  unsigned long iodirSave = IO0DIR;

  // drive address, not data
  IO0DIR = ((iodirSave | 0x00000070) & ~0x0000ff00);

  iopinMask = (unsigned long)((readAddr << 4) & 0x00000070);

  // drive the address bits
  IO0SET = iopinMask;
  IO0CLR = ((~iopinMask) & 0x00000070);

  ssiDelay();
  ssiDelay();

  // assert CS_N, then RD_N
  busCsAssert();
  ssiDelay();

  busReadAssert();
  ssiDelay();
  ssiDelay();

  // grab the data
  iopinState = IO0PIN;

  // negate read
  busReadNegate();
  ssiDelay(); // let the data settle 
  busCsNegate();
  ssiDelay(); // let the data settle 

  // restore GPIO direction
  IO0DIR = iodirSave;

  return ((unsigned char)((iopinState >> 8) & 0xff));
}
