基于S32K148快速调试TJA1101

news2024/10/5 17:25:59

文章目录

    • 1.前言
    • 2.TJA1101简介
    • 3.TJA1101调试
      • 3.1 硬件
        • 3.1.1 整体框图
        • 3.1.2 评估板
          • 3.1.2.1 参考原理图
          • 3.1.2.2 引脚说明
        • 3.1.3 转接板
          • 3.1.3.1 参考原理图
          • 3.1.3.2 模式配置
          • 3.1.3.3 原理介绍
      • 3.2 软件
        • 3.2.1 物理层(TJA1101):
        • 3.2.2 数据链路层(S32K148):
        • 3.2.3 主要代码
      • 3.3 测试
        • 3.3.1 测试normal mode
        • 3.3.2 测试link up 和 link down
        • 3.3.3 测试wake up
    • 4.参考资料

1.前言

汽车架构演变[图片来源:NXP]

如上图所示,为了适应车身越来越多的ECU节点,汽车电子架构正在从传统的分布式往集中式(Domain、Zonal)转变。在这转变的过程中,除了传统的CAN,LIN节点变多之外,汽车以太网也开始被广泛的使用。

以下图(传统的分布式架构)为例,汽车以太网主要用于大数据传输的场合,如摄像头,雷达,显示,网关等。

分布式架构中车载网络[图片来源:NXP]

在CAN、LIN收发器占据大部分市场份额的NXP也早在2017年推出了百兆车载以太网PHY芯片-TJA1100,随后又推出了TJA1101,TJA1102等产品,roadmap如下所示,下文将介绍如何快速调试TJA1101。

NXP PHY Roadmap[图片来源:NXP]

2.TJA1101简介

TJA1101为单端口IEEE 802.3bw(100BASE-T1) PHY,符合功能安全ASIL-A。可通过非屏蔽双绞线(UTP)电缆提供100Mbit/s的发送和接收能力,同时针对耦合到UTP线路的容性信号耦合进行了优化,支持至少15米的电流长度。TJA1101与介质访问控制单元(MAC)的通信接口为MII或者RMII。

TJA1101支持符合OPEN联盟TC10标准的睡眠和唤醒转发解决方案,具体如下,同时拥有和唤醒线路相关的本地唤醒引脚。

  • 全局系统唤醒
  • 通过总线进行可靠的远程唤醒检测
  • PHY层级唤醒转发
  • 进入睡眠时的握手确认
  • 节省一个额外的唤醒线路

3.TJA1101调试

目前TJA1101系列主推的是TJA1101BHN,但是笔者手上只有S32K148+TJA1101AHN的板子,TJA1101AHN和TJA1101BHN是软硬件兼容的,这里就以TJA1101AHN为例,介绍调试相关的内容。

3.1 硬件

测试环境主要由两块板子组成,一块S32K148评估板,用于驱动TJA1101,并发送数据;一块以太网转接板,将车载以太网信号转为工业以太网信号,方便在电脑上查看。

3.1.1 整体框图

整个测试环境的框图如下所示:

整体框图

3.1.2 评估板

对于TJA1101的调试工作在S32K148评估板完成,如下是S32K148评估板有关以太网部份的介绍。

3.1.2.1 参考原理图

TJA1101的推荐电路图如下所示,

TJA1101推荐电路图

其中使用本地25MHz晶振的MII和RMII连接方式如下图所示,

MII and RMII

3.1.2.2 引脚说明

TJA1101和S32K148的接口主要是®MII和SMI,S32K148用到的引脚以及功能定义如下:

MII接口和SMI接口

同时,TJA1101有一些引脚具有pin strapping的功能,如下所示:(红框中是S32K148板子的实际配置)

Pin strapping

3.1.3 转接板

以太网转接板主要元器件为一颗工业以太网PHY+以太网PHY,然后都配置成Reverse MII模式,用来实现车载以太网的信号转换成传统的工业以太网的信号

3.1.3.1 参考原理图

Reverse MII模式下的TJA1101推荐原理图如下:

