Update repo

This commit is contained in:
2026-08-30 23:04:35 -07:00
parent 749dab5721
commit ce65a0f59a
14950 changed files with 4408250 additions and 1 deletions
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_c28x_config"
device="TMS320F28388D"
cgtVersion="22.6.1.LTS"
products="C2000WARE"
outputFormat="ELF"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CPU1_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} -v28 -ml -mt --cla_support=cla2 --float_support=fpu64 --tmu_support=tmu0 --define=DEBUG --define=CPU1 --define=ETHERNET --define RAM --diag_warning=225 --diag_suppress=10063" linkerBuildOptions="--entry_point code_start --stack_size=0x3F8 --heap_size=0x200" />
<configuration name="CPU1_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=_FLASH -v28 -ml -mt --cla_support=cla2 --float_support=fpu64 --tmu_support=tmu0 --define=DEBUG --define=ETHERNET --define=CPU1 --diag_warning=225 --diag_suppress=10063" linkerBuildOptions="--entry_point code_start --stack_size=0x3F8 --heap_size=0x200 " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/device.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/device.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cpu1.cmd" targetDirectory="" applicableConfigurations="CPU1_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cpu1.cmd" targetDirectory="" applicableConfigurations="CPU1_FLASH" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/f2838x_codestartbranch.asm" targetDirectory="device" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib/ccs/Debug/driverlib.lib" targetDirectory="" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib/" targetDirectory="device" excludeFromBuild="True" />
<file action="copy" path="../../../c28x/cm_common_config_c28x/cm_common_config_c28x.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex10_lowlatency_interrupt"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
<file action="copy" path="../ethernet_ex10_lowlatency_interrupt.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex1_basic_tx_rx_loopback"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../ethernet_ex1_basic_tx_rx_loopback.c" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex2_phy_loopback"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../ethernet_ex2_phy_loopback.c" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex3_threshold_mode_phy_loopback"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../ethernet_ex3_threshold_mode_phy_loopback.c" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex4_ptp_basic_master"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../ethernet_ex4_ptp_basic_master.c" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex4_ptp_basic_slave"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../ethernet_ex4_ptp_basic_slave.c" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex5_ptp_offload_master"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../ethernet_ex5_ptp_offload_master.c" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex5_ptp_offload_slave"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 " linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../ethernet_ex5_ptp_offload_slave.c" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex6_crc_checksum_offload"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
<file action="copy" path="../ethernet_ex6_crc_checksum_offload.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex7_tranport_segmentation_offload"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
<file action="copy" path="../ethernet_ex7_tranport_segmentation_offload.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex8_vlan_filtering"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
<file action="copy" path="../ethernet_ex8_vlan_filtering.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex9_revmii_example_mii_remote"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
<file action="copy" path="../ethernet_ex9_revmii_example_mii_remote.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,25 @@
<projectSpec>
<project
name="ethernet_ex9_revmii_example_revmii_side"
device="Cortex M.TMS320F28388D"
cgtVersion="20.2.7.LTS"
products="C2000WARE"
endianness="little"
launchWizard="False"
linkerCommandFile=""
>
<configuration name="CM_RAM" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a --define RAM" />
<configuration name="CM_FLASH" compilerBuildOptions="--opt_level=off -I${PROJECT_ROOT}/device -I${C2000WARE_DLIB_ROOT} --define=DEBUG --float_support=none --define=_FLASH -mv7M4 -me --diag_warning=225 --display_error_number" linkerBuildOptions="--stack_size=1024 --heap_size=1024 --library=libc.a " />
<pathVariable name="C2000WARE_DLIB_ROOT" path="../../../../../../driverlib/f2838x/driverlib_cm/" scope="project" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/driverlib_cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/include/cm.h" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/cm.c" targetDirectory="device" />
<file action="copy" path="../../../../../../device_support/f2838x/common/targetConfigs/TMS320F28388D.ccxml" targetDirectory="targetConfigs" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_RAM_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_RAM" />
<file action="copy" path="../../../../../../device_support/f2838x/common/cmd/2838x_FLASH_lnk_cm.cmd" targetDirectory="" applicableConfigurations="CM_FLASH" />
<file action="copy" path="../../../../../../driverlib/f2838x/driverlib_cm/" targetDirectory="device" excludeFromBuild="True" />
<file action="link" path="../../../../../../driverlib/f2838x/driverlib_cm/ccs/Debug/driverlib_cm.lib" targetDirectory="" />
<file action="copy" path="../../../../../../device_support/f2838x/common/source/startup_cm.c" targetDirectory="" />
<file action="copy" path="../ethernet_ex9_revmii_example_revmii_side.c" targetDirectory="" />
</project>
</projectSpec>
@@ -0,0 +1,414 @@
//#############################################################################
//
// FILE: ethernet_ex10_lowlatency_interrupt.c
//
// TITLE: Ethernet Low Latency Interrupt Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet Low Latency Interrupt </h1>
//!
//! This example demonstrates the steps to be followed in using the
//! Ethernet of the Communication Manager Subsystem to handle
//! the Ethernet transmit,receive with minimum latency interrupts.
//! The example interrupt handlers provided in the Ethernet driver
//! help to achieve user friendly buffer management and the generic interrupt
//! handler handles different interrupt sources, these factors might be more
//! cycle consuming. This example demonstrates how to achieve lowest possible
//! latency with interrupts and buffer management with the Ethernet Driver.
//! Before running this Communication Manager code the C28x cpu1 code has to be
//! run to configure the clocks to Communication manager
//! and required IO pads for Ethernet module
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in Internal Loop back mode
//! and hence needs no external connection on the MII Data lines.
//! But it needs the MII Tx and Rx clocks to be input on those pins
//! Refer to the C28x CPU1 code of ethernet_config_c28x project
//! for which GPIOs are used for connecting to the PHY
//!
//! \b Watch \b Variables \n
//! - genericISRCount
//! - transmitISRCount
//! - receiveISRCount
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Included Files
//
#include "driverlib_cm.h"
#include "cm.h"
//
// Defines
//
#define PACKET_LENGTH 508
#define NUM_PACKETS 4
//
// Globals
//
static Ethernet_Handle emac_handle;
uint8_t pData[PACKET_LENGTH];
uint8_t rxBuffer[NUM_PACKETS*PACKET_LENGTH];
//
// The Descriptor Ring can be organized as
// Descriptors for TX Channel 0
// Descriptors for TX Channel 1
// Descriptors for RX Channel 0
// Descriptors for RX Channel 1
// Use the Descriptor pool in driver
//
extern Ethernet_HW_descriptor Ethernet_descArray[ETHERNET_DESCRIPTORS_NUM];
uint8_t indexWriteTx=0;
uint8_t indexMaxTx = ETHERNET_DESCRIPTORS_NUM_TX_PER_CHANNEL;
uint8_t indexReadTx=0;
uint8_t indexMaxRx=
(ETHERNET_DESCRIPTORS_NUM_TX+ETHERNET_DESCRIPTORS_NUM_RX_PER_CHANNEL);
uint8_t indexWriteRx=0;
uint8_t indexReadRx=0;
uint8_t buffIndex=0;
uint32_t genericISRCount,transmitISRCount, receiveISRCount,getBufferCount;
//
//This is a temporary Packet Descriptor passed to the
//Low level driver it is not linked by the driver
//
Ethernet_Pkt_Desc tempDescriptor;
Ethernet_Pkt_Desc *getPacketBuffer(void);
//
//This is a light weight implementation for sending a packet over Ethernet
//It does not maintain any software queue for the packets
//
void SendPacket(uint8_t *pData,uint32_t length)
{
Ethernet_descArray[indexWriteTx].des0 = (uint32_t)pData;
Ethernet_descArray[indexWriteTx].des1 = 0;
Ethernet_descArray[indexWriteTx].des2 = (ETHERNET_TX_DESC_IOC|length);
Ethernet_descArray[indexWriteTx].des3 = (ETHERNET_DESC_OWNER |
ETHERNET_PKT_FLAG_SOP |
ETHERNET_PKT_FLAG_EOP);
Ethernet_writeTxDescTailPointer(EMAC_BASE,
ETHERNET_DMA_CHANNEL_NUM_0,
(Ethernet_HW_descriptor *)
(&Ethernet_descArray[indexWriteTx]));
//
//End check for last descriptor
//
if(++indexWriteTx == ETHERNET_DESCRIPTORS_NUM_TX_PER_CHANNEL)
{
indexWriteTx = 0;
}
}
//
//Transmit interrupt handler only increments the book keeping variable
//and clears the interrupt can be modified as per needs
//
interrupt void transmitISR(void)
{
transmitISRCount++;
Ethernet_clearDMAChannelInterrupt(
EMAC_BASE,
ETHERNET_DMA_CHANNEL_NUM_0,
ETHERNET_DMA_CH0_STATUS_TI
);
}
//
//Receive interrupt handler called when complete packet is received
//
interrupt void receiveISR(void)
{
Ethernet_Pkt_Desc *ptrNewPacket=NULL;
//
//Clear the interrupt
//
Ethernet_clearDMAChannelInterrupt(EMAC_BASE,
ETHERNET_DMA_CHANNEL_NUM_0,
ETHERNET_DMA_CH0_STATUS_RI);
//
// Callback - Invoke any application specific callback here
//Just incrementing the indexRead here we are not consuming the buffers here
//
if(++indexReadRx >= (ETHERNET_DESCRIPTORS_NUM_TX +
ETHERNET_DESCRIPTORS_NUM_RX_PER_CHANNEL))
{
indexReadRx = ETHERNET_DESCRIPTORS_NUM_TX;
}
//
//Refill the packet buffer
//
if(Ethernet_descArray[indexReadRx].des3 & ETHERNET_DESC_OWNER )
{
ptrNewPacket = getPacketBuffer();
Ethernet_descArray[indexWriteRx].des0 =
(uint32_t)ptrNewPacket->dataBuffer;
Ethernet_descArray[indexWriteRx].des1 =0;
Ethernet_descArray[indexWriteRx].des2 = 0;
Ethernet_descArray[indexWriteRx].des3 = (ETHERNET_DESC_OWNER |
ETHERNET_RX_DESC_IOC |
ETHERNET_RX_DESC_BUF1_VALID);
if(++indexWriteRx == ETHERNET_DESCRIPTORS_NUM_TX +
ETHERNET_DESCRIPTORS_NUM_RX_PER_CHANNEL)
{
indexWriteRx = ETHERNET_DESCRIPTORS_NUM_TX;
}
}
receiveISRCount++;
}
void IntermediateFragmentCallback(uint8_t segmentnumber)
{
//
//Add contents here to service the received chunk (of partial packet)
//
}
//
//This generic ISR handles only the Early Rx completion interrupt
//If Early Transmit interrupt needs to be handled it can be added here as well
//
interrupt void genericISR(void)
{
uint16_t fragNumber;
genericISRCount++;
//
//Get the count of how many chunks of packets have come in
//If the Progammable Buffer length 32 bytes
//In threshold mode for each 32 bytes of DMA an early Rx interrupt
//is asserted by hardware which is serviced in this Generic ISR
//
fragNumber = Ethernet_getRxERICount(
EMAC_BASE,
ETHERNET_DMA_CHANNEL_NUM_0);
//
//Callback for signalling the arrival of chunk
//
IntermediateFragmentCallback(fragNumber);
//
//Clear the interrupts at hardware
//
Ethernet_clearDMAChannelInterrupt(
EMAC_BASE,
ETHERNET_DMA_CHANNEL_NUM_0,
ETHERNET_DMA_CH0_STATUS_ETI |
ETHERNET_DMA_CH0_STATUS_AIS);
Ethernet_clearDMAChannelInterrupt(
EMAC_BASE,
ETHERNET_DMA_CHANNEL_NUM_0,
ETHERNET_DMA_CH0_STATUS_ERI | ETHERNET_DMA_CH0_STATUS_NIS);
}
//
//This is a simple implementation of Buffer management it returns
//a new buffer pointer from the given packet buffer pool
//
Ethernet_Pkt_Desc *getPacketBuffer(void)
{
tempDescriptor.dataBuffer = &rxBuffer[buffIndex++ * PACKET_LENGTH];
if(buffIndex == NUM_PACKETS)
{
buffIndex= 0;
}
getBufferCount++;
return &tempDescriptor;
}
main(void)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
Ethernet_InitConfig *pInitCfg;
uint32_t i;
//
// Initialize device clock and peripherals
//
CM_init();
//
//Initialize the indexes for Descriptor Ring access
//
indexMaxTx = ETHERNET_DESCRIPTORS_NUM_TX_PER_CHANNEL;
indexMaxRx = ETHERNET_DESCRIPTORS_NUM_TX +
ETHERNET_DESCRIPTORS_NUM_RX_PER_CHANNEL;
indexWriteTx= indexReadTx = 0;
indexWriteRx = indexReadRx = ETHERNET_DESCRIPTORS_NUM_TX;
//
//Book keeping Watch variables initialized to zero
//
genericISRCount = transmitISRCount = receiveISRCount= getBufferCount= 0;
//
//Form the Packet in Memory
//
for(i=0;i<PACKET_LENGTH/4;i++)
{
if(i == 0)
*((uint32_t *)pData + i) = 0x01020304;
else if(i == 1)
*((uint32_t *)pData + i) = 0xFFFF0506;
else
HWREG((uint32_t *)pData +i) = 0xFFFFFFFF;
}
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable =
&Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable =
&Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
Ethernet_getInitConfig(pInitCfg);
pInitCfg->numChannels = 1;
for(i=0;i<pInitCfg->numChannels;i++)
{
//
//Configure the TX in Threshold mode
//
pInitCfg->chInfo[ETHERNET_CH_DIR_TX][i].storeNForward = \
ETHERNET_MTL_TXQ_OPMODE_TSF_DISABLE;
pInitCfg->chInfo[ETHERNET_CH_DIR_TX][i].dmaQueueSize =
ETHERNET_MTL_Q_OP_MODE_QSIZE_2048;
//
//Configure the IP in threshold mode
//For the RX Size
//
pInitCfg->chInfo[ETHERNET_CH_DIR_RX][i].storeNForward =
ETHERNET_MTL_RX_Q_OP_MODE_RSF_DISABLE;
}
//
//Enable the Loopback mode of MAC
//
pInitCfg->loopbackMode = ETHERNET_MAC_CONFIGURATION_LM_LOOPBACK_ENABLED;
pInitCfg->dmaMode.InterruptMode = ETHERNET_DMA_MODE_INTM_MODE1;
//
//We are implementing our own ISR and hence this callback is not needed
//
pInitCfg->pfcbRxPacket = NULL;
pInitCfg->pfcbGetPacket = &getPacketBuffer;
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Register the interrupt handlers and enable interrupts
//
Interrupt_registerHandler(INT_EMAC_TX0, transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, receiveISR);
Interrupt_registerHandler(INT_EMAC, genericISR);
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
Interrupt_enable(INT_EMAC);
//
//Enable Early receive and Early Transmit interrupts
//Abnormal interrupt is to be enabled for Early recive handling
//
Ethernet_enableDmaInterrupt(EMAC_BASE,
0,
(ETHERNET_DMA_CH0_INTERRUPT_ENABLE_AIE |
ETHERNET_DMA_CH0_INTERRUPT_ENABLE_ETIE |
ETHERNET_DMA_CH0_INTERRUPT_ENABLE_ERIE));
Ethernet_setDMAChannelTransmitStart(EMAC_BASE,ETHERNET_DMA_CHANNEL_NUM_0);
SendPacket(pData,PACKET_LENGTH);
while(1);
}
@@ -0,0 +1,244 @@
//#############################################################################
//
// FILE: ethernet_ex1_basic_tx_rx_loopback.c
//
// TITLE: Ethernet Basic Transmit and Receive MAC Loopback Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet MAC Internal Loopback </h1>
//!
//! This example demonstrates the steps to be followed in using the
//! Ethernet of the Communication Manager Subsystem to initialize
//! the Ethernet module and Configure the module in MAC Loop back mode
//! Prepares a packet to be sent, Sends the packet and reads the statistics
//! to check if the packet is received by the module
//! Before running this Communication Manager code the C28x cpu1 code has to be run
//! to configure the clocks to Communication manager
//! and required IO pads for Ethernet module
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in Internal Loop back mode
//! and hence needs no external connection on the MII Data lines.
//! But it needs the MII Tx and Rx clocks to be input on those pins
//! Refer to the C28x CPU1 code of ethernet_config_c28x project
//! for which GPIOs are used for connecting to the PHY
//!
//! \b Watch \b Variables \n
//! - None
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Included Files
//
#include "driverlib_cm.h"
#include "cm.h"
//
// Defines
//
#define PACKET_LENGTH 132
#define ETHERNET_NO_OF_RX_PACKETS 1U
//
//Change this define for changing Packet buffer length
//
#define ETHERNET_MAX_PACKET_LENGTH 1538U
//
// Globals
//
uint8_t pData[PACKET_LENGTH];
//
// Globals
//
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
//
// Main
//
void main(void)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
Ethernet_InitConfig *pInitCfg;
Ethernet_Pkt_Desc pktDesc;
uint32_t i;
Ethernet_Statistics stats;
Ethernet_Handle emac_handle;
//
// Initialize device clock and peripherals
//
CM_init();
//
//Form the unicast Packet in Memory
//
for(i=0;i<PACKET_LENGTH/4;i++)
{
//
//First 6 bytes of the packet are the MAC Destination Address
//Bytes, the Destination and CRC shall be inserted by the hardware
//
if(i == 0)
*((uint32_t *)pData + i) = 0x01020304;
else if(i == 1)
*((uint32_t *)pData + i) = 0xFFFF0506;
else
HWREG((uint32_t *)pData +i) = 0xFFFFFFFF;
}
//
//Select the MII interface of the module
//
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
//
// Get an initial configuration of known good parameters
//
Ethernet_getInitConfig(pInitCfg);
//
//Configure the Loopback mode
//
pInitCfg->loopbackMode = ETHERNET_MAC_CONFIGURATION_LM_LOOPBACK_ENABLED;
//
//Assign the callbacks for Getting packet buffer when needed
//Releasing the TxPacketBuffer on Transmit interrupt callbacks
//Receive packet callback on Receive packet completion interrupt
//
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBuffer;
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBuffer;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallback;
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
//
//The Application handle is not used by this application
//Hence using a dummy value of 1
//
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
//
//Prepare a Packet Descriptor structure to send a packet
//This contains a single buffer packet
//The Source address shall be inserted by the MAC
//Packet CRC is auto computed by the module and appended in the packet
//
pktDesc.bufferLength = PACKET_LENGTH;
pktDesc.dataOffset = 0;
pktDesc.dataBuffer = pData;
pktDesc.nextPacketDesc = 0;
pktDesc.flags = ETHERNET_PKT_FLAG_SOP |ETHERNET_PKT_FLAG_EOP|ETHERNET_PKT_FLAG_SA_INS;
pktDesc.pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
pktDesc.pktLength = PACKET_LENGTH;
pktDesc.validLength = PACKET_LENGTH;
pktDesc.numPktFrags = 1;
//
//Send the packet prepared
//
Ethernet_sendPacket(emac_handle,&pktDesc);
//
//Delay for the MAC to send the packet on the wire and receive it
//
SysCtl_delay(3000);
//
//Read the statistics of the Module
//
Ethernet_getStatistics(emac_handle, &stats);
//
//Check if a packet has been received
//
if(!stats.rxUnicastPacketsGood)
__asm(" bkpt #0");
}
@@ -0,0 +1,276 @@
//#############################################################################
//
// FILE: ethernet_ex2_phy_loopback.c
//
// TITLE: Ethernet Basic Transmit and Receive External (PHY) Loopback Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet Basic Transmit and Receive PHY Loopback </h1>
//!
//! This example demonstrates the steps to be followed in using the
//! Ethernet of the Communication Manager Subsystem to initialize
//! the Ethernet module and Configure the module in External Loop back mode
//! the packet is looped back at external PHY.
//! Prepares a packet to be sent, Sends the packet and reads the staticstics
//! to check if the packet is received by the module
//! Before running this Communication Manager code the C28x cpu1 code has to be run
//! to configure the clocks to Communication manager
//! and required IO pads for Ethernet module
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in External Loop back mode (at PHY)
//! and hence needs external connection to the PHY on the MII interface and
//! also the MDIO Pins connected to the PHY. This example assumes DP83822 PHY
//! for the PHY configurations if a different PHY is used the sequences might change
//! Refer to the C28x CPU1 code of ethernet_config_c28x project
//! for which GPIOs are used for connecting to the PHY
//!
//! \b Watch \b Variables \n
//! - phyRegContent variable can be checked to know if PHY register
//! read,write is working correctly
//! - stats to know if the packet is received correctly after loopback
//! at PHY side
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Included Files
//
#include "driverlib_cm.h"
#include "cm.h"
//
// Defines
//
#define PACKET_LENGTH 132
#define ETHERNET_NO_OF_RX_PACKETS 1U
//
//Change this define for changing Packet buffer length
//
#define ETHERNET_MAX_PACKET_LENGTH 1538U
//
// Globals
//
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
uint8_t pData[PACKET_LENGTH];
//
// Main
//
void main(void)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
Ethernet_InitConfig *pInitCfg;
Ethernet_Pkt_Desc pktDesc;
uint32_t i;
Ethernet_Statistics stats;
Ethernet_Handle emac_handle;
uint16_t phyRegContent=0;
//
// Initialize device clock and peripherals
//
CM_init();
//
//Form the unicast Packet in Memory
//
for(i=0;i<PACKET_LENGTH/4;i++)
{
//
//First 6 bytes of the packet are the MAC Destination Address
//Bytes, the Destination and CRC shall be inserted by the hardware
//
if(i == 0)
*((uint32_t *)pData + i) = 0x01020304;
else if(i == 1)
*((uint32_t *)pData + i) = 0xFFFF0506;
else
HWREG((uint32_t *)pData +i) = 0xFFFFFFFF;
}
//
//Select the MII interface of the module
//
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
//
// Get an initial configuration of known good parameters
//
Ethernet_getInitConfig(pInitCfg);
//
//Assign the callbacks for Getting packet buffer when needed
//Releasing the TxPacketBuffer on Transmit interrupt callbacks
//Receive packet callback on Receive packet completion interrupt
//
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBuffer;
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBuffer;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallback;
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
//
//The Application handle is not used by this application
//Hence using a dummy value of 1
//
Ethernet_getHandle((Ethernet_Handle) 1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
//
//Low Frequency
//value of 5 for selecting the slowest possible MDIO Clock
//Clause 22 mode
//
Ethernet_configureMDIO(EMAC_BASE,0,5,0);
//
//The DP83822 External PHY in Control Card
//takes a PHY address of 1 by default
//Configure the MDIO module to use PHY address of 0x1
//
Ethernet_configurePHYAddress(EMAC_BASE,1);
//
//Address 0 of PHY corresponds to Basic Mode Control Register(BMCR)
//Read the register to know the state
//
phyRegContent= Ethernet_readPHYRegister(EMAC_BASE,0);
//
//Bit 14 of BMCR configures the MII Loopback
//
phyRegContent |= 0x4000;
Ethernet_writePHYRegister(EMAC_BASE,0,phyRegContent);
//
//Read back the BMCR register to confirm that the MII Loopback
//is configured properly
//
phyRegContent= Ethernet_readPHYRegister(EMAC_BASE,0);
//
//Prepare a Packet Descriptor structure to send a packet
//This contains a single buffer single packet
//The Source address shall be inserted by the MAC
//Packet CRC is auto computed by the module and appended in the packet
//
pktDesc.bufferLength = PACKET_LENGTH;
pktDesc.dataOffset = 0;
pktDesc.dataBuffer = pData;
pktDesc.nextPacketDesc = 0;
pktDesc.flags = ETHERNET_PKT_FLAG_SOP |ETHERNET_PKT_FLAG_EOP|ETHERNET_PKT_FLAG_SA_INS;
pktDesc.pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
pktDesc.pktLength = PACKET_LENGTH;
pktDesc.validLength = PACKET_LENGTH;
pktDesc.numPktFrags = 1;
//
//Send the packet prepared
//
Ethernet_sendPacket(emac_handle,&pktDesc);
//
//Delay for the MAC to send the packet on the wire and receive it
//
SysCtl_delay(3000);
//
//Read the statistics of the Module
//
Ethernet_getStatistics(emac_handle, &stats);
//
//Check if a packet has been received
//
if(!stats.rxUnicastPacketsGood)
__asm(" bkpt #0");
}
@@ -0,0 +1,394 @@
//#############################################################################
//
// FILE: ethernet_ex3_threshold_mode_phy_loopback.c
//
// TITLE: Ethernet Threshold Mode Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet Threshold mode with level PHY loopback </h1>
//!
//! This example demonstrates the steps to be followed in using the
//! Ethernet of the Communication Manager Subsystem to initialize
//! the Ethernet module in Threshold mode
//! It Configures the module in MII External Loop back mode in which
//! the packet is looped back at external PHY.
//! Prepares a packet to be sent, Sends the packet and reads the staticstics
//! to check if the packet is received by the module
//! It configures the Transmit and Receive queues of Ethernet DMA
//! in Threshold mode.
//! The Transmit threshold mode generates early
//! transmit interrupts when each buffer is transmitted from the memory
//! into the transmit FIFO. The Buffer can be reclaimed by the application.
//! The Receive threshold mode generates early receive interrupts
//! where the module generates Early receive interrupts when programmed
//! threshold buffer size is transferred into receive buffer memory from
//! the receive FIFO.
//! This will be of use when dealing with Time critical receive paths
//! where the application can consume the packets at programmed burstLength
//! unlike the conventional Store and Forward mode(Default) where the module
//! generates the interrupts when the complete packet is transmitted on the Line
//! and when the complete packet is received and checksum validation is succesful
//! This example provides a starting point for configuring the threshold mode.
//! Refer to the Driver API guide for the different callbacks available in the driver.
//! It uses the example Interrupt Service Routines provided in the driver library.
//! Users can modify those ISRs or write another as per their need.
//! Before running this Communication Manager code the C28x cpu1 code has to be run
//! to configure the clocks to Communication manager and required IO pads for Ethernet module
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in External Loop back mode (at PHY)
//! and hence needs external connection to the PHY on the MII interface and
//! also the MDIO Pins connected to the PHY. This example assumes DP83822 PHY
//! for the PHY configurations if a different PHY is used the sequences might change.
//! Refer to the C28x CPU1 code of ethernet_config_c28x project
//! for which GPIOs are used for connecting to the PHY
//!
//! \b Watch \b Variables \n
//! - phyRegContent variable can be checked to know if PHY register
//! read,write is working correctly
//! - Ethernet_txInterruptCount - this variable available in driver library
//! provides a count of number of times Transmit completion interrupt
//! (on full packet transmission onto the line) occured
//! - Ethernet_rxInterruptCount - this variable provides a count of
//! number of times the complete Receive completion interrupt occured
//! - Ethernet_earlyRxInterruptCount - the number of times the early
//! receive interrupt occured. This depends on the burstLength configured
//! - Ethernet_earlyTxInterruptCount - the number of times the early
//! transmit interrupt occured. This depends on the number of fragments of the
//! packets transmitted
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Included Files
//
#include "driverlib_cm.h"
#include "cm.h"
//
// Defines
//
#define PACKET_LENGTH 1508
#define NUM_PACKETS 1
#define ETHERNET_NO_OF_RX_PACKETS 1U
//
//Change this define for changing Packet buffer length
//
#define ETHERNET_MAX_PACKET_LENGTH 1538U
//
// Globals
// We are dividing the packet into two fragments
// For demonstration we are using two different buffers
//
uint8_t pData[PACKET_LENGTH/2];
uint8_t pData2[PACKET_LENGTH/2];
//
// Globals
//
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
//
// Main
//
void main(void)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
Ethernet_InitConfig *pInitCfg;
Ethernet_Pkt_Desc pktDesc[2];
uint32_t i;
Ethernet_Handle emac_handle;
uint16_t phyRegContent=0;
//
// Initialize device clock and peripherals
//
CM_init();
//
//Form the unicast Packet in Memory
//First 6 bytes of the packet are the MAC Destination Address
//Bytes, the Destination and CRC shall be inserted by the hardware
//
for(i=0;i<PACKET_LENGTH/4;i++)
{
if(i == 0)
*((uint32_t *)pData + i) = 0x01020304;
else if(i == 1)
*((uint32_t *)pData + i) = 0xFFFF0506;
else
HWREG((uint32_t *)pData +i) = 0xFFFFFFFF;
}
//
//Second Fragment shall not contain MAC header but just data
//
for(i=0;i<PACKET_LENGTH/8;i++)
{
HWREG((uint32_t *)pData2 +i) = 0xFFFFFFFF;
}
//
//Select the MII interface of the module
//
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
//
// Get an initial configuration of known good parameters
//
Ethernet_getInitConfig(pInitCfg);
//
//Configure a single channel for Tx and Rx
//
pInitCfg->numChannels = 1;
//
// The default mode chosen by getInitConfig shall be Store and Forward
//In that mode the interrupts are generated when the complete packet is sent out
//on the line and received on the line in Receive side
//
for(i=0;i<pInitCfg->numChannels;i++)
{
//
//Configure the TX Queue in Threshold mode
//Disabling Store and Forward mode will configure Threshold mode
//
pInitCfg->chInfo[ETHERNET_CH_DIR_TX][i].storeNForward =
ETHERNET_MTL_TXQ_OPMODE_TSF_DISABLE;
//
//Configure the Rx Queue in threshold mode
//Disabling Store and Forward mode will configure Threshold mode
//
pInitCfg->chInfo[ETHERNET_CH_DIR_RX][i].storeNForward =
ETHERNET_MTL_RX_Q_OP_MODE_RSF_DISABLE;
//
//Burst Length is the number of beats(32 bits/one word)
//Configuring 32 burstLength will generate an interrupt for every
//128 bytes of data pushed into Receive Queue from the Rx line
//Please program this to a value based on the ISR latency for the
//Ethernet Combined Interrupt (SBD) handler.The value of 32 is
//chosen based on the interrrupt handler example provided in the
//driver library
//
pInitCfg->chInfo[ETHERNET_CH_DIR_RX][i].burstLength = 32;
}
//
//Assign the callbacks for Getting packet buffer when needed
//Releasing the TxPacketBuffer on Transmit interrupt callbacks
//Receive packet callback on Receive packet completion interrupt
//
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBuffer;
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBuffer;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallback;
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
//
//Get the handle for the module configured with the
//chosen parameters as configured above in addition
//to default parameters
//The Application handle is not used by this application
//Hence using a dummy value of 1
//
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
Interrupt_registerHandler(INT_EMAC, Ethernet_genericISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
Interrupt_enable(INT_EMAC);
//
//For Channel 0
//Enable the Abnormal Interrupt
//The Early Transmit interrupt and Early Receive interrupt
//which are key for handling Threshold mode of the module
//By default these interrupts are not enabled in the driver
//Generic SBD interrupt shall be generated for these events
//For this example we are relying on the example ISR provided by
//the Low level driver
//
Ethernet_enableDmaInterrupt(EMAC_BASE,
0,
ETHERNET_DMA_CH0_INTERRUPT_ENABLE_AIE
|ETHERNET_DMA_CH0_INTERRUPT_ENABLE_ETIE
|ETHERNET_DMA_CH0_INTERRUPT_ENABLE_ERIE);
//
//Low Frequency
//value of 5 for selecting the slowest possible MDIO Clock
//Clause 22 mode
//
Ethernet_configureMDIO(EMAC_BASE,0,5,0);
//
//The DP83822 External PHY in Control Card
//takes a PHY address of 1 by default
//Configure the MDIO module to use PHY address of 0x1
//
Ethernet_configurePHYAddress(EMAC_BASE,1);
//
//Address 0 of PHY corresponds to Basic Mode Control Register(BMCR)
//Read the register to know the state
//
phyRegContent= Ethernet_readPHYRegister(EMAC_BASE,0);
//
//Bit 14 of BMCR configures the MII Loopback
//
phyRegContent |= 0x4000;
Ethernet_writePHYRegister(EMAC_BASE,0,phyRegContent);
//
//Read back the BMCR register to confirm that the MII Loopback
//is configured properly
//
phyRegContent= Ethernet_readPHYRegister(EMAC_BASE,0);
//
//Prepare a Packet Descriptor structure to send a packet
//This contains a single buffer single packet
//The Source address shall be inserted by the MAC
//Packet CRC is auto computed by the module and appended in the packet
//
//In Threshold mode Transmit side the MAC shall generate early interrupt
//as when the buffer is pushed into the FIFO by the internal DMA
//the buffer can be reclaimed by the application
//With the first interrupt the buffer 0 can be reclaimed
//For the second interrupt the buffer 1 can be reclaimed by the application
//
pktDesc[0].bufferLength = PACKET_LENGTH/2;
pktDesc[0].dataOffset = 0;
pktDesc[0].dataBuffer = pData;
//
//Point to the next descriptor for forming a chain
//
pktDesc[0].nextPacketDesc =&pktDesc[1];
//
//This fragment has only SOP EOP shall be in next fragment
//
pktDesc[0].flags = ETHERNET_PKT_FLAG_SOP ;
pktDesc[0].pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
pktDesc[0].pktLength = PACKET_LENGTH;
pktDesc[0].validLength = PACKET_LENGTH/2;
//
//This packet is split into two fragments
//
pktDesc[0].numPktFrags = 2;
pktDesc[1].bufferLength = PACKET_LENGTH/2;
pktDesc[1].dataOffset = 0;
pktDesc[1].dataBuffer = pData2;
pktDesc[1].nextPacketDesc =0;
pktDesc[1].flags = ETHERNET_PKT_FLAG_EOP;
pktDesc[1].pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
pktDesc[1].pktLength = PACKET_LENGTH;
pktDesc[1].validLength = PACKET_LENGTH/2;
//
//Send the packet prepared
//
Ethernet_sendPacket(emac_handle,&pktDesc[0]);
//
//Transmit Path Interrupts:
//While the packet is being sent we should observe two early Transmit interrupts
//and one transmit completion interrupt when the packet is completely transferred
//on the wire
//On the Receive Side:
//As and when the burstLength*4 bytes are transferred from the line to the
//Memory by the Ethernet DMA there will be an early interrupt
//
while(1);
}
@@ -0,0 +1,907 @@
//#############################################################################
//
// FILE: ethernet_ex4_ptp_basic_master.c
//
// TITLE: Ethernet PTP Basic Master Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet PTP Basic Master </h1>
//!
//! This example configures the device in IEEE PTPv2 Master mode and then
//! periodically sends Sync packets to the slave. On receiving the DelayReq
//! packets from the slave, the master also sends out the DelayResp packets.
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in PTP Basic Master mode.
//! The example project \e Ethernet \e PTP \e Basic \e Slave is intended to
//! be used along with this project to see the whole PTP Protocol state in
//! action. The second device is configured as \e Slave and both devices in
//! conjunction exchange Sync, DelayReq and DelayResp packets.
//!
//! Refer to the C28x CPU1 code of ethernet_config_c28x project for configuring
//! the PTP clock that drives the system time counter on the Ethernet module.
//!
//! \b Watch \b Variables \n
//! - gPtpMasterState
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
#include "driverlib_cm.h"
#include "string.h"
#include "cm.h"
//
// This frequency is actually set in the c28x side code. If it is changed
// there, then the following value also needs to be updated since the
// timestamping module is initialized with the following values.
// Default value is 100 MHz.
//
#define PTP_REF_CLOCK_FREQ 100000000
#define PTP_REF_CLOCK_PERIOD 1000000000/PTP_REF_CLOCK_FREQ
static Ethernet_Handle emac_handle;
#define PACKET_LENGTH 200
#define ETHERNET_NO_OF_RX_PACKETS 8U
#define ETHERNET_MAX_PACKET_LENGTH PACKET_LENGTH
#define NUM_PACKET_DESC_RX_APPLICATION 8U
#define PTP_HEADER_OFFSET 14U
uint32_t Ethernet_numRxCallbackCustom = 0;
uint32_t releaseTxCount = 0;
Ethernet_Pkt_Desc pktDescriptorRXCustom[NUM_PACKET_DESC_RX_APPLICATION];
extern uint32_t Ethernet_numGetPacketBufferCallback;
extern Ethernet_Device Ethernet_device_struct;
uint8_t gMsgBuf[PACKET_LENGTH] = {0};
Ethernet_Pkt_Desc gPktDesc;
//
// Globals
//
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
// Network related definitions as follows
//
//
// Taking care of network byte order conversions using these macros.
//
#define PP_HTONS(x) ((uint16_t)((((x) & (uint16_t)0x00ffU) << 8) | \
(((x) & (uint16_t)0xff00U) >> 8)))
#define PP_NTOHS(x) PP_HTONS(x)
#define PP_HTONL(x) ((((x) & (uint32_t)0x000000ffUL) << 24) | \
(((x) & (uint32_t)0x0000ff00UL) << 8) | \
(((x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((x) & (uint32_t)0xff000000UL) >> 24))
#define PP_NTOHL(x) PP_HTONL(x)
#define flip16(x) PP_HTONS(x)
#define flip32(x) PP_HTONL(x)
//
// Following definitions and prototypes are specific to the PTP state machine
// and have been adapted from the IEEE 1588 standard spec.
//
#define PTP_TWO_STEP 0x02
#define PTP_UUID_LENGTH 6
#define CLOCK_IDENTITY_LENGTH 8
#define FLAG_FIELD_LENGTH 2
#define HEADER_LENGTH 34
#define ANNOUNCE_LENGTH 64
#define SYNC_LENGTH 44
#define FOLLOW_UP_LENGTH 44
#define PDELAY_REQ_LENGTH 54
#define DELAY_REQ_LENGTH 44
#define DELAY_RESP_LENGTH 54
#define PDELAY_RESP_LENGTH 54
#define PDELAY_RESP_FOLLOW_UP_LENGTH 54
#define MANAGEMENT_LENGTH 48
typedef enum {FALSE=0, TRUE} Boolean;
typedef char Octet;
typedef signed char Integer8;
typedef signed short Integer16;
typedef signed int Integer32;
typedef unsigned char UInteger8;
typedef unsigned short UInteger16;
typedef unsigned int UInteger32;
typedef unsigned short Enumeration16;
typedef unsigned char Enumeration8;
typedef unsigned char Enumeration4;
typedef unsigned char UInteger4;
typedef unsigned char Nibble;
//
// brief Implementation specific of Integer64 type
//
typedef struct {
unsigned int lsb;
int msb;
} Integer64;
typedef struct {
unsigned int lsb;
unsigned short msb;
} UInteger48;
typedef struct {
UInteger48 secondsField;
UInteger32 nanosecondsField;
} Timestamp;
//
// brief Time structure to handle Linux time information
//
typedef struct {
Integer32 seconds;
Integer32 nanoseconds;
} TimeInternal;
//
// brief The ClockIdentity type identifies a clock
//
typedef Octet ClockIdentity[CLOCK_IDENTITY_LENGTH];
//
// brief The PortIdentity identifies a PTP port.
//
typedef struct {
ClockIdentity clockIdentity;
UInteger16 portNumber;
} PortIdentity;
//
// brief The common header for all PTP messages (Table 18 of the spec)
//
//
// Message header
//
typedef struct {
Nibble transportSpecific;
Enumeration4 messageType;
UInteger4 versionPTP;
UInteger16 messageLength;
UInteger8 domainNumber;
Octet flagField[2];
Integer64 correctionfield;
PortIdentity sourcePortIdentity;
UInteger16 sequenceId;
UInteger8 controlField;
Integer8 logMessageInterval;
} MsgHeader;
typedef struct
{
PortIdentity portIdentity;
Octet port_uuid_field[PTP_UUID_LENGTH];
Timestamp syncTimestamp;
Timestamp delayReqRecvTimestamp;
uint16_t syncSeqId;
uint16_t portNumber;
Boolean syncTimestampAvailable;
Boolean sendingDelayResp;
MsgHeader delayReqHeader;
} PTPMasterState;
PTPMasterState gPtpMasterState = {0};
//
// brief PTP Messages
//
enum {
SYNC=0x0,
DELAY_REQ=0x1,
FOLLOW_UP = 0x8,
DELAY_RESP = 0x9,
};
//
// Function prototypes used in this example
//
void fromInternalTime(TimeInternal * internal, Timestamp * external);
void msgPackHeader(Octet * buf, PTPMasterState *ptpMasterState);
void msgPackSync(Octet * buf, PTPMasterState *ptpMasterState);
void msgPackFollowUp(Octet * buf, PTPMasterState *ptpMasterState);
void msgPackDelayResp(Octet * buf, PTPMasterState *ptpMasterState);
void msgUnpackHeader(Octet * buf, MsgHeader * header);
void InitConstants(PTPMasterState *ptpMasterState);
void sendMessage(Octet * msg,
uint32_t messageType,
PTPMasterState * ptpMasterState,
Ethernet_Pkt_Desc * pktDesc);
Ethernet_Pkt_Desc* Ethernet_getPacketBufferCustom(void);
Ethernet_Pkt_Desc* Ethernet_receivePacketCallbackCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket);
void Ethernet_releaseTxPacketBufferCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket);
main(void)
{
Ethernet_InitConfig *pInitCfg;
uint32_t i;
uint32_t varPtpConfig = 0;
Ethernet_InitInterfaceConfig initInterfaceConfig;
uint32_t timeSec;
uint32_t timeNanosec;
float subSecondInc;
//
// Initialize device clock and peripherals
//
CM_init();
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
Ethernet_getInitConfig(pInitCfg);
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBufferCustom;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallbackCustom;
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBufferCustom;
varPtpConfig = (0 << ETHERNET_MAC_TIMESTAMP_CONTROL_SNAPTYPSEL_S) |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSCTRLSSR |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSMSTRENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSEVNTENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSVER2ENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSIPENA;
//
// Subsecond increment is added to the systime counter every ptp clock tick
// hence for Digital rollover, it is simply the time period of the clock
// tick.
//
subSecondInc = PTP_REF_CLOCK_PERIOD;
Ethernet_setConfigTimestampPTP(EMAC_BASE, varPtpConfig, subSecondInc);
Ethernet_enableSysTimePTP(EMAC_BASE);
//
// Start the system with a random value.
//
Ethernet_setSysTimePTP(EMAC_BASE, 0x4132EDCA, 0x25a5a5a5);
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
Ethernet_setMACAddr(EMAC_BASE,
0,
0x00000506U,
0x01030304U,
ETHERNET_CHANNEL_0);
//
// We need to program this standard multicast address so that this device
// identifies PTP over Ethernet packets correctly. "01:1B:19:00:00:00"
//
Ethernet_setMACAddr(EMAC_BASE,
1,
0x00000000,
0x00191B01,
ETHERNET_CHANNEL_0);
Ethernet_selectTargetInterruptOrPulsePPS(
EMAC_BASE,
ETHERNET_MAC_PPS_OUT_INSTANCE_0,
ETHERNET_MAC_PPS_CONTROL_TRGTMODSEL_INTERRUPT);
//
// We need to set a standard defined Multicast address : 01:1B:19:00:00:00
// as the Destination address in the ethernet frame and that is how the
// receiver will recognize it as a valid PTP over Ethernet packet.
//
i=0; *((uint32_t *)gMsgBuf + i) = 0x00191B01;
i++; *((uint32_t *)gMsgBuf + i) = 0xF7880000;
InitConstants(&gPtpMasterState);
while(1)
{
//
// Use the system time counter to send the sync + followup messages
// every one second.
//
Ethernet_getSysTimePTP(EMAC_BASE, &timeSec, &timeNanosec);
Ethernet_setTargetTimePPS(EMAC_BASE, ETHERNET_MAC_PPS_OUT_INSTANCE_0,
timeSec + 1, timeNanosec);
//
// Waiting till the target time that we set above is reached.
// We're using the PPSOUT instance 0 as the timer.
//
while(((HWREG(EMAC_BASE + ETHERNET_O_MAC_TIMESTAMP_STATUS)) &
(ETHERNET_MAC_TIMESTAMP_STATUS_TSTARGT0)) == 0);
//
// Save the state. We want to capture the timestamp of the next SYNC
// packet that is being sent.
//
gPtpMasterState.syncTimestampAvailable = FALSE;
//
// Send out the SYNC packet.
//
sendMessage((Octet *)gMsgBuf, SYNC, &gPtpMasterState, &gPktDesc);
//
// Wait till the latest sync timestamp is captured. As soon as the
// timestamp for the SYNC packet going out is captured, this flag
// will be set to TRUE by the application.
//
while(gPtpMasterState.syncTimestampAvailable == FALSE);
//
// Since the timestamp for the last SYNC packet has been captured,
// send out the associated FOLLOW-UP packet.
//
sendMessage((Octet *)gMsgBuf, FOLLOW_UP, &gPtpMasterState, &gPktDesc);
}
}
void
fromInternalTime(TimeInternal * internal, Timestamp * external)
{
external->secondsField.lsb = internal->seconds;
external->nanosecondsField = internal->nanoseconds;
external->secondsField.msb = 0;
}
//
// Pack header message into OUT buffer of ptpClock
//
void
msgPackHeader(Octet * buf, PTPMasterState *ptpMasterState)
{
Nibble transport = 0x80;
//
// (spec annex D)
//
*(UInteger8 *) (buf + 0) = transport;
//
// PTPv2
//
*(UInteger4 *) (buf + 1) = 0x2;
//
// Default domain number is 0.
//
*(UInteger8 *) (buf + 4) = 0;
if (PTP_TWO_STEP)
*(UInteger8 *) (buf + 6) = PTP_TWO_STEP;
//
// correctionField
//
memset((buf + 8), 0, 8);
//
// sourcePortIdentity first 8 octets
//
memcpy((buf + 20), ptpMasterState->portIdentity.clockIdentity,
CLOCK_IDENTITY_LENGTH);
//
// sourcePortIdentity last 2 octets
//
*(UInteger16 *) (buf + 28) =
flip16(ptpMasterState->portIdentity.portNumber);
//
// Default value(spec Table 24)
//
*(UInteger8 *) (buf + 33) = 0x7F;
}
//
// Pack SYNC message into OUT buffer of ptpClock
//
void
msgPackSync(Octet * buf, PTPMasterState *ptpMasterState)
{
msgPackHeader(buf, ptpMasterState);
//
// changes in header
//
*(char *)(buf + 0) = *(char *)(buf + 0) & 0xF0;
//
// RAZ messageType
//
*(char *)(buf + 0) = *(char *)(buf + 0) | 0x00; /* Table 19 */
//
// messageLength
//
*(UInteger16 *) (buf + 2) = flip16(SYNC_LENGTH);
//
// Sequence Id
//
*(UInteger16 *) (buf + 30) =
flip16(ptpMasterState->syncSeqId);
//
// controlField
//
*(UInteger8 *) (buf + 32) = 0x00; /* Table 23 */
//
// logMessageInterval
//
*(Integer8 *) (buf + 33) = 0; // We'll send sync every second
if(!PTP_TWO_STEP)
{
//
// Sync message
//
*(UInteger16 *) (buf + 34) =
flip16(ptpMasterState->syncTimestamp.secondsField.msb);
*(UInteger32 *) (buf + 36) =
flip32(ptpMasterState->syncTimestamp.secondsField.lsb);
*(UInteger32 *) (buf + 40) =
flip32(ptpMasterState->syncTimestamp.nanosecondsField);
}
}
//
// pack Follow_up message into OUT buffer of ptpClock
//
void
msgPackFollowUp(Octet * buf, PTPMasterState *ptpMasterState)
{
msgPackHeader(buf, ptpMasterState);
//
// changes in header
//
*(char *)(buf + 0) = *(char *)(buf + 0) & 0xF0;
//
// RAZ messageType
//
*(char *)(buf + 0) = *(char *)(buf + 0) | 0x08; /* Table 19 */
//
// messageLength
//
*(UInteger16 *) (buf + 2) = flip16(FOLLOW_UP_LENGTH);
//
// Sequence Id
//
*(UInteger16 *) (buf + 30) =
flip16(ptpMasterState->syncSeqId);
//
// controlField
//
*(UInteger8 *) (buf + 32) = 0x02; /* Table 23 */
//
// logMessageInterval
//
*(Integer8 *) (buf + 33) = 0; // we're sending sync every one second.
//
// Follow_up message
//
*(UInteger16 *) (buf + 34) =
flip16(ptpMasterState->syncTimestamp.secondsField.msb);
*(UInteger32 *) (buf + 36) =
flip32(ptpMasterState->syncTimestamp.secondsField.lsb);
*(UInteger32 *) (buf + 40) =
flip32(ptpMasterState->syncTimestamp.nanosecondsField);
}
//
// pack delayResp message into OUT buffer of ptpClock
//
void
msgPackDelayResp(Octet * buf, PTPMasterState *ptpMasterState)
{
msgPackHeader(buf, ptpMasterState);
//
// changes in header
// Transport | messageType
//
*(char *)(buf + 0) = *(char *)(buf + 0) & 0xF0;
//
// RAZ messageType
//
*(char *)(buf + 0) = *(char *)(buf + 0) | 0x09; /* Table 19 */
//
// messageLength
//
*(UInteger16 *) (buf + 2) = flip16(DELAY_RESP_LENGTH);
//
// domain Number
//
*(UInteger8 *) (buf + 4) = ptpMasterState->delayReqHeader.domainNumber;
//
// Sequence Id
//
*(UInteger16 *) (buf + 30) =
flip16(ptpMasterState->delayReqHeader.sequenceId);
//
// controlField
//
*(UInteger8 *) (buf + 32) = 0x03; /* Table 23 */
//
// logMessageInterval
//
*(Integer8 *) (buf + 33) = 0; /* Table 24 */
*(UInteger16 *) (buf + 34) =
flip16(ptpMasterState->delayReqRecvTimestamp.secondsField.msb);
*(UInteger32 *) (buf + 36) =
flip32(ptpMasterState->delayReqRecvTimestamp.secondsField.lsb);
*(UInteger32 *) (buf + 40) =
flip32(ptpMasterState->delayReqRecvTimestamp.nanosecondsField);
memcpy((buf + 44),
ptpMasterState->delayReqHeader.sourcePortIdentity.clockIdentity,
CLOCK_IDENTITY_LENGTH);
*(UInteger16 *) (buf + 52) =
flip16(ptpMasterState->delayReqHeader.sourcePortIdentity.portNumber);
}
//
// Unpack Header from IN buffer to msgTmpHeader field
//
void
msgUnpackHeader(Octet * buf, MsgHeader * header)
{
header->transportSpecific = (*(Nibble *) (buf + 0)) >> 4;
header->messageType = (*(Enumeration4 *) (buf + 0)) & 0x0F;
header->versionPTP = (*(UInteger4 *) (buf + 1)) & 0x0F;
//
// force reserved bit to zero if not
//
header->messageLength = flip16(*(UInteger16 *) (buf + 2));
header->domainNumber = (*(UInteger8 *) (buf + 4));
memcpy(header->flagField, (buf + 6), FLAG_FIELD_LENGTH);
memcpy(&header->correctionfield.msb, (buf + 8), 4);
memcpy(&header->correctionfield.lsb, (buf + 12), 4);
header->correctionfield.msb = flip32(header->correctionfield.msb);
header->correctionfield.lsb = flip32(header->correctionfield.lsb);
memcpy(header->sourcePortIdentity.clockIdentity, (buf + 20),
CLOCK_IDENTITY_LENGTH);
header->sourcePortIdentity.portNumber =
flip16(*(UInteger16 *) (buf + 28));
header->sequenceId = flip16(*(UInteger16 *) (buf + 30));
header->controlField = (*(UInteger8 *) (buf + 32));
header->logMessageInterval = (*(Integer8 *) (buf + 33));
}
void InitConstants(PTPMasterState *ptpMasterState)
{
uint32_t mac_low,mac_high, i, j;
uint8_t *pucTemp;
Ethernet_getMACAddr(EMAC_BASE, 0, &mac_high, &mac_low);
pucTemp = (uint8_t *)&mac_low;
ptpMasterState->port_uuid_field[0] = pucTemp[0];
ptpMasterState->port_uuid_field[1] = pucTemp[1];
ptpMasterState->port_uuid_field[2] = pucTemp[2];
ptpMasterState->port_uuid_field[3] = pucTemp[3];
pucTemp = (uint8_t *)&mac_high;
ptpMasterState->port_uuid_field[4] = pucTemp[0];
ptpMasterState->port_uuid_field[5] = pucTemp[1];
//
// Init global constants.
//
for (i = 0, j = 0; i < CLOCK_IDENTITY_LENGTH; i++)
{
if (i == 3) ptpMasterState->portIdentity.clockIdentity[i] = 0xFF;
else if (i == 4) ptpMasterState->portIdentity.clockIdentity[i] = 0xFE;
else
{
ptpMasterState->portIdentity.clockIdentity[i] =
ptpMasterState->port_uuid_field[j];
j++;
}
}
}
void sendMessage(Octet * msg,
uint32_t messageType,
PTPMasterState * ptpMasterState,
Ethernet_Pkt_Desc * pktDesc)
{
uint32_t pktLen;
//
// We can't trust if the supplied descriptor is clean. Hence reset it.
//
memset(pktDesc, 0, sizeof(Ethernet_Pkt_Desc));
pktDesc->bufferLength = PACKET_LENGTH;
pktDesc->dataOffset = 0;
pktDesc->dataBuffer = (uint8_t *)msg;
pktDesc->nextPacketDesc = 0;
pktDesc->flags = ETHERNET_PKT_FLAG_SOP |
ETHERNET_PKT_FLAG_EOP |
ETHERNET_PKT_FLAG_SA_INS |
ETHERNET_PKT_FLAG_CRC_PAD_INS;
pktDesc->pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
pktDesc->numPktFrags = 1;
//
// Reset the buffer
//
memset(msg + 8, 0, PACKET_LENGTH - 8);
switch(messageType)
{
case SYNC:
pktDesc->flags |= ETHERNET_PKT_FLAG_TTSE;
msgPackSync(msg + 8, ptpMasterState);
pktLen = SYNC_LENGTH;
break;
case FOLLOW_UP:
msgPackFollowUp(msg + 8, ptpMasterState);
pktLen = FOLLOW_UP_LENGTH;
gPtpMasterState.syncSeqId++;
break;
case DELAY_RESP:
msgPackDelayResp(msg + 8, ptpMasterState);
pktLen = DELAY_RESP_LENGTH;
break;
default:
//
// Error condition, the code should never reach here
//
break;
}
pktDesc->pktLength = pktLen + 6 + 2;
pktDesc->validLength = pktDesc->pktLength;
Ethernet_sendPacket(emac_handle, pktDesc);
}
//*****************************************************************************
//
// This function is a callback function called by the example to
// get a Packet Buffer. Has to return a ETHERNET_Pkt_Desc Structure.
// Rewrite this API for custom use case.
//
//*****************************************************************************
Ethernet_Pkt_Desc* Ethernet_getPacketBufferCustom(void)
{
//
// Get the next packet descriptor from the descriptor pool
//
uint32_t shortIndex = (Ethernet_numGetPacketBufferCallback + 3)
% NUM_PACKET_DESC_RX_APPLICATION;
//
// Increment the book-keeping pointer which acts as a head pointer
// to the circular array of packet descriptor pool.
//
Ethernet_numGetPacketBufferCallback++;
//
// Update buffer length information to the newly procured packet
// descriptor.
//
pktDescriptorRXCustom[shortIndex].bufferLength =
ETHERNET_MAX_PACKET_LENGTH;
//
// Update the receive buffer address in the packer descriptor.
//
pktDescriptorRXCustom[shortIndex].dataBuffer =
&Ethernet_device_struct.rxBuffer [
(ETHERNET_MAX_PACKET_LENGTH*Ethernet_device_struct.rxBuffIndex)];
//
// Update the receive buffer pool index.
//
Ethernet_device_struct.rxBuffIndex += 1U;
Ethernet_device_struct.rxBuffIndex =
(Ethernet_device_struct.rxBuffIndex%ETHERNET_NO_OF_RX_PACKETS);
//
// Receive buffer is usable from Address 0
//
pktDescriptorRXCustom[shortIndex].dataOffset = 0U;
//
// Return this new descriptor to the driver.
//
return (&(pktDescriptorRXCustom[shortIndex]));
}
//*****************************************************************************
//
// This is a hook function and called by the driver when it receives a
// packet. Application is expected to replenish the buffer after consuming it.
// Has to return a ETHERNET_Pkt_Desc Structure.
// Rewrite this API for custom use case.
//
//*****************************************************************************
Ethernet_Pkt_Desc* Ethernet_receivePacketCallbackCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket)
{
//
// Need to unpack the header to check which packet is received.
// We expect a Delay Request packet from the slave. Ignore others.
//
msgUnpackHeader((Octet*)(pPacket->dataBuffer + PTP_HEADER_OFFSET),
&gPtpMasterState.delayReqHeader);
switch(gPtpMasterState.delayReqHeader.messageType)
{
case DELAY_REQ:
//
// Simply get the timestamp and send the delay response packet asap.
//
gPtpMasterState.delayReqRecvTimestamp.nanosecondsField =
pPacket->timeStampLow;
gPtpMasterState.delayReqRecvTimestamp.secondsField.lsb =
pPacket->timeStampHigh;
gPtpMasterState.delayReqRecvTimestamp.secondsField.msb = 0;
//
// Save this state that we are sending Delay Resp packet so that it
// doesn't affect other packets which are being sent.
//
gPtpMasterState.sendingDelayResp = TRUE;
//
// Send the corresponding Delay Response packet.
//
sendMessage((Octet *)gMsgBuf, DELAY_RESP, &gPtpMasterState, &gPktDesc);
break;
default:
//
// Error condition, the code should never reach here
//
break;
}
//
// Book-keeping to maintain number of callbacks received.
//
#ifdef ETHERNET_DEBUG
Ethernet_numRxCallbackCustom++;
#endif
return Ethernet_getPacketBufferCustom();
}
void Ethernet_releaseTxPacketBufferCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket)
{
//
// We would like to capture the timestamp for the SYNC packet only.
//
if(gPtpMasterState.sendingDelayResp == TRUE)
{
gPtpMasterState.sendingDelayResp = FALSE;
}
else if(gPtpMasterState.syncTimestampAvailable == FALSE)
{
gPtpMasterState.syncTimestamp.nanosecondsField = pPacket->timeStampLow;
gPtpMasterState.syncTimestamp.secondsField.lsb = pPacket->timeStampHigh;
gPtpMasterState.syncTimestamp.secondsField.msb = 0;
gPtpMasterState.syncTimestampAvailable = TRUE;
}
//
// Increment the book-keeping counter.
//
#if ETHERNET_DEBUG
Ethernet_releaseTxCount++;
#endif
}
@@ -0,0 +1,892 @@
//#############################################################################
//
// FILE: ethernet_ex4_ptp_basic_slave.c
//
// TITLE: Ethernet PTP Basic Slave Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet PTP Basic Slave </h1>
//!
//! This example configures the device in IEEE PTPv2 Slave mode and then
//! waits for the Sync packets from the slave. On receiving configurable number
//! of Sync packets from the master, the slave also sends out the DelayReq
//! packets. In response to the DelayReq packets, the Master also sends out the
//! DelayResp packets which is then received by the Slave. The slave parallely
//! maintains the internal state of the PTP in terms of \e Master \e to
//! \e Slave \e Delay and \e Slave \e to \e Master \e Delay. Consequently, the
//! slave also calculates \e Offset \e From \e Master and \e Mean \e Path
//! \e Delay.
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in PTP Basic Slave mode.
//! The example project \e Ethernet \e PTP \e Basic \e Master is intended to
//! be used along with this project to see the whole PTP Protocol state in
//! action. The second device is configured as \e Master and both devices in
//! conjunction exchange Sync, DelayReq and DelayResp packets.
//!
//! Refer to the C28x CPU1 code of ethernet_config_c28x project for configuring
//! the PTP clock that drives the system time counter on the Ethernet module.
//!
//! \b Watch \b Variables \n
//! - gPtpSlaveState
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
#include "driverlib_cm.h"
#include "limits.h"
#include "string.h"
//
// Definition of 1 Billion or 10^9
//
#define ONE_BILLION 1000000000
//
// This frequency is actually set in the c28x side code. If it is changed
// there, then the following value also needs to be updated since the
// timestamping module is initialized with the following values.
// Default value is 100 MHz.
//
#define PTP_REF_CLOCK_FREQ 100000000
#define PTP_REF_CLOCK_PERIOD ONE_BILLION/PTP_REF_CLOCK_FREQ
static Ethernet_Handle emac_handle;
#define PACKET_LENGTH 200
Ethernet_Pkt_Desc gPktDesc;
#define ETHERNET_NO_OF_RX_PACKETS 8U
#define ETHERNET_MAX_PACKET_LENGTH PACKET_LENGTH
#define NUM_PACKET_DESC_RX_APPLICATION 8U
#define PTP_HEADER_OFFSET 14U
//
// Globals
//
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
// Update clock if the offset from master wanders off further than this cutoff.
//
#define PTP_OFM_NANOSECONDS_CUTOFF 10000U
uint32_t Ethernet_numRxCallbackCustom = 0;
uint32_t releaseTxCount = 0;
Ethernet_Pkt_Desc pktDescriptorRXCustom[NUM_PACKET_DESC_RX_APPLICATION];
extern uint32_t Ethernet_numGetPacketBufferCallback;
extern Ethernet_Device Ethernet_device_struct;
uint8_t delayReqMsg[PACKET_LENGTH] = {0};
#define abs(x) (x<0?-x:x)
//
// Taking care of network byte order conversions using these macros.
//
#define PP_HTONS(x) ((uint16_t)((((x) & (uint16_t)0x00ffU) << 8) | \
(((x) & (uint16_t)0xff00U) >> 8)))
#define PP_NTOHS(x) PP_HTONS(x)
#define PP_HTONL(x) ((((x) & (uint32_t)0x000000ffUL) << 24) | \
(((x) & (uint32_t)0x0000ff00UL) << 8) | \
(((x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((x) & (uint32_t)0xff000000UL) >> 24))
#define PP_NTOHL(x) PP_HTONL(x)
#define flip16(x) PP_HTONS(x)
#define flip32(x) PP_HTONL(x)
//
// Following definitions and prototypes are specific to the PTP state machine
// and have been adapted from the IEEE 1588 standard spec.
//
#define PTP_TWO_STEP 0x02
#define PTP_UUID_LENGTH 6
#define CLOCK_IDENTITY_LENGTH 8
#define FLAG_FIELD_LENGTH 2
#define HEADER_LENGTH 34
#define ANNOUNCE_LENGTH 64
#define SYNC_LENGTH 44
#define FOLLOW_UP_LENGTH 44
#define PDELAY_REQ_LENGTH 54
#define DELAY_REQ_LENGTH 44
#define DELAY_RESP_LENGTH 54
#define PDELAY_RESP_LENGTH 54
#define PDELAY_RESP_FOLLOW_UP_LENGTH 54
#define MANAGEMENT_LENGTH 48
typedef enum {FALSE=0, TRUE} Boolean;
typedef char Octet;
typedef signed char Integer8;
typedef signed short Integer16;
typedef signed int Integer32;
typedef unsigned char UInteger8;
typedef unsigned short UInteger16;
typedef unsigned int UInteger32;
typedef unsigned short Enumeration16;
typedef unsigned char Enumeration8;
typedef unsigned char Enumeration4;
typedef unsigned char UInteger4;
typedef unsigned char Nibble;
//
// brief Implementation specific of Integer64 type
//
typedef struct {
unsigned int lsb;
int msb;
} Integer64;
typedef struct {
unsigned int lsb;
unsigned short msb;
} UInteger48;
typedef struct {
UInteger48 secondsField;
UInteger32 nanosecondsField;
} Timestamp;
//
// brief Time structure to handle Linux time information
//
typedef struct {
Integer32 seconds;
Integer32 nanoseconds;
} TimeInternal;
//
// brief The ClockIdentity type identifies a clock
//
typedef Octet ClockIdentity[CLOCK_IDENTITY_LENGTH];
//
// brief The PortIdentity identifies a PTP port.
//
typedef struct {
ClockIdentity clockIdentity;
UInteger16 portNumber;
} PortIdentity;
//
// brief The common header for all PTP messages (Table 18 of the spec)
//
//
// Message header
//
typedef struct {
Nibble transportSpecific;
Enumeration4 messageType;
UInteger4 versionPTP;
UInteger16 messageLength;
UInteger8 domainNumber;
Octet flagField[2];
Integer64 correctionfield;
PortIdentity sourcePortIdentity;
UInteger16 sequenceId;
UInteger8 controlField;
Integer8 logMessageInterval;
} MsgHeader;
typedef struct
{
PortIdentity portIdentity;
Octet port_uuid_field[PTP_UUID_LENGTH];
Timestamp syncRecvTimestamp;
Timestamp syncOriginTimestamp;
Timestamp delayReqSentTimestamp;
Timestamp delayReqRecvTimestamp;
TimeInternal delayMS;
TimeInternal delaySM;
TimeInternal offsetFromMaster;
TimeInternal meanPathDelay;
uint16_t lastSyncSeqId;
uint16_t delayReqSeqId;
uint16_t portNumber;
uint32_t clockUpdateCount;
Boolean waitingForFollowup;
Boolean waitingForDelayResp;
} PTPSlaveState;
PTPSlaveState gPtpSlaveState = {0};
//
// brief PTP Messages
//
enum {
SYNC=0x0,
DELAY_REQ=0x1,
FOLLOW_UP = 0x8,
DELAY_RESP = 0x9,
};
//
// Function prototypes used in this example
//
void fromInternalTime(TimeInternal * internal, Timestamp * external);
void msgPackHeader(Octet * buf, PTPSlaveState *ptpSlaveState);
void msgUnpackHeader(Octet * buf, MsgHeader * header);
void msgPackDelayReq(Octet * buf, PTPSlaveState * ptpSlaveState);
void InitConstants(PTPSlaveState *ptpSlaveState);
void normalizeTime(TimeInternal * r);
void
subTime(TimeInternal * r, const TimeInternal * x, const TimeInternal * y);
void
addTime(TimeInternal * r, const TimeInternal * x, const TimeInternal * y);
void div2Time(TimeInternal *r);
void toInternalTime(TimeInternal * internal, Timestamp * external);
void getTime(TimeInternal *time);
void setTime(TimeInternal *time);
void updateClock(void);
Ethernet_Pkt_Desc* Ethernet_getPacketBufferCustom(void);
Ethernet_Pkt_Desc* Ethernet_receivePacketCallbackCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket);
void Ethernet_releaseTxPacketBufferCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket);
main(void)
{
Ethernet_InitConfig *pInitCfg;
uint32_t varPtpConfig = 0;
Ethernet_InitInterfaceConfig initInterfaceConfig;
float subSecondInc;
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
Ethernet_getInitConfig(pInitCfg);
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBufferCustom;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallbackCustom;
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBufferCustom;
varPtpConfig = 0x0 |
(0 << ETHERNET_MAC_TIMESTAMP_CONTROL_SNAPTYPSEL_S) |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSCTRLSSR |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSEVNTENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSVER2ENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSIPENA;
//
// Subsecond increment is added to the systime counter every ptp clock tick
// hence for Digital rollover, it is simply the time period of the clock
// tick.
//
subSecondInc = PTP_REF_CLOCK_PERIOD;
Ethernet_setConfigTimestampPTP(EMAC_BASE, varPtpConfig, subSecondInc);
Ethernet_enableSysTimePTP(EMAC_BASE);
//
// Start the system with a random value.
//
Ethernet_setSysTimePTP(EMAC_BASE, 0x4132EDCA, 0x25a5a5a5);
pInitCfg->rxBuffer = Ethernet_rxBuffer;
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
//
// We need to program this standard multicast address so that this device
// identifies PTP over Ethernet packets correctly. "01:1B:19:00:00:00"
//
Ethernet_setMACAddr(EMAC_BASE,
1,
0x00000000,
0x00191B01,
ETHERNET_CHANNEL_0);
InitConstants(&gPtpSlaveState);
while(1)
{
}
}
void
fromInternalTime(TimeInternal * internal, Timestamp * external)
{
external->secondsField.lsb = internal->seconds;
external->nanosecondsField = internal->nanoseconds;
external->secondsField.msb = 0;
}
//
// Pack header message into OUT buffer of ptpClock
//
void
msgPackHeader(Octet * buf, PTPSlaveState *ptpSlaveState)
{
Nibble transport = 0x80;
//
// (spec annex D)
//
*(UInteger8 *) (buf + 0) = transport;
//
// PTPv2
//
*(UInteger4 *) (buf + 1) = 0x2;
//
// Default domain number is 0.
//
*(UInteger8 *) (buf + 4) = 0;
if (PTP_TWO_STEP)
*(UInteger8 *) (buf + 6) = PTP_TWO_STEP;
//
// correctionField
//
memset((buf + 8), 0, 8);
//
// sourcePortIdentity first 8 octets
//
memcpy((buf + 20), ptpSlaveState->portIdentity.clockIdentity,
CLOCK_IDENTITY_LENGTH);
//
// sourcePortIdentity last 2 octets
//
*(UInteger16 *) (buf + 28) =
flip16(ptpSlaveState->portIdentity.portNumber);
//
// Default value(spec Table 24)
//
*(UInteger8 *) (buf + 33) = 0x7F;
}
//
// Unpack Header from IN buffer to msgTmpHeader field
//
void
msgUnpackHeader(Octet * buf, MsgHeader * header)
{
header->transportSpecific = (*(Nibble *) (buf + 0)) >> 4;
header->messageType = (*(Enumeration4 *) (buf + 0)) & 0x0F;
header->versionPTP = (*(UInteger4 *) (buf + 1)) & 0x0F;
//
// force reserved bit to zero if not
//
header->messageLength = flip16(*(UInteger16 *) (buf + 2));
header->domainNumber = (*(UInteger8 *) (buf + 4));
memcpy(header->flagField, (buf + 6), FLAG_FIELD_LENGTH);
memcpy(&header->correctionfield.msb, (buf + 8), 4);
memcpy(&header->correctionfield.lsb, (buf + 12), 4);
header->correctionfield.msb = flip32(header->correctionfield.msb);
header->correctionfield.lsb = flip32(header->correctionfield.lsb);
memcpy(header->sourcePortIdentity.clockIdentity, (buf + 20),
CLOCK_IDENTITY_LENGTH);
header->sourcePortIdentity.portNumber =
flip16(*(UInteger16 *) (buf + 28));
header->sequenceId = flip16(*(UInteger16 *) (buf + 30));
header->controlField = (*(UInteger8 *) (buf + 32));
header->logMessageInterval = (*(Integer8 *) (buf + 33));
}
//
// pack delayReq message into OUT buffer of ptpClock
//
void
msgPackDelayReq(Octet * buf, PTPSlaveState * ptpSlaveState)
{
msgPackHeader(buf, ptpSlaveState);
//
// changes in header
//
*(char *)(buf + 0) = *(char *)(buf + 0) & 0xF0;
//
// RAZ messageType
//
*(char *)(buf + 0) = *(char *)(buf + 0) | 0x01; /* Table 19 */
//
// messageLength
//
*(UInteger16 *) (buf + 2) = flip16(DELAY_REQ_LENGTH);
//
// Sequence Id
//
*(UInteger16 *) (buf + 30) =
flip16(ptpSlaveState->delayReqSeqId);
//
// controlField
//
*(UInteger8 *) (buf + 32) = 0x01; /* Table 23 */
//
// logMessageInterval
//
*(Integer8 *) (buf + 33) = 0x7F; /* Table 24 */
}
void InitConstants(PTPSlaveState *ptpSlaveState)
{
uint32_t mac_low,mac_high, i, j;
uint8_t *pucTemp;
Ethernet_getMACAddr(EMAC_BASE, 0, &mac_high, &mac_low);
pucTemp = (uint8_t *)&mac_low;
ptpSlaveState->port_uuid_field[0] = pucTemp[0];
ptpSlaveState->port_uuid_field[1] = pucTemp[1];
ptpSlaveState->port_uuid_field[2] = pucTemp[2];
ptpSlaveState->port_uuid_field[3] = pucTemp[3];
pucTemp = (uint8_t *)&mac_high;
ptpSlaveState->port_uuid_field[4] = pucTemp[0];
ptpSlaveState->port_uuid_field[5] = pucTemp[1];
//
// Init global constants.
//
for (i = 0, j = 0; i < CLOCK_IDENTITY_LENGTH; i++)
{
if (i == 3) ptpSlaveState->portIdentity.clockIdentity[i]=0xFF;
else if (i==4) ptpSlaveState->portIdentity.clockIdentity[i]=0xFE;
else
{
ptpSlaveState->portIdentity.clockIdentity[i] =
ptpSlaveState->port_uuid_field[j];
j++;
}
}
}
void
normalizeTime(TimeInternal * r)
{
r->seconds += r->nanoseconds / ONE_BILLION;
r->nanoseconds -= r->nanoseconds / ONE_BILLION * ONE_BILLION;
if (r->seconds > 0 && r->nanoseconds < 0) {
r->seconds -= 1;
r->nanoseconds += ONE_BILLION;
} else if (r->seconds < 0 && r->nanoseconds > 0) {
r->seconds += 1;
r->nanoseconds -= ONE_BILLION;
}
}
void
addTime(TimeInternal * r, const TimeInternal * x, const TimeInternal * y)
{
r->seconds = x->seconds + y->seconds;
r->nanoseconds = x->nanoseconds + y->nanoseconds;
normalizeTime(r);
}
void
subTime(TimeInternal * r, const TimeInternal * x, const TimeInternal * y)
{
r->seconds = x->seconds - y->seconds;
r->nanoseconds = x->nanoseconds - y->nanoseconds;
normalizeTime(r);
}
void div2Time(TimeInternal *r)
{
r->nanoseconds += r->seconds % 2 * ONE_BILLION;
r->seconds /= 2;
r->nanoseconds /= 2;
normalizeTime(r);
}
void
toInternalTime(TimeInternal * internal, Timestamp * external)
{
//
// Program will not run after 2038...
//
if (external->secondsField.lsb < INT_MAX) {
internal->seconds = external->secondsField.lsb;
internal->nanoseconds = external->nanosecondsField;
}
else
{
//
// Error condition.
// Clock servo canno't be executed :
// seconds field is higher than signed integer (32bits))
//
return;
}
}
void
getTime(TimeInternal *time)
{
//
// Fetch the current system time.
//
Ethernet_getSysTimePTP(EMAC_BASE, (uint32_t *)&time->seconds,
(uint32_t *)&time->nanoseconds);
}
void
setTime(TimeInternal *time)
{
//
// Set the new system time.
//
Ethernet_setSysTimePTP(EMAC_BASE, (uint32_t)time->seconds,
(uint32_t)time->nanoseconds);
}
void updateClock(void)
{
TimeInternal timeTmp;
//
// Update the clock if either
//
if((gPtpSlaveState.offsetFromMaster.seconds > 0) ||
(abs(gPtpSlaveState.offsetFromMaster.nanoseconds) >
PTP_OFM_NANOSECONDS_CUTOFF))
{
getTime(&timeTmp);
subTime(&timeTmp, &timeTmp, &gPtpSlaveState.offsetFromMaster);
setTime(&timeTmp);
gPtpSlaveState.clockUpdateCount++;
}
}
//*****************************************************************************
//
// This function is a callback function called by the example to
// get a Packet Buffer. Has to return a ETHERNET_Pkt_Desc Structure.
// Rewrite this API for custom use case.
//
//*****************************************************************************
Ethernet_Pkt_Desc* Ethernet_getPacketBufferCustom(void)
{
//
// Get the next packet descriptor from the descriptor pool
//
uint32_t shortIndex = (Ethernet_numGetPacketBufferCallback + 3)
% NUM_PACKET_DESC_RX_APPLICATION;
//
// Increment the book-keeping pointer which acts as a head pointer
// to the circular array of packet descriptor pool.
//
Ethernet_numGetPacketBufferCallback++;
//
// Update buffer length information to the newly procured packet
// descriptor.
//
pktDescriptorRXCustom[shortIndex].bufferLength =
ETHERNET_MAX_PACKET_LENGTH;
//
// Update the receive buffer address in the packer descriptor.
//
pktDescriptorRXCustom[shortIndex].dataBuffer =
&Ethernet_device_struct.rxBuffer [ \
(ETHERNET_MAX_PACKET_LENGTH*Ethernet_device_struct.rxBuffIndex)];
//
// Update the receive buffer pool index.
//
Ethernet_device_struct.rxBuffIndex += 1U;
Ethernet_device_struct.rxBuffIndex = \
(Ethernet_device_struct.rxBuffIndex%ETHERNET_NO_OF_RX_PACKETS);
//
// Receive buffer is usable from Address 0
//
pktDescriptorRXCustom[shortIndex].dataOffset = 0U;
//
// Return this new descriptor to the driver.
//
return (&(pktDescriptorRXCustom[shortIndex]));
}
//*****************************************************************************
//
// This is a hook function and called by the driver when it receives a
// packet. Application is expected to replenish the buffer after consuming it.
// Has to return a ETHERNET_Pkt_Desc Structure.
// Rewrite this API for custom use case.
//
//*****************************************************************************
Ethernet_Pkt_Desc* Ethernet_receivePacketCallbackCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket)
{
MsgHeader header;
TimeInternal recvTime;
TimeInternal sendTime;
uint32_t i;
msgUnpackHeader((Octet*)(pPacket->dataBuffer + PTP_HEADER_OFFSET), &header);
switch(header.messageType)
{
case SYNC:
//
// 1. Save the Sync receive timestamp.
//
gPtpSlaveState.syncRecvTimestamp.nanosecondsField =
pPacket->timeStampLow;
gPtpSlaveState.syncRecvTimestamp.secondsField.lsb =
pPacket->timeStampHigh;
gPtpSlaveState.syncRecvTimestamp.secondsField.msb = 0;
gPtpSlaveState.lastSyncSeqId = header.sequenceId;
break;
case FOLLOW_UP:
//
// 1. Retrieve the Sync send timestamp.
// 2. Calculate the Master to Slave delay
// 3. Subtract this from Mean Path Delay to get "Offset from Master"
// 4. Update the clock based on this value. Course correction.
//
if(header.sequenceId == gPtpSlaveState.lastSyncSeqId)
{
gPtpSlaveState.syncOriginTimestamp.secondsField.msb =
flip16(*(UInteger16 *) (pPacket->dataBuffer + PTP_HEADER_OFFSET + 34 ));
gPtpSlaveState.syncOriginTimestamp.secondsField.lsb =
flip32(*(UInteger32 *) (pPacket->dataBuffer + PTP_HEADER_OFFSET + 36));
gPtpSlaveState.syncOriginTimestamp.nanosecondsField =
flip32(*(UInteger32 *) (pPacket->dataBuffer + PTP_HEADER_OFFSET + 40));
while(gPtpSlaveState.syncOriginTimestamp.secondsField.lsb == 0x2000CE44);
//
// converting the origin timestamp to internal time
//
toInternalTime(&sendTime, &gPtpSlaveState.syncOriginTimestamp);
//
// converting the sync receive timestamp to internal time
//
toInternalTime(&recvTime, &gPtpSlaveState.syncRecvTimestamp);
//
// Calculate Master to slave delay
//
subTime(&gPtpSlaveState.delayMS, &recvTime, &sendTime);
//
// Calculate offset from master
//
subTime(&gPtpSlaveState.offsetFromMaster,
&gPtpSlaveState.delayMS,
&gPtpSlaveState.meanPathDelay);
updateClock();
//
// If sufficient sync/followups have been received, then issue a
// delay request packet.
//
if(!((gPtpSlaveState.lastSyncSeqId + 1) % 10))
{
//
// We need to set a standard defined Multicast address : 01:1B:19:00:00:00
// as the Destination address in the ethernet frame and that is how the
// receiver will recognize it as a valid PTP over Ethernet packet.
//
i=0; *((uint32_t *)delayReqMsg + i) = 0x00191B01;
i++; *((uint32_t *)delayReqMsg + i) = 0xF7880000;
//
// Reset the buffer next sync packet.
//
memset(delayReqMsg+8, 0, PACKET_LENGTH-8);
msgPackDelayReq((Octet *)delayReqMsg + 8, &gPtpSlaveState);
gPktDesc.bufferLength = PACKET_LENGTH;
gPktDesc.dataOffset = 0;
gPktDesc.dataBuffer = delayReqMsg;
gPktDesc.nextPacketDesc = 0;
gPktDesc.flags = ETHERNET_PKT_FLAG_TTSE |
ETHERNET_PKT_FLAG_SOP |
ETHERNET_PKT_FLAG_EOP |
ETHERNET_PKT_FLAG_SA_INS |
ETHERNET_PKT_FLAG_CRC_PAD_INS;
gPktDesc.pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
gPktDesc.pktLength = DELAY_REQ_LENGTH + 6 + 2;
gPktDesc.validLength = gPktDesc.pktLength;
gPktDesc.numPktFrags = 1;
Ethernet_sendPacket(emac_handle,&gPktDesc);
gPtpSlaveState.delayReqSeqId++;
}
}
break;
case DELAY_RESP:
//
// 1. Get the "Delay Request receive timestamp.
// 2. Calculate the Slave to Master Delay.
// 3. Calculate the Mean Path Delay and save it.
//
if(gPtpSlaveState.waitingForDelayResp == TRUE)
{
gPtpSlaveState.waitingForDelayResp = FALSE;
gPtpSlaveState.delayReqRecvTimestamp.secondsField.msb =
flip16(*(UInteger16 *) (pPacket->dataBuffer + PTP_HEADER_OFFSET + 34 ));
gPtpSlaveState.delayReqRecvTimestamp.secondsField.lsb =
flip32(*(UInteger32 *) (pPacket->dataBuffer + PTP_HEADER_OFFSET + 36));
gPtpSlaveState.delayReqRecvTimestamp.nanosecondsField =
flip32(*(UInteger32 *) (pPacket->dataBuffer + PTP_HEADER_OFFSET + 40));
//
// Update delay and calculate Mean Path Delay.
//
toInternalTime(&sendTime, &gPtpSlaveState.delayReqSentTimestamp);
toInternalTime(&recvTime, &gPtpSlaveState.delayReqRecvTimestamp);
subTime(&gPtpSlaveState.delaySM, &recvTime, &sendTime);
addTime(&gPtpSlaveState.meanPathDelay,
&gPtpSlaveState.delaySM,
&gPtpSlaveState.delayMS);
div2Time(&gPtpSlaveState.meanPathDelay);
}
break;
}
//
// Book-keeping to maintain number of callbacks received.
//
#ifdef ETHERNET_DEBUG
Ethernet_numRxCallbackCustom++;
#endif
return Ethernet_getPacketBufferCustom();
}
void Ethernet_releaseTxPacketBufferCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket)
{
gPtpSlaveState.delayReqSentTimestamp.nanosecondsField =
pPacket->timeStampLow;
gPtpSlaveState.delayReqSentTimestamp.secondsField.lsb =
pPacket->timeStampHigh;
gPtpSlaveState.delayReqSentTimestamp.secondsField.msb = 0;
gPtpSlaveState.waitingForDelayResp = TRUE;
//
// Increment the book-keeping counter.
//
#ifdef ETHERNET_DEBUG
releaseTxCount++;
#endif
}
@@ -0,0 +1,335 @@
//#############################################################################
//
// FILE: ethernet_ex5_ptp_offload_master.c
//
// TITLE: Ethernet PTP Offload Master Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet PTP Offload Master </h1>
//!
//! This example configures the device in IEEE PTPv2 Master mode and sets the
//! options that are needed by the offload engine to operate such as the
//! \e domainNumber, \e LogSyncInterval among others. After that it enables
//! sending SYNC messages periodically according to the interval already set
//! previously.
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in PTP Offload Master mode.
//! The example project \e Ethernet \e PTP \e Offload \e Slave is intended to
//! be used along with this project to see the whole PTP Offload engine in
//! action. The second device is configured as \e Slave and both devices in
//! conjunction exchange Sync, DelayReq and DelayResp packets.
//!
//! Refer to the C28x CPU1 code of ethernet_config_c28x project for configuring
//! the PTP clock that drives the system time counter on the Ethernet module.
//!
//! \b Watch \b Variables \n
//! - Ethernet_ptpDelayReqPktCount
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
#include "driverlib_cm.h"
#include "cm.h"
//
// This frequency is actually set in the c28x side code. If it is changed
// there, then the following value also needs to be updated since the
// timestamping module is initialized with the following values.
// Default value is 100 MHz.
//
#define PTP_REF_CLOCK_FREQ 100000000
#define PTP_REF_CLOCK_PERIOD 1000000000/PTP_REF_CLOCK_FREQ
#define NUM_PACKET_DESC_RX_APPLICATION 8U
#define ETHERNET_NO_OF_RX_PACKETS 8U
#define ETHERNET_MAX_PACKET_LENGTH 100U
static Ethernet_Handle emac_handle;
extern Ethernet_Device Ethernet_device_struct;
//
// Globals
//
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
//
// This function is a callback function called by the LLD to
// Get a Packet Buffer. Has to return a ETHERNET_Pkt_Desc Structure filled
// User or upper level stack can rewrite this API for their own use case
//
uint32_t Ethernet_numGetPacketBufferCallbackCustom = 0;
uint32_t Ethernet_numRxCallbackCustom = 0;
uint32_t Ethernet_ptpDelayReqPktCount = 0;
Ethernet_Pkt_Desc pktDescriptorRXCustom[NUM_PACKET_DESC_RX_APPLICATION];
Ethernet_Pkt_Desc* Ethernet_getPacketBufferCustom(void)
{
uint32_t shortIndex = (Ethernet_numGetPacketBufferCallbackCustom + 3) %
NUM_PACKET_DESC_RX_APPLICATION;
Ethernet_numGetPacketBufferCallbackCustom++;
pktDescriptorRXCustom[shortIndex].bufferLength =
ETHERNET_MAX_PACKET_LENGTH;
pktDescriptorRXCustom[shortIndex].dataBuffer =
&Ethernet_device_struct.rxBuffer [
(ETHERNET_MAX_PACKET_LENGTH * Ethernet_device_struct.rxBuffIndex)];
//
// Wrap around
//
Ethernet_device_struct.rxBuffIndex += 1U;
Ethernet_device_struct.rxBuffIndex =
(Ethernet_device_struct.rxBuffIndex%ETHERNET_NO_OF_RX_PACKETS);
//
// Usable from Address 0
//
pktDescriptorRXCustom[shortIndex].dataOffset = 0U;
return (&(pktDescriptorRXCustom[shortIndex]));
}
Ethernet_Pkt_Desc* Ethernet_receivePacketCallbackCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket)
{
//
// 14th byte in the received packet is 'messageType' field of
// ptp frame format.
//
// messageType == 0x1 indicates "DelayReq" packet.
//
if ((pPacket->dataBuffer[14] & 0x0F) == 0x1)
Ethernet_ptpDelayReqPktCount++;
Ethernet_numRxCallbackCustom++;
//
// This is a placeholder for Application specific handling
// We are replenishing the buffer received with another buffer
//
return Ethernet_getPacketBufferCustom();
}
main(void)
{
Ethernet_InitConfig *pInitCfg;
Ethernet_InitInterfaceConfig initInterfaceConfig;
uint32_t varPtpConfig = 0;
float subSecondInc;
//
// Initialize device clock and peripherals
//
CM_init();
//
// Hardcoded MAC Address
//
uint32_t mac_lower = 0x00F363A8;
uint32_t mac_higher = 0x00800000;
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
Ethernet_getInitConfig(pInitCfg);
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallbackCustom;
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBufferCustom;
pInitCfg->rxBuffer = Ethernet_rxBuffer;
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
Interrupt_registerHandler(INT_EMAC,Ethernet_genericISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
Interrupt_enable(INT_EMAC);
Ethernet_setMACAddr(EMAC_BASE,
0,
mac_higher,
mac_lower,
ETHERNET_CHANNEL_0);
//
// We need to program this standard multicast address so that this device
// identifies PTP over Ethernet packets correctly. "01:1B:19:00:00:00"
//
Ethernet_setMACAddr(EMAC_BASE,
1,
0x00000000,
0x00191B01,
ETHERNET_CHANNEL_0);
//
// Ethernet PTP module is configured with:
// - Master
// - Identify event messages (Sync, DelayReq)
// - Identify PTP over Ethernet packets
// - PTP version 2
// - Digital Rollover
//
varPtpConfig = 0x0 |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSEVNTENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSMSTRENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSIPENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSVER2ENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSCTRLSSR;
subSecondInc = PTP_REF_CLOCK_PERIOD;
Ethernet_setConfigTimestampPTP(EMAC_BASE, varPtpConfig, subSecondInc);
Ethernet_enableSysTimePTP(EMAC_BASE);
Ethernet_setSysTimePTP(EMAC_BASE, 0x4132EDCA, 0x25a5a5a5);
//
// PTP Offlad related configuration follows. This is used to automatically
// assemble the PTP Header for the packets which will be ultimately sent
// out by the PTP Offload engine.
//
Ethernet_PTPOffloadConfigParams ptoConfigParams = {0};
//
// "sourcePortIdentity" field in the PTP Header.
//
ptoConfigParams.srcPortId.id0 = 0xFFFFFFFF;
ptoConfigParams.srcPortId.id1 = 0xFFFFFFFF;
ptoConfigParams.srcPortId.id2 = 0xFFFF;
//
// "logMessageInterval" field in the PTP Header.
//
ptoConfigParams.logMsgIntervalConf.delayReqToSyncRatio = 2;
ptoConfigParams.logMsgIntervalConf.logMinPdelayReqInterval= 0;
ptoConfigParams.logMsgIntervalConf.logSyncInterval = 0;
//
// "domainNumber" field in the PTP Header.
//
ptoConfigParams.domainNumber = 0x00;
//
// Automatic Message reply switches follow
//
//
// Peer to Peer mechanism not required, so disable sending of PDelayReq
// packet.
//
ptoConfigParams.ptoAutoPDelayReqMode =
ETHERNET_PTO_AUTO_P_DELAY_REQ_MESSAGE_DISABLE;
//
// This is Master code, so enable sending of Sync packets.
//
ptoConfigParams.ptoAutoPtpSyncMode =
ETHERNET_PTO_AUTO_SYNC_MESSAGE_ENABLE;
//
// Since this is Master code, enabling this switch will result in sending
// of automatic DelayResp messages in response to the DelayReq messages
// sent by the slave.
//
ptoConfigParams.ptoDelayReqRespMode =
ETHERNET_PTO_DELAY_REQ_DELAY_RESP_ENABLE;
//
// Peer to Peer mechanism not required, so disable sending of PDelayResp
// packet.
//
ptoConfigParams.ptoPDelayRespMode =
ETHERNET_PTO_P_DELAY_RESP_MESSAGE_DISABLE;
//
// Pass the configuration to the Ethernet driver to program the hardware
// with this.
//
Ethernet_setConfigPTPOffload(EMAC_BASE, ptoConfigParams);
//
// Finally, enable the PTP offload engine for above configuration to take
// effect.
//
Ethernet_enableDisablePTPOffload(EMAC_BASE, ETHERNET_PTP_OFFLOAD_ENABLE);
while(1)
{
}
}
@@ -0,0 +1,396 @@
//#############################################################################
//
// FILE: ethernet_ex5_ptp_offload_slave.c
//
// TITLE: Ethernet PTP Offload Slave Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet PTP Offload Slave </h1>
//!
//! This example configures the device in IEEE PTPv2 Slave mode and sets the
//! options that are needed by the offload engine to operate such as the
//! \e domainNumber, \e LogSyncInterval among others. After that it enables
//! sending DelayReq messages periodically for every configurable number of
//! Sync packets.
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in PTP Offload Slave mode.
//! The example project \e Ethernet \e PTP \e Offload \e Master is intended to
//! be used along with this project to see the whole PTP Offload engine in
//! action. The second device is configured as \e Slave and both devices in
//! conjunction exchange Sync, DelayReq and DelayResp packets.
//!
//! Refer to the C28x CPU1 code of ethernet_config_c28x project for configuring
//! the PTP clock that drives the system time counter on the Ethernet module.
//!
//! \b Watch \b Variables \n
//! - Ethernet_ptpSyncPktCount
//! - Ethernet_ptpDelayRespPktCount
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
#include "driverlib_cm.h"
#include "cm.h"
//
// This frequency is actually set in the c28x side code. If it is changed
// there, then the following value also needs to be updated since the
// timestamping module is initialized with the following values.
//
#define PTP_REF_CLOCK_FREQ 100000000
#define PTP_REF_CLOCK_PERIOD 1000000000/PTP_REF_CLOCK_FREQ
#define NUM_PACKET_DESC_RX_APPLICATION 8U
#define ETHERNET_NO_OF_RX_PACKETS 8U
#define ETHERNET_MAX_PACKET_LENGTH 100U
static Ethernet_Handle emac_handle;
extern Ethernet_Device Ethernet_device_struct;
extern void Ethernet_enableMACInterrupt(uint32_t base, uint32_t flags);
//
// Prototype definitions for this example
//
interrupt void Ethernet_customGenericISR(void);
// This function is a callback function called by the LLD to
// Get a Packet Buffer. Has to return a ETHERNET_Pkt_Desc Structure filled
// User or upper level stack can rewrite this API for their own use case
//
uint32_t Ethernet_numRxCallbackCustom = 0;
uint32_t Ethernet_ptpSyncPktCount = 0;
uint32_t Ethernet_ptpDelayRespPktCount = 0;
uint32_t Ethernet_customGenericInterruptCount = 0;
uint32_t Ethernet_numGetPacketBufferCallbackCustom;
Ethernet_Pkt_Desc pktDescriptorRXCustom[NUM_PACKET_DESC_RX_APPLICATION];
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
Ethernet_Pkt_Desc* Ethernet_getPacketBufferCustom(void)
{
uint32_t shortIndex = (Ethernet_numGetPacketBufferCallbackCustom + 3) %
NUM_PACKET_DESC_RX_APPLICATION;
Ethernet_numGetPacketBufferCallbackCustom++;
pktDescriptorRXCustom[shortIndex].bufferLength =
ETHERNET_MAX_PACKET_LENGTH;
pktDescriptorRXCustom[shortIndex].dataBuffer =
&Ethernet_device_struct.rxBuffer[
(ETHERNET_MAX_PACKET_LENGTH * Ethernet_device_struct.rxBuffIndex)];
//
// Wrap around
//
Ethernet_device_struct.rxBuffIndex += 1U;
Ethernet_device_struct.rxBuffIndex =
(Ethernet_device_struct.rxBuffIndex % ETHERNET_NO_OF_RX_PACKETS);
//
// Usable from Address 0
//
pktDescriptorRXCustom[shortIndex].dataOffset = 0U;
return (&(pktDescriptorRXCustom[shortIndex]));
}
Ethernet_Pkt_Desc* Ethernet_receivePacketCallbackCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket)
{
//
// 14th byte in the received packet is 'messageType' field of
// ptp frame format.
//
// messageType == 0x0 indicates "Sync" packet.
// messageType == 0x9 indicates "DelayResp" packet.
//
if ((pPacket->dataBuffer[14] & 0x0F) == 0x0)
Ethernet_ptpSyncPktCount++;
else if ((pPacket->dataBuffer[14] & 0x0F) == 0x9)
Ethernet_ptpDelayRespPktCount++;
Ethernet_numRxCallbackCustom++;
//
// This is a placeholder for Application specific handling
// We are replenishing the buffer received with another buffer
//
return Ethernet_getPacketBufferCustom();
}
main(void)
{
Ethernet_InitConfig *pInitCfg;
Ethernet_InitInterfaceConfig initInterfaceConfig;
uint32_t varPtpConfig = 0;
float subSecondInc;
//
// Hardcoded MAC Address
//
uint32_t mac_lower = 0x00F263A8;
uint32_t mac_higher = 0x00800000;
//
// Initialize device clock and peripherals
//
CM_init();
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
Ethernet_getInitConfig(pInitCfg);
pInitCfg->pfcbRxPacket=&Ethernet_receivePacketCallbackCustom;
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBufferCustom;
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg, &emac_handle);
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
Interrupt_registerHandler(INT_EMAC, Ethernet_customGenericISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
Interrupt_enable(INT_EMAC);
Ethernet_setMACAddr(EMAC_BASE,
0,
mac_higher,
mac_lower,
ETHERNET_CHANNEL_0);
//
// We need to program this standard multicast address so that this device
// identifies PTP over Ethernet packets correctly. "01:1B:19:00:00:00"
//
Ethernet_setMACAddr(EMAC_BASE,
1,
0x00000000,
0x00191B01,
ETHERNET_CHANNEL_0);
//
// Ethernet PTP module is configured with:
// - Slave
// - Identify event messages (Sync, DelayReq)
// - Identify PTP over Ethernet packets
// - PTP version 2
// - Digital Rollover
//
varPtpConfig = ETHERNET_MAC_TIMESTAMP_CONTROL_TSEVNTENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSIPENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSVER2ENA |
ETHERNET_MAC_TIMESTAMP_CONTROL_TSCTRLSSR;
subSecondInc = PTP_REF_CLOCK_PERIOD;
Ethernet_setConfigTimestampPTP(EMAC_BASE, varPtpConfig, subSecondInc);
Ethernet_enableSysTimePTP(EMAC_BASE);
Ethernet_setSysTimePTP(EMAC_BASE, 0x4132EDCA, 0x25a5a5a5);
//
// Enable the timestamp interrupt to get an interrupt when timestamp is
// captured for the outgoing DelayReq packet.
//
Ethernet_enableMACInterrupt(EMAC_BASE, ETHERNET_MAC_INTERRUPT_ENABLE_TSIE);
//
// PTP Offlad related configuration follows. This is used to automatically
// assemble the PTP Header for the packets which will be ultimately sent
// out by the PTP Offload engine.
//
Ethernet_PTPOffloadConfigParams ptoConfigParams = {0};
//
// "sourcePortIdentity" field in the PTP Header.
//
ptoConfigParams.srcPortId.id0 = 0xFFFFFFFF;
ptoConfigParams.srcPortId.id1 = 0xFFFFFFFF;
ptoConfigParams.srcPortId.id2 = 0x0000;
//
// "logMessageInterval" field in the PTP Header.
//
ptoConfigParams.logMsgIntervalConf.delayReqToSyncRatio = 2;
ptoConfigParams.logMsgIntervalConf.logMinPdelayReqInterval= 0;
ptoConfigParams.logMsgIntervalConf.logSyncInterval = 0;
//
// "domainNumber" field in the PTP Header.
//
ptoConfigParams.domainNumber = 0x00;
//
// Automatic Message reply switches follow
//
//
// Peer to Peer mechanism not required, so disable sending of PDelayReq
// packet.
//
ptoConfigParams.ptoAutoPDelayReqMode =
ETHERNET_PTO_AUTO_P_DELAY_REQ_MESSAGE_DISABLE;
//
// This is slave code, so disable sending of Sync packets.
//
ptoConfigParams.ptoAutoPtpSyncMode =
ETHERNET_PTO_AUTO_SYNC_MESSAGE_DISABLE;
//
// Since this is slave code, enabling this switch will result in sending
// of automatic DelayReq messages in response to a configurable number of
// Sync packets.
//
ptoConfigParams.ptoDelayReqRespMode =
ETHERNET_PTO_DELAY_REQ_DELAY_RESP_ENABLE;
//
// Peer to Peer mechanism not required, so disable sending of PDelayResp
// packet.
//
ptoConfigParams.ptoPDelayRespMode =
ETHERNET_PTO_P_DELAY_RESP_MESSAGE_DISABLE;
//
// Pass the configuration to the Ethernet driver to program the hardware
// with this.
//
Ethernet_setConfigPTPOffload(EMAC_BASE, ptoConfigParams);
//
// Finally, enable the PTP offload engine for above configuration to take
// effect.
//
Ethernet_enableDisablePTPOffload(EMAC_BASE, ETHERNET_PTP_OFFLOAD_ENABLE);
//
// Wait forever. Sending of the messages is handled by the PTP Offload
// hardware.
//
while(1)
{
}
}
interrupt void Ethernet_customGenericISR(void)
{
//
// Increment the generic interrupt receive count
//
Ethernet_customGenericInterruptCount++;
if(true == Ethernet_isTimestampIntActive())
{
//
// Placeholder to call any Timestamp Interrupt Handler API.
//
// Following is a dummy implementation for a case
// when tx timestamp is captured for an outgoing packet
// in PTP Offload mode. Refer to
// individual APIs for more information.
// Note: For this particular case, when the interrupt
// is generated for transmit timestamp capture
// in PTP offload mode the Interrupt is cleared
// only when the actual timestamp
// is read from the Timestamp Status
// Seconds and Nanoseconds registers
//
uint32_t seconds, nanoSeconds;
//
// Check if the transmit timestamp status is set.
//
if(true == Ethernet_isTransmitTimestampStatusSet())
{
//
// Read the timestamp for the transmitted packet to
//clear this interrupt
//
Ethernet_getOneStepTransmitTimestampPTP(
Ethernet_device_struct.baseAddresses.enet_base,
&seconds,
&nanoSeconds);
}
}
}
@@ -0,0 +1,256 @@
//#############################################################################
//
// FILE: ethernet_ex6_basic_crc_checksum_offload.c
//
// TITLE: Ethernet CRC and Checksum Offloading Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet MAC CRC and Checksum Offload </h1>
//!
//! This example demonstrates the steps to be followed in using the
//! Ethernet of the Communication Manager Subsystem to initialize
//! the Ethernet module and Configure the module in MAC Loop back mode.
//! Demonstrates how to program the CRC offload
//! and Checksum Offload(IP Checksum)
//! Prepares a packet to be sent, Sends the packet and reads the statistics
//! to check if the packet is received by the module
//! Before running this Communication Manager code the C28x cpu1 code has to be run
//! to configure the clocks to Communication manager
//! and required IO pads for Ethernet module
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in Internal Loop back mode
//! and hence needs no external connection on the MII Data lines.
//! But it needs the MII Tx and Rx clocks to be input on those pins
//! Refer to the C28x CPU1 code of ethernet_config_c28x project
//! for which GPIOs are used for connecting to the PHY
//!
//! \b Watch \b Variables \n
//! - None
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Included Files
//
#include "driverlib_cm.h"
#include "cm.h"
//
// Defines
//
#define ETHERNET_NO_OF_RX_PACKETS 1U
//
//Change this define for changing Packet buffer length
//
#define ETHERNET_MAX_PACKET_LENGTH 128U
//
// Globals
//
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
//
//This is an example IP protocol packet
//
uint8_t icmp98[92] = {
//0xa8, 0x63, 0xf2, 0x00, 0x00, 0x80,
0x04, 0x03, 0x02, 0x01, 0x06, 0x05,
/* Since the sender MAC address is going to be embedded
* before sending the packet, we comment the following 6 bytes
*/
/*0x78, 0xa5, // .c....x. // 0x04, 0xc8, 0xa5, 0x0b,*/
0x08, 0x00, 0x45, 0x00, /* ......E. */
0x00, 0x54, 0xb1, 0xa2, 0x40, 0x00, 0x40, 0x01, /* .T..@.@. */
0x07, 0xae, 0xc0, 0xa8, 0x00, 0x03, 0xc0, 0xa8, /* ........ */
0x00, 0x04, 0x07, 0x00, 0x32, 0x4a, 0x57, 0xe8, /* ....2JW. */
0x00, 0x01, 0x73, 0x84, 0xfe, 0x58, 0x04, 0xec, /* ..s..X.. */
0x0c, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, /* ........ */
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, /* ........ */
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, /* ........ */
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, /* .. !"#$% */
0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, /* &'()*+,- */
0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, /* ./012345 */
0x36, 0x38 /* 67 */
};
#define PACKET_LENGTH sizeof(icmp98)
//
// Main
//
void main(void)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
Ethernet_InitConfig *pInitCfg;
Ethernet_Pkt_Desc pktDesc;
Ethernet_Statistics stats;
Ethernet_Handle emac_handle;
//
// Initialize device clock and peripherals
//
CM_init();
//
//Select the MII interface of the module
//
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
//
// Get an initial configuration of known good parameters
//
Ethernet_getInitConfig(pInitCfg);
//
//Configure the Loopback mode
//
pInitCfg->loopbackMode = ETHERNET_MAC_CONFIGURATION_LM_LOOPBACK_ENABLED;
//
//Assign the callbacks for Getting packet buffer when needed
//Releasing the TxPacketBuffer on Transmit interrupt callbacks
//Receive packet callback on Receive packet completion interrupt
//
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBuffer;
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBuffer;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallback;
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
//
//The Application handle is not used by this application
//Hence using a dummy value of 1
//
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
//
//Prepare a Packet Descriptor structure to send a packet
//This contains a single buffer packet
pktDesc.bufferLength = PACKET_LENGTH;
pktDesc.dataOffset = 0;
pktDesc.dataBuffer = icmp98;
pktDesc.nextPacketDesc = 0;
//The Source address shall be inserted by the MAC
//Packet CRC is auto computed by the module and appended in the packet
//Please OR these values to achieve required CRC offloading
//ETHERNET_PKT_FLAG_CRC_PAD_INS value is zero which corresponds to CRC
//Insertion and Pad enabling
//Use ETHERNET_PKT_FLAG_CRC_INS_NO_PAD to insert CRC but no padding
//Use ETHERNET_PKT_FLAG_CRC_PAD_DIS to disable CRC and Disable padding
//Use ETHERNET_PKT_FLAG_CRC_REPL_NO_PAD to replace CRC and disable padding
//
//ETHERNET_PKT_FLAG_CIC flag enables the Checksum offload feature at driver
//which turns on the Hardware Checksum feature with this flag being set
//
pktDesc.flags = (ETHERNET_PKT_FLAG_SOP | ETHERNET_PKT_FLAG_EOP |
ETHERNET_PKT_FLAG_SA_INS | ETHERNET_PKT_FLAG_CIC);
pktDesc.pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
pktDesc.pktLength = PACKET_LENGTH;
pktDesc.validLength = PACKET_LENGTH;
pktDesc.numPktFrags = 1;
//
//Send the packet prepared
//
Ethernet_sendPacket(emac_handle,&pktDesc);
//
//Delay for the MAC to send the packet on the wire and receive it
//
SysCtl_delay(3000);
//
//Read the statistics of the Module
//
Ethernet_getStatistics(emac_handle, &stats);
//
//Check if a packet has been received
//
if(!stats.rxUnicastPacketsGood)
__asm(" bkpt #0");
}
@@ -0,0 +1,438 @@
//#############################################################################
//
// FILE: ethernet_ex7_transport_segmentation_offload.c
//
// TITLE: Ethernet Transport Segmentation Offload Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet Transmit Segmentation Offload </h1>
//!
//! This example demonstrates the steps to be followed in using the
//! Ethernet of the Communication Manager Subsystem to initialize
//! the Ethernet module and Configure the module in MAC Loop back mode.
//! Demonstrates how to program the Transport Segmentation Offload feature
//! in the Low level driver which in turn programs the feature in the hardware
//! The Hardware segments a single packet into configured segment size
//! Prepares a packet to be sent, Sends the packet and reads the statistics
//! to check if the packet is received by the module
//! Before running this Communication Manager code the C28x cpu1 code has to be run
//! to configure the clocks to Communication manager
//! and required IO pads for Ethernet module
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in Internal Loop back mode
//! and hence needs no external connection on the MII Data lines.
//! But it needs the MII Tx and Rx clocks to be input on those pins
//! Refer to the C28x CPU1 code of ethernet_config_c28x project
//! for which GPIOs are used for connecting to the PHY
//!
//! \b Watch \b Variables \n
//! - None
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Included Files
//
#include "driverlib_cm.h"
#include "cm.h"
//
// Defines
//
#define PACKET_LENGTH 1334
#define NO_OF_RX_PACKETS 4U
//
//Change this define for changing Packet buffer length
//
#define MAX_PACKET_LENGTH 450U
uint8_t Ethernet_rxBuffer[NO_OF_RX_PACKETS *
MAX_PACKET_LENGTH];
//
// Globals
//
Ethernet_Pkt_Desc pktDescriptorRX;
uint32_t rxBuffIndex=0;
//
//This is an example IP protocol packet
//
uint8_t pSegmentData[PACKET_LENGTH]= {
0x04, 0x03, 0x02, 0x01, 0x06, 0x05, 0x08, 0x00,
0x45, 0x00, 0x05, 0x28, 0x00, 0x00, 0x40, 0x00,
0x40, 0x06, 0xB3, 0x7F, 0xC0, 0xA8, 0x00, 0x01,
0xC0, 0xA8, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x50, 0x00, 0xFF, 0xFC, 0x67, 0x58, 0x00, 0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
};
Ethernet_Pkt_Desc *getPacketBufferCustom(void);
//
// Main
//
void main(void)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
Ethernet_InitConfig *pInitCfg;
Ethernet_Pkt_Desc pktDesc;
uint32_t i;
Ethernet_Statistics stats;
Ethernet_Handle emac_handle;
//
// Initialize device clock and peripherals
//
CM_init();
//
//Select the MII interface of the module
//
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
//
// Get an initial configuration of known good parameters
//
Ethernet_getInitConfig(pInitCfg);
for(i=0;i<pInitCfg->numChannels;i++)
{
pInitCfg->chInfo[ETHERNET_CH_DIR_TX][i].dmaQueueSize = ETHERNET_MTL_Q_OP_MODE_QSIZE_2048;
//
//This enables the Transport Segmentation Engine
//
pInitCfg->chInfo[ETHERNET_CH_DIR_TX][i].enableTSE = ETHERNET_TX_CHANNEL_TSE_ENABLE;
//
//This configures the Segment Size for each Transport Segment going
//out/Transmitted by the MAC
//
pInitCfg->chInfo[ETHERNET_CH_DIR_TX][i].maximumSegmentSize = 0x140;
}
//
//Configure the Loopback mode
//
pInitCfg->loopbackMode = ETHERNET_MAC_CONFIGURATION_LM_LOOPBACK_ENABLED;
//
//Assign the callbacks for Getting packet buffer when needed
//Releasing the TxPacketBuffer on Transmit interrupt callbacks
//Receive packet callback on Receive packet completion interrupt
//
pInitCfg->pfcbGetPacket = &getPacketBufferCustom;
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBuffer;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallback;
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
//
//The Application handle is not used by this application
//Hence using a dummy value of 1
//
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
//
//Prepare a Packet Descriptor structure to send a packet
//This contains a single buffer packet
pktDesc.bufferLength = PACKET_LENGTH;
pktDesc.dataOffset = 0;
pktDesc.dataBuffer = pSegmentData;
//
//Second dataBuffer points to location where the Transport Segment starts
//
pktDesc.dataBuffer2 = pSegmentData+48;
pktDesc.nextPacketDesc = 0;
//
//Enable Transport Segmentation on the packet
//This also enables CRC offload engine
//Source Address is to be auto inserted by the MAC
//
pktDesc.flags = ETHERNET_PKT_FLAG_SOP | ETHERNET_PKT_FLAG_EOP |
ETHERNET_PKT_FLAG_SA_INS | ETHERNET_PKT_FLAG_TSE;
pktDesc.pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
//
//
//
pktDesc.pktLength = 1280;
pktDesc.validLength = 48; //Header Buffer 1
pktDesc.buffer2Length = 1280;//Payload length
pktDesc.numPktFrags = 1;
//
//Send the packet prepared
//
Ethernet_sendPacket(emac_handle,&pktDesc);
//
//Delay for the MAC to send the packet on the wire and receive it
//
SysCtl_delay(3000);
//
//Read the statistics of the Module
//
Ethernet_getStatistics(emac_handle, &stats);
//
//Check if a packet has been received
//There should be three packets received since
//There are three segments/frames sent by the MAC after segmentation
//
while(1);
}
Ethernet_Pkt_Desc *getPacketBufferCustom(void)
{
pktDescriptorRX.bufferLength = MAX_PACKET_LENGTH;
pktDescriptorRX.dataBuffer = &Ethernet_rxBuffer [
(MAX_PACKET_LENGTH * rxBuffIndex)];
//
//Wrap around
//
rxBuffIndex += 1U;
rxBuffIndex = rxBuffIndex% NO_OF_RX_PACKETS;
return(&pktDescriptorRX);
}
@@ -0,0 +1,297 @@
//#############################################################################
//
// FILE: ethernet_ex8_vlan_filtering.c
//
// TITLE: Ethernet VLAN and VLAN Filter Example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet MAC Internal Loopback </h1>
//!
//! This example demonstrates the steps to be followed in using the
//! Ethernet of the Communication Manager Subsystem to initialize
//! the Ethernet module and Configure the module in MAC Loop back mode
//! The packet sent is inserted with a VLAN tag.
//! A VLAN filter is configured to route it to a different channel
//! Prepares a packet to be sent, Sends the packet and reads the statistics
//! to check if the packet is received by the module
//! Before running this Communication Manager code the C28x cpu1 code has to be run
//! to configure the clocks to Communication manager
//! and required IO pads for Ethernet module
//!
//! \b External \b Connections \n
//! This example programs the Ethernet module in Internal Loop back mode
//! and hence needs no external connection on the MII Data lines.
//! But it needs the MII Tx and Rx clocks to be input on those pins
//! Refer to the C28x CPU1 code of ethernet_config_c28x project
//! for which GPIOs are used for connecting to the PHY
//!
//! \b Watch \b Variables \n
//! - None
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Included Files
//
#include "driverlib_cm.h"
#include "cm.h"
//
// Defines
//
#define ETHERNET_NO_OF_RX_PACKETS 1U
//
//Change this define for changing Packet buffer length
//
#define ETHERNET_MAX_PACKET_LENGTH 1538U
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
//
// Globals
//
#define PACKET_LENGTH 1508
uint8_t pData[PACKET_LENGTH];
//
// Main
//
void main(void)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
Ethernet_InitConfig *pInitCfg;
Ethernet_Pkt_Desc pktDesc;
uint32_t i;
Ethernet_Statistics stats;
Ethernet_VlanConfig vLANConfig;
Ethernet_VLAN_Perfect_FilterParams vlanPerfectFilterParams;
Ethernet_Handle emac_handle;
//
// Initialize device clock and peripherals
//
CM_init();
//
//Select the MII interface of the module
//
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
//
// Get an initial configuration of known good parameters
//
Ethernet_getInitConfig(pInitCfg);
//
//Configure the Loopback mode
//
pInitCfg->loopbackMode = ETHERNET_MAC_CONFIGURATION_LM_LOOPBACK_ENABLED;
//
//Assign the callbacks for Getting packet buffer when needed
//Releasing the TxPacketBuffer on Transmit interrupt callbacks
//Receive packet callback on Receive packet completion interrupt
//
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBuffer;
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBuffer;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallback;
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
//
//The Application handle is not used by this application
//Hence using a dummy value of 1
//
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_TX1, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
Interrupt_registerHandler(INT_EMAC_RX1, Ethernet_receiveISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
Interrupt_enable(INT_EMAC_TX1);
Interrupt_enable(INT_EMAC_RX1);
//
//Setup VLAN Parameters
//
vLANConfig.vlan_tag =0x0B0B;
vLANConfig.vlanType = ETHERNET_VLAN_TYPE_C;
vLANConfig.vlanTagControl = ETHERNET_VLAN_TX_INSERT;
//
//This sets a VLAN Tag insertion for all the packets going out of the MAC
//
Ethernet_setConfig(emac_handle,ETHERNET_SET_CONFIG_VLAN_TX_OUTER,
&vLANConfig,sizeof(vLANConfig));
//
//Make the Queues to assign based on dynamic Queues
//Hence the DMA channels will be selected as programmed in the VLAN Filter
//This is needed for any Dynamic Queue handling based on incoming parameter
//
Ethernet_setDMARxQueueMode(EMAC_BASE, ETHERNET_RX_DMA_QUEUE_DYNAMIC, \
ETHERNET_QUEUE_0, ETHERNET_CHANNEL_1);
Ethernet_setDMARxQueueMode(EMAC_BASE, ETHERNET_RX_DMA_QUEUE_DYNAMIC, \
ETHERNET_QUEUE_1, ETHERNET_CHANNEL_1);
//
//Now Set up the VLAN Filter Parameters
//
vlanPerfectFilterParams.dmaChannelEnable = ETHERNET_DMA_CHANNELNUM_ENABLED;
//
//Let the packet come into dma Channel 1 for a matching VLAN tag
//
vlanPerfectFilterParams.dmaChannelNum = ETHERNET_CHANNEL_1;
vlanPerfectFilterParams.filterid = 1;
vlanPerfectFilterParams.vlanid =0x0B0B;
vlanPerfectFilterParams.vlanEnableDisable = (Ethernet_VlanRxPerfectFilterEnable)ETHERNET_VLAN_RX_FILTER_INNER_VLAN_ENABLED;
vlanPerfectFilterParams.vlanFilterMode = ETHERNET_VLAN_PERFECT_FILTER_COMPARE_12BITS;
vlanPerfectFilterParams.vlanPerfectTypeComparisonDisable = ETHERNET_VLAN_PERFECT_FILTER_TYPE_COMPARISON_ENABLED;
//Check for 0x8100
vlanPerfectFilterParams.vlanType = ETHERNET_VLAN_TYPE_C;
//Check only OuterVLAN
vlanPerfectFilterParams.innerVLANEnabled = ETHERNET_VLAN_RX_FILTER_INNER_VLAN_DISABLED;
Ethernet_setConfig(emac_handle,ETHERNET_SET_CONFIG_FILTER_VLAN_PERFECT,
&vlanPerfectFilterParams,sizeof(vlanPerfectFilterParams));
//
//Form the Packet in Memory
//
for(i=0;i<PACKET_LENGTH/4;i++)
{
if(i == 0)
*((uint32_t *)pData + i) = 0x01020304;
else if(i == 1)
*((uint32_t *)pData + i) = 0xFFFF0506;
else
HWREG((uint32_t *)pData +i) = 0xFFFFFFFF;
}
//
//Prepare a Packet Descriptor structure to send a packet
//This contains a single buffer packet
//
pktDesc.bufferLength = PACKET_LENGTH;
pktDesc.dataOffset = 0;
pktDesc.dataBuffer = pData;
pktDesc.nextPacketDesc = 0;
//
//The Source address shall be inserted by the MAC
//Packet CRC is auto computed by the module and appended in the packet
//Please OR these values to achieve required CRC offloading
//ETHERNET_PKT_FLAG_CRC_PAD_INS value is zero which corresponds to CRC
//Insertion and Pad enabling
//Use ETHERNET_PKT_FLAG_CRC_INS_NO_PAD to insert CRC but no padding
//Use ETHERNET_PKT_FLAG_CRC_PAD_DIS to disable CRC and Disable padding
//Use ETHERNET_PKT_FLAG_CRC_REPL_NO_PAD to replace CRC and disable padding
//
pktDesc.flags = (ETHERNET_PKT_FLAG_SOP | ETHERNET_PKT_FLAG_EOP |
ETHERNET_PKT_FLAG_SA_INS );
pktDesc.pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
pktDesc.pktLength = PACKET_LENGTH;
pktDesc.validLength = PACKET_LENGTH;
pktDesc.numPktFrags = 1;
//
//Send the packet prepared
//
Ethernet_sendPacket(emac_handle,&pktDesc);
//
//Delay for the MAC to send the packet on the wire and receive it
//
SysCtl_delay(3000);
//
//Read the statistics of the Module
//
Ethernet_getStatistics(emac_handle, &stats);
//
//Check if a packet has been received
//The packet should have come through Receive DMA Channel 1
//
if(!stats.rxUnicastPacketsGood)
__asm(" bkpt #0");
}
@@ -0,0 +1,251 @@
//#############################################################################
//
// FILE: ethernet_ex9_revmii_example_mii_remote.c
//
// TITLE: Ethernet RevMII example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet RevMII Example MII side </h1>
//!
//! This example demonstrates the steps to be followed in using the
//! Ethernet of the Communication Manager Subsystem to initialize
//! the Ethernet module and Configure the module in MII mode.
//! The other device is running a RevMII mode
//! This demonstrates the sequence for MII - RevMII communication
//! Before running this Communication Manager code the C28x cpu1 code has to be run
//! to configure the clocks to Communication manager
//! and required IO pads for Ethernet module
//! This Example has been validated on an TI internal board and will not run on
//! Control Card. This has been run with RevMII Example Remote MAC side.
//! Once the RevMII mode is configured this appears like a PHY to the external
//! MAC which is connected over MDIO. Even though there is no physical PHY
//! the RevMII mode lets the remote MAC see this side as a MAC.
//!
//! \b External \b Connections \n
//! TBD
//!
//! \b Watch \b Variables \n
//! - None
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Included Files
//
#include "driverlib_cm.h"
#include "cm.h"
//
// Defines
//
#define PACKET_LENGTH 132
#define ETHERNET_NO_OF_RX_PACKETS 1U
//
//Change this define for changing Packet buffer length
//
#define ETHERNET_MAX_PACKET_LENGTH 128U
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
#define REVMII_REMOTE_PHY_ADDRESS 0U
#define REVMII_LOCAL_PHY_ADDRESS 0xAU
//
// Globals
//
uint8_t pData[PACKET_LENGTH];
//
// Main
//
void main(void)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
Ethernet_InitConfig *pInitCfg;
Ethernet_Pkt_Desc pktDesc;
uint32_t i;
Ethernet_Statistics stats;
Ethernet_Handle emac_handle;
uint16_t revmiiIntStatus;
//
// Initialize device clock and peripherals
//
CM_init();
//
//Select the MII interface of the module
//
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
//
// Get an initial configuration of known good parameters
//
Ethernet_getInitConfig(pInitCfg);
//
//Assign the callbacks for Getting packet buffer when needed
//Releasing the TxPacketBuffer on Transmit interrupt callbacks
//Receive packet callback on Receive packet completion interrupt
//
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBuffer;
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBuffer;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallback;
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
//
//The Application handle is not used by this application
//Hence using a dummy value of 1
//
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
//
//Form the Packet in Memory
//
for(i=0;i<PACKET_LENGTH/4;i++)
{
if(i == 0)
*((uint32_t *)pData + i) = 0x01020304;
else if(i == 1)
*((uint32_t *)pData + i) = 0xFFFF0506;
else
HWREG((uint32_t *)pData +i) = 0xFFFFFFFF;
}
//
//Configure the PHY address for Remote PHY in the MDIO module
//
Ethernet_configurePHYAddress(EMAC_BASE,REVMII_REMOTE_PHY_ADDRESS);
//
//Rev MII PHY control register
//Loopback and 100mbps mode
//Ethernet_writePHYRegister(EMAC_BASE,0x0,0x6100);
//No Loopback and 100mbps mode
//
Ethernet_readPHYRegister(EMAC_BASE,
0x0);
Ethernet_writePHYRegister(EMAC_BASE,0x0,0x2100);
//Check for RevMII link status change interrupt
//Read RevMII Interrupt Status Mask Register
revmiiIntStatus = Ethernet_readPHYRegister(EMAC_BASE,
0x10);
if(revmiiIntStatus& 0x100)
{
//
//Clear the interrupt by writing to LSI field of RevMII Interrupt
//Status Mask Register
//
revmiiIntStatus &= 0x100;
Ethernet_writePHYRegister(EMAC_BASE,
0x10,
revmiiIntStatus);
}
pktDesc.bufferLength = PACKET_LENGTH;
pktDesc.dataOffset = 0;
pktDesc.dataBuffer = pData;
pktDesc.nextPacketDesc = 0;
pktDesc.flags = ETHERNET_PKT_FLAG_SOP |ETHERNET_PKT_FLAG_EOP|ETHERNET_PKT_FLAG_SA_INS;
pktDesc.pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
pktDesc.pktLength = PACKET_LENGTH;
pktDesc.validLength = PACKET_LENGTH;
pktDesc.numPktFrags = 1;
Ethernet_sendPacket(emac_handle,&pktDesc);
//
//We expect a packet to come from Remote side
//Query Statistics to check if a packet has come
//
Ethernet_getStatistics(emac_handle, &stats);
if(stats.rxUnicastPacketsGood)
__asm(" bkpt #0");
else
__asm(" bkpt #0");
}
@@ -0,0 +1,255 @@
//#############################################################################
//
// FILE: ethernet_ex9_revmii_example_revmii_side.c
//
// TITLE: Ethernet RevMII example
//
//! \addtogroup driver_example_cm_list
//! <h1> Ethernet RevMII Example RevMII side </h1>
//!
//! This example demonstrates the steps to be followed in using the
//! Ethernet of the Communication Manager Subsystem to initialize
//! the Ethernet module and Configure the module in RevMII mode.
//! Before running this Communication Manager code the C28x cpu1 code has to be run
//! to configure the clocks to Communication manager
//! and required IO pads for Ethernet module
//! This Example has been validated on an TI internal board and will not run on
//! Control Card. This has been run with RevMII Example Remote MAC side.
//! Once the RevMII mode is configured this appears like a PHY to the external
//! MAC which is connected over MDIO. Even though there is no physical PHY
//! the RevMII mode lets the remote MAC see this side as a PHY.
//!
//! \b External \b Connections \n
//! TBD
//!
//! \b Watch \b Variables \n
//! - None
//!
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Included Files
//
#include "driverlib_cm.h"
#include "cm.h"
//
// Defines
//
#define PACKET_LENGTH 132
#define ETHERNET_NO_OF_RX_PACKETS 1U
//
//Change this define for changing Packet buffer length
//
#define ETHERNET_MAX_PACKET_LENGTH 128U
uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
ETHERNET_MAX_PACKET_LENGTH];
#define REVMII_REMOTE_PHY_ADDRESS 0U
#define REVMII_LOCAL_PHY_ADDRESS 0xAU
//
// Globals
//
uint8_t pData[PACKET_LENGTH];
//
// Main
//
void main(void)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
Ethernet_InitConfig *pInitCfg;
Ethernet_Pkt_Desc pktDesc;
uint32_t i;
Ethernet_Handle emac_handle;
//
// Initialize device clock and peripherals
//
CM_init();
//
//Select the MII interface of the module
//
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_REVMII;
//
//This configures external 25MHZ clock as the source for RevMII
//
initInterfaceConfig.clockSel = ETHERNET_SS_CLK_SRC_INTERNAL;
//
//This is the MDIO address used to access the internal RevMII registers
//Local PHY
//
initInterfaceConfig.localPhyAddress = REVMII_LOCAL_PHY_ADDRESS;
//
//This is the PHY address for the Remote PHY
//
initInterfaceConfig.remotePhyAddress = REVMII_REMOTE_PHY_ADDRESS;
//
//Assign SoC specific functions for Enabling,Disabling interrupts
//and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable = &Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable = &Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable = &Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset = &Platform_resetPeripheral;
//
//Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
//Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
//
// Get an initial configuration of known good parameters
//
Ethernet_getInitConfig(pInitCfg);
//
//Assign the callbacks for Getting packet buffer when needed
//Releasing the TxPacketBuffer on Transmit interrupt callbacks
//Receive packet callback on Receive packet completion interrupt
//
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBuffer;
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBuffer;
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallback;
//
//Assign the Buffer to be used by the Low level driver for receiving
//Packets. This should be accessible by the Ethernet DMA
//
pInitCfg->rxBuffer = Ethernet_rxBuffer;
//
//The Application handle is not used by this application
//Hence using a dummy value of 1
//
Ethernet_getHandle((Ethernet_Handle)1,pInitCfg , &emac_handle);
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
//
//Enable the default interrupt handlers
//
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
//
//Configure the PHY address for Local PHY in the MDIO module
//
Ethernet_configurePHYAddress(EMAC_BASE,REVMII_LOCAL_PHY_ADDRESS);
//
//Read RevMII Interrupt Status Mask Register
//
Ethernet_readPHYRegister(EMAC_BASE,0x0);
//
//Rev MII PHY control register
//Loopback and 100mbps mode
//No Loopback and 100mbps mode
//
Ethernet_writePHYRegister(EMAC_BASE,0x0,0x2100);
//
//Form the Packet in Memory
//
for(i=0;i<PACKET_LENGTH/4;i++)
{
if(i == 0)
*((uint32_t *)pData + i) = 0x01020304;
else if(i == 1)
*((uint32_t *)pData + i) = 0xFFFF0506;
else
HWREG((uint32_t *)pData +i) = 0xFFFFFFFF;
}
//
//Prepare a Packet Descriptor structure to send a packet
//This contains a single buffer packet
//
pktDesc.bufferLength = PACKET_LENGTH;
pktDesc.dataOffset = 0;
pktDesc.dataBuffer = pData;
pktDesc.nextPacketDesc = 0;
//The Source address shall be inserted by the MAC
//Packet CRC is auto computed by the module and appended in the packet
//Please OR these values to achieve required CRC offloading
//ETHERNET_PKT_FLAG_CRC_PAD_INS value is zero which corresponds to CRC
//Insertion and Pad enabling
//Use ETHERNET_PKT_FLAG_CRC_INS_NO_PAD to insert CRC but no padding
//Use ETHERNET_PKT_FLAG_CRC_PAD_DIS to disable CRC and Disable padding
//Use ETHERNET_PKT_FLAG_CRC_REPL_NO_PAD to replace CRC and disable padding
//
pktDesc.flags = (ETHERNET_PKT_FLAG_SOP | ETHERNET_PKT_FLAG_EOP |
ETHERNET_PKT_FLAG_SA_INS);
pktDesc.pktChannel = ETHERNET_DMA_CHANNEL_NUM_0;
pktDesc.pktLength = PACKET_LENGTH;
pktDesc.validLength = PACKET_LENGTH;
pktDesc.numPktFrags = 1;
//
//Send the packet prepared
//
Ethernet_sendPacket(emac_handle,&pktDesc);
//
//Delay for the MAC to send the packet on the wire
//
SysCtl_delay(3000);
__asm(" bkpt #0");
}