Skip to content
This repository has been archived by the owner on Jan 7, 2019. It is now read-only.

[stm32l4] I2C Driver #248

Merged

Conversation

strongly-typed
Copy link
Member

Tested in hardware with STM32L476.

nextOperation = static_cast<xpcc::I2c::Operation>(reading.next);

DEBUG_STREAM("read op: reading=" << reading.length);
// stream << "nextOperation = " << nextOperation << xpcc::endl;
Copy link
Member

@salkinium salkinium May 3, 2017

Choose a reason for hiding this comment

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

btw, you can also do:

DEBUG_STREAM("nextOperation =" << nextOperation);

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. That's much nicer!

// Configure Addressing Master mode
if (addressingMode == AddressingMode::Bit10) {
I2C1->CR2 = (I2C_CR2_ADD10);
}
Copy link
Member

Choose a reason for hiding this comment

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

Duplicate and wrong code.

Copy link
Member Author

Choose a reason for hiding this comment

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

Uups, from copy-paste ...

xpcc::I2cMaster::Error
xpcc::stm32::I2cMaster{{ id }}::getErrorState()
{
return error;
Copy link
Member

Choose a reason for hiding this comment

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

Oh hey, look, we've got our own version of errno!1!!

Copy link
Member Author

Choose a reason for hiding this comment

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

I did not invent it :-)

constexpr float max_rise_time = -2.333333f * (float(baudrate) / 1000.f) + 1233.333333f;
// calculate trise
constexpr float trise_raw = max_rise_time < 0 ? 0 : std::floor(max_rise_time / (1000.f / freq));
constexpr uint8_t trise = trise_raw > 62 ? 63 : (trise_raw + 1);
Copy link
Member

Choose a reason for hiding this comment

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

I'm working on the correct timing calculation.

Copy link
Member

Choose a reason for hiding this comment

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

I've looked at the documentation, and this is a bit more complicated than I can currently spend time on, so I suggest the following to not block this PR: Let's keep this configuration hardcoded for now, and replace these computations with a static_assert (and // FIXME:) for 100kHz baudrate at 48MHz clock.

Copy link
Member Author

Choose a reason for hiding this comment

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

No problem. A hardcoded LUT would be OK for the beginning. The LUT now has one entry ;-) Just pushed the change.

Copy link
Member

@salkinium salkinium left a comment

Choose a reason for hiding this comment

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

Nice!

@@ -129,7 +129,7 @@
<driver type="adc" name="stm32l4" instances="1,2,3"/>
<driver type="can" name="stm32" instances="1"/>
<driver type="clock" name="stm32"/>
<driver type="i2c" name="stm32" instances="1,2,3"/>
<driver type="i2c" name="stm32l4" instances="1,2,3"/>
Copy link
Member

Choose a reason for hiding this comment

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

Is this driver also compatible with the other L4 devices? If so, can you also change the DFG output, so I don't forget when porting to modm?

Copy link
Member Author

Choose a reason for hiding this comment

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

By visually comparing the I2C register map from all STM32L series

Reference Manual Series Compatible
RM0038 STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx NO
RM0351 STM32L4x5 and STM32L4x6 YES
RM0377 STM32L0x1 YES
RM0392 STM32L4x1 YES
RM0393 STM32L4x2 YES
RM0394 STM32L43xxx STM32L44xxx STM32L45xxx STM32L46xxx YES
RM0395 STM32L4x5 YES

I found no obvious difference for STM32L0 and STM32L4. So it seems to be a general rule that the L0 and L4 series uses this 'new' I2C IP. So the name stm32l4 might not be optimal.

The STM32L1 series looks like the STM32F4 but missing the FLTR register.

I updated the DFG without testing. @salkinium Could you please update the device files?

@strongly-typed
Copy link
Member Author

strongly-typed commented May 13, 2017

Maybe my last comment here got lost ...

I visually compared the I2C register maps from the reference manuals of all STM32L* processors.

Reference Manual MCUs I2C_CR1 PECEN
RM0038 STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx missing
RM0351 STM32L4x5 and STM32L4x6
RM0377 STM32L0x1
RM0392 STM32L4x1
RM0393 STM32L4x2
RM0394 STM32L43xxx STM32L44xxx STM32L45xxx STM32L46xxx
RM0395 STM32L4x5

STM32L4 and STM32L0 seem to share the same I2C, but STM32L1 does not.

@salkinium
Copy link
Member

STM32L4 and STM32L0 seem to share the same I2C, but STM32L1 does not.

Yeah, obviously. Why simple, when it can be complicated?2??

@salkinium salkinium merged commit fab699d into roboterclubaachen:develop May 13, 2017
@salkinium salkinium moved this from In Progress to Done in xpcc May 13, 2017
@salkinium
Copy link
Member

Thanks for the good work!

@strongly-typed strongly-typed deleted the feature/stm32l4_i2c branch May 13, 2017 23:37
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
xpcc
Done
Development

Successfully merging this pull request may close these issues.

None yet

2 participants