Browse Source

!165 update i2c for 1M and change can example

pull/166/head
Amire-wzq 4 months ago
committed by wangxiaodong
parent
commit
800f41bb94
  1. 22
      doc/ChangeLog.md
  2. 89
      drivers/can/fcan/fcan_intr.c
  3. 12
      drivers/i2c/fi2c/fi2c_hw.c
  4. 75
      example/peripherals/can/can/src/can_box_example.c
  5. 5
      example/peripherals/i2c/README.md
  6. BIN
      example/peripherals/i2c/fig/speed_rate_100k.png
  7. BIN
      example/peripherals/i2c/fig/speed_rate_1M.png
  8. BIN
      example/peripherals/i2c/fig/speed_rate_400k.png

22
doc/ChangeLog.md

@ -1,3 +1,25 @@
# Phytium Standalone SDK 2024-07-05 ChangeLog
Change Log since 2024-07-03
## drivrs
- modify the I2C driver to support 1M speed
## example
- modify the doc and readme for i2c example
# Phytium Standalone SDK 2024-07-03 ChangeLog
Change Log since 2024-07-03
## drivers
- modify the FCanIntrHandler function
## example
- can box example to add interrupt callback function
# Phytium Standalone SDK 2024-07-03 ChangeLog

89
drivers/can/fcan/fcan_intr.c

@ -13,7 +13,7 @@
*
* FilePath: fcan_intr.c
* Date: 2022-02-10 14:53:42
* LastEditTime: 2022-02-18 08:29:10
* LastEditTime: 2024-06-24 08:29:10
* Description:  This files is for the can interrupt functions
*
* Modify History:
@ -21,6 +21,7 @@
* ----- ------     --------    --------------------------------------
* 1.0 wangxiaodong 2022/5/26 first release
* 1.1 zhangyan 2022/12/7 improve functions
* 1.2 huangjin 2024/06/24 modify the FCanIntrHandler function
*/
#include "fcan.h"
@ -74,6 +75,7 @@ void FCanIntrHandler(s32 vector, void *args)
FASSERT(instance_p != NULL);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
config_p = &instance_p->config;
/* 获取中断状态 */
irq_status = FCAN_READ_REG32(config_p->base_address, FCAN_INTR_OFFSET);
if (0 == irq_status)
@ -81,75 +83,62 @@ void FCanIntrHandler(s32 vector, void *args)
return;
}
/* Check for the type of interrupt and Processing it */
if (irq_status & FCAN_INTR_TEIS_MASK)
/* 检查接收FIFO满中断标志 */
if (irq_status & FCAN_INTR_RFIS_MASK)
{
irq_status &= ~FCAN_INTR_REIS_MASK;
FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET,
FCAN_INTR_TEIC_MASK | FCAN_INTR_REIC_MASK);
FCAN_CLEARBIT(config_p->base_address, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
FCAN_SETBIT(config_p->base_address, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK);
FCAN_SETBIT(config_p->base_address, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_SEND);
FCAN_DEBUG("rx_fifo is full!!!");
FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_RFIE_MASK);
FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_RFIC_MASK);
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_FIFOFULL);
}
if (irq_status & (FCAN_INTR_EIS_MASK | FCAN_INTR_RFIS_MASK | FCAN_INTR_TFIS_MASK |
FCAN_INTR_BOIS_MASK | FCAN_INTR_PEIS_MASK | FCAN_INTR_PWIS_MASK))
/* 检查发送FIFO空中断标志 */
if (irq_status & FCAN_INTR_TFIS_MASK)
{
FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET,
(FCAN_INTR_EIC_MASK | FCAN_INTR_RFIC_MASK | FCAN_INTR_BOIC_MASK |
FCAN_INTR_PEIC_MASK | FCAN_INTR_PWIC_MASK | FCAN_INTR_TFIC_MASK));
FCAN_DEBUG("tx_fifo is empty!!!");
FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_TFIE_MASK);
FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_TFIC_MASK);
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_FIFOEMPTY);
}
/* Check for rx fifo full interrupt and output error information */
if (irq_status & FCAN_INTR_RFIS_MASK)
{
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_FIFOFULL);
FCAN_DEBUG("rx_fifo is full!!!");
/* disable rx fifo full interrupt */
FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_RFIE_MASK);
}
if (irq_status & FCAN_INTR_TFIS_MASK)
/* 检查错误中断的类型并处理 */
if ( irq_status & (FCAN_INTR_BOIS_MASK | FCAN_INTR_EIS_MASK | FCAN_INTR_PEIS_MASK | FCAN_INTR_PWIS_MASK) )
{
FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, (FCAN_INTR_BOIE_MASK | FCAN_INTR_EIE_MASK | FCAN_INTR_PEIE_MASK | FCAN_INTR_PWIE_MASK));
if (irq_status & FCAN_INTR_BOIS_MASK)
{
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_FIFOEMPTY);
FCAN_DEBUG("tx_fifo is empty!!!");
/* disable tx fifo empty interrupt */
FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_TFIE_MASK);
FCAN_ERROR("Bus off!!!");
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_BUSOFF);
}
if (irq_status & FCAN_INTR_EIS_MASK)
{
FCAN_ERROR("Error occurred!!!");
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_ERROR);
FCAN_ERROR("Error occurred!!!");
/* disable error interrupt */
FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_EIE_MASK);
}
if (irq_status & FCAN_INTR_BOIS_MASK)
{
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_BUSOFF);
FCAN_ERROR("Bus off!!!");
/* disable busoff interrupt */
FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_BOIE_MASK);
}
if (irq_status & FCAN_INTR_PEIS_MASK)
{
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_PERROE);
FCAN_ERROR("Passive error occurred!!!");
/* disable passive error interrupt */
FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_PEIE_MASK);
FCAN_ERROR("Passive error occurred!!!");
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_PERROE);
}
if (irq_status & FCAN_INTR_PWIS_MASK)
{
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_PWARN);
FCAN_ERROR("Passive warning!!!");
/* disable passive warning interrupt */
FCAN_CLEARBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_PWIE_MASK);
FCAN_ERROR("Passive warning!!!");
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_PWARN);
}
FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, (FCAN_INTR_BOIC_MASK | FCAN_INTR_EIC_MASK | FCAN_INTR_PEIC_MASK | FCAN_INTR_PWIC_MASK));
}
/* 检查发送完成中断标志 */
if (irq_status & FCAN_INTR_TEIS_MASK)
{
irq_status &= ~FCAN_INTR_REIS_MASK;
FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_TEIC_MASK | FCAN_INTR_REIC_MASK);
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_SEND);
}
/* 检查接收完成中断标志 */
if (irq_status & FCAN_INTR_REIS_MASK)
{
FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_REIE_MASK);
FCAN_SETBIT(config_p->base_address, FCAN_INTR_OFFSET, FCAN_INTR_REIC_MASK);
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_RECV);
FCAN_CALL_INTR_EVENT_HANDLDER(instance_p, FCAN_INTR_EVENT_RECV);
}
}

