Browse Source

add SM2130 driver

Signed-off-by: surenyi <surenyi82@163.com>
master
surenyi 3 weeks ago
parent
commit
cd6226fb54
  1. 127
      .clang-format
  2. 20
      40vxbSm2130SpiDev.cdf
  3. 3
      Makefile
  4. 20
      config.h
  5. 1
      ft2000-4.h
  6. 26
      hwconf.c
  7. 60
      vxbFtGpio.c
  8. 257
      vxbFtSpi.c
  9. 13
      vxbFtSpi.h
  10. 302
      vxbSm2130SpiDev.c
  11. 23
      vxbSm2130SpiDev.h

127
.clang-format

@ -0,0 +1,127 @@
# SPDX-License-Identifier: GPL-2.0
#
# clang-format configuration file. Intended for clang-format >= 11.
#
# For more information, see:
#
# Documentation/process/clang-format.rst
# https://clang.llvm.org/docs/ClangFormat.html
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
#
# :lua vim.lsp.buf.format({timeout=2000})
---
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
# Taken from:
# git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ tools/ \
# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \
# | LC_ALL=C sort -u
ForEachMacros:
- 'list_for_each'
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentGotoLabels: false
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
# Taken from git's rules
PenaltyBreakAssignment: 10
PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 0
PenaltyBreakString: 10
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatementsExceptForEachMacros
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp03
TabWidth: 4
UseTab: Never
...

20
40vxbSm2130SpiDev.cdf

@ -0,0 +1,20 @@
/* 40vxbSm2310SpiDev.cdf - Component configuration file */
/*
* modification history
* --------------------
* 2024-10-16: surenyi written.
*/
Component DRV_SPIDEV_SM2130 {
NAME State Micro SM2130 SPI 1553B vxBus Driver
SYNOPSIS This enables access to SM2310 1553B protocol chip
INIT_RTN vxbSm2130SpiDevRegister();
PROTOTYPE void vxbSm2130SpiDevRegister (void);
_INIT_ORDER hardWareInterFaceBusInit
INIT_AFTER INCLUDE_SPI_BUS
REQUIRES INCLUDE_VXBUS \
INCLUDE_PLB_BUS \
INCLUDE_SPI_BUS
_CHILDREN FOLDER_DRIVERS
}

3
Makefile

@ -22,7 +22,8 @@ RELEASE += bootrom_uncmp.hex
MACH_EXTRA += vxbArmGenIntCtlrV3.o vxbArmv7GenTimer.o vxbArmv7AuxTimer.o \
vxbFtPcie.o vxbAhciStorage.o vxbFtGmacEnd.o vxbFtcan.o vxbPci.o \
vxbFtSdCtrl.o vxbFtI2c.o vxbYt8521Phy.o genericPhy.o vxbFtQspi.o\
vxbSp25SpiFlash.o vxbFtGpio.o vxbFtSpi.o usrStubs.o vxbLfsLib.o
vxbSp25SpiFlash.o vxbFtGpio.o vxbFtSpi.o vxbSm2130SpiDev.o \
usrStubs.o vxbLfsLib.o
ifneq ($(findstring bootrom,$(MAKECMDGOALS)),bootrom)
LIB_EXTRA = lib/libFtX100dcdrv.a

20
config.h

