Browse Source

improv sm2130 chip driver

Signed-off-by: surenyi <surenyi82@163.com>
master
surenyi 2 weeks ago
parent
commit
caa486d56b
  1. 5
      bspApi.h
  2. 47
      bspStubs.c
  3. 16
      hwconf.c
  4. 167
      vxbSm2130SpiDev.c
  5. 17
      vxbSm2130SpiDev.h

5
bspApi.h

@ -16,6 +16,9 @@ extern "C" {
#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_REGRD (__SM2130__IOC_MAGIC | 0x21)
#define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22)
@ -29,6 +32,8 @@ struct sm2130_xfer {
};
typedef struct sm2130_xfer SM2130_XFER;
#define SMX_MAX_WORDS (64)
struct sm2130_xfer_mem {
int count;
UINT8 reg;

47
bspStubs.c

@ -8,6 +8,7 @@
#include <ioLib.h>
#include <sysSymTbl.h>
#include <fcntl.h>
#include <logLib.h>
#include <hwif/vxbus/vxBus.h>
#include <hwif/util/vxbParamSys.h>
#include "config.h"
@ -30,6 +31,7 @@ IMPORT int uenvInit();
IMPORT void lfsDevRegister(void);
IMPORT void vxbSpiRawDevRegister(void);
IMPORT void sysMsDelay(UINT delay);
IMPORT void sysUsDelay(int us);
/* bsp glue functions */
void bspPinMuxInitialize(void)
@ -109,27 +111,39 @@ void bspDriverRegiser(void)
}
/* {{{ 1553B IO */
/* GPIO1_A4 */
int bspSm1553bIrqConnect(void *data, void (*isr)(void *data))
/* MR: GPIO1_B7 (reset) */
void bspSm1553bReset(BOOL value)
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 1);
if (pDev == NULL) {
printf("Can't find ftGpio1\r\n");
return ERROR;
logMsg("Can't find ftGpio1\r\n", 1, 2, 3, 4, 5, 6);
return;
}
pCtrl = pDev->pDrvCtrl;
/* MR: GPIO1_B7 (reset) */
pCtrl->gpioOutput(pDev, 1, 7, 0);
sysMsDelay(10);
pCtrl->gpioOutput(pDev, 1, 7, 1);
pCtrl->gpioOutput(pDev, 1, 7, value);
}
/* GPIO1_A4 */
void bspSm1553bIrqConnect(void *data, void (*isr)(void *data))
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 1);
if (pDev == NULL) {
logMsg("Can't find ftGpio1\r\n", 1, 2, 3, 4, 5, 6);
return;
}
pCtrl = pDev->pDrvCtrl;
/* GPIO1_A4 (irq) */
pCtrl->gpioISRSet(pDev, 4, isr, data);
return OK;
}
/* GPIO0_B7: SM2130_READY */
@ -140,7 +154,7 @@ int bspSm1553bChipReady(void)
pDev = vxbInstByNameFind("ftGpio", 0);
if (pDev == NULL) {
printf("Can't find ftGpio0\r\n");
logMsg("Can't find ftGpio0\r\n", 1, 2, 3, 4, 5, 6);
return 0;
}
pCtrl = pDev->pDrvCtrl;
@ -148,9 +162,20 @@ int bspSm1553bChipReady(void)
return pCtrl->gpioInput(pDev, 1, 7);
}
void bspSm1553bAckIrq(void)
/* GPIO0_B6: M2130_ACKIRQ */
void bspSm1553bAckIrq(BOOL value)
{
logMsg("Sm1553b Irq\r\n", 1, 2, 3, 4, 5, 6);
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 0);
if (pDev == NULL) {
return;
}
pCtrl = pDev->pDrvCtrl;
pCtrl->gpioOutput(pDev, 1, 6, value);
logMsg("ackirq Sm1553b Irq\r\n", 1, 2, 3, 4, 5, 6);
}
/* }}} */

16
hwconf.c

