[DemoCode下载] I3C你用过吗,快来看看

[复制链接]
929|10
 楼主| wahahaheihei 发表于 2024-1-28 18:43 | 显示全部楼层 |阅读模式
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
  4. * [url=home.php?mod=space&uid=247401]@brief[/url]    Demonstrate how to use I3C0 Slave to reveive and transmit the data from a Master.
  5. *
  6. * [url=home.php?mod=space&uid=17282]@CopyRight[/url] SPDX-License-Identifier: Apache-2.0
  7. * @copyright Copyright (C) 2022 Nuvoton Technology Corp. All rights reserved.
  8. ******************************************************************************/
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "NuMicro.h"


  12. //#define DGBINT          printf
  13. #define DGBINT(...)

  14. /*---------------------------------------------------------------------------------------------------------*/
  15. /* Functions and variables declaration                                                                     */
  16. /*---------------------------------------------------------------------------------------------------------*/
  17. #define I3CS0_SA        (0x68)
  18. #define I3CS0_MID       (0x8123UL)
  19. #define I3CS0_PID       (0xA13573C0UL)

  20. volatile uint32_t   g_RespQ[I3CS_DEVICE_RESP_QUEUE_CNT];
  21. volatile uint32_t   g_RxBuf[I3CS_DEVICE_RX_BUF_CNT], g_TxBuf[I3CS_DEVICE_RX_BUF_CNT];
  22. volatile uint32_t   g_u32IntSelMask = 0, g_u32IntOccurredMask = 0;
  23. volatile uint32_t   g_u32RespStatus = I3CS_STS_NO_ERR;

  24. int32_t I3CS_ProcessNoneRespInt(I3CS_T *i3cs, uint32_t i32IntMask);
  25. int32_t I3CS_ProcessRespError(I3CS_T *i3cs, uint32_t u32RespStatus);
  26. void I3CS0_IRQHandler(void);
  27. void SYS_Init(void);
  28. void UART_Init(void);


  29. /**
  30.   * @brief  Process interrupt events except Response Ready interrupt.
  31.   */
  32. int32_t I3CS_ProcessNoneRespInt(I3CS_T *i3cs, uint32_t u32IntMask)
  33. {
  34.     if(u32IntMask & I3CS_INTEN_DA_ASSIGNED)
  35.         printf("[ Set I3C Dynamic Address 0x%02x ]\n\n", (uint32_t)I3CS_GET_I3CS_DA(i3cs));
  36.     if(u32IntMask & I3CS_INTEN_TRANSFER_ERR)
  37.         printf("[ Transfer error ]\n\n");
  38.     if(u32IntMask & I3CS_INTEN_READ_REQUEST)
  39.         printf("[ Master read request event ]\n\n");
  40.     if(u32IntMask & I3CS_INTEN_CCC_UPDATED)
  41.     {
  42.         printf("[ CCC Updated event ]\n");
  43.         if(i3cs->SLVEVNTS & I3CS_SLVEVNTS_MWLUPD_Msk)
  44.         {
  45.             i3cs->SLVEVNTS = I3CS_SLVEVNTS_MWLUPD_Msk;
  46.             printf("\t* Updated MWL to 0x%x\n\n", (uint32_t)((i3cs->SLVMXLEN&I3CS_SLVMXLEN_MWL_Msk) >> I3CS_SLVMXLEN_MWL_Pos));
  47.         }
  48.         else if(i3cs->SLVEVNTS & I3CS_SLVEVNTS_MRLUPD_Msk)
  49.         {
  50.             i3cs->SLVEVNTS = I3CS_SLVEVNTS_MRLUPD_Msk;
  51.             printf("\t* Updated MRL to 0x%x\n\n", (uint32_t)((i3cs->SLVMXLEN&I3CS_SLVMXLEN_MRL_Msk) >> I3CS_SLVMXLEN_MRL_Pos));
  52.             /* Reset TX FIFO and CMDQ FIFO -> apply resume */
  53.             I3CS_ResetAndResume(i3cs, (I3CS_RESET_TX_BUF | I3CS_RESET_CMD_QUEUE), TRUE);
  54.         }
  55.         else
  56.         {
  57.             printf("\t* Updated - ENTAS%d\n", (uint32_t)((i3cs->SLVEVNTS&I3CS_SLVEVNTS_ACTSTATE_Msk) >> I3CS_SLVEVNTS_ACTSTATE_Pos));
  58.             printf("\t* Updated - HJEN %d\n", (uint32_t)((i3cs->SLVEVNTS&I3CS_SLVEVNTS_HJEN_Msk) >> I3CS_SLVEVNTS_HJEN_Pos));
  59.             printf("\t* Updated - SIREN %d\n", (uint32_t)((i3cs->SLVEVNTS&I3CS_SLVEVNTS_SIREN_Msk) >> I3CS_SLVEVNTS_SIREN_Pos));
  60.         }
  61.     }
  62.    
  63.     return 0;
  64. }

  65. /**
  66.   * @brief  Process response error event.
  67.   */
  68. int32_t I3CS_ProcessRespError(I3CS_T *i3cs, uint32_t u32RespStatus)
  69. {
  70.     printf("[ Resp Error 0x%x] ", (u32RespStatus >> I3CS_RESPQUE_ERRSTS_Pos));
  71.     if(u32RespStatus == I3CS_RESP_CRC_ERR)            
  72.         printf("CRC error\n");
  73.     else if(u32RespStatus == I3CS_RESP_PARITY_ERR)
  74.         printf("Parity error\n");
  75.     else if(u32RespStatus == I3CS_RESP_FRAME_ERRR)
  76.         printf("Frame error\n");
  77.     else if(u32RespStatus == I3CS_RESP_FLOW_ERR)
  78.         printf("Underflow/Overflow error\n");
  79.     else if(u32RespStatus == I3CS_RESP_MASTER_TERMINATE_ERR)
  80.         printf("Master early termination error\n");
  81.     else
  82.         printf("Unknow error\n");

  83.     if(I3CS_IS_PROTOCOL_ERR(i3cs))
  84.         printf("[ Device Protocol Error ] (0x%04x)\n\n", I3CS_GET_DEVICE_STATUS(i3cs));
  85.     if(I3CS_IS_UNDERFLOW_ERR(i3cs))
  86.         printf("[ Device Underflow Error ] (0x%04x)\n\n", I3CS_GET_DEVICE_STATUS(i3cs));
  87.     if(I3CS_IS_OVERFLOW_ERR(i3cs))
  88.         printf("[ Device Overflow Error ] (0x%04x)\n\n", I3CS_GET_DEVICE_STATUS(i3cs));
  89.     if(I3CS_IS_DATA_NOT_READY(i3cs))
  90.         printf("[ Device Data Not Ready Status ] (0x%04x)\n\n", I3CS_GET_DEVICE_STATUS(i3cs));
  91.     if(I3CS_IS_BUFFER_NOT_AVAIL(i3cs))
  92.         printf("[ Device Buffer Not Available Status ] (0x%04x)\n\n", I3CS_GET_DEVICE_STATUS(i3cs));
  93.     if(I3CS_IS_FRAME_ERR(i3cs))
  94.         printf("[ Device Frame Error ] (0x%04x)\n\n", I3CS_GET_DEVICE_STATUS(i3cs));
  95.     if(I3CS_IS_SLAVE_BUSY(i3cs))
  96.     {   
  97.         printf("[ Device Slave Busy Status ] (0x%04x)\n\n", I3CS_GET_DEVICE_STATUS(i3cs));
  98.         printf("\tPerform FIFO/Queue reset then wait RESUME complete ... ");
  99.         I3CS_RespErrorRecovery(I3CS0, g_u32RespStatus);
  100.         printf("done.\n\n");
  101.     }
  102.    
  103.     return 0;
  104. }

  105. /**
  106.   * @brief  The I3CS0 default IRQ, declared in startup_NUC1263.s.
  107.   */
  108. void I3CS0_IRQHandler(void)
  109. {   
  110.     DGBINT("\n");
  111.    
  112.     if(g_u32IntSelMask & I3CS_INTEN_TX_EMPTY_THLD)
  113.     {
  114.         if(I3CS_IS_INT_STATUS(I3CS0, I3CS_INTSTS_TX_EMPTY_THLD))
  115.         {
  116.             DGBINT("[ INT ] TX_EMPTY_THLD\n");
  117.             g_u32IntOccurredMask |= I3CS_INTSTS_TX_EMPTY_THLD;
  118.         }        
  119.     }
  120.    
  121.     if(g_u32IntSelMask & I3CS_INTEN_RX_THLD)
  122.     {
  123.         if(I3CS_IS_INT_STATUS(I3CS0, I3CS_INTSTS_RX_THLD))
  124.         {
  125.             DGBINT("[ INT ] INTSTS_RX_THLD\n");
  126.             g_u32IntOccurredMask |= I3CS_INTSTS_RX_THLD;
  127.         }
  128.     }
  129.    
  130.     if(g_u32IntSelMask & I3CS_INTEN_CMDQ_EMPTY_THLD)
  131.     {
  132.         if(I3CS_IS_INT_STATUS(I3CS0, I3CS_INTSTS_CMDQ_EMPTY_THLD))
  133.         {
  134.             DGBINT("[ INT ] CMDQ_EMPTY_THLD\n");        
  135.             g_u32IntOccurredMask |= I3CS_INTSTS_CMDQ_EMPTY_THLD;
  136.         }
  137.     }
  138.         
  139.     if(g_u32IntSelMask & I3CS_INTEN_RESPQ_READY)
  140.     {
  141.         if(I3CS_IS_INT_STATUS(I3CS0, I3CS_INTSTS_RESPQ_READY))
  142.         {
  143.             DGBINT("[ INT ] RESPQ_READY\n");        
  144.             g_u32IntOccurredMask |= I3CS_INTSTS_RESPQ_READY;
  145.         }
  146.     }
  147.         
  148.     if(g_u32IntSelMask & I3CS_INTEN_CCC_UPDATED)
  149.     {
  150.         if(I3CS_IS_INT_STATUS(I3CS0, I3CS_INTSTS_CCC_UPDATED))
  151.         {
  152.             DGBINT("[ INT ] CCC_UPDATED\n");
  153.             I3CS_CLEAR_CCC_UPDATED_STATUS(I3CS0);
  154.             g_u32IntOccurredMask |= I3CS_INTSTS_CCC_UPDATED;
  155.         }
  156.     }
  157.         
  158.     if(g_u32IntSelMask & I3CS_INTEN_DA_ASSIGNED)
  159.     {
  160.         if(I3CS_IS_INT_STATUS(I3CS0, I3CS_INTSTS_DA_ASSIGNED))
  161.         {
  162.             DGBINT("[ INT ] DA_ASSIGNED\n");
  163.             I3CS_CLEAR_DA_ASSIGNED_STATUS(I3CS0);
  164.             g_u32IntOccurredMask |= I3CS_INTSTS_DA_ASSIGNED;
  165.         }        
  166.     }
  167.         
  168.     if(g_u32IntSelMask & I3CS_INTEN_TRANSFER_ERR)
  169.     {
  170.         if(I3CS_IS_INT_STATUS(I3CS0, I3CS_INTSTS_TRANSFER_ERR))
  171.         {
  172.             DGBINT("[ INT ] TRANSFER_ERR\n");
  173.             I3CS_CLEAR_TRANSFER_ERR_STATUS(I3CS0);
  174.             g_u32IntOccurredMask |= I3CS_INTSTS_TRANSFER_ERR;
  175.         }      
  176.     }
  177.         
  178.     if(g_u32IntSelMask & I3CS_INTEN_READ_REQUEST)
  179.     {
  180.         if(I3CS_IS_INT_STATUS(I3CS0, I3CS_INTSTS_READ_REQUEST))
  181.         {
  182.             DGBINT("[ INT ] READ_REQUEST\n");
  183.             I3CS_CLEAR_READ_REQUEST_STATUS(I3CS0);
  184.             g_u32IntOccurredMask |= I3CS_INTSTS_READ_REQUEST;
  185.         }        
  186.     }
  187.         
  188.     if(g_u32IntSelMask & I3CS_INTEN_IBI_UPDATED)
  189.     {
  190.         if(I3CS_IS_INT_STATUS(I3CS0, I3CS_INTSTS_IBI_UPDATED))
  191.         {
  192.             DGBINT("[ INT ] IBI_UPDATED\n");
  193.             I3CS_CLEAR_IBI_UPDATED_STATUS(I3CS0);
  194.             g_u32IntOccurredMask |= I3CS_INTSTS_IBI_UPDATED;
  195.         }        
  196.     }
  197.    
  198.     if(g_u32IntOccurredMask & I3CS_INTSTS_RESPQ_READY)
  199.     {
  200.         g_u32RespStatus = (uint32_t)I3CS_ParseRespQueue(I3CS0, (uint32_t *)(&g_RespQ[0]));
  201.     }
  202.         
  203.     DGBINT("[ INT EXIT ] INTSTS: 0x%08x. Occurred: 0x%08x.\n\n", I3CS0->INTSTS, g_u32IntOccurredMask);
  204. }

  205. void SYS_Init(void)
  206. {
  207.     /*---------------------------------------------------------------------------------------------------------*/
  208.     /* Init System Clock                                                                                       */
  209.     /*---------------------------------------------------------------------------------------------------------*/
  210.     /* Enable HIRC clock */
  211.     CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

  212.     /* Wait for HIRC clock ready */
  213.     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

  214.     /* Set core clock to 72MHz */
  215.     CLK_SetCoreClock(72000000);
  216.    
  217.     /* Enable UART0 module clock */
  218.     CLK_EnableModuleClock(UART0_MODULE);

  219.     /* Select UART0 module clock source as HIRC/2 and UART0 module clock divider as 1 */
  220.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC_DIV2, CLK_CLKDIV0_UART0(1));

  221.     /*---------------------------------------------------------------------------------------------------------*/
  222.     /* Init I/O Multi-function                                                                                 */
  223.     /*---------------------------------------------------------------------------------------------------------*/
  224.     /* Set multi-function pins for UART0 RXD and TXD */
  225.     SET_UART0_RXD_PB12();
  226.     SET_UART0_TXD_PB13();

  227.     /*---------------------------------------------------------------------------------------------------------*/
  228.     /* Initialization for sample code                                                                          */
  229.     /*---------------------------------------------------------------------------------------------------------*/   
  230.     /* Enable peripheral clock */
  231.     CLK_EnableModuleClock(I3CS0_MODULE);

  232.     /* Set multi-function pins for I3CS0 pin */
  233.     SET_I3CS0_SDA_PA0();
  234.     SET_I3CS0_SCL_PA1();
  235. }

  236. void UART_Init(void)
  237. {
  238.     /*---------------------------------------------------------------------------------------------------------*/
  239.     /* Init UART                                                                                               */
  240.     /*---------------------------------------------------------------------------------------------------------*/
  241.     /* Reset UART module */
  242.     SYS_ResetModule(UART0_RST);

  243.     /* Configure UART0 and set UART0 Baudrate */
  244.     UART_Open(UART0, 115200);
  245. }
  246.                                                                                                                                
  247. /*---------------------------------------------------------------------------------------------------------*/
  248. /*  MAIN function                                                                                          */
  249. /*---------------------------------------------------------------------------------------------------------*/
  250. int main(void)
  251. {
  252.     uint16_t    i, u16Len;
  253.     uint8_t     *pu8Data, u8TID;
  254.     uint8_t     qn, u8RespQCnt;
  255.     uint32_t    u32ActiveIntMask;
  256.     int32_t     iErrCode = I3CS_STS_NO_ERR;

  257.     /* Unlock protected registers */
  258.     SYS_UnlockReg();

  259.     /* Init System, peripheral clock and multi-function I/O */
  260.     SYS_Init();

  261.     /* Init UART0 for printf */
  262.     UART_Init();
  263.    
  264.     printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %d Hz\n", SystemCoreClock);
  265.     printf("+----------------------------------------+\n");
  266.     printf("|    I3C0 Slave Read/Write Sample Code   |\n");
  267.     printf("+----------------------------------------+\n\n");
  268.             
  269.     /* Reset I3CS0 module */
  270.     SYS_ResetModule(I3CS0_RST);
  271.    
  272.     /* Initial I3CS0 default settings */
  273.     I3CS0->SLVMID = I3CS0_MID;
  274.     I3CS0->SLVPID = I3CS0_PID;
  275.     I3CS_Open(I3CS0, I3CS0_SA, I3CS_SUPPORT_ENTDAA);
  276.    
  277.     /* Enable I3CS0 interrupts */
  278.     g_u32IntSelMask = (I3CS_INTEN_RESPQ_READY | I3CS_INTEN_CCC_UPDATED | I3CS_INTEN_DA_ASSIGNED |
  279.                         I3CS_INTEN_TRANSFER_ERR | I3CS_INTEN_READ_REQUEST);
  280.     I3CS_ENABLE_INT(I3CS0, g_u32IntSelMask);
  281.     NVIC_EnableIRQ(I3CS0_IRQn);

  282.     /* Enable I3CS0 controller */
  283.     I3CS_Enable(I3CS0);

  284.     printf("# I3C0 Slave settings:\n");
  285.     printf("    - SDA on PA.0\n");
  286.     printf("    - SCL on PA.1\n");
  287.     printf("    - I2C Static Address 0x%02x\n", I3CS0_SA);
  288.     printf("    - RespQ interrupt threshold %d\n", (uint32_t)(I3CS_GET_RESPQ_THLD(I3CS0) + 1));
  289.     printf("    - The first operation of the I3CS enable bit requires at least bus SCLx4 to become active\n");
  290.     printf("# An I3C Master can write N-bytes data to Slave,\n");
  291.     printf("  then perform a read request to receive the N-bytes data from Slave.\n");
  292.     printf("    - The write data should be equal to the received data\n");
  293.     printf("\n");
  294.         
  295.         
  296.     while(1)
  297.     {
  298.         while(g_u32IntOccurredMask != 0)
  299.         {
  300.             /* Get active interrupt **ents */
  301.             u32ActiveIntMask = g_u32IntOccurredMask;
  302.             g_u32IntOccurredMask = 0;
  303.             
  304.             if(u32ActiveIntMask & I3CS_INTSTS_RESPQ_READY)
  305.             {
  306.                 /* Process Response */

  307.                 if(g_u32RespStatus == I3CS_STS_NO_ERR)
  308.                 {
  309.                     /* Response no error */
  310.                     
  311.                     u8RespQCnt = I3CS_GET_RESPQ_THLD(I3CS0) + 1;
  312.                     
  313.                     qn = 0; // Queue number
  314.                     do {
  315.                         if(I3CS_IS_RESP_RX(g_RespQ[qn]))
  316.                         {
  317.                             /* Master write request */
  318.                                                         
  319.                             u16Len = I3CS_GET_RESP_DATA_LEN(g_RespQ[qn]);
  320.                             printf("Slave receives %d-bytes:\n\thex: ", u16Len);
  321.                             /* Read Rx data from data port */
  322.                             for(i=0; i<((u16Len+3)/4); i++)
  323.                                 g_RxBuf[i] = I3CS0->TXRXDAT;
  324.                             pu8Data = (uint8_t *)(&g_RxBuf[0]);
  325.                             for(i=0; i<u16Len; i++)
  326.                                 printf("%02x ", pu8Data[i]);
  327.                             printf("\n\n");
  328.                            
  329.                             /* Set CmdQ and response data for a Master read request */
  330.                             memcpy((uint8_t *)(&g_TxBuf[0]), (uint8_t *)(&g_RxBuf[0]), u16Len);
  331.                             u8TID = (pu8Data[0] % 8);
  332.                             iErrCode = I3CS_SetCmdQueueAndData(I3CS0, u8TID, (uint32_t *)&g_TxBuf[0], u16Len);
  333.                             if(iErrCode != I3CS_STS_NO_ERR)
  334.                                 printf("\tSet TX data error, %d.\n\n", iErrCode);
  335.                             else
  336.                                 printf("[ Set TX %d-bytes and TID %d for Master read request ]\n\n", u16Len, u8TID);
  337.                         }
  338.                         else
  339.                         {
  340.                             /* Master read request -> Slave transmits data done */
  341.                             printf("Slave transmits ID-%d done.\n\n", (uint32_t)I3CS_GET_RESP_TID(g_RespQ[qn]));                        
  342.                         }
  343.                         
  344.                         qn++;                        
  345.                         u8RespQCnt--;
  346.                     }while(u8RespQCnt);
  347.                 }
  348.                 else
  349.                 {                    
  350.                     /* Response has error */
  351.                     
  352.                     I3CS_ProcessRespError(I3CS0, g_u32RespStatus);
  353.                 }
  354.                     
  355.                 g_u32RespStatus = I3CS_STS_NO_ERR;
  356.             }
  357.             else
  358.             {                                                   
  359.                 /* Process others interrupt event */
  360.                
  361.                 I3CS_ProcessNoneRespInt(I3CS0, u32ActiveIntMask);
  362.             }
  363.         }
  364.     }
  365. }


 楼主| wahahaheihei 发表于 2024-1-28 18:44 | 显示全部楼层
