OpenCores
URL https://opencores.org/ocsvn/gecko3/gecko3/trunk

Subversion Repositories gecko3

[/] [gecko3/] [trunk/] [GECKO3COM/] [gecko3com-fw/] [firmware/] [src/] [spi.c] - Rev 32

Compare with Previous | Blame | View Log

/* -*- c++ -*- */
/*
 * Copyright 2004,2006 Free Software Foundation, Inc.
 * 
 * This file is part of GNU Radio
 * 
 * GNU Radio is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 * 
 * GNU Radio is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with GNU Radio; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
 */
/************************************************************/
/** \file    spi.c
 *************************************************************
 *  \brief   SPI bus functions 
 *   
 *  \details Library to communicate with SPI devices
 *
 *  \author  GNU Radio guys
 */
 
#include "spi.h"
#include "debugprint.h"
 
#if 0
/*
static unsigned char
count_bits8 (unsigned char v)
{
  static unsigned char count4[16] = {
    0,	// 0
    1,	// 1
    1,	// 2
    2,	// 3
    1,	// 4
    2,	// 5
    2,	// 6
    3,	// 7
    1,	// 8
    2,	// 9
    2,	// a
    3,	// b
    2,	// c
    3,	// d
    3,	// e
    4	// f
  };
  return count4[v & 0xf] + count4[(v >> 4) & 0xf];
}
*/
#else
 
 /** \brief internal helper function to count the number of active (1) bits in a byte */
static unsigned char
count_bits8 (unsigned char v)
{
  unsigned char count = 0;
  if (v & (1 << 0)) count++;
  if (v & (1 << 1)) count++;
  if (v & (1 << 2)) count++;
  if (v & (1 << 3)) count++;
  if (v & (1 << 4)) count++;
  if (v & (1 << 5)) count++;
  if (v & (1 << 6)) count++;
  if (v & (1 << 7)) count++;
  return count;
}
#endif
 
 
static void
setup_enables (unsigned char enables)
{
  // Software eanbles are active high.
  // Hardware enables are active low.
 
  if(count_bits8(enables) > 1) {
    print_info("too many enables acitve\n");
    return;
  }
  else {
    enables &= bmSPI_CS_MASK;
    SPI_CS_PORT |= bmSPI_CS_MASK;   //disable all chipselect signals
    SPI_CS_PORT &= ~enables;
  }
}
 
/** \brief disables all devices on the SPI bus */
#define disable_all()	setup_enables (0)
 
void
init_spi (void)
{
  disable_all ();		/* disable all devs	  */
  bitSPI_MOSI = 0;		/* idle state has CLK = 0 */
}
static void
write_byte_msb (unsigned char v);
 
static void
write_bytes_msb (const xdata unsigned char *buf, unsigned char len);
 
static void
read_bytes_msb (xdata unsigned char *buf, unsigned char len);
 
 
// returns non-zero if successful, else 0
unsigned char
spi_read (unsigned char header_hi, unsigned char header_lo,
	  unsigned char enables, unsigned char format,
	  xdata unsigned char *buf, unsigned char len)
{
  if (count_bits8 (enables) > 1)
    return 0;		// error, too many enables set
 
  setup_enables (enables);
  /*
  if (format & bmSPI_FMT_LSB){		// order: LSB
#if 1
    return 0;		// error, not implemented
#else
    switch (format & bmSPI_HEADER){
    case SPI_HEADER_0:
      break;
    case bmSPI_HEADER_1:
      write_byte_lsb (header_lo);
      break;
    case bmSPI_HEADER_2:
      write_byte_lsb (header_lo);
      write_byte_lsb (header_hi);
      break;
    default:
      return 0;		// error
    }
    if (len != 0)
      read_bytes_lsb (buf, len);
#endif
  }
 
  else {		// order: MSB
  */
    switch (format & bmSPI_HEADER){
    case bmSPI_HEADER_0:
      break;
    case bmSPI_HEADER_1:
      write_byte_msb (header_lo);
      break;
    case bmSPI_HEADER_2:
      write_byte_msb (header_hi);
      write_byte_msb (header_lo);
      break;
    default:
      return 0;		// error
    }
    if (len != 0)
      read_bytes_msb (buf, len);
    //}
 
  disable_all ();
  return 1;		// success
}
 
 
// returns non-zero if successful, else 0
unsigned char
spi_write (unsigned char header_hi, unsigned char header_lo,
	   unsigned char enables, unsigned char format,
	   const xdata unsigned char *buf, unsigned char len)
{
  setup_enables (enables);
 
  /*  if (format & bmSPI_FORMAT_LSB){		// order: LSB
#if 1
    return 0;		// error, not implemented
#else
    switch (format & bmSPI_HEADER){
    case bmSPI_HEADER_0:
      break;
    case bmSPI_HEADER_1:
      write_byte_lsb (header_lo);
      break;
    case bmSPI_HEADER_2:
      write_byte_lsb (header_lo);
      write_byte_lsb (header_hi);
      break;
    default:
      return 0;		// error
    }
    if (len != 0)
      write_bytes_lsb (buf, len);
#endif
  }
 
  else {		// order: MSB
  */
    switch (format & bmSPI_HEADER){
    case bmSPI_HEADER_0:
      break;
    case bmSPI_HEADER_1:
      write_byte_msb (header_lo);
      break;
    case bmSPI_HEADER_2:
      write_byte_msb (header_hi);
      write_byte_msb (header_lo);
      break;
    default:
      return 0;		// error
    }
    if (len != 0)
      write_bytes_msb (buf, len);
    //}
 
  disable_all ();
  return 1;		// success
}
 