Reverse MII

3.1.3.2 模式配置

参考上一章节有关pin strapping的描述,转接板上TJA1101的配置为:Master,自主模式,Reverse MII。

3.1.3.3 原理介绍

如果需要深入了解转接板的原理图,可以查看胡工的公众号文章,链接如下:

  • 汽车以太网(100BASE-T1)转工业以太网(100BASE-TX)转换器工作原理介绍 (qq.com)

3.2 软件

接下来是软件的配置介绍,本次对于TJA1101的调试基于S32DS 2.2自带的如下例程进行修改。

phy_tja1101_s32k148

打开例程后,图形化界面相关的组件有三个,其中GPIO口的配置参考3.1.2.2章节进行设置,phy和mac的设置介绍如下。

3.2.1 物理层(TJA1101):

打开phy组件的图形化界面,如下所示:

PHY配置

其中,有四项配置说明下:

  • Address设置需要和pin strapping的设置匹配,或者使用广播地址0x00
  • PHY Role,设置为自动,跟随pin strapping,为从机模式
  • link Up Event Callback,填充link up事件发生时调用的回调函数名称
  • link Down Event Callback,填充link down事件发生时调用的回调函数名称

3.2.2 数据链路层(S32K148):

打开ethernet组件的图形化界面,如下所示:

MAC配置

其中,有两项配置说明下:

  • MAC Address,测试时随便填充即可,实际使用时车厂统一分配
  • MII configuration,选择模式,速度以及全双工/半双工

3.2.3 主要代码

#define GPIO_PORT   PTE
#define PCC_CLOCK   PCC_PORTE_CLOCK
#define LED1_RED    (1 << 21U)
#define LED2_YELLOW  (1 << 22U)
#define LED3_BLUE   (1 << 23U)
#define PTB_PHY_INT (1 << 20U)
#define PTC_BTN0    (1 << 12U)
#define PTC_BTN1    (1 << 13U)


#define PHY_CONFIG1                  18U
#define PHY_CONFIG1_FWDREM           0x0004U
#define PHY_EXTENDED_CTRL_ADDR       17U
#define PHY_EXTENDED_CTRL_CONFIG_EN  0x0004U
#define PHY_COM_CONFIG               27U
#define PHY_COM_CONFIG_WAKE          0x0040U

static uint8_t srcMacaddress[]={0x11,0x22,0x33,0x44,0x55,0x99};

typedef struct {
	uint8_t destAddr[6];
	uint8_t srcAddr[6];
	uint16_t length;
	uint8_t payload[1500];
} mac_frame_t;

void copyBuff(uint8_t *dest, uint8_t *src, uint32_t len)
{
	uint32_t i;

	for (i = 0; i < len; i++)
	{
		dest[i] = src[i];
	}
}

void rx_callback(uint8_t instance, enet_event_t event, uint8_t ring)
{
	(void)instance;

	if (event == ENET_RX_EVENT)
	{
		enet_buffer_t buff;
		status_t status;

		status = ENET_DRV_ReadFrame(INST_ETHERNET1, ring, &buff, NULL);
		if (status == STATUS_SUCCESS)
		{
			mac_frame_t *frame;

			frame = (mac_frame_t *) buff.data;

			/* You can process the payload here */
			(void)frame->payload;

//	        /*turn off Blue led*/
//	        PINS_DRV_SetPins(GPIO_PORT, LED3_BLUE);

			ENET_DRV_ProvideRxBuff(INST_ETHERNET1, ring, &buff);
		}
	}
}

