npl.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005 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 
00052 #include <dev/npl.h>
00053 
00054 #if 0
00055 /* Use for local debugging. */
00056 #define NUTDEBUG
00057 #include <stdio.h>
00058 #endif
00059 
00064 
00065 static int npl_registered;
00066 
00067 /*
00068  * NIC interrupt entry.
00069  */
00070 static void NplInterrupt(void *arg)
00071 {
00072     uint16_t slr;
00073 
00074     /* Read signal latch register and clear all enabled interrupts. */
00075     slr = inw(NPL_SLR) & inw(NPL_IMR);
00076 
00077     /* RS232 CTS activated. */
00078     if (slr & NPL_RSCTS) {
00079         if (sig_RSCTS.ir_handler) {
00080             (sig_RSCTS.ir_handler) (sig_RSCTS.ir_arg);
00081         }
00082     }
00083     /* RS232 DSR activated. */
00084     if (slr & NPL_RSDSR) {
00085         if (sig_RSDSR.ir_handler) {
00086             (sig_RSDSR.ir_handler) (sig_RSDSR.ir_arg);
00087         }
00088     }
00089     /* RS232 DCD activated. */
00090     if (slr & NPL_RSDCD) {
00091         if (sig_RSDCD.ir_handler) {
00092             (sig_RSDCD.ir_handler) (sig_RSDCD.ir_arg);
00093         }
00094     }
00095     /* RS232 RI activated. */
00096     if (slr & NPL_RSRI) {
00097         if (sig_RSRI.ir_handler) {
00098             (sig_RSRI.ir_handler) (sig_RSRI.ir_arg);
00099         }
00100     }
00101     /* RTC Alarm activated. */
00102     if (slr & NPL_RTCALARM) {
00103         if (sig_RTCALARM.ir_handler) {
00104             (sig_RTCALARM.ir_handler) (sig_RTCALARM.ir_arg);
00105         }
00106     }
00107     /* LAN wakeup activated. */
00108     if (slr & NPL_LANWAKEUP) {
00109         if (sig_LANWAKEUP.ir_handler) {
00110             (sig_LANWAKEUP.ir_handler) (sig_LANWAKEUP.ir_arg);
00111         }
00112     }
00113     /* FLASH ready activated. */
00114     if (slr & NPL_FMBUSY) {
00115         if (sig_FMBUSY.ir_handler) {
00116             (sig_FMBUSY.ir_handler) (sig_FMBUSY.ir_arg);
00117         }
00118     }
00119     /* RS232 signal valid. */
00120     if (slr & NPL_RSINVAL) {
00121         if (sig_RSINVAL.ir_handler) {
00122             (sig_RSINVAL.ir_handler) (sig_RSINVAL.ir_arg);
00123         }
00124     }
00125     /* RS232 signal invalid. */
00126     if (slr & NPL_NRSINVAL) {
00127         if (sig_NRSINVAL.ir_handler) {
00128             (sig_NRSINVAL.ir_handler) (sig_NRSINVAL.ir_arg);
00129         }
00130     }
00131     /* Multimedia card inserted. */
00132     if (slr & NPL_MMCD) {
00133         if (sig_MMCD.ir_handler) {
00134             (sig_MMCD.ir_handler) (sig_MMCD.ir_arg);
00135         }
00136     }
00137     /* Multimedia card removed. */
00138     if (slr & NPL_NMMCD) {
00139         if (sig_NMMCD.ir_handler) {
00140             (sig_NMMCD.ir_handler) (sig_NMMCD.ir_arg);
00141         }
00142     }
00143     outw(NPL_SCR, slr);
00144 }
00145 
00146 static int NplIrqCtl(int cmd, void *param, IRQ_HANDLER * irq, u_int mask)
00147 {
00148     int rc = 0;
00149     u_int *ival = (u_int *) param;
00150     uint16_t enabled = inw(NPL_IMR) & mask;
00151 
00152     /* Disable interrupt. */
00153     if (enabled) {
00154         outw(NPL_IMR, enabled & ~mask);
00155     }
00156     switch (cmd) {
00157     case NUT_IRQCTL_INIT:
00158         /* Clear interrupt */
00159         outw(NPL_SCR, mask);
00160         break;
00161     case NUT_IRQCTL_STATUS:
00162         if (enabled) {
00163             *ival |= 1;
00164         } else {
00165             *ival &= ~1;
00166         }
00167         break;
00168     case NUT_IRQCTL_ENABLE:
00169         enabled = 1;
00170         break;
00171     case NUT_IRQCTL_DISABLE:
00172         enabled = 0;
00173         break;
00174 #ifdef NUT_PERFMON
00175     case NUT_IRQCTL_GETCOUNT:
00176         *ival = (u_int) irq->ir_count;
00177         irq->ir_count = 0;
00178         break;
00179 #endif
00180     default:
00181         rc = -1;
00182         break;
00183     }
00184 
00185     /* Enable interrupt. */
00186     if (enabled) {
00187         outw(NPL_IMR, inw(NPL_IMR) | mask);
00188     }
00189     return rc;
00190 }
00191 
00192 
00193 static int NplRsCtsCtl(int cmd, void *param)
00194 {
00195     return NplIrqCtl(cmd, param, &sig_RSCTS, NPL_RSCTS);
00196 }
00197 
00198 static int NplRsDsrCtl(int cmd, void *param)
00199 {
00200     return NplIrqCtl(cmd, param, &sig_RSDSR, NPL_RSDSR);
00201 }
00202 
00203 static int NplRsDcdCtl(int cmd, void *param)
00204 {
00205     return NplIrqCtl(cmd, param, &sig_RSDCD, NPL_RSDCD);
00206 }
00207 
00208 static int NplRsRiCtl(int cmd, void *param)
00209 {
00210     return NplIrqCtl(cmd, param, &sig_RSRI, NPL_RSRI);
00211 }
00212 
00213 static int NplRtcAlarmCtl(int cmd, void *param)
00214 {
00215     return NplIrqCtl(cmd, param, &sig_RTCALARM, NPL_RTCALARM);
00216 }
00217 
00218 static int NplLanWakeupCtl(int cmd, void *param)
00219 {
00220     return NplIrqCtl(cmd, param, &sig_LANWAKEUP, NPL_LANWAKEUP);
00221 }
00222 
00223 static int NplFmBusyCtl(int cmd, void *param)
00224 {
00225     return NplIrqCtl(cmd, param, &sig_FMBUSY, NPL_FMBUSY);
00226 }
00227 
00228 static int NplRsInvalCtl(int cmd, void *param)
00229 {
00230     return NplIrqCtl(cmd, param, &sig_RSINVAL, NPL_RSINVAL);
00231 }
00232 
00233 static int NplRsValidCtl(int cmd, void *param)
00234 {
00235     return NplIrqCtl(cmd, param, &sig_NRSINVAL, NPL_NRSINVAL);
00236 }
00237 
00238 static int NplMmcInsertCtl(int cmd, void *param)
00239 {
00240     return NplIrqCtl(cmd, param, &sig_MMCD, NPL_MMCD);
00241 }
00242 
00243 static int NplMmcRemoveCtl(int cmd, void *param)
00244 {
00245     return NplIrqCtl(cmd, param, &sig_NMMCD, NPL_NMMCD);
00246 }
00247 
00248 
00263 int NplRegisterIrqHandler(IRQ_HANDLER * irq, void (*handler) (void *), void *arg)
00264 {
00265     int rc;
00266 
00267     /* Initialize this interrupt. */
00268     rc = (irq->ir_ctl) (NUT_IRQCTL_INIT, NULL);
00269 
00270     if (rc == 0) {
00271         /* Set the interrupt handler. */
00272         irq->ir_arg = arg;
00273         irq->ir_handler = handler;
00274 
00275         if (!npl_registered) {
00276             npl_registered = 1;
00277 #if defined(ETHERNUT3)
00278             outr(PIO_PDR, _BV(9));
00279 #endif
00280             if ((rc = NutRegisterIrqHandler(&sig_INTERRUPT0, NplInterrupt, NULL)) == 0) {
00281                 NutIrqSetMode(&sig_INTERRUPT0, NUT_IRQMODE_LOWLEVEL);
00282                 NutIrqEnable(&sig_INTERRUPT0);
00283             }
00284         }
00285     }
00286     return rc;
00287 }
00288 
00296 int NplIrqEnable(IRQ_HANDLER * irq)
00297 {
00298     return (irq->ir_ctl) (NUT_IRQCTL_ENABLE, NULL);
00299 }
00300 
00308 int NplIrqDisable(IRQ_HANDLER * irq)
00309 {
00310     return (irq->ir_ctl) (NUT_IRQCTL_DISABLE, NULL);
00311 }
00312 
00316 IRQ_HANDLER sig_RSCTS = {
00317 #ifdef NUT_PERFMON
00318     0,                          /* Interrupt counter, ir_count. */
00319 #endif
00320     NULL,                       /* Passed argument, ir_arg. */
00321     NULL,                       /* Handler subroutine, ir_handler. */
00322     NplRsCtsCtl                 /* Interrupt control, ir_ctl. */
00323 };
00324 
00328 IRQ_HANDLER sig_RSDSR = {
00329 #ifdef NUT_PERFMON
00330     0,                          /* Interrupt counter, ir_count. */
00331 #endif
00332     NULL,                       /* Passed argument, ir_arg. */
00333     NULL,                       /* Handler subroutine, ir_handler. */
00334     NplRsDsrCtl                 /* Interrupt control, ir_ctl. */
00335 };
00336 
00340 IRQ_HANDLER sig_RSDCD = {
00341 #ifdef NUT_PERFMON
00342     0,                          /* Interrupt counter, ir_count. */
00343 #endif
00344     NULL,                       /* Passed argument, ir_arg. */
00345     NULL,                       /* Handler subroutine, ir_handler. */
00346     NplRsDcdCtl                 /* Interrupt control, ir_ctl. */
00347 };
00348 
00352 IRQ_HANDLER sig_RSRI = {
00353 #ifdef NUT_PERFMON
00354     0,                          /* Interrupt counter, ir_count. */
00355 #endif
00356     NULL,                       /* Passed argument, ir_arg. */
00357     NULL,                       /* Handler subroutine, ir_handler. */
00358     NplRsRiCtl                  /* Interrupt control, ir_ctl. */
00359 };
00360 
00364 IRQ_HANDLER sig_RTCALARM = {
00365 #ifdef NUT_PERFMON
00366     0,                          /* Interrupt counter, ir_count. */
00367 #endif
00368     NULL,                       /* Passed argument, ir_arg. */
00369     NULL,                       /* Handler subroutine, ir_handler. */
00370     NplRtcAlarmCtl              /* Interrupt control, ir_ctl. */
00371 };
00372 
00376 IRQ_HANDLER sig_LANWAKEUP = {
00377 #ifdef NUT_PERFMON
00378     0,                          /* Interrupt counter, ir_count. */
00379 #endif
00380     NULL,                       /* Passed argument, ir_arg. */
00381     NULL,                       /* Handler subroutine, ir_handler. */
00382     NplLanWakeupCtl             /* Interrupt control, ir_ctl. */
00383 };
00384 
00388 IRQ_HANDLER sig_FMBUSY = {
00389 #ifdef NUT_PERFMON
00390     0,                          /* Interrupt counter, ir_count. */
00391 #endif
00392     NULL,                       /* Passed argument, ir_arg. */
00393     NULL,                       /* Handler subroutine, ir_handler. */
00394     NplFmBusyCtl                /* Interrupt control, ir_ctl. */
00395 };
00396 
00400 IRQ_HANDLER sig_RSINVAL = {
00401 #ifdef NUT_PERFMON
00402     0,                          /* Interrupt counter, ir_count. */
00403 #endif
00404     NULL,                       /* Passed argument, ir_arg. */
00405     NULL,                       /* Handler subroutine, ir_handler. */
00406     NplRsInvalCtl               /* Interrupt control, ir_ctl. */
00407 };
00408 
00412 IRQ_HANDLER sig_NRSINVAL = {
00413 #ifdef NUT_PERFMON
00414     0,                          /* Interrupt counter, ir_count. */
00415 #endif
00416     NULL,                       /* Passed argument, ir_arg. */
00417     NULL,                       /* Handler subroutine, ir_handler. */
00418     NplRsValidCtl               /* Interrupt control, ir_ctl. */
00419 };
00420 
00424 IRQ_HANDLER sig_MMCD = {
00425 #ifdef NUT_PERFMON
00426     0,                          /* Interrupt counter, ir_count. */
00427 #endif
00428     NULL,                       /* Passed argument, ir_arg. */
00429     NULL,                       /* Handler subroutine, ir_handler. */
00430     NplMmcInsertCtl             /* Interrupt control, ir_ctl. */
00431 };
00432 
00436 IRQ_HANDLER sig_NMMCD = {
00437 #ifdef NUT_PERFMON
00438     0,                          /* Interrupt counter, ir_count. */
00439 #endif
00440     NULL,                       /* Passed argument, ir_arg. */
00441     NULL,                       /* Handler subroutine, ir_handler. */
00442     NplMmcRemoveCtl             /* Interrupt control, ir_ctl. */
00443 };
00444 

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