@ -45,8 +45,10 @@ extern "C" {
#define DRV_FTQSPI
#define DRV_FTSPI
#define DRV_SPIFLASH_SP25
#define INCLUDE_YT8521PHY
#define DRV_SPIDEV_SM2130
#undef INCLUDE_YT8521PHY
#define DRV_FTGPIO
#if defined(INCLUDE_PC_CONSOLE)||defined(INCLUDE_WINDML)
#define DRV_X100DC
#endif
@ -68,6 +70,8 @@ extern "C" {
#define INCLUDE_USB_GEN2_STORAGE_INIT
#endif
#define INCLUDE_TFFS
#undef INCLUDE_DRV_STORAGE_AHCI
#if defined(INCLUDE_USB) || \
defined(INCLUDE_DRV_STORAGE_PIIX) || defined(INCLUDE_DRV_STORAGE_AHCI)
@ -79,6 +83,12 @@ extern "C" {
#define INCLUDE_DOSFS_SHOW
#define INCLUDE_DOSFS_DIR_VFAT
#define INCLUDE_DOSFS_DIR_FIXED
#endif
#if defined(INCLUDE_USB) || \
defined(INCLUDE_DRV_STORAGE_PIIX) || defined(INCLUDE_TFFS) || defined(INCLUDE_DRV_STORAGE_AHCI)
#define INCLUDE_HRFS_FORMAT
#define INCLUDE_HRFS_CHKDSK
#define INCLUDE_FS_MONITOR
#define INCLUDE_FS_EVENT_UTIL
#define INCLUDE_ERF
@ -91,14 +101,9 @@ extern "C" {
#define INCLUDE_DISK_UTIL
#endif
#define INCLUDE_TFFS
#if defined(INCLUDE_TFFS)
#endif
/*#define INCLUDE_HRFS*/
#define DRV_VXBEND_FTGMAC
# define INCLUDE_HRFS_FORMAT
# define INCLUDE_HRFS_CHKDSK
#undef DRV_PCIBUS_FT
#ifdef DRV_PCIBUS_FT
@ -276,6 +281,7 @@ extern "C" {
#endif /* _WRS_CONFIG_SMP */
#define INCLUDE_SHELL
#define INCLUDE_SYM_TBL
#define INCLUDE_SYM_TBL_INIT
/*#define INCLUDE_STANDALONE_SYM_TBL*/

1
ft2000-4.h

@ -83,6 +83,7 @@ enum can_bitrate{
#define FTCAN2_IRQ 124
#define FTCAN2_BITRATE FTCAN_BRATE_DEFAULT
#define FT2000_SPI_CLK (48000000) /* SPI clock */
#define FTSPI0_BASE 0x2800c000
#define FTSPI0_IRQ 50

26
hwconf.c

@ -62,11 +62,11 @@ LOCAL struct intrCtlrInputs gicInputs[] = {
{ 61, "legacy", 0, 61},
{ 62, "legacy", 0, 62},
{ 63, "legacy", 0, 63},
{ 52, "ftSdhci", 0, 0 },
#ifdef DRV_FTSPI
{ FTSPI0_IRQ, FT_SPI_NAME, 0, 0 },
{ FTSPI1_IRQ, FT_SPI_NAME, 1, 0 },
#endif
{ 52, "ftSdhci", 0, 0 },
{ 53, "ftSdhci", 0, 1 },
{ 54, "ftSdhci", 0, 2 },
{ I2C_0_INTR_IRQ, "ftI2c", 0, 0 },
@ -99,6 +99,10 @@ LOCAL const struct intrCtlrPriority gicPriority[] = {
{ 61, 0x10 },
{ 62, 0x10 },
{ 63, 0x10 },
#ifdef DRV_FTSPI
{ FTSPI0_IRQ, 0x10},
{ FTSPI1_IRQ, 0x10},
#endif
{ 52, 0x20 }, /*ftSdhci interrupt number : 52,53,54*/
{ 53, 0x20 },
{ 54, 0x20 },
@ -126,6 +130,10 @@ struct intrCtlrCpu gicCpu[] = {
{ 61, 0 },
{ 62, 0 },
{ 63, 0 },
#ifdef DRV_FTSPI
{ FTSPI0_IRQ, 0},
{ FTSPI1_IRQ, 0},
#endif
{ 52, 0 }, /*ftSdhci interrupt number : 52,53,54*/
{ 53, 0 },
{ 54, 0 },
@ -253,12 +261,14 @@ struct hcfResource qspiResources[] = {
#ifdef DRV_FTSPI
struct vxbSpiDevInfo spiDevTbl1[] = {
/* name cs width freq mode */
{ "SM2130", 0, 8, 500000, 1},
{ "SM2130", 0, 8, 5000000, 3},
};
struct hcfResource spiResources1[] = {
{ "regBase", HCF_RES_INT, { (void *)(FTSPI1_BASE) } },
{ "clkDiv", HCF_RES_INT, { (void *)(2) } },
{ "clkFreq", HCF_RES_INT, { (void *)(FT2000_SPI_CLK) } },
{ "speed", HCF_RES_INT, { (void *)(4000000) } },
{ "mode", HCF_RES_INT, { (void *)3} },
{ "spiDev", HCF_RES_ADDR, { (void *)&spiDevTbl1[0]} },
{ "spiDevNum", HCF_RES_INT, { (void *)NELEMENTS(spiDevTbl1)}},
};
@ -348,14 +358,14 @@ struct hcfResource i2cDev3Resources[] = {
LOCAL UINT8 gpio0PortAModeTable[] = {
/*pin of portA can be used as interrupt mode*/
/*portA-pinX: 0 1 2 3 4 5 6 7 */
3, 2, 1, 0, 0, 0, 0, 0 /* 0:GPIO_MODE_NOT_USED 1:GPIO_MODE_IN
0, 2, 0, 0, 0, 0, 0, 0 /* 0:GPIO_MODE_NOT_USED 1:GPIO_MODE_IN
2:GPIO_MODE_OUT 3:GPIO_MODE_INT*/
};
/*This table is used to set the default pin mode of portB*/
LOCAL UINT8 gpio0PortBModeTable[] = {
/*pin of portB can not be used as interrupt mode*/
/*portB-pinX: 0 1 2 3 4 5 6 7 */
1, 2, 1, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 2, 1 /* GPIO0_B6: SM2130_ACKIRQ; GPIO0_B7: SM2130_READY */
};
struct hcfResource gpioDev0Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)GPIO_0_BASE_ADR } },
@ -369,12 +379,12 @@ struct hcfResource gpioDev0Resources[] = {
LOCAL UINT8 gpio1PortAModeTable[] = {
/*portA-pinX: 0 1 2 3 4 5 6 7 */
0, 0, 0, 0, 0, 0, 0, 0 /* 0:GPIO_MODE_NOT_USED 1:GPIO_MODE_IN
2:GPIO_MODE_OUT 3:GPIO_MODE_INT*/
0, 0, 0, 0, 3, 0, 0, 0 /* 0:GPIO_MODE_NOT_USED 1:GPIO_MODE_IN
2:GPIO_MODE_OUT 3:GPIO_MODE_INT*/ /* GPIO1_A4: SM2130_IRQ */
};
LOCAL UINT8 gpio1PortBModeTable[] = {
/*portB-pinX: 0 1 2 3 4 5 6 7 */
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 2 /* GPIO1_B7: SM2130_MR */
};
struct hcfResource gpioDev1Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)GPIO_1_BASE_ADR } },

60
vxbFtGpio.c

@ -47,6 +47,7 @@ IMPORT FUNCPTR _func_logMsg;
LOCAL void vxbFtGpioInstInit(VXB_DEVICE_ID pInst);
LOCAL void vxbFtGpioInstInit2(VXB_DEVICE_ID pInst);
LOCAL void vxbFtGpioInstConnect(VXB_DEVICE_ID pInst);
LOCAL void vxbFtGpioShow (VXB_DEVICE_ID pDev, int verbose);
LOCAL STATUS vxbFtGpioPinModeSet (VXB_DEVICE_ID pDev, UINT32 port, UINT32 pin,UINT32 mode);
LOCAL UINT32 vxbFtGpioPinInput (VXB_DEVICE_ID pDev, UINT32 port, UINT32 pin);
@ -65,6 +66,7 @@ LOCAL struct drvBusFuncs vxbFtGpioDrvFuncs =
LOCAL device_method_t vxbFtGpioDrv_methods[] =
{
DEVMETHOD (busDevShow, vxbFtGpioShow),
DEVMETHOD_END
};
@ -154,8 +156,8 @@ LOCAL void vxbFtGpioInstInit2
FT_GPIO_DRVCTRL * pDrvCtrl;
UINT32 port = 0, pin = 0;
HCF_DEVICE * pHcf;
UINT32 ** ppPortModeTable[GPIO_PORT_MUM];
UINT32 *pPortModeTable[GPIO_PORT_MUM];
UINT8 ** ppPortModeTable[GPIO_PORT_MUM];
UINT8 *pPortModeTable[GPIO_PORT_MUM];
pDrvCtrl = (FT_GPIO_DRVCTRL *)hwMemAlloc(sizeof (FT_GPIO_DRVCTRL));
@ -417,7 +419,7 @@ LOCAL STATUS vxbFtGpioPinModeSet
case GPIO_MODE_IN:
if (port == GPIO_PORT_A)
{
st |= vxbFtGpioPinIntDisable(pDev, pin);
/* st |= */vxbFtGpioPinIntDisable(pDev, pin);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DDR_A, pin, GPIO_DIR_IN);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTMASK_A, pin, GPIO_INT_MASK);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTEN_A, pin, GPIO_INT_DIS);
@ -430,7 +432,7 @@ LOCAL STATUS vxbFtGpioPinModeSet
case GPIO_MODE_OUT:
if (port == GPIO_PORT_A)
{
st |= vxbFtGpioPinIntDisable(pDev, pin);
/* st |= */vxbFtGpioPinIntDisable(pDev, pin);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DDR_A, pin, GPIO_DIR_OUT);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTMASK_A, pin, GPIO_INT_MASK);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTEN_A, pin, GPIO_INT_DIS);
@ -466,7 +468,7 @@ LOCAL STATUS vxbFtGpioPinModeSet
GPIO_DBG(GPIO_DBG_ERR, "Mode set error of port %d pin %d: trigger mode error \r\n", port, pin,3,4,5,6);
return ERROR;
}
st |= vxbFtGpioPinIntEnable(pDev, pin);
/* st |= */vxbFtGpioPinIntEnable(pDev, pin);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DDR_A, pin, GPIO_DIR_IN);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTMASK_A, pin, GPIO_INT_NOT_MASK);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTTYPE_LEVEL_A, pin, level);
@ -477,7 +479,6 @@ LOCAL STATUS vxbFtGpioPinModeSet
default:
return ERROR;
}
if (OK != st)
{
pDrvCtrl->pinMode[port][pin] = GPIO_MODE_NOT_USED;
@ -679,6 +680,35 @@ exit:
return;
}
LOCAL void vxbFtGpioShow (VXB_DEVICE_ID pDev, int verbose)
{
FT_GPIO_DRVCTRL * pDrvCtrl;
/* check for valid parameter */
VXB_ASSERT_NONNULL_V (pDev);
pDrvCtrl = (FT_GPIO_DRVCTRL *) pDev->pDrvCtrl;
printf (" %s unit %d on %s @ %p with busInfo %08p\n",
pDev->pName,
pDev->unitNumber,
vxbBusTypeString (pDev->busID),
pDev,
pDev->u.pSubordinateBus);
if (verbose > 0) {
int i, j;
printf (" BAR0 @ 0x%08x (memory mapped)\n",pDev->pRegBase[0]);
for (i = 0; i < GPIO_PORT_MUM; ++i) {
printf(" port %c:", i == 0 ? 'A' : 'B');
for (j = 0; j < FT_GPIO_PORT_WIDTH; ++j) {
printf(" %d", pDrvCtrl->pinMode[i][j]);
}
printf("\n");
}
}
}
#define FT_GPIO_DEBUD
#ifdef FT_GPIO_DEBUD
void gpioModeShow(UINT32 gpio)
@ -688,6 +718,9 @@ void gpioModeShow(UINT32 gpio)
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
if (pDev == NULL) {
return;
}
pCtrl = pDev->pDrvCtrl;
for(i = 0; i < GPIO_PORT_MUM; i++)
@ -706,7 +739,9 @@ void gpioModeSetTest (UINT32 gpio, UINT32 port, UINT32 pin, UINT32 mode)
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
if (pDev == NULL) {
return;
}
pCtrl = pDev->pDrvCtrl;
pCtrl->gpioModeSet(pDev, port, pin, mode);
@ -719,6 +754,9 @@ void gpioOutTest (UINT32 gpio, UINT32 port, UINT32 pin, UINT32 val)
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
if (pDev == NULL) {
return;
}
pCtrl = pDev->pDrvCtrl;
@ -731,7 +769,9 @@ void gpioInTest (UINT32 gpio, UINT32 port, UINT32 pin)
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
if (pDev == NULL) {
return;
}
pCtrl = pDev->pDrvCtrl;
printf("input val %d\n", pCtrl->gpioInput(pDev, port, pin));
@ -752,7 +792,9 @@ void gpioIsrSetTest (UINT32 gpio, UINT32 pin)
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
if (pDev == NULL) {
return;
}
pCtrl = pDev->pDrvCtrl;
isrArgTest = pin;

