sbbif0.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 /*
00035  * $Log: sbbif0.c,v $
00036  * Revision 1.1  2007/04/12 09:07:54  haraldkipp
00037  * Configurable SPI added.
00038  *
00039  */
00040 
00041 #include <cfg/arch/avr.h>
00042 #include <sys/timer.h>
00043 #include <dev/sbbif0.h>
00044 
00045 /* SPI modes of all devices. */
00046 static ureg_t sbbi0_mode[SBBI0_MAX_DEVICES];
00047 
00048 /* SPI mode of the currently selected device. */
00049 static ureg_t sel_mode;
00050 
00051 /* SPI bit delay of all devices. */
00052 static ureg_t sbbi0_delay[SBBI0_MAX_DEVICES];
00053 
00054 /* SPI bit delay of the currently selected device. */
00055 static ureg_t sel_delay;
00056 
00074 int Sbbi0SetMode(ureg_t ix, ureg_t mode)
00075 {
00076     if (ix < SBBI0_MAX_DEVICES && mode <= 3) {
00077         sbbi0_mode[ix] = mode;
00078         return 0;
00079     }
00080     return -1;
00081 }
00082 
00092 void Sbbi0SetSpeed(ureg_t ix, u_long rate)
00093 {
00094     u_long fosc = NutGetCpuClock() / 16;
00095 
00096     if (rate) {
00097         fosc /= rate;
00098     }
00099     if (fosc < 5) {
00100         sbbi0_delay[ix] = 0;
00101     }
00102     else if (fosc < 255) {
00103         sbbi0_delay[ix] = (ureg_t)fosc;
00104     } else {
00105         sbbi0_delay[ix] = 255;
00106     }
00107 }
00108 
00109 static INLINE void Sbbi0Delay(void)
00110 {
00111     if (sel_delay) {
00112         ureg_t d;
00113 
00114         for (d = sel_delay; d; d--) {
00115             _NOP();
00116         }
00117     }
00118 }
00119 
00128 void Sbbi0Enable(ureg_t ix)
00129 {
00130     sel_mode = sbbi0_mode[ix];
00131     sel_delay = sbbi0_delay[ix];
00132 
00133     SBBI0_MOSI_CLR();
00134     SBBI0_MOSI_ENA();
00135     SBBI0_MISO_ENA();
00136     if (sel_mode == 0 || sel_mode == 1) {
00137         SBBI0_SCK_CLR();
00138     }
00139     else {
00140         SBBI0_SCK_SET();
00141     }
00142     SBBI0_SCK_ENA();
00143 }
00144 
00155 void Sbbi0ChipReset(ureg_t ix, ureg_t hi)
00156 {
00157 #if defined(SBBI0_RST0_BIT)
00158     if (ix == 0) {
00159         if (hi) {
00160             SBBI0_RST0_SET();
00161         } else {
00162             SBBI0_RST0_CLR();
00163         }
00164         SBBI0_RST0_ENA();
00165     }
00166 #endif
00167 #if defined(SBBI0_RST1_BIT)
00168     if (ix == 1) {
00169         if (hi) {
00170             SBBI0_RST1_SET();
00171         } else {
00172             SBBI0_RST1_CLR();
00173         }
00174         SBBI0_RST1_ENA();
00175     }
00176 #endif
00177 #if defined(SBBI0_RST2_BIT)
00178     if (ix == 2) {
00179         if (hi) {
00180             SBBI0_RST2_SET();
00181         } else {
00182             SBBI0_RST2_CLR();
00183         }
00184         SBBI0_RST2_ENA();
00185     }
00186 #endif
00187 #if defined(SBBI0_RST3_BIT)
00188     if (ix == 3) {
00189         if (hi) {
00190             SBBI0_RST3_SET();
00191         } else {
00192             SBBI0_RST3_CLR();
00193         }
00194         SBBI0_RST3_ENA();
00195     }
00196 #endif
00197 }
00198 
00210 void Sbbi0ChipSelect(ureg_t ix, ureg_t hi)
00211 {
00212 #if defined(SBBI0_CS0_BIT)
00213     if (ix == 0) {
00214         if (hi) {
00215             SBBI0_CS0_SET();
00216         } else {
00217             SBBI0_CS0_CLR();
00218         }
00219         SBBI0_CS0_ENA();
00220     }
00221 #endif
00222 #if defined(SBBI0_CS1_BIT)
00223     if (ix == 1) {
00224         if (hi) {
00225             SBBI0_CS1_SET();
00226         } else {
00227             SBBI0_CS1_CLR();
00228         }
00229         SBBI0_CS1_ENA();
00230     }
00231 #endif
00232 #if defined(SBBI0_CS2_BIT)
00233     if (ix == 2) {
00234         if (hi) {
00235             SBBI0_CS2_SET();
00236         } else {
00237             SBBI0_CS2_CLR();
00238         }
00239         SBBI0_CS2_ENA();
00240     }
00241 #endif
00242 #if defined(SBBI0_CS3_BIT)
00243     if (ix == 3) {
00244         if (hi) {
00245             SBBI0_CS3_SET();
00246         } else {
00247             SBBI0_CS3_CLR();
00248         }
00249         SBBI0_CS3_ENA();
00250     }
00251 #endif
00252 }
00253 
00265 void Sbbi0SelectDevice(ureg_t ix)
00266 {
00267     Sbbi0Enable(ix);
00268     Sbbi0ChipSelect(ix, 1);
00269 }
00270 
00279 void Sbbi0DeselectDevice(ureg_t ix)
00280 {
00281     Sbbi0ChipSelect(ix, 0);
00282 }
00283 
00295 void Sbbi0NegSelectDevice(ureg_t ix)
00296 {
00297     Sbbi0Enable(ix);
00298     Sbbi0ChipSelect(ix, 0);
00299 }
00300 
00309 void Sbbi0NegDeselectDevice(ureg_t ix)
00310 {
00311     Sbbi0ChipSelect(ix, 1);
00312 }
00313 
00321 u_char Sbbi0Byte(u_char data)
00322 {
00323     ureg_t mask;
00324 
00325     if (sel_mode == 3) {
00326         /* Mode 3: Leading edge is falling, data sampled on rising edge. */
00327         for (mask = 0x80; mask; mask >>= 1) {
00328             SBBI0_SCK_CLR();
00329             if (data & mask) {
00330                 SBBI0_MOSI_SET();
00331             } else {
00332                 SBBI0_MOSI_CLR();
00333             }
00334             Sbbi0Delay();
00335             SBBI0_SCK_SET();
00336             if (SBBI0_MISO_TST()) {
00337                 data |= mask;
00338             }
00339             else {
00340                 data &= ~mask;
00341             }
00342             Sbbi0Delay();
00343         }
00344     }
00345     else if (sel_mode == 2) {
00346         /* Mode 2: Leading edge is falling, data sampled on falling edge. */
00347         for (mask = 0x80; mask; mask >>= 1) {
00348             SBBI0_SCK_SET();
00349             if (data & mask) {
00350                 SBBI0_MOSI_SET();
00351             } else {
00352                 SBBI0_MOSI_CLR();
00353             }
00354             Sbbi0Delay();
00355             SBBI0_SCK_CLR();
00356             if (SBBI0_MISO_TST()) {
00357                 data |= mask;
00358             }
00359             else {
00360                 data &= ~mask;
00361             }
00362             Sbbi0Delay();
00363         }
00364         SBBI0_SCK_SET();
00365     }
00366     else if (sel_mode == 1) {
00367         /* Mode 1: Leading edge is rising, data sampled on falling edge. */
00368         for (mask = 0x80; mask; mask >>= 1) {
00369             SBBI0_SCK_SET();
00370             if (data & mask) {
00371                 SBBI0_MOSI_SET();
00372             } else {
00373                 SBBI0_MOSI_CLR();
00374             }
00375             Sbbi0Delay();
00376             SBBI0_SCK_CLR();
00377             if (SBBI0_MISO_TST()) {
00378                 data |= mask;
00379             }
00380             else {
00381                 data &= ~mask;
00382             }
00383             Sbbi0Delay();
00384         }
00385     }
00386     else {
00387         /* Mode 0: Leading edge is rising, data sampled on rising edge. */
00388         for (mask = 0x80; mask; mask >>= 1) {
00389             SBBI0_SCK_CLR();
00390             if (data & mask) {
00391                 SBBI0_MOSI_SET();
00392             } else {
00393                 SBBI0_MOSI_CLR();
00394             }
00395             Sbbi0Delay();
00396             SBBI0_SCK_SET();
00397             if (SBBI0_MISO_TST()) {
00398                 data |= mask;
00399             }
00400             else {
00401                 data &= ~mask;
00402             }
00403             Sbbi0Delay();
00404         }
00405         SBBI0_SCK_CLR();
00406     }
00407     return data;
00408 }
00409 
00426 void Sbbi0Transact(CONST void *wdata, void *rdata, size_t len)
00427 {
00428     CONST u_char *wp = (CONST u_char *)wdata;
00429 
00430     if (rdata) {
00431         u_char *rp = (u_char *)rdata;
00432 
00433         while(len--) {
00434             *rp++ = Sbbi0Byte(*wp);
00435             wp++;
00436         }
00437     } else {
00438         while(len--) {
00439             Sbbi0Byte(*wp);
00440             wp++;
00441         }
00442     }
00443 }
00444 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/