// ----------------------------------------------------------------
 
static void
write_byte_msb (unsigned char v)
{
  v = (v << 1) | (v >> 7);	// rotate left (MSB into bottom bit)
  bitSPI_MOSI = v & 0x1;
  bitSPI_CLK = 1;
  bitSPI_CLK = 0;
 
  v = (v << 1) | (v >> 7);	// rotate left (MSB into bottom bit)
  bitSPI_MOSI = v & 0x1;
  bitSPI_CLK = 1;
  bitSPI_CLK = 0;
 
  v = (v << 1) | (v >> 7);	// rotate left (MSB into bottom bit)
  bitSPI_MOSI = v & 0x1;
  bitSPI_CLK = 1;
  bitSPI_CLK = 0;
 
  v = (v << 1) | (v >> 7);	// rotate left (MSB into bottom bit)
  bitSPI_MOSI = v & 0x1;
  bitSPI_CLK = 1;
  bitSPI_CLK = 0;
 
  v = (v << 1) | (v >> 7);	// rotate left (MSB into bottom bit)
  bitSPI_MOSI = v & 0x1;
  bitSPI_CLK = 1;
  bitSPI_CLK = 0;
 
  v = (v << 1) | (v >> 7);	// rotate left (MSB into bottom bit)
  bitSPI_MOSI = v & 0x1;
  bitSPI_CLK = 1;
  bitSPI_CLK = 0;
 
  v = (v << 1) | (v >> 7);	// rotate left (MSB into bottom bit)
  bitSPI_MOSI = v & 0x1;
  bitSPI_CLK = 1;
  bitSPI_CLK = 0;
 
  v = (v << 1) | (v >> 7);	// rotate left (MSB into bottom bit)
  bitSPI_MOSI = v & 0x1;
  bitSPI_CLK = 1;
  bitSPI_CLK = 0;
}
 
static void
write_bytes_msb (const xdata unsigned char *buf, unsigned char len)
{
  while (len-- != 0){
    write_byte_msb (*buf++);
  }
}
 
#if 0
/*
 * This is incorrectly compiled by SDCC 2.4.0
 */
/*static unsigned char
read_byte_msb (void)
{
  unsigned char v = 0;
 
  bitSPI_CLK = 1;
  v |= bitSPI_MISO;
  bitSPI_CLK = 0;
 
  v = v << 1;
  bitSPI_CLK = 1;
  v |= bitSPI_MISO;
  bitSPI_CLK = 0;
 
  v = v << 1;
  bitSPI_CLK = 1;
  v |= bitSPI_MISO;
  bitSPI_CLK = 0;
 
  v = v << 1;
  bitSPI_CLK = 1;
  v |= bitSPI_MISO;
  bitSPI_CLK = 0;
 
  v = v << 1;
  bitSPI_CLK = 1;
  v |= bitSPI_MISO;
  bitSPI_CLK = 0;
 
  v = v << 1;
  bitSPI_CLK = 1;
  v |= bitSPI_MISO;
  bitSPI_CLK = 0;
 
  v = v << 1;
  bitSPI_CLK = 1;
  v |= bitSPI_MISO;
  bitSPI_CLK = 0;
 
  v = v << 1;
  bitSPI_CLK = 1;
  v |= bitSPI_MISO;
  bitSPI_CLK = 0;
 
  return v;
  } */
#else
static unsigned char
read_byte_msb (void) _naked
{
  _asm
	clr	a
 
	setb	_bitSPI_CLK
        mov	c, _bitSPI_MISO
	rlc	a
	clr	_bitSPI_CLK
 
	setb	_bitSPI_CLK
        mov	c, _bitSPI_MISO
	rlc	a
	clr	_bitSPI_CLK
 
	setb	_bitSPI_CLK
        mov	c, _bitSPI_MISO
	rlc	a
	clr	_bitSPI_CLK
 
	setb	_bitSPI_CLK
        mov	c, _bitSPI_MISO
	rlc	a
	clr	_bitSPI_CLK
 
	setb	_bitSPI_CLK
        mov	c, _bitSPI_MISO
	rlc	a
	clr	_bitSPI_CLK
 
	setb	_bitSPI_CLK
        mov	c, _bitSPI_MISO
	rlc	a
	clr	_bitSPI_CLK
 
	setb	_bitSPI_CLK
        mov	c, _bitSPI_MISO
	rlc	a
	clr	_bitSPI_CLK
 
	setb	_bitSPI_CLK
        mov	c, _bitSPI_MISO
	rlc	a
	clr	_bitSPI_CLK
 
	mov	dpl,a
	ret
  _endasm;
}
#endif
 
static void
read_bytes_msb (xdata unsigned char *buf, unsigned char len)
{
  while (len-- != 0){
    *buf++ = read_byte_msb ();
  }
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.