Windows10 IoT Enterprise W21H2-1-4-1 How to support HID over I2C

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Windows10 IoT Enterprise W21H2-1-4-1 How to support HID over I2C

525 Views
okuda
Contributor III

Hi.

Currently, Windows is running on the NXP iMX8mp reference board with binaries created with Windows10 IoT Enterprise BSP W21H2-1-4-1.
Using the reference board's I2C port, HID over I2C
and want to use I2C devices via HID.

I'm reading the "hid-over-i2c-protocol-spec-v1-0.docx" document that I downloaded from the Microsoft homepage, but I can't really figure out what to do.

What steps should I take to use HID over I2C with the I2C port of the NXP reference board?

Best Regards,
Koji Okuda

0 Kudos
Reply
3 Replies

438 Views
okuda
Contributor III

Hi.

In order to realize HID over I2C, we have confirmed the operation of the current I2C driver alone.
I wanted to check using I2C5, but since it is CAN1 by default, I made the following modifications.

MX8M_PLUS_EVK.dsc
#
# Board configuration
#
giMX8TokenSpaceGuid.PcdCAN1InsteadOfI2C5|FALSE<----Change from TRUE to FALSE
giMX8TokenSpaceGuid.PcdCAN2InsteadOfPDMStream3|TRUE

After implementing the above modifications and starting the OS with the built version, I checked the device manager and it recognized I2C5.
However, when I tested it from the application, it did not work properly.

We reviewed the NXP porting again and made the following two corrections.