12
drivers/i2c/fi2c/fi2c_hw.c

@ -71,10 +71,10 @@ static const FI2cSpeedModeInfo I2C_SPEED_CFG[FI2C_SPEED_MODE_MAX] =
},
[FI2C_HIGH_SPEED] = {
FI2C_SPEED_HIGH_RATE,
390,
460,
60,
160,
20,
20,
}
};
@ -203,22 +203,25 @@ static FError FI2cCalcSpeedCfg(uintptr addr, u32 speed, u32 bus_clk_hz, FI2cSpee
if (FI2C_SPEED_HIGH_RATE <= speed)
{
speed_cfg_p->speed_mode = FI2C_HIGH_SPEED;
spk_cnt = FI2C_READ_REG32(addr, FI2C_HS_SPKLEN_OFFSET);
}
if (FI2C_SPEED_FAST_RATE <= speed)
else if (FI2C_SPEED_FAST_RATE <= speed)
{
speed_cfg_p->speed_mode = FI2C_FAST_SPEED;
spk_cnt = FI2C_READ_REG32(addr, FI2C_FS_SPKLEN_OFFSET);
}
else if (FI2C_SPEED_STANDARD_RATE <= speed)
{
speed_cfg_p->speed_mode = FI2C_STANDARD_SPEED;
spk_cnt = FI2C_READ_REG32(addr, FI2C_FS_SPKLEN_OFFSET);
}
else
{
return FI2C_ERR_INVAL_PARM;
}
spk_cnt = FI2C_READ_REG32(addr, FI2C_FS_SPKLEN_OFFSET);
return FI2cCalcTiming(bus_clk_hz, spk_cnt, speed_cfg_p);
}
@ -264,6 +267,7 @@ FError FI2cSetSpeed(uintptr addr, u32 speed_rate)
reg_val |= FI2C_CON_HIGH_SPEED;
FI2C_WRITE_REG32(addr, FI2C_HS_SCL_HCNT_OFFSET, speed_cfg.scl_hcnt);
FI2C_WRITE_REG32(addr, FI2C_HS_SCL_LCNT_OFFSET, speed_cfg.scl_lcnt);
break;
default:
ret |= FI2C_ERR_INVAL_PARM;
break;

75
example/peripherals/can/can/src/can_box_example.c

