Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(PeriphDrivers): Add MAX32657 I3C driver #1026

Merged
merged 2 commits into from
Jul 10, 2024
Merged

Conversation

ttmut
Copy link
Contributor

@ttmut ttmut commented May 28, 2024

Description

Add I3C driver for MAX32657. Basic controller and target APIs are provided.

Note: Will be tested when the test environment is ready.

I3C has been tested with an LPS22HH pressure and temperature sensor.
Legacy I2C has been tested with an AT24C04 EEPROM.

  1. Read provisioned ID, using static address (0x5C) as dynamic address.
    msdk_pid_read

  2. Read pressure data, using static address (0x5C) as dynamic address.
    msdk_pressure_data_read

Pressure value = (0x3D << 16) | (0xC5 << 8) | 0x31;
Pressure value = 4048177;
Pressure(hPa) = Pressure value / Sensitivity
Pressure(hPa) = 4048177 / 4096 = 988hPa;
Pressure(kPa) = 98.8kPa (Atmospheric pressure at sea level is 101kPa)
  1. Assign 0x34 as dynamic address. Written to device as 0x68, 1-bit shifted to the left.
    msdk_daa_0x34

  2. Read WHO_AM_I register using newly assigned dynamic address 0x34.
    msdk_whoami_daa

  3. I2C write 8 bytes to EEPROM
    msdk_i2c_write

  4. I2C read 8 bytes from EEPROM
    msdk_i2c_read

Checklist Before Requesting Review

  • PR Title follows correct guidelines.
  • Description of changes and all other relevant information.
  • (Optional) Provide info on any relevant functional testing/validation. For API changes or significant features, this is not optional.

@github-actions github-actions bot added the Register Change This issue or pull request involves a change to the MSDK registers. label May 28, 2024
@sihyung-maxim
Copy link
Contributor

sihyung-maxim commented May 28, 2024

Please refer to the feat/ME30 branch to keep in sync with all design and user guide changes. All internal teams requiring the bare metal SDK are referencing this branch.

The i3c_regs.h file is scrubbed for the user guide and synced with design's finalization of the IP configuration.

Also, please note that the I3C source drivers will require hardware revision files for easier portability across parts. That means, there will at least be an i3c_me30.c, i3c_reva.c, i3c_reva.h, and i3c_reva_regs.h files.

The i3c_me30.c level only contains code specific to the ME30 (such as pin configuration, enabling I3C peripheral clock, and any peripheral API setup), and it generally does not contain any direct register access to the I3C IP.

The i3c_reva* files contain the pure driver implementation of the IP at the register level. This file contains the functions that the i3c_me30.c file will call. The i3c_reva_regs.h file is the universal, superset register file that i3c_reva.* uses. The i3c_regs.h file contains the register set specific to an MCU, and design could vary the IP configuration/register set depending on customer needs for future MCUs reusing the same IP, so having a "universal" register file prevents build errors resulting from feature differences.

You can reference our other peripheral drivers to see how this is all set up. Let me know if you have any questions.

@ttmut
Copy link
Contributor Author

ttmut commented May 28, 2024

I missed the latest register updates so put my own for the work in progress. I will look into adapting into feat/ME30 branch. Thanks for the response.

@github-actions github-actions bot added MAX32655 Related to the MAX32655 (ME17) MAX32670 Related to the MAX32670 (ME15) MAX32672 Related to the MAX32672 (ME21) MAX32675 Related to the MAX32675 (ME16) MAX32680 Related to the MAX32680 (ME20) MAX32690 Related to the MAX32690 (ME18) MAX78000 Related to the MAX78000 (AI85) MAX78002 Related to the MAX78002 (AI87) Tools This issue or pull request involves a change to the Tools Workflow Related to Workflow development MAX32662 Related to the MAX32662 (ME12) MAX32572 Related to the MAX32572 (ME55) labels Jun 3, 2024
@ttmut ttmut changed the base branch from main to feat/ME30 June 3, 2024 12:43
@ttmut ttmut marked this pull request as ready for review June 3, 2024 12:43
@github-actions github-actions bot removed MAX32655 Related to the MAX32655 (ME17) MAX32670 Related to the MAX32670 (ME15) MAX32672 Related to the MAX32672 (ME21) MAX32675 Related to the MAX32675 (ME16) MAX32680 Related to the MAX32680 (ME20) MAX32690 Related to the MAX32690 (ME18) MAX78000 Related to the MAX78000 (AI85) MAX78002 Related to the MAX78002 (AI87) Tools This issue or pull request involves a change to the Tools Workflow Related to Workflow development MAX32662 Related to the MAX32662 (ME12) labels Jun 3, 2024
@ttmut ttmut removed the WIP work in progress label Jul 4, 2024
@ttmut ttmut force-pushed the feat/ME30-I3C branch 6 times, most recently from 41844d7 to 0a8c0f6 Compare July 8, 2024 12:32
Copy link
Contributor

