diff --git a/bspApi.h b/bspApi.h index 7e381e8..2ed0270 100644 --- a/bspApi.h +++ b/bspApi.h @@ -15,10 +15,11 @@ extern "C" { #define FIOC_SM2130_WR (__SM2130__IOC_MAGIC | XFER_TYPE_WR) #define FIOC_SM2130_RD (__SM2130__IOC_MAGIC | XFER_TYPE_RD) -#define FIOC_SM2130_READY (__SM2130__IOC_MAGIC | 0x10) -#define FIOC_SM2130_ACKIRQ (__SM2130__IOC_MAGIC | 0x11) -#define FIOC_SM2130_RST (__SM2130__IOC_MAGIC | 0x12) -#define FIOC_SM2130_REQISR (__SM2130__IOC_MAGIC | 0x13) +#define FIOC_SM2130_READY (__SM2130__IOC_MAGIC | 0x10) +#define FIOC_SM2130_ACKABLE (__SM2130__IOC_MAGIC | 0x11) +#define FIOC_SM2130_ACKIRQ (__SM2130__IOC_MAGIC | 0x12) +#define FIOC_SM2130_RST (__SM2130__IOC_MAGIC | 0x13) +#define FIOC_SM2130_REQISR (__SM2130__IOC_MAGIC | 0x14) #define FIOC_SM2130_REGRD (__SM2130__IOC_MAGIC | 0x21) #define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22) diff --git a/bspStubs.c b/bspStubs.c index b6e2e67..484783b 100644 --- a/bspStubs.c +++ b/bspStubs.c @@ -175,7 +175,7 @@ void bspSm1553bAckIrq(BOOL value) pCtrl = pDev->pDrvCtrl; pCtrl->gpioOutput(pDev, 1, 6, value); - logMsg("ackirq Sm1553b Irq\r\n", 1, 2, 3, 4, 5, 6); + /* logMsg("ackirq Sm1553b Irq\r\n", 1, 2, 3, 4, 5, 6); */ } /* }}} */ diff --git a/vxbSm2130SpiDev.c b/vxbSm2130SpiDev.c index 3099b14..5a69edc 100644 --- a/vxbSm2130SpiDev.c +++ b/vxbSm2130SpiDev.c @@ -11,12 +11,12 @@ #include #include #include +#include #include #include #include #include #include - #include #include "vxbSm2130SpiDev.h" #include @@ -28,7 +28,7 @@ typedef struct _Sm2310_DEV_HANDLE { SEL_WAKEUP_LIST selList; - volatile BOOL irqFlag; + BOOL ackable; void (*usrIsr)(); @@ -353,13 +353,16 @@ LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg) semTake(pDrvCtrl->muteSem, WAIT_FOREVER); switch (cmd) { case FIOSELECT: - if (dev->irqFlag) { + spinLockIsrTake(&pDrvCtrl->spinLock); + if (dev->ackable && pDrvCtrl->irqFlag) { selWakeup((SEL_WAKEUP_NODE *)arg); - } else { - if (selNodeAdd(&dev->selList, (SEL_WAKEUP_NODE *)arg) == ERROR) { - selWakeup((SEL_WAKEUP_NODE *)arg); - } + spinLockIsrGive(&pDrvCtrl->spinLock); + break; } + if (selNodeAdd(&dev->selList, (SEL_WAKEUP_NODE *)arg) != OK) { + selWakeup((SEL_WAKEUP_NODE *)arg); + } + spinLockIsrGive(&pDrvCtrl->spinLock); break; case FIOUNSELECT: selNodeDelete(&dev->selList, (SEL_WAKEUP_NODE *)arg); @@ -368,6 +371,10 @@ LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg) xfer = (SM2130_XFER *)(arg); pDrvCtrl->write(pDrvCtrl->pDev, xfer->reg, xfer->val); break; + case FIOC_SM2130_ACKABLE: + dev->ackable = (BOOL)arg; + break; + case FIOC_SM2130_RD: xfer = (SM2130_XFER *)(arg); xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, xfer->reg); @@ -393,15 +400,18 @@ LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg) break; case FIOC_SM2130_ACKIRQ: - iflag = dev->irqFlag; - dev->irqFlag = FALSE; - if (pDrvCtrl->funcAckIrq && iflag) { + iflag = pDrvCtrl->irqFlag; + pDrvCtrl->irqFlag = FALSE; + if (pDrvCtrl->funcAckIrq) { UINT32 us = (UINT32)arg; if (us == 0) { us = 100; } + pDrvCtrl->funcAckIrq(FALSE); pDrvCtrl->funcAckIrq(TRUE); - sysUsDelay(us); + if (iflag) { + sysUsDelay(us); + } pDrvCtrl->funcAckIrq(FALSE); } else { if (!pDrvCtrl->funcAckIrq) { @@ -440,6 +450,9 @@ LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg) break; } semGive(pDrvCtrl->muteSem); + if (ret == OK) { + errnoSet(OK); + } return (ret); } /* }}} */ @@ -466,6 +479,8 @@ LOCAL void sm2130SpiDevInstInit2(VXB_DEVICE_ID pDev) /* Mutex semaphore is initialized and necessary at this point */ pDrvCtrl->muteSem = semMCreate(SPI_DEV_MUTEX_OPT); + spinLockIsrInit(&pDrvCtrl->spinLock, SPIN_LOCK_EMPTY); + pFunc = vxbDevMethodGet(vxbDevParent(pDev), (VXB_METHOD_ID)vxbSpiSpecialGet_desc); /* Retrieve the SPI master special information */ @@ -480,14 +495,15 @@ LOCAL void sm1553isr(void *data) ++pDrvCtrl->irqCount; - dev->irqFlag = TRUE; + pDrvCtrl->irqFlag = TRUE; //logMsg("sm1553isr interrupt", 1, 2, 3, 4, 5, 6); if (dev->usrIsr) { dev->usrIsr(); } - + spinLockIsrTake(&pDrvCtrl->spinLock); selWakeupAll(&dev->selList, SELREAD); + spinLockIsrGive(&pDrvCtrl->spinLock); } /* @@ -538,7 +554,8 @@ LOCAL void sm2130SpiDevInstConnect(VXB_DEVICE_ID pDev) if (dev) { pDrvCtrl->refcount = 0; dev->usrIsr = NULL; - dev->irqFlag = FALSE; + dev->ackable = FALSE; + pDrvCtrl->irqFlag = FALSE; selWakeupListInit(&dev->selList); if (iosDevAdd(&dev->devHdr, pDrvCtrl->devName, sm2130_driver_node) == OK) { pDrvCtrl->devHandle = dev; @@ -625,6 +642,7 @@ LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose) printf(" refCount: %d\n", pDrvCtrl->refcount); printf(" funcReqIsr: %p\n", pDrvCtrl->funcReqIsr); printf(" irqCount: %u\n", pDrvCtrl->irqCount); + printf(" irqFlag: %s\n", pDrvCtrl->irqFlag ? "TRUE" : "FALSE"); printf(" isReady: %s\n", checkReady(pDrvCtrl)); } diff --git a/vxbSm2130SpiDev.h b/vxbSm2130SpiDev.h index 9e64953..b797e17 100644 --- a/vxbSm2130SpiDev.h +++ b/vxbSm2130SpiDev.h @@ -13,10 +13,11 @@ #define FIOC_SM2130_WR (__SM2130__IOC_MAGIC | XFER_TYPE_WR) #define FIOC_SM2130_RD (__SM2130__IOC_MAGIC | XFER_TYPE_RD) -#define FIOC_SM2130_READY (__SM2130__IOC_MAGIC | 0x10) -#define FIOC_SM2130_ACKIRQ (__SM2130__IOC_MAGIC | 0x11) -#define FIOC_SM2130_RST (__SM2130__IOC_MAGIC | 0x12) -#define FIOC_SM2130_REQISR (__SM2130__IOC_MAGIC | 0x13) +#define FIOC_SM2130_READY (__SM2130__IOC_MAGIC | 0x10) +#define FIOC_SM2130_ACKABLE (__SM2130__IOC_MAGIC | 0x11) +#define FIOC_SM2130_ACKIRQ (__SM2130__IOC_MAGIC | 0x12) +#define FIOC_SM2130_RST (__SM2130__IOC_MAGIC | 0x13) +#define FIOC_SM2130_REQISR (__SM2130__IOC_MAGIC | 0x14) #define FIOC_SM2130_REGRD (__SM2130__IOC_MAGIC | 0x21) #define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22) @@ -50,6 +51,10 @@ typedef struct _spi_1553b_drv_ctrl { volatile UINT32 irqCount; + volatile BOOL irqFlag; + + spinlockIsr_t spinLock; + void *devHandle; int (*funcReqIsr)(void *data, void (*isr)(void *data));