257
vxbFtSpi.c

@ -15,7 +15,24 @@
#include <../src/hwif/h/vxbus/vxbAccess.h>
#include <hwif/vxbus/vxbSpiLib.h>
#include "vxbFtSpi.h"
#include "ft2000-4.h"
#define CTRLR0 0x0
#define CTRLR1 0x4
#define SSIENR 0x8
#define MWCR 0xc
#define SER 0x10
#define BAUDR 0x14
#define TXFTLR 0x18
#define RXFTLR 0x1c
#define TXFLR 0x20
#define RXFLR 0x24
#define SR 0x28
#define IMR 0x2c
#define ISR 0x30
#define DMACR 0x4c
#define DR 0x60
#define RX_SAMPLE_DLY 0xfc
/* debug macro */
#undef SPI_DBG_ON
#ifdef SPI_DBG_ON
@ -49,6 +66,30 @@ IMPORT FUNCPTR _func_logMsg;
# define SPI_REG_HANDLE_SWAP(x) (x)
#endif /* _BYTE_ORDER == _BIG_ENDIAN */
/* read write macros */
#define VXB_FT_SPI_REG(pChan, reg) \
(UINT32 *)((UINT32) ((pChan)->regBase) + (reg))
#define VXB_FT_SPI_REG16(pChan, reg) \
(UINT16 *)((UINT32) ((pChan)->regBase) + (reg))
#define VXB_FT_SPI_REG8(pChan, reg) \
(UINT8 *)((UINT32) ((pChan)->regBase) + (reg))
#define VXB_FT_SPI_REG_READ(pChan, reg, result) \
(result) = vxbRead32 ((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg))
#define VXB_FT_SPI_REG_WRITE(pChan, reg, data) \
vxbWrite32 ((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg), (data))
#define VXB_FT_SPI_REG_BIT_SET(pChan, reg, data) \
VXB_FT_SPI_REG_WRITE (pChan, reg, \
vxbRead32 ((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg)) | (data))
#define VXB_FT_SPI_REG_BIT_CLR(pChan, reg, data) \
VXB_FT_SPI_REG_WRITE (pChan, reg, \
vxbRead32 ((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg)) & (~(data)))
/* VxBus methods */
LOCAL void vxbFtSpiInstInit (VXB_DEVICE_ID pDev);
LOCAL void vxbFtSpiInstInit2 (VXB_DEVICE_ID pDev);
@ -58,6 +99,8 @@ LOCAL void vxbFtSpiShow (VXB_DEVICE_ID, int);
LOCAL STATUS vxbFtSpiInstUnlink (VXB_DEVICE_ID pDev, void * unused);
/* forward declarations */
LOCAL void vxbFtSpiCtrlInit (VXB_DEVICE_ID pDev);
LOCAL STATUS vxbFtSpiTransfer (VXB_DEVICE_ID pDev, SPI_HARDWARE * pSpiDev,
SPI_TRANSFER * pPkg);
/* locals */
@ -89,7 +132,6 @@ LOCAL struct vxbPlbRegister vxbFtSpiDevRegistration = {
};
/*
*
* vxbFtSpiRegister - register with the VxBus subsystem
*
* This routine registers the SPI driver with VxBus Systems.
@ -104,7 +146,6 @@ void vxbFtSpiRegister (void)
}
/*
*
* vxbFtSpiInstInit - initialize SPI controller
*
* This function implements the VxBus instInit handler for a SPI controller
@ -161,13 +202,28 @@ LOCAL void vxbFtSpiInstInit(VXB_DEVICE_ID pDev)
return;
}
if (devResourceGet (pHcf, "clkDiv", HCF_RES_INT,(void *) &pDrvCtrl->clkDiv) != OK) {
pDrvCtrl->clkDiv = 2;
if (devResourceGet (pHcf, "clkFreq", HCF_RES_INT,(void *) &pDrvCtrl->clkFreq) != OK) {
pDrvCtrl->clkFreq = FT2000_SPI_CLK;
}
if (devResourceGet (pHcf, "speed", HCF_RES_INT,(void *) &pDrvCtrl->speed) != OK) {
pDrvCtrl->speed = 1000000;
}
if (devResourceGet (pHcf, "mode", HCF_RES_INT,(void *) &pDrvCtrl->mode) != OK) {
pDrvCtrl->mode = 0;
}
if (devResourceGet (pHcf, "dataWidth", HCF_RES_INT,(void *) &pDrvCtrl->dataWidth) != OK) {
pDrvCtrl->dataWidth = 8;
}
if (devResourceGet (pHcf, "spiDevNum", HCF_RES_INT, (void *) &pDrvCtrl->spiDevNum) != OK) {
pDrvCtrl->spiDevNum = 0;
}
pDrvCtrl->cs = 0;
vxbFtSpiCtrlInit(pDev);
pDrvCtrl->vxbSpiCtrl.spiTransfer = (void *)vxbFtSpiTransfer;
@ -181,7 +237,6 @@ LOCAL void vxbFtSpiInstInit(VXB_DEVICE_ID pDev)
}
/*
*
* vxbFtSpiInstInit2 - second level initialization routine of SPI controller
*
* This routine performs the second level initialization of the SPI controller.
@ -213,7 +268,6 @@ LOCAL void vxbFtSpiInstInit2(VXB_DEVICE_ID pDev)
}
/*
*
* vxbFtSpiInstConnect - third level initialization
*
* This routine performs the third level initialization of the QSPI controller
@ -232,7 +286,6 @@ LOCAL void vxbFtSpiInstConnect(VXB_DEVICE_ID pDev)
}
/*
*
* vxbFtSpiCtrlGet - get the SPI controller struct
*
* This routine returns the QSPI controller struct pointer (VXB_SPI_BUS_CTRL *)
@ -260,7 +313,89 @@ LOCAL VXB_SPI_BUS_CTRL * vxbFtSpiCtrlGet(VXB_DEVICE_ID pDev)
}
/*
* vxbFtSpiCtrlInit - SPI controller initialization
*
* This routine performs the SPI controller initialization.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
LOCAL void vxbFtSpiCtrlInit(VXB_DEVICE_ID pDev)
{
FT_SPI_CTRL *pDrvCtrl;
UINT32 regval, clkDiv;
pDrvCtrl = (FT_SPI_CTRL *) pDev->pDrvCtrl;
/* disable the controller */
VXB_FT_SPI_REG_WRITE(pDrvCtrl, SSIENR, 0x0);
/* CTRLR0 */
VXB_FT_SPI_REG_READ(pDrvCtrl, CTRLR0, regval);
/* normal mode */
regval &= ~(1 << 11);
/* data width */
regval &= ~(0xf);
regval |= (pDrvCtrl->dataWidth - 1) & 0xf;
/*
* spi mode mapping:
*
* CPOL CPHA
* 0 0 mode 0
* 0 1 mode 1
* 1 0 mode 2
* 1 1 mode 3
*/
if (pDrvCtrl->mode & 0x1) {
regval |= (1 << 6); /* CPHA */
} else {
regval &= ~(1 << 6);
}
if (pDrvCtrl->mode & 0x2) {
regval |= (1 << 7);
} else {
regval &= ~(1 << 7);
}
/* rx & tx */
regval &= ~(0x3 << 8);
/* slv_oe = 1 (slave disable) */
regval &= ~(1 << 10);
VXB_FT_SPI_REG_WRITE(pDrvCtrl, CTRLR0, regval);
VXB_FT_SPI_REG_WRITE(pDrvCtrl, CTRLR1, 0);
/* disable DMA */
VXB_FT_SPI_REG_WRITE(pDrvCtrl, DMACR, 0);
/* baudrate */
clkDiv = pDrvCtrl->clkFreq / pDrvCtrl->speed;
if (clkDiv < 2) {
clkDiv = 2;
}
if (clkDiv > 65534) {
clkDiv = 65534;
}
VXB_FT_SPI_REG_WRITE(pDrvCtrl, BAUDR, clkDiv);
VXB_FT_SPI_REG_WRITE(pDrvCtrl, RX_SAMPLE_DLY, 0);
VXB_FT_SPI_REG_WRITE(pDrvCtrl, RXFTLR, 0);
VXB_FT_SPI_REG_WRITE(pDrvCtrl, TXFTLR, 0);
VXB_FT_SPI_REG_BIT_CLR(pDrvCtrl, IMR, 0x1f); /* disable all interrupts */
regval = (1 << pDrvCtrl->cs);
VXB_FT_SPI_REG_BIT_SET(pDrvCtrl, SER, regval);
}
/*
* vxbFtSpiTransfer - SPI transfer routine
*
* This routine is used to perform one transmission. It is the interface which
@ -278,9 +413,11 @@ LOCAL STATUS vxbFtSpiTransfer(
)
{
STATUS sts = OK;
UINT32 cmd;
UINT32 alignSize;
FT_SPI_CTRL * pDrvCtrl;
int i, len;
UINT8 dummy8;
UINT16 dummy16, *dptr;
/* check if the pointers are valid */
if (pDev == NULL || pSpiDev == NULL || pPkg == NULL || pSpiDev->devInfo == NULL) {
@ -340,8 +477,7 @@ LOCAL STATUS vxbFtSpiTransfer(
return ERROR;
}
pDrvCtrl->channel = pSpiDev->devInfo->chipSelect;
if (pDrvCtrl->channel >= SPI_MAX_CS_NUM) {
if ( pSpiDev->devInfo->chipSelect >= SPI_MAX_CS_NUM) {
SPI_DBG (SPI_DBG_ERR,
"vxbFtQspiTransfer invalid channel[%x] \n",
pDrvCtrl->channel, 2, 3, 4, 5, 6);
@ -358,57 +494,55 @@ LOCAL STATUS vxbFtSpiTransfer(
(void)semTake (pDrvCtrl->muxSem, WAIT_FOREVER);
}
pDrvCtrl->txBuf = pPkg->txBuf;
pDrvCtrl->txLen = pPkg->txLen;
pDrvCtrl->rxBuf = pPkg->rxBuf;
pDrvCtrl->rxLen = pPkg->rxLen;
cmd = pDrvCtrl->txBuf[0];
#if 0
switch (cmd) {
case QSPI_FLASH_CMD_RDID:
case QSPI_FLASH_CMD_RDSR1:
vxbFtQspiFlashRegGet(pDev);
break;
case QSPI_FLASH_CMD_4BAM:
pDrvCtrl->addrMode = QSPI_ADDR_SEL_4;
/*vxbFtQspiFlashRegSet(pDev);*/
break;
case QSPI_FLASH_CMD_4BEX:
pDrvCtrl->addrMode = QSPI_ADDR_SEL_3;
/*vxbFtQspiFlashRegSet(pDev);*/
break;
case QSPI_FLASH_CMD_WREN:
case QSPI_FLASH_CMD_WRDI:
case QSPI_FLASH_CMD_BE:
case QSPI_FLASH_CMD_WRR:
vxbFtQspiFlashRegSet(pDev);
break;
case QSPI_FLASH_CMD_SE:
if(pDrvCtrl->addrMode == QSPI_ADDR_SEL_4)
{
pDrvCtrl->txBuf[0] = QSPI_FLASH_CMD_4SE;
if ((pSpiDev->devInfo->devFreq != pDrvCtrl->speed) || (pSpiDev->devInfo->bitWidth != pDrvCtrl->dataWidth)
|| (pSpiDev->devInfo->mode != pDrvCtrl->mode) || (pSpiDev->devInfo->chipSelect != pDrvCtrl->cs)) {
pDrvCtrl->mode = pSpiDev->devInfo->mode;
pDrvCtrl->speed = pSpiDev->devInfo->devFreq;
pDrvCtrl->dataWidth = pSpiDev->devInfo->bitWidth;
pDrvCtrl->cs = pSpiDev->devInfo->chipSelect;
vxbFtSpiCtrlInit(pDev);
}
vxbFtQspiFlashRegSetWithAddr(pDev);
break;
case QSPI_FLASH_CMD_PP:
if(pDrvCtrl->addrMode == QSPI_ADDR_SEL_4)
{
pDrvCtrl->txBuf[0] = QSPI_FLASH_CMD_4PP;
VXB_FT_SPI_REG_WRITE(pDrvCtrl, SSIENR, 0x1);
if (pPkg->txLen > 0) {
if (alignSize == 1) {
for (i = 0;i < pPkg->txLen; ++i) {
vxbWrite8(pDrvCtrl->regHandle, VXB_FT_SPI_REG8(pDrvCtrl, DR), pPkg->txBuf[i]);
dummy8 = vxbRead8(pDrvCtrl->regHandle, VXB_FT_SPI_REG8(pDrvCtrl, DR));
(void)dummy8;
}
} else {
dptr = (UINT16 *)(pPkg->txBuf);
len = pPkg->txLen >> 1;
for (i = 0; i < len; ++i) {
vxbWrite16(pDrvCtrl->regHandle, VXB_FT_SPI_REG16(pDrvCtrl, DR), dptr[i]);
dummy16 = vxbRead16(pDrvCtrl->regHandle, VXB_FT_SPI_REG16(pDrvCtrl, DR));
(void)dummy16;
}
vxbFtQspiFlashPageWrite(pDev);
break;
case QSPI_FLASH_CMD_READ:
if(pDrvCtrl->addrMode == QSPI_ADDR_SEL_4)
{
pDrvCtrl->txBuf[0] = QSPI_FLASH_CMD_4READ;
}
vxbFtQspiFlashRead(pDev);
break;
default:
break;
}
#endif
printf(" xfer :%x\n",cmd);
if (pPkg->rxLen > 0) {
if (alignSize == 1) {
dummy8 = 0x0;
for (i = 0;i < pPkg->rxLen; ++i) {
vxbWrite8(pDrvCtrl->regHandle, VXB_FT_SPI_REG8(pDrvCtrl, DR), dummy8);
pPkg->rxBuf[i] = vxbRead8(pDrvCtrl->regHandle, VXB_FT_SPI_REG8(pDrvCtrl, DR));
}
} else {
dummy16 = 0;
dptr = (UINT16 *)(pPkg->rxBuf);
len = pPkg->rxLen >> 1;
for (i = 0; i < len; ++i) {
vxbWrite16(pDrvCtrl->regHandle, VXB_FT_SPI_REG16(pDrvCtrl, DR), dummy16);
dptr[i] = vxbRead16(pDrvCtrl->regHandle, VXB_FT_SPI_REG16(pDrvCtrl, DR));
}
}
}
VXB_FT_SPI_REG_WRITE(pDrvCtrl, SSIENR, 0x0);
printf(" xfer : tx %d bytes, rx %d bytes\n",pPkg->txLen, pPkg->rxLen);
if (pPkg->usDelay > 0) {
vxbUsDelay(pPkg->usDelay);
@ -421,7 +555,6 @@ LOCAL STATUS vxbFtSpiTransfer(
}
/*
*
* vxbFtSpiShow - show the controller info
*
* This function shows the SPI controller's info.
@ -450,13 +583,15 @@ LOCAL void vxbFtSpiShow(VXB_DEVICE_ID pDev,int verbose)
printf (" BAR0 @ 0x%08x (memory mapped)\n",pDev->pRegBase[0]);
printf (" pDrvCtrl @ 0x%08x\n", pDev->pDrvCtrl);
printf (" initPhase : %u\n", pDrvCtrl->initPhase);
printf (" clkDiv : %u\n", pDrvCtrl->clkDiv);
printf (" clkFreq : %u\n", pDrvCtrl->clkFreq);
printf (" speed : %u\n", pDrvCtrl->speed);
printf (" bitWidth : %u\n", pDrvCtrl->dataWidth);
printf (" mode : %u\n", pDrvCtrl->mode);
printf (" spiDevNum : %u\n", pDrvCtrl->spiDevNum);
}
}
/*
*
* vxbFtSpiInstUnlink - VxBus unlink handler
*
* This function shuts down a SPI controller instance in response to an

13
vxbFtSpi.h

@ -12,19 +12,20 @@
#define FT_SPI_NAME "ftSpi"
#define SPI_MAX_CS_NUM 4
/* structure holding the instance specific details */
typedef struct _ft_spi_drv_ctrl {
VXB_DEVICE_ID pDev;
void * regBase;
void * regHandle;
UINT32 clkDiv;
UINT32 clkFreq;
UINT32 speed;
int mode;
int dataWidth;
int cs;
UINT32 length;
UINT32 spiDevNum;
UINT32 channel;
UINT32 initPhase;
UINT8 * txBuf;
UINT32 txLen;
UINT8 * rxBuf;
UINT32 rxLen;
SEM_ID muxSem;
VXB_SPI_BUS_CTRL vxbSpiCtrl;
} FT_SPI_CTRL;

302
vxbSm2130SpiDev.c

@ -0,0 +1,302 @@
#include <vxWorks.h>
#include <stdio.h>
#include <string.h>
#include <logLib.h>
#include <vxBusLib.h>
#include <semLib.h>
#include <taskLib.h>
#include <sysLib.h>
#include <tickLib.h>
#include <hwif/vxbus/vxBus.h>
#include <hwif/vxbus/hwConf.h>
#include <hwif/vxbus/vxbPlbLib.h>
#include <hwif/util/hwMemLib.h>
#include <hwif/util/vxbParamSys.h>
#include <hwif/vxbus/vxbSpiLib.h>
#include "vxbSm2130SpiDev.h"
#include <usrLib.h>
/* locals */
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose);
LOCAL INT32 spiDevRead(VXB_DEVICE_ID pDev, UINT8 cmd);
LOCAL STATUS spiDevWrite(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var);
/* VxBus methods */
LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev);
LOCAL void sm2130SpiDevInstInit2(VXB_DEVICE_ID pDev);
LOCAL void sm2130SpiDevInstConnect(VXB_DEVICE_ID pDev);
LOCAL STATUS sm2130SpiDevInstUnlink(VXB_DEVICE_ID pDev, void *unused);
/* Structs */
LOCAL struct drvBusFuncs sm2130SpiDevFuncs = {
sm2130SpiDevInstInit, /* devInstanceInit */
sm2130SpiDevInstInit2, /* devInstanceInit2 */
sm2130SpiDevInstConnect /* devConnect */
};
/* Publish the methods for the resources controlled with this file */
LOCAL struct vxbDeviceMethod sm2130SpiDevMethods[] = {
DEVMETHOD(busDevShow, sm2130SpiDevShow),
DEVMETHOD(vxbDrvUnlink, sm2130SpiDevInstUnlink),
{ 0, 0 }
};
LOCAL struct vxbSpiRegister sm2130SpiDevRegister = {
{
NULL, /* pNext */
VXB_DEVID_DEVICE, /* devID */
VXB_BUSID_SPI, /* busID = SPI */
VXB_VER_4_0_0, /* vxbVersion */
SPI_DEV_SM2130, /* drvName */
&sm2130SpiDevFuncs, /* pDrvBusFuncs */
sm2130SpiDevMethods, /* pMethods */
NULL, //sm2130Probe, /* devProbe */
NULL, /* pParamDefaults */
},
};
/*
*
* vxbSm2130SpiDevRegister - register with the VxBus subsystem
*
* This routine registers the driver to VxBus Systems.
*
* RETURNS: N/A
*
* ERRNO: N/A
*
* \NOMANUAL
*/
void vxbSm2130SpiDevRegister(void)
{
(void)vxbDevRegister((struct vxbDevRegInfo *)&sm2130SpiDevRegister);
}
/*
*
* sm2130SpiDevInstInit - first level initialization routine of spi flash device
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev)
{
SM2130_SPI_DEV *pDrvCtrl;
/* Check for vaild parameter */
VXB_ASSERT_NONNULL_V(pDev);
pDrvCtrl = (SM2130_SPI_DEV *)hwMemAlloc(sizeof(SM2130_SPI_DEV));
if (pDrvCtrl == NULL) {
return;
}
pDrvCtrl->pDev = pDev;
pDev->pDrvCtrl = pDrvCtrl;
pDrvCtrl->read = spiDevRead;
pDrvCtrl->write = spiDevWrite;
vxbNextUnitGet(pDev);
}
/*
*
* sm2130SpiDevInstInit2 - first level initialization routine of spi flash device
*
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
LOCAL void sm2130SpiDevInstInit2(VXB_DEVICE_ID pDev)
{
SM2130_SPI_DEV *pDrvCtrl;
FUNCPTR pFunc;
/* Check for vaild parameter */
VXB_ASSERT_NONNULL_V(pDev);
pDrvCtrl = (SM2130_SPI_DEV *)pDev->pDrvCtrl;
/* Mutex semaphore is initialized and necessary at this point */
pDrvCtrl->muteSem = semMCreate(SPI_DEV_MUTEX_OPT);
pFunc = vxbDevMethodGet(vxbDevParent(pDev),
(VXB_METHOD_ID)vxbSpiSpecialGet_desc);
/* Retrieve the SPI master special information */
if (pFunc != NULL)
(*pFunc)(vxbDevParent(pDev), &pDrvCtrl->specialInfo);
}
/*
* sm2130SpiDevInstConnect - third level initialization routine of spi flash
*
* This function implements the VxBus instConnect handler for a SPI Flash
* device instance.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
LOCAL void sm2130SpiDevInstConnect(VXB_DEVICE_ID pDev)
{
SM2130_SPI_DEV *pDrvCtrl;
/* Check for vaild parameter */
VXB_ASSERT_NONNULL_V(pDev);
pDrvCtrl = (SM2130_SPI_DEV *)pDev->pDrvCtrl;
}
/*
* sm2130SpiDevInstUnlink - VxBus unlink handler
*
* This function shuts down a SPI Flash device instance in response to an
* unlink event from VxBus. This may occur if our VxBus instance has been
* terminated, or if the driver has been unloaded.
*
* RETURNS: OK always.
*
* ERRNO: N/A
*/
LOCAL STATUS sm2130SpiDevInstUnlink(VXB_DEVICE_ID pDev, void *unused)
{
SM2130_SPI_DEV *pDrvCtrl;
/* Check for vaild parameter */
VXB_ASSERT_NONNULL_V(pDev);
pDrvCtrl = (SM2130_SPI_DEV *)pDev->pDrvCtrl;
if (pDrvCtrl->muteSem) {
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
(void)semDelete(pDrvCtrl->muteSem);
pDrvCtrl->muteSem = NULL;
}
#ifndef _VXBUS_BASIC_HWMEMLIB
hwMemFree((char *)pDrvCtrl);
#endif /* _VXBUS_BASIC_HWMEMLIB */
pDev->pDrvCtrl = NULL;
return OK;
}
/*
*
* sm2130SpiDevShow - show the SPI 1553B info.
*
* This routine show the SPI flash info by vxBusShow.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose)
{
printf(" %s unit %d on %s @ 0x%08x", pDev->pName, pDev->unitNumber,
vxbBusTypeString(pDev->busID), pDev);
printf(" with busInfo %p\n", pDev->u.pSubordinateBus);
if (verbose) {
}
return;
}
/*
* spiDevWrite - VxBus SPI device write by name support routine
*
* This routine firstly finds the VXB_DEVICE_ID for a given instance
* identified by name and unit number, then call vxbI2cDevWrite() routine to
* write the device.
*
* RETURNS: OK/ERROR
*
* ERRNO : N/A
*/
LOCAL STATUS spiDevWrite(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var)
{
SPI_TRANSFER transInfo = {NULL, NULL, 0, 0, 0};
UINT8 buf[3];
/* Check if the pDev pointer is valid */
VXB_ASSERT(pDev != NULL, ERROR)
buf[0] = cmd;
buf[1] = var & 0xff;
buf[1] = (var >> 8) & 0xff;
transInfo.txBuf = buf;
transInfo.txLen = 3;
return (vxbSpiTransfer(pDev, &transInfo));
}
/*
* spiDevRead - read register routine
*
* This is the SPI flash status /config register read out routine.
*
* RETURNS: status register value.
*
* ERRNO: N/A
*/
LOCAL INT32 spiDevRead(VXB_DEVICE_ID pDev, UINT8 cmd)
{
SPI_TRANSFER transInfo = {NULL, NULL, 0, 0, 0};
UINT16 buffer = 0xffff;
/* check if the pDev pointer is valid */
VXB_ASSERT(pDev != NULL, ERROR)
transInfo.txBuf = &cmd;
transInfo.txLen = 1;
transInfo.rxBuf = (UINT8 *)&buffer;
transInfo.rxLen = 2;
if (vxbSpiTransfer(pDev, &transInfo) != OK)
return ERROR;
else
return (buffer);
}
INT32 sm2130Read(UINT8 cmd)
{
VXB_DEVICE_ID pDev;
SM2130_SPI_DEV * pCtrl;
pDev = vxbInstByNameFind(SPI_DEV_SM2130, 0);
if (pDev == NULL) {
return ERROR;
}
pCtrl = pDev->pDrvCtrl;
/* printf("pDev @ %p, pCtrl %p\n", pDev, pCtrl); */
return pCtrl->read(pDev, cmd);
}
STATUS sm2130Write(UINT8 cmd, UINT16 var)
{
VXB_DEVICE_ID pDev;
SM2130_SPI_DEV * pCtrl;
pDev = vxbInstByNameFind(SPI_DEV_SM2130, 0);
if (pDev == NULL) {
return ERROR;
}
pCtrl = pDev->pDrvCtrl;
/* printf("pDev @ %p, pCtrl %p\n", pDev, pCtrl); */
return pCtrl->write(pDev, cmd, var);
}

23
vxbSm2130SpiDev.h

@ -0,0 +1,23 @@
#ifndef __VXB_SM2130_SPI_DEV_H
#define __VXB_SM2130_SPI_DEV_H
#define SPI_DEV_SM2130 "SM2130"
#define SPI_DEV_MUTEX_OPT \
(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE)
typedef struct _spi_1553b_drv_ctrl {
VXB_DEVICE_ID pDev;
int cs;
int mode;
unsigned int freq;
INT32 (*read)(VXB_DEVICE_ID pDev, UINT8 cmd);
STATUS (*write)(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var);
SEM_ID muteSem; /* operation semaphore */
VXB_SPI_MAST_SPEC *specialInfo;
} SM2130_SPI_DEV;
#endif
Loading…
Cancel
Save