Browse Source

improve Sm2130 driver

Signed-off-by: surenyi <surenyi82@163.com>
master
surenyi 2 weeks ago
parent
commit
6fc9a5f2b3
  1. 15
      bspApi.h
  2. 64
      bspStubs.c
  3. 10
      hwconf.c
  4. 179
      vxbSm2130SpiDev.c
  5. 24
      vxbSm2130SpiDev.h
  6. 2
      vxbSpiRawDev.c

15
bspApi.h

@ -14,7 +14,14 @@ 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_MEM (__SM2130__IOC_MAGIC | (XFER_TYPE_WR + XFER_TYPE_RD))
#define FIOC_SM2130_READY (__SM2130__IOC_MAGIC | 0x10)
#define FIOC_SM2130_REGRD (__SM2130__IOC_MAGIC | 0x21)
#define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22)
#define FIOC_SM2130_SMADDR (__SM2130__IOC_MAGIC | 0x23)
#define FIOC_SM2130_RDMEM (__SM2130__IOC_MAGIC | 0x24)
#define FIOC_SM2130_WRMEM (__SM2130__IOC_MAGIC | 0x25)
struct sm2130_xfer {
UINT8 reg;
@ -23,9 +30,9 @@ struct sm2130_xfer {
typedef struct sm2130_xfer SM2130_XFER;
struct sm2130_xfer_mem {
int type;
int count;
UINT8 *regbuf;
int count;
UINT8 reg;
UINT16 address;
UINT16 *membuf;
};
typedef struct sm2130_xfer_mem SM2130_MEM_XFER;

64
bspStubs.c

@ -29,7 +29,7 @@ IMPORT unsigned int uenvGetUint(const char *varname);
IMPORT int uenvInit();
IMPORT void lfsDevRegister(void);
IMPORT void vxbSpiRawDevRegister(void);
IMPORT void sysMsDelay(UINT delay);
/* bsp glue functions */
void bspPinMuxInitialize(void)
@ -108,6 +108,53 @@ void bspDriverRegiser(void)
#endif
}
/* {{{ 1553B IO */
/* GPIO1_A4 */
int bspSm1553bIrqConnect(void *data, void (*isr)(void *data))
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 1);
if (pDev == NULL) {
printf("Can't find ftGpio1\r\n");
return ERROR;
}
pCtrl = pDev->pDrvCtrl;
/* MR: GPIO1_B7 (reset) */
pCtrl->gpioOutput(pDev, 1, 7, 0);
sysMsDelay(10);
pCtrl->gpioOutput(pDev, 1, 7, 1);
/* GPIO1_A4 (irq) */
pCtrl->gpioISRSet(pDev, 4, isr, data);
return OK;
}
/* GPIO0_B7: SM2130_READY */
int bspSm1553bChipReady(void)
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 0);
if (pDev == NULL) {
printf("Can't find ftGpio0\r\n");
return 0;
}
pCtrl = pDev->pDrvCtrl;
return pCtrl->gpioInput(pDev, 1, 7);
}
void bspSm1553bAckIrq(void)
{
logMsg("Sm1553b Irq\r\n", 1, 2, 3, 4, 5, 6);
}
/* }}} */
int bspLoadUserApp()
{
SEGMENT_ID seg;
@ -213,21 +260,6 @@ int bsp_ipftps_authenticate_nopasswd(Ipftps_session *session, char *password)
}
#endif
/* GPIO1_A4 */
int bspSm1553bIrqConnect(void *data, void (*isr)(void *data))
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 1);
if (pDev == NULL) {
return ERROR;
}
pCtrl = pDev->pDrvCtrl;
pCtrl->gpioISRSet(pDev, 4, isr, data);
return OK;
}
int mw(unsigned long addr, unsigned int val)
{
volatile unsigned int long *ptr = (volatile unsigned long *)(addr);

10
hwconf.c

@ -260,7 +260,7 @@ struct hcfResource qspiResources[] = {
#ifdef DRV_FTSPI
struct vxbSpiDevInfo sm2130DevRes[] = {
/* name cs width freq mode */
{ "SM2130", 0, 8, 5000000, 3},
{ "SM2130", 0, 8, 16000000, 3},
};
struct vxbSpiDevInfo spiRawDevRes[] = {
@ -281,7 +281,7 @@ struct hcfResource spiResources0[] = {
struct hcfResource spiResources1[] = {
{ "regBase", HCF_RES_INT, { (void *)(FTSPI1_BASE) } },
{ "clkFreq", HCF_RES_INT, { (void *)(FT2000_SPI_CLK) } },
{ "speed", HCF_RES_INT, { (void *)(4000000) } },
{ "speed", HCF_RES_INT, { (void *)(16000000) } },
{ "mode", HCF_RES_INT, { (void *)3} },
{ "spiDev", HCF_RES_ADDR, { (void *)&sm2130DevRes[0]} },
{ "spiDevNum", HCF_RES_INT, { (void *)NELEMENTS(sm2130DevRes)}},
@ -530,11 +530,15 @@ struct hcfResource lfsResources[] = {
#define lfsResNum NELEMENTS(lfsResources)
#endif
extern int bspSm1553bIrqConnect(void *data, void (*isr)(void *data));
IMPORT int bspSm1553bIrqConnect(void *data, void (*isr)(void *data));
IMPORT int bspSm1553bChipReady(void);
IMPORT void bspSm1553bAckIrq(void);
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}},
};
#define sm2130ResNum NELEMENTS(sm2130Resources)

179
vxbSm2130SpiDev.c

@ -128,6 +128,12 @@ LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev)
if (devResourceGet(pHcf, "reqIsr", HCF_RES_ADDR, (void *)&pDrvCtrl->reqIsr) != OK) {
pDrvCtrl->reqIsr = NULL;
}
if (devResourceGet(pHcf, "isReady", HCF_RES_ADDR, (void *)&pDrvCtrl->isReady) != OK) {
pDrvCtrl->isReady = NULL;
}
if (devResourceGet(pHcf, "ackIrq", HCF_RES_ADDR, (void *)&pDrvCtrl->ackIrq) != OK) {
pDrvCtrl->ackIrq = NULL;
}
}
pDrvCtrl->read = sm2130BusDevRead;
@ -140,7 +146,7 @@ LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev)
LOCAL SM2310_DEV_HANDLE *drv1553bOpen(SM2310_DEV_HANDLE *dev, const char *name, int flags, int mode)
{
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
++pDrvCtrl->refcount;
(void)semGive(pDrvCtrl->muteSem);
@ -157,34 +163,125 @@ LOCAL int drv1553bClose(SM2310_DEV_HANDLE *dev)
return (OK);
}
LOCAL int doXferMem(SM2130_SPI_DEV * pDrvCtrl, SM2130_MEM_XFER *mxfr)
LOCAL int readReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer)
{
STATUS ret = OK;
int i;
UINT8 cmd;
if (mxfr->type == XFER_TYPE_WR) {
for (i = 0; i < mxfr->count; ++i) {
pDrvCtrl->write(pDrvCtrl->pDev, mxfr->regbuf[i], mxfr->membuf[i]);
}
} else if (mxfr->type == XFER_TYPE_RD) {
for (i = 0; i < mxfr->count; ++i) {
mxfr->membuf[i] = pDrvCtrl->read(pDrvCtrl->pDev, mxfr->regbuf[i]);
}
if (xfer->reg <= 15) {
cmd = (xfer->reg << 2);
} else {
ret = ERROR;
cmd = xfer->reg & 0xff;
}
return (OK);
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, cmd);
return 0;
}
LOCAL int writeReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer)
{
UINT8 cmd;
if (xfer->reg <= 63) {
cmd = 0x80 | (xfer->reg & 0x3f);
} else {
cmd = xfer->reg & 0xff;
}
pDrvCtrl->write(pDrvCtrl->pDev, cmd, xfer->val);
return 0;
}
LOCAL int setMemAddress(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer)
{
SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 };
UINT8 cmd;
transInfo.txBuf = &cmd;
transInfo.txLen = 1;
if (xfer->reg >= 0xb && xfer->reg <= 0xE) {
cmd =(xfer->reg - 0xB) + 0xD8;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
return pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | xfer->reg, xfer->val);
}
errnoSet(EINVAL);
return ERROR;
}
LOCAL int readMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
{
SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 };
UINT8 *ptr;
UINT8 cmd;
if ((mxfr->count <= 0) || (mxfr->count >= (sizeof (pDrvCtrl->regmem) / sizeof (pDrvCtrl->regmem[0])))) {
errnoSet(EINVAL);
return ERROR;
}
if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) {
cmd =(mxfr->reg - 0xB) + 0xD8;
transInfo.txBuf = &cmd;
transInfo.txLen = 1;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | mxfr->reg, mxfr->address);
}
cmd = 0x40;
ptr = (UINT8 *)pDrvCtrl->regmem;
transInfo.txBuf = &cmd;
transInfo.txLen = 1;
transInfo.rxBuf = ptr;
transInfo.rxLen = 1 + mxfr->count * 2;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
memcpy(mxfr->membuf, ptr + 1, mxfr->count * 2);
return OK;
}
LOCAL int writeMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
{
SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 };
UINT8 *ptr;
UINT8 cmd;
if ((mxfr->count <= 0) || (mxfr->count >= (sizeof (pDrvCtrl->regmem) / sizeof (pDrvCtrl->regmem[0])))) {
errnoSet(EINVAL);
return ERROR;
}
if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) {
cmd =(mxfr->reg - 0xB) + 0xD8;
transInfo.txBuf = &cmd;
transInfo.txLen = 1;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | mxfr->reg, mxfr->address);
}
ptr = (UINT8 *)pDrvCtrl->regmem;
ptr[0] = 0xC0;
memcpy(ptr + 1, (UINT8*)mxfr->membuf, mxfr->count * 2);
transInfo.txBuf = ptr;
transInfo.txLen = 1 + mxfr->count * 2;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
return OK;
}
LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg)
{
SM2130_XFER *xfer;
SM2130_MEM_XFER *mxfr;
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
STATUS ret = OK;
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
switch (cmd) {
case FIOSELECT:
ret = selNodeAdd(&dev->selList, (SEL_WAKEUP_NODE *)arg);
@ -200,11 +297,28 @@ 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_MEM:
mxfr = (SM2130_MEM_XFER *)(arg);
if (mxfr) {
doXferMem(pDrvCtrl, mxfr);
case FIOC_SM2130_READY:
if (pDrvCtrl->isReady) {
*(int *)(arg) = pDrvCtrl->isReady();
} else {
errnoSet(EIO);
ret = ERROR;
}
break;
case FIOC_SM2130_REGRD:
ret = readReg(pDrvCtrl, (SM2130_XFER *)(arg));
break;
case FIOC_SM2130_REGWR:
ret = writeReg(pDrvCtrl, (SM2130_XFER *)(arg));
break;
case FIOC_SM2130_SMADDR:
ret = setMemAddress(pDrvCtrl, (SM2130_XFER *)(arg));
break;
case FIOC_SM2130_RDMEM:
ret = readMemory(pDrvCtrl, (SM2130_MEM_XFER *)(arg));
break;
case FIOC_SM2130_WRMEM:
ret = writeMemory(pDrvCtrl, (SM2130_MEM_XFER *)(arg));
break;
default:
printf("sm2130 unsupported ioctl: %d\r\n", cmd);
@ -244,12 +358,18 @@ 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)
{
SM2310_DEV_HANDLE *dev = data;
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
if (pDrvCtrl->ackIrq) {
pDrvCtrl->ackIrq();
}
logMsg("sm1553isr interrupt", 1, 2, 3, 4, 5, 6);
selWakeupAll(&dev->selList, SELREAD);
}
@ -296,7 +416,7 @@ LOCAL void sm2130SpiDevInstConnect(VXB_DEVICE_ID pDev)
pDrvCtrl->devHandle = dev;
dev->pDevCtrl = pDrvCtrl;
if (pDrvCtrl->reqIsr) {
pDrvCtrl->reqIsr(dev, sm1553isr);
pDrvCtrl->irqStage = pDrvCtrl->reqIsr(dev, sm1553isr);
}
} else {
#ifndef _VXBUS_BASIC_HWMEMLIB
@ -351,6 +471,19 @@ LOCAL STATUS sm2130SpiDevInstUnlink(VXB_DEVICE_ID pDev, void *unused)
*
* ERRNO: N/A
*/
LOCAL const char *checkReady(SM2130_SPI_DEV *pDrvCtrl)
{
if (!pDrvCtrl->isReady()) {
return "Unknown";
}
if (pDrvCtrl->isReady()) {
return "Ready";
}
return "Not Ready";
}
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose)
{
SM2130_SPI_DEV *pDrvCtrl = (SM2130_SPI_DEV *)pDev->pDrvCtrl;
@ -363,6 +496,8 @@ LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose)
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(" isReady: %s\n", checkReady(pDrvCtrl));
}
return;
@ -388,7 +523,7 @@ LOCAL STATUS sm2130BusDevWrite(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var)
VXB_ASSERT(pDev != NULL, ERROR)
buf[0] = cmd;
buf[1] = var & 0xff;
buf[1] = (var >> 8) & 0xff;
buf[2] = (var >> 8) & 0xff;
transInfo.txBuf = buf;
transInfo.txLen = 3;