@ -13,13 +13,14 @@
*
* FilePath: can_box_example.c
* Date: 2023-12-05 16:05:49
* LastEditTime: 2023-12-05 16:05:49
* LastEditTime: 2024-06-24 16:05:49
* Description: This file is for can box test
*
* Modify History:
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------
* 1.0 huangjin 2023/12/05 first release
* 1.1 huangjin 2024/06/24 added interrupt callback function
*/
#include <stdio.h>
@ -46,6 +47,18 @@ static u32 RecvFrame(FCanCtrl *instance_p);
static FCanCtrl can[FCAN_NUM];
/*Configuring interrupt service functions*/
static void FCanRxFifoFullCallback(void *args)
{
FCanCtrl *instance_p = (FCanCtrl *)args;
FCAN_TEST_DEBUG("Can %d rx_fifo full callback", instance_p->config.instance_id);
}
static void FCanTxFifoEmptyCallback(void *args)
{
FCanCtrl *instance_p = (FCanCtrl *)args;
FCAN_TEST_DEBUG("Can %d tx_fifo empty callback", instance_p->config.instance_id);
}
static void FCanTxIrqCallback(void *args)
{
FCanCtrl *instance_p = (FCanCtrl *)args;
@ -59,6 +72,30 @@ static void FCanRxIrqCallback(void *args)
FCAN_TEST_DEBUG("Can%d irq recv frame callback", instance_p->config.instance_id);
}
static void FCanErrorCallback(void *args)
{
FCanCtrl *instance_p = (FCanCtrl *)args;
FCAN_TEST_DEBUG("Can %d is under error", instance_p->config.instance_id);
}
static void FCanBusoffCallback(void *args)
{
FCanCtrl *instance_p = (FCanCtrl *)args;
FCAN_TEST_DEBUG("Can %d bus off", instance_p->config.instance_id);
}
static void FCanPerrorCallback(void *args)
{
FCanCtrl *instance_p = (FCanCtrl *)args;
FCAN_TEST_DEBUG("Can %d passion error callback", instance_p->config.instance_id);
}
static void FCanPwarnCallback(void *args)
{
FCanCtrl *instance_p = (FCanCtrl *)args;
FCAN_TEST_DEBUG("Can %d passion warn callback", instance_p->config.instance_id);
}
static void FCanIrqSet(FCanCtrl *instance_p)
{
u32 cpu_id;
@ -81,6 +118,42 @@ static void FCanIrqSet(FCanCtrl *instance_p)
FCanRegisterInterruptHandler(instance_p, &intr_event);
FCanInterruptEnable(instance_p, intr_event.type);
intr_event.type = FCAN_INTR_EVENT_ERROR;
intr_event.handler = FCanErrorCallback;
intr_event.param = (void *)instance_p;
FCanRegisterInterruptHandler(instance_p, &intr_event);
FCanInterruptEnable(instance_p, intr_event.type);
intr_event.type = FCAN_INTR_EVENT_BUSOFF;
intr_event.handler = FCanBusoffCallback;
intr_event.param = (void *)instance_p;
FCanRegisterInterruptHandler(instance_p, &intr_event);
FCanInterruptEnable(instance_p, intr_event.type);
intr_event.type = FCAN_INTR_EVENT_PERROE;
intr_event.handler = FCanPerrorCallback;
intr_event.param = (void *)instance_p;
FCanRegisterInterruptHandler(instance_p, &intr_event);
FCanInterruptEnable(instance_p, intr_event.type);
intr_event.type = FCAN_INTR_EVENT_PWARN;
intr_event.handler = FCanPwarnCallback;
intr_event.param = (void *)instance_p;
FCanRegisterInterruptHandler(instance_p, &intr_event);
FCanInterruptEnable(instance_p, intr_event.type);
intr_event.type = FCAN_INTR_EVENT_FIFOFULL;
intr_event.handler = FCanRxFifoFullCallback;
intr_event.param = (void *)instance_p;
FCanRegisterInterruptHandler(instance_p, &intr_event);
FCanInterruptEnable(instance_p, intr_event.type);
intr_event.type = FCAN_INTR_EVENT_FIFOEMPTY;
intr_event.handler = FCanTxFifoEmptyCallback;
intr_event.param = (void *)instance_p;
FCanRegisterInterruptHandler(instance_p, &intr_event);
FCanInterruptEnable(instance_p, intr_event.type);
InterruptSetPriority(instance_p->config.irq_num, 0);
InterruptInstall(instance_p->config.irq_num, FCanIntrHandler, instance_p, "can");
InterruptUmask(instance_p->config.irq_num);

5
example/peripherals/i2c/README.md

@ -153,6 +153,11 @@ i2c ms_example
![一键运行](./fig/ms_example.png "ms_example.png")
i2c 速率设置为1M时,实测读写速率:![1M](fig/speed_rate_1M.png)
i2c 速率设置为400k时,实测读写速率:![400k](fig/speed_rate_400k.png)
i2c 速率设置为100k时,实测读写速率:![100k](fig/speed_rate_100k.png)
注:在使用i2c 例程中,因外部元器件或测量工具影响,可能导致读写速率存在一定偏差
## 3. 如何解决问题

BIN
example/peripherals/i2c/fig/speed_rate_100k.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
example/peripherals/i2c/fig/speed_rate_1M.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
example/peripherals/i2c/fig/speed_rate_400k.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Loading…
Cancel
Save