@Jake-Carter Jake-Carter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ttmut, some minor change requests below

Libraries/PeriphDrivers/Include/MAX32657/i3c.h Outdated Show resolved Hide resolved
Libraries/PeriphDrivers/Include/MAX32657/i3c.h Outdated Show resolved Hide resolved
Libraries/PeriphDrivers/Include/MAX32657/i3c.h Outdated Show resolved Hide resolved
Libraries/PeriphDrivers/Include/MAX32657/i3c.h Outdated Show resolved Hide resolved
Libraries/PeriphDrivers/Source/I3C/i3c_me30.c Show resolved Hide resolved
Libraries/PeriphDrivers/Source/I3C/i3c_reva.h Outdated Show resolved Hide resolved
@ttmut
Copy link
Contributor Author

ttmut commented Jul 9, 2024

Thanks @Jake-Carter for your review. I have addressed your comments so could you have a look once more?

Comment on lines +147 to +153
val = 0 << 6; /* Device role: target */
if (i3c->targ_cap1 & MXC_S_I3C_REVA_TARG_CAP1_CCCH_LIMITS) {
val |= 1 << 0; /* Max data speed limitation */
}
if (i3c->targ_cap1 & MXC_S_I3C_REVA_TARG_CAP1_CCCH_BASIC) {
val |= 1 << 5; /* Supports advanced capabiliries */
}
if (i3c->targ_cap1 & MXC_S_I3C_REVA_TARG_CAP1_IBI_EVENTS_IBI) {
val |= 1 << 1; /* Supports IBI generation */
}
if (i3c->targ_cap1 & MXC_S_I3C_REVA_TARG_CAP1_IBI_EVENTS_PAYLOAD) {
val |= 1 << 2; /* MDB and additional data bytes may follow the IBI */
}
val |= 1 << 3; /* Offline capable */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a good idea to bring these out as enumerated definitions in the register file so you don't have to hardcode these values.

Comment on lines 202 to 235
int retries = 3;

while (retries && MXC_I3C_RevA_GetState(i3c) == MXC_V_I3C_REVA_CONT_STATUS_STATE_SDR_NORM) {
MXC_I3C_RevA_EmitStop(i3c);
retries--;
}

retries = 20;
while (retries-- && GET_FIELD(cont_status, CONT_STATUS_TARG_START)) {
MXC_I3C_RevA_AutoIBI(i3c);
MXC_I3C_RevA_WaitForDone(i3c, 1000);
MXC_I3C_RevA_ClearRXFIFO(i3c);
}

retries = 10;
while (retries && MXC_I3C_RevA_GetState(i3c) != MXC_V_I3C_REVA_CONT_STATUS_STATE_IDLE) {
retries--;
}

if (retries == 0) {
return E_TIME_OUT;
}

return 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, are the number of retries given by the spec or something we chose that is probably a good amount?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the first one, I observed that it gets stuck there sometimes, i.e., TARG_START is continuously being set even after IBI request is handled. Therefore, I made it fall through after 20 retries, expecting less than 20 devices on the bus. I3C specs do not put a limit on the number of supported devices on an I3C bus. In earlier specs it was given as 11.

Second one is used for delay though I realize now that 10 loops is too short for a delay. The reason I did not want to use MXC_Delay function for delays is that it could conflict with Zephyr OS which also uses SysTick for timing and delays.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a second look, it seems I forgot to clear TARG_START bit. I will try to see if it solves the problem I mentioned.

Copy link
Contributor

@sihyung-maxim sihyung-maxim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

If you want to be consistent with the Controller vs Target names, the Docs team and I have been separating these two terms on the ME30 for readability because this IP is designed with a clear separation between these two features.

As a general naming rule with controller and target:

The register-fields would either have a CONT_/TARG_ prefix or _CONT/_TARG suffix in their names. So CONT_INTEN/TARG_INTEN is used instead of CONTINTEN/TARGINTEN for the interrupt enable register names.

The function names would have a section dedicated to these two blocks, _Controller_ and _Target_, if one generic function can't handle a feature for both the controller and target.

The general format for the function name:
MXC_{PERIPH}_{Sub-Blocks, if any}_{FunctionName}(...)

