summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorJiaojinxing <jiaojinxing1987@gmail.com>2016-12-12 02:19:47 (GMT)
committer Jiaojinxing <jiaojinxing1987@gmail.com>2016-12-12 02:19:47 (GMT)
commiteff2959c420c555d4dc5617fbb15cac12c0666fa (patch)
tree9236c57785ecc46722c32c9bda5614bfc63dd4ec
parentc2bf1f1c0ac9853384f83b9c6bfe3e18753b57e2 (diff)
downloadbspam335x-eff2959c420c555d4dc5617fbb15cac12c0666fa.zip
bspam335x-eff2959c420c555d4dc5617fbb15cac12c0666fa.tar.gz
bspam335x-eff2959c420c555d4dc5617fbb15cac12c0666fa.tar.bz2
Updated i2c driver.
-rw-r--r--SylixOS/bsp/forlinx/config_ok335xs.h2
-rw-r--r--SylixOS/driver/i2c/am335x_i2c.c304
-rw-r--r--SylixOS/driver/netif/am335x_cpsw.c16
3 files changed, 149 insertions, 173 deletions
diff --git a/SylixOS/bsp/forlinx/config_ok335xs.h b/SylixOS/bsp/forlinx/config_ok335xs.h
index df53c28..812617f 100644
--- a/SylixOS/bsp/forlinx/config_ok335xs.h
+++ b/SylixOS/bsp/forlinx/config_ok335xs.h
@@ -102,6 +102,8 @@
#define BSP_CFG_STD_FILE "/dev/ttyS0"
+#define BSP_CFG_RTC_RX8010 1
+
#endif /* CONFIG_OK335XS_H_ */
/*********************************************************************************************************
END
diff --git a/SylixOS/driver/i2c/am335x_i2c.c b/SylixOS/driver/i2c/am335x_i2c.c
index f8b6f39..76b0c09 100644
--- a/SylixOS/driver/i2c/am335x_i2c.c
+++ b/SylixOS/driver/i2c/am335x_i2c.c
@@ -36,58 +36,7 @@
#define __I2C_BUS_FREQ_MAX (400)
#define __I2C_BUS_FREQ_MIN (100)
-/*
- * I2C Status Register (I2C_STAT):
- */
-#define I2C_STAT_BB (1 << 12) /* Bus busy */
-#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */
-#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */
-#define I2C_STAT_AAS (1 << 9) /* Address as slave */
-#define I2C_STAT_BF (1 << 8)
-#define I2C_STAT_GC (1 << 5)
-#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */
-#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */
-#define I2C_STAT_ARDY (1 << 2) /* Register access ready */
-#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */
-#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */
-
-/*
- * I2C Interrupt Enable Register (I2C_IE):
- */
-#define I2C_IE_BF_IE (1 << 8)
-#define I2C_IE_GC_IE (1 << 5)
-#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */
-#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */
-#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */
-#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */
-#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */
-
-#define I2C_TIMEOUT (1<<16)
-
-#define I2C_WAIT_TICK 3000
-
-#define CHECK_NACK(iStat) \
- do { \
- if (iStat & I2C_STAT_NACK) { \
- I2CMasterStop(pI2cChannel->I2CCHAN_ulVirtAddrBase); \
- printk(KERN_ERR "checked I2C_STA_NACK \n"); \
- return (PX_ERROR); \
- } \
- } while(0)
-
-#define I2C_INTERRUPT_WAIT_STAT() \
- do { \
- uiError = API_SemaphoreBPend(pI2cChannel->I2CCHAN_hSignal, I2C_WAIT_TICK); \
- if (uiError != ERROR_NONE) { \
- printk(KERN_ERR " I2C_INTERRUPT_WAIT_STAT API_SemaphoreBPend error\n"); \
- return (PX_ERROR); \
- } \
- } while(0)
-
-#define I2C_INTERRUPT_SET(X) \
- I2CMasterIntEnableEx(pI2cChannel->I2CCHAN_ulVirtAddrBase, \
- I2C_IE_AL_IE | I2C_IE_NACK_IE | \
- I2C_IE_GC_IE | X)
+#define __I2C_WAIT_TICK (50U)
/*********************************************************************************************************
i2c 通道类型定义
*********************************************************************************************************/
@@ -97,7 +46,6 @@ typedef struct {
ULONG I2CCHAN_ulVector; /* 中断向量 */
UINT I2CCHAN_uiIntPriority; /* 中断优先级 */
UINT I2CCHAN_uiBusFreq;
- UINT I2CCHAN_uiIntStat; /* 中断状态 */
UINT I2CCHAN_uiMask;
addr_t I2CCHAN_ulVirtAddrBase; /* 虚拟地址基地址 */
@@ -133,151 +81,174 @@ static __AM335X_I2C_CHANNEL _G_am335xI2cChannels[__I2C_CHANNEL_NR] = {
}
};
/*********************************************************************************************************
-** 函数名称: __am335xI2cIrqPoll
-** 功能描述: i2c 状态查询函数
-** 输 入 : uiBaseAddr 寄存器基地址
-** iMask 检查状态位
-** 输 出 : NONE
+** 函数名称: __am335xI2cIsr
+** 功能描述: I2C 通道中断服务例程
+** 输 入 : pI2cChannel I2C 通道
+** ulVector 中断向量
+** 输 出 : 中断返回值
** 全局变量:
** 调用模块:
*********************************************************************************************************/
-static UINT __am335xI2cIrqPoll (UINT uiBaseAddr, UINT iMask)
+static irqreturn_t __am335xI2cIsr (__PAM335X_I2C_CHANNEL pI2cChannel, ULONG ulVector)
{
- UINT iStat = 0, iTimeout;
-
- for (iTimeout = 0; iTimeout < 10; iTimeout++) {
- iStat = I2CMasterIntStatus(uiBaseAddr);
- if (iStat & iMask) {
- return (iStat);
- }
- bspDelayUs(1000);
+ UINT32 uiStat;
+ addr_t atBaseAddr;
+
+ atBaseAddr = pI2cChannel->I2CCHAN_ulVirtAddrBase;
+
+ /* Get only Enabled interrupt status */
+ uiStat = I2CMasterIntStatus(atBaseAddr);
+
+ /*
+ * Clear all enabled interrupt status except receive ready and
+ * transmit ready interrupt status
+ */
+ I2CMasterIntClearEx(atBaseAddr,
+ (uiStat & ~(I2C_INT_RECV_READY | I2C_INT_TRANSMIT_READY)));
+
+ if (uiStat & I2C_INT_RECV_READY) {
+ /* Receive data from data receive register */
+ *(pI2cChannel->I2CCHAN_pucBuffer++) = I2CMasterDataGet(atBaseAddr);
+ pI2cChannel->I2CCHAN_uiBufferLen--;
+
+ /* Clear receive ready interrupt status */
+ I2CMasterIntClearEx(atBaseAddr, I2C_INT_RECV_READY);
+
+ if (pI2cChannel->I2CCHAN_uiBufferLen == 0) {
+ /* Disable the receive ready interrupt */
+ I2CMasterIntDisableEx(atBaseAddr, I2C_INT_RECV_READY);
+ /* Generate a STOP */
+ I2CMasterStop(atBaseAddr);
+ }
}
- I2CMasterIntClearEx(uiBaseAddr, 0x7fff);
+ if (uiStat & I2C_INT_TRANSMIT_READY) {
+ /* Put data to data transmit register of i2c */
+ I2CMasterDataPut(atBaseAddr, *(pI2cChannel->I2CCHAN_pucBuffer++));
+ pI2cChannel->I2CCHAN_uiBufferLen--;
+ /* Clear Transmit interrupt status */
+ I2CMasterIntClearEx(atBaseAddr, I2C_INT_TRANSMIT_READY);
+
+ if (pI2cChannel->I2CCHAN_uiBufferLen == 0) {
+ /* Disable the transmit ready interrupt */
+ I2CMasterIntDisableEx(atBaseAddr, I2C_INT_TRANSMIT_READY);
+ API_SemaphoreBPost(pI2cChannel->I2CCHAN_hSignal); /* 释放同步信号 */
+ }
+ }
- return (iStat | I2C_TIMEOUT);
-}
+ if (uiStat & I2C_INT_STOP_CONDITION) {
+ /* Disable transmit data ready and receive data read interupt */
+ I2CMasterIntDisableEx(atBaseAddr, I2C_INT_TRANSMIT_READY |
+ I2C_INT_RECV_READY |
+ I2C_INT_STOP_CONDITION);
+ API_SemaphoreBPost(pI2cChannel->I2CCHAN_hSignal); /* 释放同步信号 */
+ }
+ if(uiStat & I2C_INT_NO_ACK) {
+ I2CMasterIntDisableEx(atBaseAddr, I2C_INT_TRANSMIT_READY |
+ I2C_INT_RECV_READY |
+ I2C_INT_NO_ACK |
+ I2C_INT_STOP_CONDITION);
+ /* Generate a STOP */
+ I2CMasterStop(atBaseAddr);
+ API_SemaphoreBPost(pI2cChannel->I2CCHAN_hSignal); /* 释放同步信号 */
+ }
+ return (LW_IRQ_HANDLED);
+}
/*********************************************************************************************************
-** 函数名称: __am335xI2cIsr
-** 功能描述: I2C 通道中断服务例程
-** 输 入 : pI2cChannel I2C 通道
-** ulVector 中断向量
-** 输 出 : 中断返回值
+** 函数名称: __am335xI2cClrAllInterrupts
+** 功能描述: 清除所有 I2C 中断
+** 输 入 : ulBaseAddr i2c 寄存器基地址
+** 输 出 : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
-static irqreturn_t __am335xI2cIsr (__PAM335X_I2C_CHANNEL pI2cChannel, ULONG ulVector)
+static VOID __am335xI2cClrAllInterrupts (addr_t ulBaseAddr)
{
- pI2cChannel->I2CCHAN_uiIntStat = I2CMasterIntStatus(pI2cChannel->I2CCHAN_ulVirtAddrBase);
- /* 获取中断状态 */
- I2CMasterIntDisableEx(pI2cChannel->I2CCHAN_ulVirtAddrBase,
- I2C_IE_AL_IE | I2C_IE_NACK_IE |
- I2C_IE_ARDY_IE | I2C_IE_RRDY_IE |
- I2C_IE_XRDY_IE | I2C_IE_GC_IE); /* 禁止相应中断位 */
- I2CMasterIntClearEx(pI2cChannel->I2CCHAN_ulVirtAddrBase, 0x7fff); /* 清除中断状态 */
- API_SemaphoreBPost(pI2cChannel->I2CCHAN_hSignal); /* 释放同步信号 */
-
- return (LW_IRQ_HANDLED);
+ I2CMasterIntEnableEx(ulBaseAddr, 0x7FF);
+ I2CMasterIntClearEx(ulBaseAddr, 0x7FF);
+ I2CMasterIntDisableEx(ulBaseAddr, 0x7FF);
}
/*********************************************************************************************************
** 函数名称: __am335xI2cTransferMsg
** 功能描述: i2c 传输消息
** 输 入 : pI2cChannel i2c 通道
-** pI2cAdapter i2c 适配器
** pI2cMsg i2c 传输消息组
-** iNum 消息数量
** 输 出 : 完成传输的消息数量
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT __am335xI2cTransferMsg (__PAM335X_I2C_CHANNEL pI2cChannel,
- PLW_I2C_MESSAGE pI2cMsg,
- BOOL bIsFirstMsg,
- BOOL bIsLastMsg)
+ PLW_I2C_MESSAGE pI2cMsg)
{
- INT i;
- UINT uiError;
+ UINT uiTimeTick;
+ INT iError;
+ addr_t ulBaseAddr;
+
+ if (pI2cMsg->I2CMSG_usLen == 0 ||
+ pI2cMsg->I2CMSG_pucBuffer == NULL) {
+ return (PX_ERROR);
+ }
+ ulBaseAddr = pI2cChannel->I2CCHAN_ulVirtAddrBase;
+ pI2cChannel->I2CCHAN_pucBuffer = pI2cMsg->I2CMSG_pucBuffer;
+ pI2cChannel->I2CCHAN_uiBufferLen = pI2cMsg->I2CMSG_usLen;
+ uiTimeTick = pI2cChannel->I2CCHAN_uiBufferLen * __I2C_WAIT_TICK;
if (pI2cMsg->I2CMSG_usFlag & LW_I2C_M_RD) {
- /* Data Count specifies the number of bytes to be received. */
- I2CSetDataCount(pI2cChannel->I2CCHAN_ulVirtAddrBase, pI2cMsg->I2CMSG_usLen);
+ /* Data Count specifies the number of bytes to be received */
+ I2CSetDataCount(ulBaseAddr, pI2cChannel->I2CCHAN_uiBufferLen);
- /* Set I2C slave address. */
- I2CMasterSlaveAddrSet(pI2cChannel->I2CCHAN_ulVirtAddrBase, pI2cMsg->I2CMSG_usAddr);
+ /* Clear status of all interrupts */
+ __am335xI2cClrAllInterrupts(ulBaseAddr);
/* Configure I2C controller in Master Receiver mode */
- I2CMasterControl(pI2cChannel->I2CCHAN_ulVirtAddrBase, I2C_CFG_MST_RX );
-
- /*
- * STT = 1, STP = 1, Conditions = Start-Stop (DCOUNT=n), Bus
- * Activities = S-A-D..(n)..D-P.
- */
- I2CMasterStart(pI2cChannel->I2CCHAN_ulVirtAddrBase);
- I2CMasterStop(pI2cChannel->I2CCHAN_ulVirtAddrBase);
- for (i = 0; i < pI2cMsg->I2CMSG_usLen; i++) {
- /*
- * 检查NACK, RRDY中断
- */
- I2C_INTERRUPT_SET(I2C_IE_RRDY_IE);
- I2C_INTERRUPT_WAIT_STAT();
- CHECK_NACK(pI2cChannel->I2CCHAN_uiIntStat);
- /*
- * 检查到中断,等待保证数据寄存器更新最新
- */
- bspDelayUs(200);
-
- if(pI2cChannel->I2CCHAN_uiIntStat & I2C_STAT_RRDY) {
- pI2cMsg->I2CMSG_pucBuffer[i] =
- I2CMasterDataGet(pI2cChannel->I2CCHAN_ulVirtAddrBase);
- } else {
- printk(KERN_ERR "NO CHECK I2C_STAT_RRDY state\n");
- return (PX_ERROR);
- }
+ I2CMasterControl(ulBaseAddr, I2C_CFG_MST_RX);
+
+ /* Receive and Stop Condition Interrupts are enabled */
+ I2CMasterIntEnableEx(ulBaseAddr, I2C_INT_RECV_READY |
+ I2C_INT_STOP_CONDITION);
+
+ /* Generate Start Condition over I2C bus */
+ I2CMasterStart(ulBaseAddr);
+
+ while (I2CMasterBusBusy(ulBaseAddr) == 0) {
+ }
+
+ iError = API_SemaphoreBPend(pI2cChannel->I2CCHAN_hSignal, uiTimeTick);
+ if (iError != ERROR_NONE) {
+ printk(KERN_ERR "__am335xI2cTransferMsg(): API_SemaphoreBPend error 1\n");
+ return (PX_ERROR);
}
- __am335xI2cIrqPoll(pI2cChannel->I2CCHAN_ulVirtAddrBase, I2C_STAT_ARDY);
} else {
- /* Data Count specifies the number of bytes to be received. */
- I2CSetDataCount(pI2cChannel->I2CCHAN_ulVirtAddrBase, pI2cMsg->I2CMSG_usLen);
+ /* Data Count specifies the number of bytes to be transmitted */
+ I2CSetDataCount(ulBaseAddr, pI2cChannel->I2CCHAN_uiBufferLen);
- /* Set I2C slave address. */
- I2CMasterSlaveAddrSet(pI2cChannel->I2CCHAN_ulVirtAddrBase, pI2cMsg->I2CMSG_usAddr);
+ /* Clear status of all interrupts */
+ __am335xI2cClrAllInterrupts(ulBaseAddr);
- /* Configure I2C controller in Master Receiver mode */
- I2CMasterControl(pI2cChannel->I2CCHAN_ulVirtAddrBase, I2C_CFG_MST_TX );
-
- /*
- * STT = 1, STP = 1, Conditions = Start-Stop (DCOUNT=n), Bus
- * Activities = S-A-D..(n)..D-P.
- */
- I2CMasterStart(pI2cChannel->I2CCHAN_ulVirtAddrBase);
- I2CMasterStop(pI2cChannel->I2CCHAN_ulVirtAddrBase);
- for (i = 0; i < pI2cMsg->I2CMSG_usLen; i++) {
- /*
- * 检查NACK, XRDY中断
- */
- I2C_INTERRUPT_SET(I2C_IE_XRDY_IE);
- I2C_INTERRUPT_WAIT_STAT();
- CHECK_NACK(pI2cChannel->I2CCHAN_uiIntStat);
-
- if(pI2cChannel->I2CCHAN_uiIntStat & I2C_STAT_XRDY) {
- I2CMasterDataPut(pI2cChannel->I2CCHAN_ulVirtAddrBase,
- pI2cMsg->I2CMSG_pucBuffer[i]);
- } else {
- printk(KERN_ERR "NO CHECK I2C_STAT_XRDY\n");
- return (PX_ERROR);
- }
- /*
- * 检查到中断,保证数据寄存器当前字节传输结束
- */
- bspDelayUs(200);
+ /* Configure I2C controller in Master Transmitter mode */
+ I2CMasterControl(ulBaseAddr, I2C_CFG_MST_TX);
+
+ /* Transmit interrupt is enabled */
+ I2CMasterIntEnableEx(ulBaseAddr, I2C_INT_TRANSMIT_READY);
+
+ /* Generate Start Condition over I2C bus */
+ I2CMasterStart(ulBaseAddr);
+
+ while (I2CMasterBusBusy(ulBaseAddr) == 0) {
}
- I2C_INTERRUPT_SET(I2C_IE_ARDY_IE);
- I2C_INTERRUPT_WAIT_STAT();
- CHECK_NACK(pI2cChannel->I2CCHAN_uiIntStat);
+ iError = API_SemaphoreBPend(pI2cChannel->I2CCHAN_hSignal, uiTimeTick);
+ if (iError != ERROR_NONE) {
+ printk(KERN_ERR "__am335xI2cTransferMsg(): API_SemaphoreBPend error 2\n");
+ return (PX_ERROR);
+ }
+
+ /* Wait untill I2C registers are ready to access */
+ while (!(I2CMasterIntRawStatus(ulBaseAddr) & (I2C_INT_ADRR_READY_ACESS))) {
+ }
}
return (ERROR_NONE);
@@ -303,8 +274,6 @@ static INT __am335xI2cTryTransfer (__PAM335X_I2C_CHANNEL pI2cChannel,
/* Put I2C in reset/disabled state. */
I2CMasterDisable(pI2cChannel->I2CCHAN_ulVirtAddrBase);
- I2CSoftReset(pI2cChannel->I2CCHAN_ulVirtAddrBase);
-
/* Disable Auto-Idle functionality. */
I2CAutoIdleDisable(pI2cChannel->I2CCHAN_ulVirtAddrBase);
@@ -325,23 +294,16 @@ static INT __am335xI2cTryTransfer (__PAM335X_I2C_CHANNEL pI2cChannel,
I2CMasterEnable(pI2cChannel->I2CCHAN_ulVirtAddrBase);
while(!I2CSystemStatusGet(pI2cChannel->I2CCHAN_ulVirtAddrBase)) {
- ;
}
for (i = 0; i < iNum; i++, pI2cMsg++) {
if (__am335xI2cTransferMsg(pI2cChannel,
- pI2cMsg,
- ((i == 0) ? LW_TRUE : LW_FALSE),
- ((i == iNum - 1) ? LW_TRUE : LW_FALSE)) != ERROR_NONE) {
+ pI2cMsg) != ERROR_NONE) {
I2CMasterStop(pI2cChannel->I2CCHAN_ulVirtAddrBase);
break;
}
}
- I2CMasterDisable(pI2cChannel->I2CCHAN_ulVirtAddrBase);
- I2CMasterStop(pI2cChannel->I2CCHAN_ulVirtAddrBase);
- I2CMasterIntClearEx(pI2cChannel->I2CCHAN_ulVirtAddrBase, 0x7fff);
-
return (i);
}
/*********************************************************************************************************
@@ -486,7 +448,6 @@ static INT __am335xI2c2MasterCtl (PLW_I2C_ADAPTER pI2cAdapter,
{
return (__am335xI2cMasterCtl(&_G_am335xI2cChannels[2], pI2cAdapter, iCmd, lArg));
}
-
/*********************************************************************************************************
** 函数名称: __am335xI2cHwInit
** 功能描述: 初始化 i2c 硬件通道
@@ -500,6 +461,7 @@ static INT __am335xI2cHwInit (__PAM335X_I2C_CHANNEL pI2cChannel, PAM335X_PINMU
UINT uiChannel = pI2cChannel - &_G_am335xI2cChannels[0];
switch (uiChannel) {
+
case 0:
/* Enable the clock for I2C0. */
am335xEnableModuleClock(am335xModuleIdGet("I2C0"));
diff --git a/SylixOS/driver/netif/am335x_cpsw.c b/SylixOS/driver/netif/am335x_cpsw.c
index c722a59..4fc17bb 100644
--- a/SylixOS/driver/netif/am335x_cpsw.c
+++ b/SylixOS/driver/netif/am335x_cpsw.c
@@ -342,7 +342,13 @@ static VOID __am335xCpswLinkStatusCheck (struct netdev *pNetdev)
if (uiSpeed != 0) {
netdev_set_linkup(pNetdev, 1, uiSpeed);
printk(KERN_ALERT "netif %c%c%d link up\n",
- pNetdev->if_name[0], pNetdev->if_name[1], uiInstNum + 1);
+ pNetdev->if_name[0],
+ pNetdev->if_name[1],
+#ifdef CPSW_SWITCH_CONFIG
+ uiInstNum + 1);
+#else
+ uiSlavePortNum);
+#endif
}
}
}
@@ -365,7 +371,13 @@ static VOID __am335xCpswLinkStatusCheck (struct netdev *pNetdev)
netdev_set_linkup(pNetdev, 0, 0);
printk(KERN_ALERT "netif %c%c%d link down\n",
- pNetdev->if_name[0], pNetdev->if_name[1], uiInstNum + 1);
+ pNetdev->if_name[0],
+ pNetdev->if_name[1],
+#ifdef CPSW_SWITCH_CONFIG
+ uiInstNum + 1);
+#else
+ uiSlavePortNum);
+#endif
}
}
}