/* Port C IRQ handler */
void portc_Handler(void)
{
	uint32_t flags;
	static bool loopback;
	static phy_role_t phyRole = PHY_ROLE_MASTER;
	uint32_t delay = 1000000U;

	do
	{
		/* wait some time to allow capturing pushing multiple buttons at once */
		delay--;
	}
	while(delay != 0);

	flags = PINS_DRV_GetPortIntFlag(PORTC);
	if ((flags & (PTC_BTN1 | PTC_BTN0)) == (PTC_BTN1 | PTC_BTN0))
	{
		/* both buttons pressed - change master/slave settings */
		PHY_SetRole(0, phyRole);
		phyRole = (phyRole == PHY_ROLE_MASTER) ? (PHY_ROLE_SLAVE) : (PHY_ROLE_MASTER);
	}
	else
	{
		if ((flags & PTC_BTN1) != 0U)
		{
			PHY_Sleep(0);
		}
		if ((flags & PTC_BTN0) != 0U)
		{
			if (loopback)
			{
				PHY_SetLoopback(0, PHY_LOOPBACK_NONE);
			}
			else
			{
				PHY_SetLoopback(0, PHY_LOOPBACK_INTERNAL);
			}
			loopback = !loopback;
		}
	}
    /* Clear interrupt flag */
	PINS_DRV_ClearPortIntFlagCmd(PORTC);
}

/* Link up callback */
void link_up(uint8_t phy)
{
	if (phy == 0U)
	{
		/* if link up,turn off red led and turn on yellow led*/
		PINS_DRV_ClearPins(GPIO_PORT, LED2_YELLOW);
		PINS_DRV_SetPins(GPIO_PORT, LED1_RED);
		PINS_DRV_SetPins(GPIO_PORT, LED3_BLUE);
	}
}

/* Link down callback  */
void link_down(uint8_t phy)
{
	if (phy == 0U)
	{
		/* set PTE21 to low for turning on Red led*/
		PINS_DRV_ClearPins(GPIO_PORT, LED1_RED);
		PINS_DRV_SetPins(GPIO_PORT, LED2_YELLOW);
		PINS_DRV_SetPins(GPIO_PORT, LED3_BLUE);
	}
}

/*!
 \brief The main function for the project.
 \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
 */
int main(void)
{
  /* Write your local variable definition here */
  enet_buffer_t buff;
  mac_frame_t frame;
  uint8_t i;
  status_t ENET_status;
  static uint16_t extCtrl = 0;

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
#ifdef PEX_RTOS_INIT
  PEX_RTOS_INIT(); /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
#endif
  /*** End of Processor Expert internal initialization.                    ***/

  /* Initialize and configure clocks
   * 	-	see clock manager component for details
   */
  CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,
                 g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
  CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);

  /* Initialize pins
   *	-	See PinSettings component for more info
   */
  PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);

  /* Initialize ENET instance */
  ENET_DRV_Init(INST_ETHERNET1, &ethernet1_State, &ethernet1_InitConfig0, ethernet1_buffConfigArr0, ethernet1_MacAddr);
  ENET_DRV_EnableMDIO(INST_ETHERNET1, false);

  /* turn on Red led for init */
  PINS_DRV_ClearPins(GPIO_PORT, LED1_RED);

  PHY_FrameworkInit(phyConfig, phyDrivers);
  PHY_Init(0);

  /* make custom settings */
  PHY_RMR(0, PHY_EXTENDED_CTRL_ADDR, PHY_EXTENDED_CTRL_CONFIG_EN, PHY_EXTENDED_CTRL_CONFIG_EN);
  PHY_RMR(0, PHY_CONFIG1, PHY_CONFIG1_FWDREM, PHY_CONFIG1_FWDREM);
  PHY_RMR(0, PHY_COM_CONFIG, PHY_COM_CONFIG_WAKE, PHY_COM_CONFIG_WAKE);  /* ratio metric threshold on wake pin */
  PHY_RMR(0, PHY_EXTENDED_CTRL_ADDR, 0, PHY_EXTENDED_CTRL_CONFIG_EN);

  INT_SYS_InstallHandler(PORTC_IRQn, portc_Handler, (isr_t *)0);
  INT_SYS_EnableIRQ(PORTC_IRQn);

