Nut/OS  4.10.3
API Reference
spibus_avr.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2009 by egnite GmbH
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in the
00014  *    documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the copyright holders nor the names of
00016  *    contributors may be used to endorse or promote products derived
00017  *    from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00023  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00026  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00027  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00028  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00029  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  * For additional information see http://www.ethernut.de/
00033  */
00034 
00044 #include <sys/timer.h>
00045 
00046 #include <dev/spibus_avr.h>
00047 
00051 int AvrSpiSetup(NUTSPINODE * node)
00052 {
00053     uint_fast8_t i;
00054     uint32_t clk;
00055     AVRSPIREG *spireg;
00056 
00057     spireg = node->node_stat;
00058 
00059     /* Select SPI master mode. */
00060     spireg->avrspi_spcr = _BV(SPE) | _BV(MSTR) | (uint8_t)(node->node_mode & SPI_MODE_3) << 2;
00061 
00062     /* Find the frequency that is below or equal the requested 
00063        ** one, using the double speed bit if available. */
00064     clk = NutClockGet(NUT_HWCLK_PERIPHERAL);
00065 #if defined(SPI2X)
00066     for (i = 0; i < 7; i++) {
00067         clk >>= 1;
00068         if (clk <= node->node_rate) {
00069             break;
00070         }
00071     }
00072     spireg->avrspi_spcr |= (i >> 1);
00073     if (i < 6) {
00074         spireg->avrspi_spsr = ~i & _BV(SPI2X);
00075     }
00076 #else
00077     for (i = 0; i < 3; i++) {
00078         clk >>= 2;
00079         if (clk <= node->node_rate) {
00080             break;
00081         }
00082     }
00083     spireg->avrspi_spcr |= i;
00084 #endif
00085 
00086     /* Update interface parameters. */
00087     node->node_rate = clk;
00088     node->node_mode &= ~SPI_MODE_UPDATE;
00089 
00090     return 0;
00091 }