24
vxbSm2130SpiDev.h

@ -10,9 +10,16 @@
#define XFER_TYPE_WR (1)
#define XFER_TYPE_RD (2)
#define FIOC_SM2130_WR (__SM2130__IOC_MAGIC | XFER_TYPE_WR)
#define FIOC_SM2130_RD (__SM2130__IOC_MAGIC | XFER_TYPE_RD)
#define FIOC_SM2130_MEM (__SM2130__IOC_MAGIC | (XFER_TYPE_WR + XFER_TYPE_RD))
#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_REGRD (__SM2130__IOC_MAGIC | 0x21)
#define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22)
#define FIOC_SM2130_SMADDR (__SM2130__IOC_MAGIC | 0x23)
#define FIOC_SM2130_RDMEM (__SM2130__IOC_MAGIC | 0x24)
#define FIOC_SM2130_WRMEM (__SM2130__IOC_MAGIC | 0x25)
struct sm2130_xfer {
UINT8 reg;
@ -21,9 +28,9 @@ struct sm2130_xfer {
typedef struct sm2130_xfer SM2130_XFER;
struct sm2130_xfer_mem {
int type;
int count;
UINT8 *regbuf;
UINT8 reg;
UINT16 address;
UINT16 *membuf;
};
typedef struct sm2130_xfer_mem SM2130_MEM_XFER;
@ -37,11 +44,18 @@ typedef struct _spi_1553b_drv_ctrl {
int refcount;
int irqStage;
void *devHandle;
int (*reqIsr)(void *data, void (*isr)(void *data));
int (*isReady)();
void (*ackIrq)();
INT32 (*read)(VXB_DEVICE_ID pDev, UINT8 cmd);
STATUS (*write)(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var);
UINT16 regmem[64];
SEM_ID muteSem; /* operation semaphore */
VXB_SPI_MAST_SPEC *specialInfo;

2
vxbSpiRawDev.c

@ -207,7 +207,7 @@ LOCAL void spiRawDevShow(VXB_DEVICE_ID pDev, int verbose)
if (verbose) {
printf(" devName: %s\n", pDrvCtrl->name);
printf(" refCount: %s\n", pDrvCtrl->refCount);
printf(" refCount: %d\n", pDrvCtrl->refCount);
}
}
/* }}} */

Loading…
Cancel
Save