//  /* set tja1101 into internal loopback mode */
//  PHY_SetLoopback(0, PHY_LOOPBACK_INTERNAL);


  /* prepare for sending data */
  for (i = 0; i < 50U; i++)
  {
	  frame.payload[i] = i;
  }
  copyBuff(frame.destAddr, ethernet1_MacAddr, 6U);
  copyBuff(frame.srcAddr, srcMacaddress, 6U);
  frame.length = 50U;
  buff.data = (uint8_t *)&frame;
  /* Length == 12 bytes MAC addresses + 2 bytes length + 50 bytes payload */
  buff.length = 64U;

  ENET_DRV_SendFrame(INST_ETHERNET1, 0U, &buff, NULL);
  OSIF_TimeDelay(500);
  while (1)
  {
	  /* Provides polling support, by handling specific events */
	  PHY_MainFunction(0);

	  ENET_status = ENET_DRV_GetTransmitStatus(INST_ETHERNET1,0,&buff, NULL);
	  if (ENET_status == STATUS_SUCCESS)
	  {
		  ENET_DRV_SendFrame(INST_ETHERNET1, 0U, &buff, NULL);
		  /* if send ok, toggle yellow led*/
		  PINS_DRV_TogglePins(GPIO_PORT, LED2_YELLOW);
	  }

      PHY_Read(0, PHY_EXTENDED_CTRL_ADDR, &extCtrl);
      if (extCtrl == 0xD000U)
      {
          /* when tja1101 go to sleep mode, toggle on blue led*/
    	  PINS_DRV_TogglePins(GPIO_PORT, LED3_BLUE);
  		  PINS_DRV_SetPins(GPIO_PORT, LED1_RED);
  		  PINS_DRV_SetPins(GPIO_PORT, LED2_YELLOW);
      }

	  OSIF_TimeDelay(500);
  }

3.3 测试

3.3.1 测试normal mode

连上S32K148开发板、以太网转接板以及电脑,然后上电,红色LED短暂亮一下,然后黄色LED闪烁,在电脑的抓包软件wireshark上能看到S32K148循环发送的以太网数据。

wireshark抓取的部分数据如下图:

wireshark抓取的数据

3.3.2 测试link up 和 link down

两种中断状态进入的条件如下:

link up and down

测试情况为:

  • 上电之后,先打开红色LED,然后进入link_up回调函数,关闭红色LED,打开黄色LED。wireshark显示数据正常发送的同时,黄色LED闪烁。

  • 接着断开双绞线(TRX_P和TRX_N),进入link_down回调函数,关闭黄色LED,打开红色LED。wireshark面板上没有数据显示。

  • 最后接上双绞线(TRX_P和TRX_N),进入link_up回调函数,关闭红色LED,打开黄色LED。wireshark显示数据正常发送的同时,黄色LED闪烁。

3.3.3 测试wake up

通过在WAKE_IN_OUT引脚产生上升沿去产生唤醒事件,从而唤醒TJA1101。
测试情况为:

  • 上电之后红色LED短暂亮一下,然后黄色LED闪烁。按下开发板的按钮,配置TJA1101进入sleep模式,黄色LED熄灭,蓝色LED点亮,wireshark面板上没有数据显示。

  • 在WAKE_IN_OUT引脚短接一下VDD,产生一个上升沿,唤醒TJA1101,进入normal模式,关闭蓝色LED,黄色LED闪烁,wireshark显示数据正常发送。

4.参考资料

  • TJA1101B, 100BASE-T1 PHY for automotive Ethernet – Data Sheet (nxp.com)
  • Automotive Ethernet Switches & PHY Transceivers Brochure (nxp.com)

本文主要介绍了如何快速调试TJA1101,对于很多细节的东西没有展开。后面有时间会专门写几篇文章分别介绍TJA1101的硬件设计,软件驱动以及测试注意事项。


如果觉得本文对你有用,不妨给个一键三连!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/390125.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

05_Pulsar的主要组件介绍与命令使用、名称空间、Pulsar的topic相关操作、Pulsar Topic(主题)相关操作_高级操作、

