-- Title: SPI_sw_Master  (spi_sw_master.jal)
-- Author H.v.Broekhuyzen (henk@henkzelf.nl)
-- Compiler: 2.4m
--
-- This file is a part of jallib (http:jallib.googlecode.com)
-- Released under the ZLIB licence:
--                       (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This module aims to be an alternative for: spi_master_hw.jal
-- for PIC's without an SPI interface or, when this interface hardware
-- of the PIC is in use for i2c
--.
-- As a consequence:
-- 1) Data-transfer is much slower than when using spi_master_hw.jal (as fast
--    as the software is able)
--    On 16F876 at 20MHz ~~ 3,8 us/ bit =~ 260kb/sec =~ 36us/byte =~ 28000 B/s)
-- 2) parameter spi_rate of function spi_init is not implemented
-- 3) For the time being: parameter spi_mode of function spi_init is also not
--    implemented, but: Mode 1 (clock idle on 0, datatransmitted on rising edge)
--    is implemented. This is OK for communication with a SPI-RAM 23K256 and
--    tranceivers of firm HOPE.
--    Implementing this parameter would make datatranfer even slower.
-- 4) The calling must define IO pins for the SPI signals and
--    set the direction of these pins. e.g.:
--
--    alias SSPI_SCK   is pin_b0  pin_b0_direction = output ; SPI clock signal
--    alias SSPI_DO    is pin_b1  pin_b1_direction = output ; SPI data-out
--    alias SSPI_DI    is pin_b2  pin_b2_direction = input  ; SPI data-in
--
-- 5) 3 procedures / functions of spi_master_hw.jal have "_hw" in their labels.
--    Using these labels could cause misunderstanding.
--    That why the alternatives are:
------------------------------------------+-----------------------------------
--      in  spi_master_hw.jal             |  in SPI_sw_master.jal
------------------------------------------+-----------------------------------
-- procedure spi_init(spi_mode,spiRate)   |  spi_master_init(dummyM, dummyR)
--  function spi_master_hw_exchange(data) |  spy_master_exchange(data)
-- procedure spi_master_hw'put(data)      |  spi_master_put_byte(data)
--  function spi_master_hw'get()          |  spi_master_get_byte()
------------------------------------------+-----------------------------------
-- In future spi_master_hw.jal may be followed-up by SPI_sw_master.jal, where
-- the procedure and function names are changed to: "as in SPI_sw_master.jal".
-- In this way switching between SPI_hw_master and SPI_sw_master is as easy
-- as switching between JALLIB's I2C_hw_master.jal and I2C_sw_master.jal

--***********************************************************************
-- output one byte while input of a byte
--***********************************************************************
function spi_master_exchange(byte in B_out) return byte is
   var byte data
   var bit  inb at data : 0
   var bit outb at data : 7
   data = B_out
   for 8 loop
      SSPI_DO = outb
      SSPI_SCK = 1
      data = data << 1
      inb = SSPI_DI
      SSPI_SCK = 0
   end loop
   return data
end function

--***********************************************************************
-- output one byte (not using spi_master_exchange for speed)
--***********************************************************************
procedure spi_master_put_byte( byte in x ) is
-- In the version below, sending a byte takes 35 us,
-- Data to clock 1 us, clock = 0,7 us, clock to next data 2,2, == 3,8 us /bit
-- (measured on 16F73 with 20 MHz X-tal)
   var bit b at x : 7
   for 8 loop
      SSPI_DO = b
      x = x << 1
      SSPI_SCK = 1
      SSPI_SCK = 0
   end loop
   SSPI_DO = 0 ; to save power in level translation R's and for RF12B
end procedure
--***********************************************************************
-- input one byte  (not using spi_master_exchange for speed)
--***********************************************************************
function spi_master_get_byte() return byte is
   var byte data
   var bit b at data : 0
   for 8 loop
      SSPI_SCK = 1
      data = data << 1
      b = SSPI_DI
      SSPI_SCK = 0
   end loop
   return data
end function
--***********************************************************************
-- initialise
--***********************************************************************
procedure spi_master_init(byte in dummyM, byte in dummyR) is
    SSPI_SCK = 0
    SSPI_DO  = 0
end procedure




