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

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