1.5.Apache Pulsar的主要组件介绍与命令使用 1.5.1.多租户模式 1.5.1.1. 什么是多租户 1.5.1.2.Pulsar多租户的相关特征_安全性&#xff08;认证和授权&#xff09; 1.5.1.3.Pulsar多租户的相关特性_隔离性 1.5.1.4.Pulsar多租户的相关操作 1-获取租户列表 2-创建租户 3-获取配…

RocketMQ单机安装与启动

RocketMQ单机安装与启动系统要求下载地址安装步骤RocketMq启动NameServer查看是否启动成功启动BrokerProxy查看是否启动成功修改tool.sh测试消息产生消息的消费关闭服务器系统要求 下载地址 官网下载地址 二进制包是已经编译完成后可以直接运行的&#xff0c;源码包是需要编译…

Vant2 源码分析之 vant-sticky

前言 原打算借鉴 vant-sticky 源码&#xff0c;实现业务需求的某个功能&#xff0c;第一眼看以为看懂了&#xff0c;拿来用的时候&#xff0c;才发现一知半解。看第二遍时&#xff0c;对不起&#xff0c;是我肤浅了。这里侧重分析实现原理&#xff0c;其他部分不拓展开来&…

轮转数组(每日一题)

目录 一、题目描述 二、题目分析 2.1 方法一 2.1.1 思路 2.1.2 代码 2.2 方法二 2.2.1 思路 2.2.2 代码 2.3 方法三 2.3.1 思路 2.3.2 代码 一、题目描述 oj链接&#xff1a;https://leetcode.cn/problems/rotate-array 给定一个整数数组 nums&#xff0c;将数组中的…

GDScript 导出变量 (Godot4.0)

概述 导出变量的功能在3.x版本中也是有的&#xff0c;但是4.0版本对其进行了语法上的改进。 导出变量在日常的游戏制作中提供节点的自定义参数化调节功能时非常有用&#xff0c;除此之外还用于自定义资源。 本文是&#xff08;Bilibili巽星石&#xff09;在4.0官方文档《GDScr…

手把手创建flask项目

Flask 框架流程 什么是Flask&#xff1a; Flask诞生于2010年, 使用python语言基于Werkzeug工具箱编写的轻量级Web开发框架 Flask本身相当于一个内核, 其他几乎所有的功能都要用到扩展(邮件:Flask-Mail, 用户认证:Flask-Login, 数据库:Flask-SQLAlchemy). Flask的核心在于Werkz…

在线图书借阅网站( Python +Vue 实现)

功能介绍 平台采用B/S结构&#xff0c;后端采用主流的Python语言进行开发&#xff0c;前端采用主流的Vue.js进行开发。 整个平台包括前台和后台两个部分。 前台功能包括&#xff1a;首页、图书详情页、用户中心模块。后台功能包括&#xff1a;总览、借阅管理、图书管理、分类…

unity知识点小结02

虚拟轴 虚拟轴就是一个数值在-11内的轴&#xff0c;这个数轴上重要的数值就是-1,0和1。当使用按键模拟一个完整的虚拟轴时需要用到两个按键&#xff0c;即将按键1设置为负轴按键&#xff0c;按键2设置为正轴按键。在没有按下任何按键的时候&#xff0c;虚拟轴的数值为0&#xf…

【UEFI基础】UEFI事件介绍

简述 在【UEFI基础】System Table和Architecture Protocols介绍Boot Service时提到有一部分与事件相关的接口&#xff0c;它们创建、触发、等待和关闭事件&#xff0c;来完成某些功能&#xff0c;本文将进一步介绍事件。 需要注意&#xff0c;因为Boot Service需要在DXE阶段才…

用数组名作函数参数的详解,以及形参实参采用数组名,形参实参采用指针变量的几种情况解析

关于地址&#xff0c;指针&#xff0c;指针变量可以参考我的这篇文章&#xff1a; 地址&#xff0c;指针&#xff0c;指针变量是什么&#xff1f;他们的区别&#xff1f;符号&#xff08;*&#xff09;在不同位置的解释&#xff1f;_juechen333的博客-CSDN博客https://blog.csd…

Kali的安装与配置

