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 }