From 06ae1ef9e5fe5ecaddce8408f8bd9df8bd08fb2f Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Fri, 17 Apr 2009 00:25:25 +0200 Subject: * digital/avr/modules/spi: - added software driver. --- digital/avr/modules/spi/Makefile.module | 2 +- digital/avr/modules/spi/spi.h | 2 +- digital/avr/modules/spi/spi_soft.avr.c | 101 ++++++++++++++++++++++++++++++++ digital/avr/modules/spi/spi_soft.h | 62 ++++++++++++++++++++ 4 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 digital/avr/modules/spi/spi_soft.avr.c create mode 100644 digital/avr/modules/spi/spi_soft.h diff --git a/digital/avr/modules/spi/Makefile.module b/digital/avr/modules/spi/Makefile.module index eb5567ef..b016517c 100644 --- a/digital/avr/modules/spi/Makefile.module +++ b/digital/avr/modules/spi/Makefile.module @@ -1 +1 @@ -spi_SOURCES = spi_hard.avr.c +spi_SOURCES = spi_hard.avr.c spi_soft.avr.c diff --git a/digital/avr/modules/spi/spi.h b/digital/avr/modules/spi/spi.h index 0b0acf27..834e9ea5 100644 --- a/digital/avr/modules/spi/spi.h +++ b/digital/avr/modules/spi/spi.h @@ -73,7 +73,7 @@ # include "spi_hard.h" #endif #if SPI0_DRIVER == SPI_DRIVER_SOFT || SPI1_DRIVER == SPI_DRIVER_SOFT -# error "spi: driver soft not supported yet" +# include "spi_soft.h" #endif /* Map names to drivers. */ diff --git a/digital/avr/modules/spi/spi_soft.avr.c b/digital/avr/modules/spi/spi_soft.avr.c new file mode 100644 index 00000000..d73b4de8 --- /dev/null +++ b/digital/avr/modules/spi/spi_soft.avr.c @@ -0,0 +1,101 @@ +/* spi_soft.avr.c - SPI driver using regular GPIO. */ +/* avr.spi - SPI AVR module. {{{ + * + * Copyright (C) 2009 Nicolas Schodet + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ +#include "common.h" + +#include "io.h" +#include "modules/utils/utils.h" + +#include "spi.h" + +#if SPI0_DRIVER == SPI_DRIVER_SOFT || SPI1_DRIVER == SPI_DRIVER_SOFT + +#if SPI0_DRIVER == SPI_DRIVER_SOFT +# define SPI_SCK_IO AC_SPI0_SOFT_SCK_IO +# define SPI_MOSI_IO AC_SPI0_SOFT_MOSI_IO +# define SPI_MISO_IO AC_SPI0_SOFT_MISO_IO +#else +# define SPI_SCK_IO AC_SPI1_SOFT_SCK_IO +# define SPI_MOSI_IO AC_SPI1_SOFT_MOSI_IO +# define SPI_MISO_IO AC_SPI1_SOFT_MISO_IO +#endif + +/** SPI speed, SCK period (us). */ +static uint8_t spi_speed; + +void +spi_soft_init_ (uint8_t speed) +{ + /* Set ports. */ + IO_DDR (SPI_MISO_IO) &= ~IO_BV (SPI_MISO_IO); + IO_PORT (SPI_MISO_IO) |= IO_BV (SPI_MISO_IO); + IO_PORT (SPI_MOSI_IO) &= ~IO_BV (SPI_MOSI_IO); + IO_DDR (SPI_MOSI_IO) |= IO_BV (SPI_MOSI_IO); + IO_PORT (SPI_SCK_IO) &= ~IO_BV (SPI_SCK_IO); + IO_DDR (SPI_SCK_IO) |= IO_BV (SPI_SCK_IO); + /* Store speed. */ + spi_speed = speed; +} + +void +spi_soft_send (uint8_t data) +{ + spi_soft_send_and_recv (data); +} + +uint8_t +spi_soft_recv (void) +{ + return spi_soft_send_and_recv (0); +} + +uint8_t +spi_soft_send_and_recv (uint8_t data) +{ + uint8_t recv, i, j; + recv = 0; + for (i = 0x80; i; i >>= 1) + { + /* Setup data. */ + if (data & i) + IO_PORT (SPI_MOSI_IO) |= IO_BV (SPI_MOSI_IO); + else + IO_PORT (SPI_MOSI_IO) &= ~IO_BV (SPI_MOSI_IO); + /* Delay with SCK low. */ + for (j = 0; j < spi_speed; j++) + utils_delay_us (0.5); + /* SCK high, sample. */ + if (IO_PIN (SPI_MISO_IO) & IO_BV (SPI_MISO_IO)) + recv |= i; + IO_PORT (SPI_SCK_IO) |= IO_BV (SPI_SCK_IO); + /* Delay with SCK high. */ + for (j = 0; j < spi_speed; j++) + utils_delay_us (0.5); + /* SCK low. */ + IO_PORT (SPI_SCK_IO) &= ~IO_BV (SPI_SCK_IO); + } + return recv; +} + +#endif /* SPI0_DRIVER == SPI_DRIVER_SOFT || SPI1_DRIVER == SPI_DRIVER_SOFT */ diff --git a/digital/avr/modules/spi/spi_soft.h b/digital/avr/modules/spi/spi_soft.h new file mode 100644 index 00000000..8d4de289 --- /dev/null +++ b/digital/avr/modules/spi/spi_soft.h @@ -0,0 +1,62 @@ +#ifndef spi_soft_h +#define spi_soft_h +/* spi_soft.h */ +/* avr.spi - SPI AVR module. {{{ + * + * Copyright (C) 2009 Nicolas Schodet + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ + +/* Do not be fooled by symbol names, theses are the supported modes (others + * will trigger descriptive compilation errors): */ +#define SPI_MASTER_not_supported /* supported */ +#define SPI_MODE_0_not_supported /* supported */ +#define SPI_MSB_FIRST_not_supported /* supported */ + +/** Initialise SPI driver. + * - master: slave or master mode + * - mode: clock polarity and phase + * - order: byte order (MSB or LSB) + * - speed: clock rate (SCK duration) + * + * Only mode supported is MASTER, MODE_0, MSB_FIRST. + */ +#define spi_soft_init(master, mode, order, speed) \ + master ## _not_supported \ + mode ## _not_supported \ + order ## _not_supported \ + spi_soft_init_ (speed) +void +spi_soft_init_ (uint8_t speed); + +/** Send data. */ +void +spi_soft_send (uint8_t data); + +/** Receive data. */ +uint8_t +spi_soft_recv (void); + +/** Send and receive data. */ +uint8_t +spi_soft_send_and_recv (uint8_t data); + +#endif /* spi_soft_h */ -- cgit v1.2.3