I3C,全称为"Improved Inter-Integrated Circuit",是一种串行通信接口标准,旨在提供一种更高性能、更灵活且更节省能源的替代方案,用于连接芯片之间的通信。I3C 的设计目标是兼容现有的I2C(Inter-Integrated Circuit)和SMBus(System Management Bus)标准,同时增加新的特性和改进性能。
 楼主| wahahaheihei 发表于 2024-1-28 18:44 | 显示全部楼层
高性能和更高的数据传输速率: I3C支持更高的数据传输速率,相较于I2C,它提供更高的带宽和更短的传输时间。
 楼主| wahahaheihei 发表于 2024-1-28 18:44 | 显示全部楼层
多主机和多从机支持: I3C引入了一种更灵活的多主机体系结构,允许多个主机设备同时与总线通信,同时支持多个从机设备。
 楼主| wahahaheihei 发表于 2024-1-28 18:44 | 显示全部楼层
动态地址分配: I3C支持动态地址分配,从而更好地管理总线上的设备地址,提高系统的可扩展性和灵活性。
 楼主| wahahaheihei 发表于 2024-1-28 18:44 | 显示全部楼层
硬件层级控制: I3C引入了硬件层级控制的概念,使得总线上的设备能够根据其在系统中的地位进行动态配置和控制。
 楼主| wahahaheihei 发表于 2024-1-28 18:45 | 显示全部楼层
低功耗: I3C设计时考虑了能源效率,支持低功耗操作,有助于延长设备电池寿命。
 楼主| wahahaheihei 发表于 2024-1-28 18:45 | 显示全部楼层
传感器融合: I3C在设计时特别关注传感器融合,为连接各种传感器提供了更好的支持,使得传感器网络更容易集成到系统中。
 楼主| wahahaheihei 发表于 2024-1-28 18:45 | 显示全部楼层
总体而言,I3C是一个面向未来的、先进的串行通信标准,旨在满足不断增长的设备互联和通信的需求。它保留了I2C和SMBus的兼容性,同时引入了许多新的特性,使得设备之间的通信更为高效和灵活。
埃娃 发表于 2024-1-29 10:19 来自手机 | 显示全部楼层
这个是什么方面用的多啊
suncat0504 发表于 2024-7-7 14:31 | 显示全部楼层
现在市面上使用I3C的传感器还不是很多。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

234

主题

3227

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部