iMX8BoardInit.c
Added I2C5 daisy chain setting
VOID I2cInit()
{
IOMUXC_SW_MUX_CTL_PAD_I2C1_SCL = IOMUXC_MUX_ALT0 | IOMUXC_MUX_SION_ENABLED;
IOMUXC_SW_MUX_CTL_PAD_I2C1_SDA = IOMUXC_MUX_ALT0 | IOMUXC_MUX_SION_ENABLED;
IOMUXC_SW_MUX_CTL_PAD_I2C2_SCL = IOMUXC_MUX_ALT0 | IOMUXC_MUX_SION_ENABLED;
IOMUXC_SW_MUX_CTL_PAD_I2C2_SDA = IOMUXC_MUX_ALT0 | IOMUXC_MUX_SION_ENABLED;
IOMUXC_SW_MUX_CTL_PAD_I2C3_SCL = IOMUXC_MUX_ALT0 | IOMUXC_MUX_SION_ENABLED;
IOMUXC_SW_MUX_CTL_PAD_I2C3_SDA = IOMUXC_MUX_ALT0 | IOMUXC_MUX_SION_ENABLED;
IOMUXC_SW_MUX_CTL_PAD_SPDIF_TX = IOMUXC_MUX_ALT2 | IOMUXC_MUX_SION_ENABLED;
IOMUXC_SW_MUX_CTL_PAD_SPDIF_RX = IOMUXC_MUX_ALT2 | IOMUXC_MUX_SION_ENABLED;

/*** I2C5-CAN Debug for DMC 2023/10/23 Start ***/
IOMUXC_I2C5_SCL_IN_SELECT_INPUT = IOMUXC_MUX_ALT2;
IOMUXC_I2C5_SDA_IN_SELECT_INPUT = IOMUXC_MUX_ALT2;
/*** I2C5-CAN Debug for DMC 2023/10/23 End ***/

CAN1 initialization disabled when using I2C5
VOID CanInit(IN BOOLEAN UseCAN)
/*** I2C5-CAN Debug for DMC 2023/10/23 End ***/
{
// IOMUX CAN PINS
/*** I2C5-CAN Debug for DMC 2023/10/23 Start ***/
// IOMUXC_SW_MUX_CTL_PAD_SPDIF_TX = IOMUXC_MUX_ALT4; // CAN1_TX -> PAD_SPDIF_TX
// IOMUXC_SW_MUX_CTL_PAD_SPDIF_RX = IOMUXC_MUX_ALT4; // CAN1_RX -> CAN1_RX_SELECT_INPUT
// IOMUXC_CAN1_CANRX_SELECT_INPUT = IOMUXC_MUX_ALT2; // CAN1_RX_SELECT_INPUT -> PAD_SPDIF_RX
// IOMUXC_SW_PAD_CTL_PAD_SPDIF_TX = CAN_PAD_CTRL;
// IOMUXC_SW_PAD_CTL_PAD_SPDIF_RX = CAN_PAD_CTRL;


if( UseCAN ){
IOMUXC_SW_MUX_CTL_PAD_SPDIF_TX = IOMUXC_MUX_ALT4; // CAN1_TX -> PAD_SPDIF_TX
IOMUXC_SW_MUX_CTL_PAD_SPDIF_RX = IOMUXC_MUX_ALT4; // CAN1_RX -> CAN1_RX_SELECT_INPUT
IOMUXC_CAN1_CANRX_SELECT_INPUT = IOMUXC_MUX_ALT2; // CAN1_RX_SELECT_INPUT -> PAD_SPDIF_RX
IOMUXC_SW_PAD_CTL_PAD_SPDIF_TX = CAN_PAD_CTRL;
IOMUXC_SW_PAD_CTL_PAD_SPDIF_RX = CAN_PAD_CTRL;
}else{
SerialPortWrite( (UINT8 *)("---- MUX_CTRL not Init for CAN1 not Use\r\n"), (UINTN)sizeof("---- MUX_CTRL not Init for CAN1 not Use\r\n") );
}
/*** I2C5-CAN Debug for DMC 2023/10/23 End ***/

IOMUXC_SW_MUX_CTL_PAD_SAI5_RXD3 = IOMUXC_MUX_ALT6; // CAN2_TX -> PAD_SAI5_RXD3
IOMUXC_SW_MUX_CTL_PAD_SAI5_MCLK = IOMUXC_MUX_ALT6; // CAN2_RX -> CAN2_RX_SELECT_INPUT
IOMUXC_CAN2_CANRX_SELECT_INPUT = IOMUXC_MUX_ALT0; // CAN2_RX_SELECT_INPUT -> PAD_SAI5_MCLK
IOMUXC_SW_PAD_CTL_PAD_SAI5_RXD3 = CAN_PAD_CTRL;
IOMUXC_SW_PAD_CTL_PAD_SAI5_MCLK = CAN_PAD_CTRL;

// Configures GPIO5_IO05 as output with "1". This signal is connected to the STBN1 pin of the TJA1048T chip.
// The goal is for the CAN transceiver TJA1048T to leave standby mode
/*** I2C5-CAN Debug for DMC 2023/10/23 Start ***/
// IOMUXC_SW_MUX_CTL_PAD_SPDIF_EXT_CLK = IOMUXC_MUX_ALT5; // GPIO5_IO5 -> PAD_SPDIF_EXT_CLK
// IOMUXC_SW_PAD_CTL_PAD_SPDIF_EXT_CLK = CAN_PAD_CTRL;
// GPIO5_DR |= (0x01 << 5); // Set the pad to the high level
// GPIO5_GDIR |= (0x01 << 5);
if( UseCAN ){
IOMUXC_SW_MUX_CTL_PAD_SPDIF_EXT_CLK = IOMUXC_MUX_ALT5; // GPIO5_IO5 -> PAD_SPDIF_EXT_CLK
IOMUXC_SW_PAD_CTL_PAD_SPDIF_EXT_CLK = CAN_PAD_CTRL;
GPIO5_DR |= (0x01 << 5); // Set the pad to the high level
GPIO5_GDIR |= (0x01 << 5);
}else{
SerialPortWrite( (UINT8 *)("---- PAD_CTRL not Init for CAN1 not Use\r\n"), (UINTN)sizeof("---- PAD_CTRL not Init for CAN1 not Use\r\n") );
}
/*** I2C5-CAN Debug for DMC 2023/10/23 End ***/

// Configures GPIO4_IO27 as output with "1". This signal is connected to the STBN2 pin of the TJA1048T chip.
IOMUXC_SW_MUX_CTL_PAD_SAI2_MCLK = IOMUXC_MUX_ALT5; // GPIO4_IO27 -> PAD_SAI2_MCLK
IOMUXC_SW_PAD_CTL_PAD_SAI2_MCLK = CAN_PAD_CTRL;
GPIO4_DR |= (0x01 << 27); // Set the pad to the high level
GPIO4_GDIR |= (0x01 << 27);

// CAN clock
CCM_CCGR_CAN1 = 0x00;
CCM_CCGR_CAN2 = 0x00;
/*** I2C5-CAN Debug for DMC 2023/10/23 Start ***/
//#if FixedPcdGet32(PcdCAN1XTALEnable)
// Configure CAN1 Clksrc=24M_REF_CLK (24 MHz), PreDiv = 1, PostDiv = 1, Fout = 24 MHz
// CCM_TARGET_ROOT_CAN1 = CCM_TARGET_ROOT_MUX(0) | CCM_TARGET_ROOT_PRE_PODF(0) | CCM_TARGET_ROOT_POST_PODF(0) | CCM_TARGET_ROOT_ENABLE_MASK;
//#else
// Configure CAN1 Clksrc=SYSTEM_PLL1_DIV20 (40 MHz, PLL1 = 800 MHz), PreDiv = 1, PostDiv = 1, Fout = 40 MHz
// CCM_TARGET_ROOT_CAN1 = CCM_TARGET_ROOT_MUX(2) | CCM_TARGET_ROOT_PRE_PODF(0) | CCM_TARGET_ROOT_POST_PODF(0) | CCM_TARGET_ROOT_ENABLE_MASK;
//#endif
if( UseCAN ){
#if FixedPcdGet32(PcdCAN1XTALEnable)
// Configure CAN1 Clksrc=24M_REF_CLK (24 MHz), PreDiv = 1, PostDiv = 1, Fout = 24 MHz
CCM_TARGET_ROOT_CAN1 = CCM_TARGET_ROOT_MUX(0) | CCM_TARGET_ROOT_PRE_PODF(0) | CCM_TARGET_ROOT_POST_PODF(0) | CCM_TARGET_ROOT_ENABLE_MASK;
#else
// Configure CAN1 Clksrc=SYSTEM_PLL1_DIV20 (40 MHz, PLL1 = 800 MHz), PreDiv = 1, PostDiv = 1, Fout = 40 MHz
CCM_TARGET_ROOT_CAN1 = CCM_TARGET_ROOT_MUX(2) | CCM_TARGET_ROOT_PRE_PODF(0) | CCM_TARGET_ROOT_POST_PODF(0) | CCM_TARGET_ROOT_ENABLE_MASK;
#endif
}else{
SerialPortWrite( (UINT8 *)("---- XTAL not Init for CAN1 not Use\r\n"), (UINTN)sizeof("---- XTAL not Init for CAN1 not Use\r\n") );
}
/*** I2C5-CAN Debug for DMC 2023/10/23 End ***/
#if FixedPcdGet32(PcdCAN2XTALEnable)
// Configure CAN2 Clksrc=24M_REF_CLK (24 MHz), PreDiv = 1, PostDiv = 1, Fout = 24 MHz
CCM_TARGET_ROOT_CAN2 = CCM_TARGET_ROOT_MUX(0) | CCM_TARGET_ROOT_PRE_PODF(0) | CCM_TARGET_ROOT_POST_PODF(0) | CCM_TARGET_ROOT_ENABLE_MASK;
#else
// Configure CAN2 Clksrc=SYSTEM_PLL1_DIV20 (40 MHz, PLL1 = 800 MHz), PreDiv = 1, PostDiv = 1, Fout = 40 MHz
CCM_TARGET_ROOT_CAN2 = CCM_TARGET_ROOT_MUX(2) | CCM_TARGET_ROOT_PRE_PODF(0) | CCM_TARGET_ROOT_POST_PODF(0) | CCM_TARGET_ROOT_ENABLE_MASK;
#endif
/*** I2C5-CAN Debug for DMC 2023/10/23 Start ***/
// CCM_CCGR_CAN1 = 0x03;
if( UseCAN ){
CCM_CCGR_CAN1 = 0x03;
}else{
SerialPortWrite( (UINT8 *)("---- CLK not Init for CAN1 not Use\r\n"), (UINTN)sizeof("---- CLK not Init for CAN1 not Use\r\n") );
}
/*** I2C5-CAN Debug for DMC 2023/10/23 End ***/
CCM_CCGR_CAN2 = 0x03;
}

By implementing the above modifications, I2C5 can now be accessed normally from the application.
Is the above fix the right way to fix it to use I2C5?

Best Regards,
Koji Okuda



0 Kudos
Reply

496 Views
Bio_TICFSL
NXP TechSupport
NXP TechSupport

Could  @MichalMinarcik  help here?

 

Regards

0 Kudos
Reply

484 Views
okuda
Contributor III

Hello Bio_TICFSL

Thank you for your reply.
@MichalMinarcik seems to have replied about LCD, but I don't understand how it has anything to do with HID over I2C.

It would be helpful if you could explain a little more.

Best Regards,
Koji Okuda

0 Kudos
Reply