Following the format, for example, the MXC_I3C_ControllerEnableInt(...) function would be MXC_I3C_Controller_EnableInt(...). And MXC_I3C_TargetEnableInt(...) => MXC_I3C_Target_EnableInt(...)

Hope this made sense. A good example of this function naming convention is with the Crypto Tool Box (CTB) in the ME13, ME18, ME21, and ME55.

@ttmut
Copy link
Contributor Author

ttmut commented Jul 9, 2024

Looks good.

If you want to be consistent with the Controller vs Target names, the Docs team and I have been separating these two terms on the ME30 for readability because this IP is designed with a clear separation between these two features.

As a general naming rule with controller and target:

The register-fields would either have a CONT_/TARG_ prefix or _CONT/_TARG suffix in their names. So CONT_INTEN/TARG_INTEN is used instead of CONTINTEN/TARGINTEN for the interrupt enable register names.

The function names would have a section dedicated to these two blocks, _Controller_ and _Target_, if one generic function can't handle a feature for both the controller and target.

The general format for the function name: MXC_{PERIPH}_{Sub-Blocks, if any}_{FunctionName}(...)

Following the format, for example, the MXC_I3C_ControllerEnableInt(...) function would be MXC_I3C_Controller_EnableInt(...). And MXC_I3C_TargetEnableInt(...) => MXC_I3C_Target_EnableInt(...)

Hope this made sense. A good example of this function naming convention is with the Crypto Tool Box (CTB) in the ME13, ME18, ME21, and ME55.

I see your point. I was just trying to avoid using Controller_, Target_ prefixes whenever possible to prevent function names becoming too long. For example, clock can only be generated by controller so MXC_I3C_SetXXFrequency functions are inherently controller-specific. Anyway, I will update the function names accordingly. Thanks for your detailed response.

@sihyung-maxim
Copy link
Contributor

Looks good.
If you want to be consistent with the Controller vs Target names, the Docs team and I have been separating these two terms on the ME30 for readability because this IP is designed with a clear separation between these two features.
As a general naming rule with controller and target:
The register-fields would either have a CONT_/TARG_ prefix or _CONT/_TARG suffix in their names. So CONT_INTEN/TARG_INTEN is used instead of CONTINTEN/TARGINTEN for the interrupt enable register names.
The function names would have a section dedicated to these two blocks, _Controller_ and _Target_, if one generic function can't handle a feature for both the controller and target.
The general format for the function name: MXC_{PERIPH}_{Sub-Blocks, if any}_{FunctionName}(...)
Following the format, for example, the MXC_I3C_ControllerEnableInt(...) function would be MXC_I3C_Controller_EnableInt(...). And MXC_I3C_TargetEnableInt(...) => MXC_I3C_Target_EnableInt(...)
Hope this made sense. A good example of this function naming convention is with the Crypto Tool Box (CTB) in the ME13, ME18, ME21, and ME55.

I see your point. I was just trying to avoid using Controller_, Target_ prefixes whenever possible to prevent function names becoming too long. For example, clock can only be generated by controller so MXC_I3C_SetXXFrequency functions are inherently controller-specific. Anyway, I will update the function names accordingly. Thanks for your detailed response.

It's not a hard rule. I was mainly referring to "duplicate" functions like _Enable/DisableInt(...) and _Clear/GetFlags(...) where the target and controller need to be identified. If a function is inherently controller-specific and there's no target equivalent like MXC_I3C_SetXXFrequency(...), then it's probably fine to not add the _Controller_ name. As long as the documentation indicates it, it's your call on whatever you decide is best for the end user who matters most!

Copy link
Contributor

@Jake-Carter Jake-Carter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ttmut, let me know when you are ready to merge

CONT_REQ must be 2 and HOTJOIN_REQ must be 3.

Add enumerations for IBI_EVENTS and CCCH fields of TARG_CAP1 register.

Signed-off-by: Tahsin Mutlugun <[email protected]>
Add I3C driver support for ME30.c.

Signed-off-by: Tahsin Mutlugun <[email protected]>
@ttmut
Copy link
Contributor Author

ttmut commented Jul 10, 2024

Thanks @ttmut, let me know when you are ready to merge

I do not have anything else to add at the moment. Let's also wait @sihyung-maxim's approval.

@sihyung-maxim sihyung-maxim merged commit 0a9575b into feat/ME30 Jul 10, 2024
4 checks passed
@sihyung-maxim sihyung-maxim deleted the feat/ME30-I3C branch July 10, 2024 18:35
sihyung-maxim pushed a commit to analogdevicesinc/hal_adi that referenced this pull request Jul 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Register Change This issue or pull request involves a change to the MSDK registers.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants