// spi (hard tested on m8, mx8)
 
#include "main.h"

//#define SS              B,2,L
#define MOSI            A,3,H
//#define MISO            B,4,H           //not used
#define SCK             A,1,H           //rising
#define REG_OE          A,0,L           
#define REG_LD          A,2,H           //latch

#define SOFT_SPI        1
#define LOW_BYTE_FIRST  1
#define LSB_FIRST       1
#define INVERTED_DATA   0                 

/*
  When the SPI is configured as a Master (MSTR in SPCR is set), the user can determine the
  direction of the SS pin.
  If SS is configured as an output, the pin is a general output pin which does not affect
  the SPI system. Typically, the pin will be driving the SS pin of the SPI Slave.
  If SS is configured as an input, it must be held high to ensure Master SPI operation.
  If the SS pin is driven low by peripheral circuitry when the SPI is configured as a Master
  with the SS pin defined as an input, the SPI system interprets this as another master
  selecting the SPI as a slave and starting to send data to it.

    SPCR - SPI Control Register:
  SPR0            0       // SPI Clock Rate Select 0
  SPR1            1       // SPI Clock Rate Select 1
  CPHA            2       // Clock Phase
  CPOL            3       // Clock polarity
  MSTR            4       // Master/Slave Select
  DORD            5       // Data Order (LSB/MSB)
  SPE             6       // SPI Enable
  SPIE            7       // SPI Interrupt Enable

    SPI Modes
  SPI Mode   Conditions     Leading Edge     Trailing Edge
     0     CPOL=0, CPHA=0  Sample (Rising)  Setup (Falling)
     1     CPOL=0, CPHA=1  Setup (Rising)   Sample (Falling)
     2     CPOL=1, CPHA=0  Sample (Falling) Setup (Rising)
     3     CPOL=1, CPHA=1  Setup (Falling)  Sample (Rising)
     
    CPOL Functionality
  CPOL  Leading Edge  Trailing Edge
   0    Rising        Falling
   1    Falling       Rising

    CPHA Functionality
  CPHA  Leading Edge  Trailing Edge
   0    Sample        Setup
   1    Setup         Sample

    Relationship Between SCK and the Oscillator Frequency 
  SPI2X SPR1 SPR0 SCK Frequency
    0    0    0    fosc/4
    0    0    1    fosc/16
    0    1    0    fosc/64
    0    1    1    fosc/128
    1    0    0    fosc/2
    1    0    1    fosc/8
    1    1    0    fosc/32
    1    1    1    fosc/64
    
*/
#if SOFT_SPI
#define SPI_SET_MODE()    
#define SPI_INT_CLEAR()

#else//SOFT_SPI                         //CPHA - bad
#if LSB_FIRST
#define SPI_SET_MODE()    (SPCR = 1<<SPE | 1<<MSTR | 1<<DORD)
#else
#define SPI_SET_MODE()    (SPCR = 1<<SPE | 1<<MSTR)
#endif
/*
    SPSR - SPI Status Register:
  SPI2X           0       // Double SPI Speed Bit
  WCOL            6       // Write Collision Flag
  SPIF            7       // SPI Interrupt Flag
*/
#define SPI_INT_CLEAR()   (SPSR = 0)
#define SPI_READY         (SPSR & 1<<SPIF)
#define SPI_DATA          SPDR          //SPI Data Register
#endif//SOFT_SPI


void SpiInit(void); 
void SpiSend(u08 *buf, u08 len);