@ -150,7 +150,7 @@ LOCAL const struct intrCtlrTrigger gicTrigger[] = {
/* pin, sensitivity */
{ INT_VEC_GPIO0INTR, VXB_INTR_TRIG_RISING_EDGE },
{ INT_VEC_GPIO1INTR, VXB_INTR_TRIG_RISING_EDGE },
{ INT_VEC_GPIO1INTR, VXB_INTR_TRIG_FALLING_EDGE },
};
@ -406,7 +406,7 @@ struct hcfResource gpioDev1Resources[] = {
{ "portAModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio1PortAModeTable)} },
{ "portBModeTable", HCF_RES_ADDR, { (void *)&gpio1PortBModeTable[0] } },
{ "portBModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio1PortBModeTable)} },
{ "trigger", HCF_RES_INT, { (void *)VXB_INTR_TRIG_RISING_EDGE} },
{ "trigger", HCF_RES_INT, { (void *)VXB_INTR_TRIG_FALLING_EDGE } },
};
#define gpioDev1Num NELEMENTS(gpioDev1Resources)
#endif
@ -530,15 +530,17 @@ struct hcfResource lfsResources[] = {
#define lfsResNum NELEMENTS(lfsResources)
#endif
IMPORT int bspSm1553bIrqConnect(void *data, void (*isr)(void *data));
IMPORT void bspSm1553bIrqConnect(void *data, void (*isr)(void *data));
IMPORT int bspSm1553bChipReady(void);
IMPORT void bspSm1553bAckIrq(void);
IMPORT void bspSm1553bAckIrq(BOOL);
IMPORT void bspSm1553bReset(BOOL);
struct hcfResource sm2130Resources[] = {
{ "devName" , HCF_RES_STRING, {(void *)"/sm1553b" } },
{ "reqIsr" , HCF_RES_ADDR, {(void *)bspSm1553bIrqConnect}},
{ "isReady" , HCF_RES_ADDR, {(void *)bspSm1553bChipReady}},
{ "ackIrq" , HCF_RES_ADDR, {(void *)bspSm1553bAckIrq}},
{ "funcReqIsr" , HCF_RES_ADDR, {(void *)bspSm1553bIrqConnect } },
{ "funcIsReady" , HCF_RES_ADDR, {(void *)bspSm1553bChipReady } },
{ "funcAckIrq" , HCF_RES_ADDR, {(void *)bspSm1553bAckIrq } },
{ "funcReset" , HCF_RES_ADDR, {(void *)bspSm1553bReset } },
};
#define sm2130ResNum NELEMENTS(sm2130Resources)

167
vxbSm2130SpiDev.c

@ -28,11 +28,16 @@ typedef struct _Sm2310_DEV_HANDLE {
SEL_WAKEUP_LIST selList;
void (*usrIsr)();
SM2130_SPI_DEV *pDevCtrl;
} SM2310_DEV_HANDLE;
LOCAL int sm2130_driver_node = -1;
/* Declare */
IMPORT void sysUsDelay(UINT32 us);
/* locals */
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose);
LOCAL INT32 sm2130BusDevRead(VXB_DEVICE_ID pDev, UINT8 cmd);
@ -125,14 +130,18 @@ LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev)
if (devResourceGet(pHcf, "devName", HCF_RES_STRING, (void *)&pDrvCtrl->devName) != OK) {
pDrvCtrl->devName = pDrvCtrl->name;
}
if (devResourceGet(pHcf, "reqIsr", HCF_RES_ADDR, (void *)&pDrvCtrl->reqIsr) != OK) {
pDrvCtrl->reqIsr = NULL;
if (devResourceGet(pHcf, "funcReqIsr", HCF_RES_ADDR, (void *)&pDrvCtrl->funcReqIsr) != OK) {
pDrvCtrl->funcReqIsr = NULL;
}
if (devResourceGet(pHcf, "isReady", HCF_RES_ADDR, (void *)&pDrvCtrl->isReady) != OK) {
pDrvCtrl->isReady = NULL;
if (devResourceGet(pHcf, "funcIsReady", HCF_RES_ADDR, (void *)&pDrvCtrl->funcIsReady) != OK) {
pDrvCtrl->funcIsReady = NULL;
}
if (devResourceGet(pHcf, "ackIrq", HCF_RES_ADDR, (void *)&pDrvCtrl->ackIrq) != OK) {
pDrvCtrl->ackIrq = NULL;
if (devResourceGet(pHcf, "funcAckIrq", HCF_RES_ADDR, (void *)&pDrvCtrl->funcAckIrq) != OK) {
pDrvCtrl->funcAckIrq = NULL;
}
if (devResourceGet(pHcf, "funcReset", HCF_RES_ADDR, (void *)&pDrvCtrl->funcReset) != OK) {
pDrvCtrl->funcReset = NULL;
}
}
@ -147,9 +156,14 @@ LOCAL SM2310_DEV_HANDLE *drv1553bOpen(SM2310_DEV_HANDLE *dev, const char *name,
{
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
if (pDrvCtrl->refcount > 0) {
errnoSet(EBUSY);
return (void *)ERROR;
}
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
++pDrvCtrl->refcount;
(void)semGive(pDrvCtrl->muteSem);
semGive(pDrvCtrl->muteSem);
return dev;
}
@ -157,9 +171,9 @@ LOCAL int drv1553bClose(SM2310_DEV_HANDLE *dev)
{
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
--pDrvCtrl->refcount;
(void)semGive(pDrvCtrl->muteSem);
semGive(pDrvCtrl->muteSem);
return (OK);
}
@ -215,7 +229,7 @@ LOCAL int readMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
UINT8 *ptr;
UINT8 cmd;
if ((mxfr->count <= 0) || (mxfr->count >= (sizeof (pDrvCtrl->regmem) / sizeof (pDrvCtrl->regmem[0])))) {
if ((mxfr->count <= 0) || (mxfr->count > SMX_MAX_WORDS)) {
errnoSet(EINVAL);
return ERROR;
}
@ -249,7 +263,7 @@ LOCAL int writeMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
UINT8 *ptr;
UINT8 cmd;
if ((mxfr->count <= 0) || (mxfr->count >= (sizeof (pDrvCtrl->regmem) / sizeof (pDrvCtrl->regmem[0])))) {
if ((mxfr->count <= 0) || (mxfr->count > SMX_MAX_WORDS)) {
errnoSet(EINVAL);
return ERROR;
}
@ -275,6 +289,58 @@ LOCAL int writeMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
return OK;
}
LOCAL ssize_t drv1553bRead(SM2310_DEV_HANDLE *dev, char *buffer, size_t maxbytes)
{
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
int max_words = maxbytes / 2;
SM2130_MEM_XFER smx = { 0, 0, 0, NULL };
STATUS error;
if (max_words > SMX_MAX_WORDS) {
max_words = SMX_MAX_WORDS;
}
smx.count = max_words;
smx.membuf = (UINT16 *)buffer;
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
error = readMemory(pDrvCtrl, &smx);
semGive(pDrvCtrl->muteSem);
if (error != OK) {
errnoSet(EIO);
return -1;
}
return max_words * 2;
}
LOCAL ssize_t drv1553bWrite(SM2310_DEV_HANDLE *dev, char *buffer, size_t nbytes)
{
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
int max_words = nbytes / 2;
SM2130_MEM_XFER smx = { 0, 0, 0, NULL };
STATUS error;
if (max_words > SMX_MAX_WORDS) {
max_words = SMX_MAX_WORDS;
}
smx.count = max_words;
smx.membuf = (UINT16 *)buffer;
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
error = writeMemory(pDrvCtrl, &smx);
semGive(pDrvCtrl->muteSem);
if (error != OK) {
errnoSet(EIO);
return -1;
}
return max_words * 2;
}
LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg)
{
SM2130_XFER *xfer;
@ -297,9 +363,46 @@ LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg)
xfer = (SM2130_XFER *)(arg);
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, xfer->reg);
break;
case FIOC_SM2130_RST:
if (pDrvCtrl->funcReset) {
UINT32 us = (UINT32)arg;
if (us == 0) {
us = 10000;
}
pDrvCtrl->funcReset(TRUE);
sysUsDelay(us);
pDrvCtrl->funcReset(FALSE);
} else {
errnoSet(ENOTSUP);
ret = ERROR;
}
break;
case FIOC_SM2130_REQISR:
dev->usrIsr = (void *)(arg);
break;
case FIOC_SM2130_ACKIRQ:
if (pDrvCtrl->funcAckIrq) {
if (pDrvCtrl->irqCount > 0) {
UINT32 us = (UINT32)arg;
if (us == 0) {
us = 100;
}
pDrvCtrl->funcAckIrq(TRUE);
sysUsDelay(us);
pDrvCtrl->funcAckIrq(FALSE);
}
} else {
errnoSet(ENOTSUP);
ret = ERROR;
}
pDrvCtrl->irqCount = 0;
break;
case FIOC_SM2130_READY:
if (pDrvCtrl->isReady) {
*(int *)(arg) = pDrvCtrl->isReady();
if (pDrvCtrl->funcIsReady) {
*(int *)(arg) = pDrvCtrl->funcIsReady();
} else {
errnoSet(EIO);
ret = ERROR;
@ -358,7 +461,6 @@ LOCAL void sm2130SpiDevInstInit2(VXB_DEVICE_ID pDev)
/* Retrieve the SPI master special information */
if (pFunc != NULL)
(*pFunc)(vxbDevParent(pDev), &pDrvCtrl->specialInfo);
pDrvCtrl->irqStage = -128;
}
LOCAL void sm1553isr(void *data)
@ -366,11 +468,13 @@ LOCAL void sm1553isr(void *data)
SM2310_DEV_HANDLE *dev = data;
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
if (pDrvCtrl->ackIrq) {
pDrvCtrl->ackIrq();
++pDrvCtrl->irqCount;
//logMsg("sm1553isr interrupt", 1, 2, 3, 4, 5, 6);
if (dev->usrIsr) {
dev->usrIsr();
}
logMsg("sm1553isr interrupt", 1, 2, 3, 4, 5, 6);
selWakeupAll(&dev->selList, SELREAD);
}
@ -400,23 +504,34 @@ LOCAL void sm2130SpiDevInstConnect(VXB_DEVICE_ID pDev)
(DRV_REMOVE_PTR)NULL ,
(DRV_OPEN_PTR)drv1553bOpen ,
(DRV_CLOSE_PTR)drv1553bClose ,
(DRV_READ_PTR)NULL ,
(DRV_WRITE_PTR)NULL ,
(DRV_READ_PTR)drv1553bRead ,
(DRV_WRITE_PTR)drv1553bWrite ,
(DRV_IOCTL_PTR)drv1553bIoctl);
/* clang-format on */
}
if (pDrvCtrl->funcAckIrq) {
pDrvCtrl->funcAckIrq(FALSE);
}
if (pDrvCtrl->funcReset) {
pDrvCtrl->funcReset(FALSE);
sysUsDelay(10000);
pDrvCtrl->funcReset(TRUE);
}
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
if (sm2130_driver_node > 0) {
dev = (SM2310_DEV_HANDLE *)hwMemAlloc(sizeof(SM2310_DEV_HANDLE));
if (dev) {
pDrvCtrl->refcount = 0;
dev->usrIsr = NULL;
selWakeupListInit(&dev->selList);
if (iosDevAdd(&dev->devHdr, pDrvCtrl->devName, sm2130_driver_node) == OK) {
pDrvCtrl->devHandle = dev;
dev->pDevCtrl = pDrvCtrl;
if (pDrvCtrl->reqIsr) {
pDrvCtrl->irqStage = pDrvCtrl->reqIsr(dev, sm1553isr);
if (pDrvCtrl->funcReqIsr) {
pDrvCtrl->funcReqIsr(dev, sm1553isr);
}
} else {
#ifndef _VXBUS_BASIC_HWMEMLIB
@ -473,11 +588,11 @@ LOCAL STATUS sm2130SpiDevInstUnlink(VXB_DEVICE_ID pDev, void *unused)
*/
LOCAL const char *checkReady(SM2130_SPI_DEV *pDrvCtrl)
{
if (!pDrvCtrl->isReady()) {
if (!pDrvCtrl->funcIsReady) {
return "Unknown";
}
if (pDrvCtrl->isReady()) {
if (pDrvCtrl->funcIsReady()) {
return "Ready";
}
@ -495,8 +610,8 @@ LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose)
printf(" devName: %s\n", pDrvCtrl->devName);
printf(" devHandle: %p\n", pDrvCtrl->devHandle);
printf(" refCount: %d\n", pDrvCtrl->refcount);
printf(" reqIsr: %p\n", pDrvCtrl->reqIsr);
printf(" irqStatus: %d\n", pDrvCtrl->irqStage);
printf(" funcReqIsr: %p\n", pDrvCtrl->funcReqIsr);
printf(" irqCount: %u\n", pDrvCtrl->irqCount);
printf(" isReady: %s\n", checkReady(pDrvCtrl));
}

17
vxbSm2130SpiDev.h

@ -14,6 +14,9 @@
#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_REGRD (__SM2130__IOC_MAGIC | 0x21)
#define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22)
@ -27,6 +30,7 @@ struct sm2130_xfer {
};
typedef struct sm2130_xfer SM2130_XFER;
#define SMX_MAX_WORDS (64)
struct sm2130_xfer_mem {
int count;
UINT8 reg;
@ -42,20 +46,21 @@ typedef struct _spi_1553b_drv_ctrl {
const char *devName;
int refcount;
volatile int refcount;
int irqStage;
volatile UINT32 irqCount;
void *devHandle;
int (*reqIsr)(void *data, void (*isr)(void *data));
int (*isReady)();
void (*ackIrq)();
int (*funcReqIsr)(void *data, void (*isr)(void *data));
int (*funcIsReady)();
void (*funcAckIrq)(BOOL);
void (*funcReset)(BOOL);
INT32 (*read)(VXB_DEVICE_ID pDev, UINT8 cmd);
STATUS (*write)(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var);
UINT16 regmem[64];
UINT16 regmem[SMX_MAX_WORDS+1]; /* add 1 dummy slot */
SEM_ID muteSem; /* operation semaphore */
VXB_SPI_MAST_SPEC *specialInfo;

Loading…
Cancel
Save