虚拟机安装kali Kali下载 官网下载地址 注&#xff1a;下载VMware版本 百度网盘 提取码&#xff1a;Chen 创建虚拟机 将下载的压缩包放到合适的位置解压 双击运行虚拟机 登录 默认的账号密码都为kali 基本配置 修改root账户密码 打开命令行输入 sudo su root 输入kali 输…

【机器学习】验证集loss震荡(loss的其他问题)

训练过程中发现&#xff0c;train loss一直下降&#xff0c;train acc一直上升&#xff1b;但是val loss、val acc却一直震荡。loss一会上一会下&#xff0c;但是总体趋势是向下的。 “loss震荡但验证集准确率总体下降” 如何解决&#xff1f; 测试集准确率这样震荡是正常的吗…

python2.7/3.8版本安装教程

Wiondos-Python环境安装 Python2.7 下载地址 官网 速度比较慢 百度网盘 提取码:Chen 安装Python2.7 直接next 选择安装目录 注意这一步将最后一项勾选 安装完成 cmd中输入python 检查pip是否安装 cmd中输入pip --version Python3.8 下载地址 官网 速度比较慢 百度网…

蓝桥杯C/C++程序设计 往届真题汇总(进阶篇)

文章目录1. 最短路2. 数字三角形3. 递增序列4. 杨辉三角形5. 跳跃6. 路径7. 迷宫8. 装饰珠9. 明码10. 字串分值11. 作物杂交12. 承压计算13. 全球变暖14. 直线15. 平面切分1. 最短路 题目描述&#xff1a; 如下图所示&#xff0c;G是一个无向图&#xff0c;其中蓝色边的长度是…

线程池执行父子任务,导致线程死锁

前言&#xff0c; 一次线程池的不当使用&#xff0c;导致了现场出现了线程死锁&#xff0c;接口一直不返回。而且由于这是一个公共的线程池&#xff0c;其他使用了次线程池的业务也一直阻塞&#xff0c;系统出现了OOM&#xff0c;不过是幸好是线程同事测试出来的&#xff0c;没…

RPC通信原理解析

一、什么是RPC框架&#xff1f; RPC&#xff0c;全称为Remote Procedure Call&#xff0c;即远程过程调用&#xff0c;是一种计算机通信协议。 比如现在有两台机器&#xff1a;A机器和B机器&#xff0c;并且分别部署了应用A和应用B。假设此时位于A机器上的A应用想要调用位于B机…

第十一届蓝桥杯大赛青少组国赛Python真题2

第十一届蓝桥杯大赛青少组Python 真题 第二题 提示信息&#xff1a; 杨辉三角形&#xff0c;是二项式系数在三角形中的一种几何排列。中国南宋数学家杨辉在 1261 年所著的《详 解九章算法》一书有明确记载。欧洲数学家帕斯卡在 1654 年发现这一规律&#xff0c;所以又叫做帕斯卡…

Rabbit快速入门

入门案例 需求&#xff1a;使用简单模式完成消息传递 步骤&#xff1a; 创建工程&#xff08;生成者、消费者&#xff09; 分别添加依赖 编写生产者发送消息 编写消费者接收消息 3.1.2. 添加依赖 往heima-rabbitmq的pom.xml文件中添加如下依赖&#xff1a; <dependenc…

RabbitMQ的安装和配置

注意: 请使用资料里提供的CentOS-7-x86_64-DVD-1810.iso 安装虚拟机. 1. 安装依赖环境 在线安装依赖环境&#xff1a; yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c kernel-devel m4 ncurses-devel tk tc xz2. 安装Erlang 上…

【完整版】国内网络编译,Ambari 2.7.6 全部模块源码编译笔记

本次编译 ambari 2.7.6 没有使用科学上网的工具,使用的普通网络,可以编译成功,过程比 ambari 2.7.5 编译时要顺畅。 以下是笔记完整版。如果想单独查看本篇编译笔记,可参考:《Ambari 2.7.6 全部模块源码编译笔记》 该版本相对 2.7.5 版本以来,共有 26 个 contributors …