I've got most of 'em in there already, including TMR and PIT. Adding a few more now, including GPT, PWM, PXP, and I2S.@shawn, are you working through the T4.x peripheral set? Can you summarize which you've implemented so far? The timer peripherals are really the ones where I've done any significant work at the register level.
Hmm ... so if I want to write a method likeEverything is passed as a template parameter and also inlined, that's why it compiles down to something equivalent to using masks and shifts directly.
I believe my approach does allows different peripheral parts to have different bits. I'll throw in the SAI fields and commit that so you can see.
bool initSAI(SAI& mySAI, SAImode_t mode) // mode is I2S, TDM, S/PDIF etc.
{
switch (mode)
{
case SAI_mode_I2S:
mySAI.TCR1 = value for TCR1
mySAI.TCR2 = value for TCR2
...
break;
case SAI_mode_TDM:
mySAI.TCR1 = different value for TCR1
mySAI.TCR2 = another value for TCR2
...
break;
}
}
Agreed. Strongly.Ever used a debugger with templated code? Or worse with STL classes? Heavy obfuscation is commonplace.
Oh, I see what you mean now. Let me explore that.Hmm ... so if I want to write a method like
I don't quite see how I do something like that with your header, resulting in efficient code. Yes, I could template it, but I'd expect to end up with two copies of the binary, differing only in the base address of the hardware ... unless the optimiser is fantasically good at its job, of course. I'd rather not rely on that.C++:bool initSAI(SAI& mySAI, SAImode_t mode) // mode is I2S, TDM, S/PDIF etc. { switch (mode) { case SAI_mode_I2S: mySAI.TCR1 = value for TCR1 mySAI.TCR2 = value for TCR2 ... break; case SAI_mode_TDM: mySAI.TCR1 = different value for TCR1 mySAI.TCR2 = another value for TCR2 ... break; } }
I'll just add a clarification: I'm designing it so that the user of the library doesn't need to use templates. More info about your SAI use case on the way...I don't quite see how I do something like that with your header, resulting in efficient code. Yes, I could template it, but I'd expect to end up with two copies of the binary, differing only in the base address of the hardware ... unless the optimiser is fantasically good at its job, of course. I'd rather not rely on that.
bool initSAI(I2S_Layout* mySAI, SAImode_t mode) // mode is I2S, TDM, S/PDIF etc.
{
switch (mode)
{
case SAI_mode_I2S:
mySAI->TCR1 = value for TCR1
mySAI->TCR2 = value for TCR2
...
break;
case SAI_mode_TDM:
mySAI->TCR1 = different value for TCR1
mySAI->TCR2 = another value for TCR2
...
break;
}
}
// Configure specific groups
initSAI(&I2S1::group, my_mode1);
initSAI(&I2S2::group, my_mode2);
bool initSAI(I2S_Layout& mySAI, SAImode_t mode) // mode is I2S, TDM, S/PDIF etc.
{
switch (mode)
{
case SAI_mode_I2S:
mySAI.TCR1 = value for TCR1
mySAI.TCR2 = value for TCR2
...
break;
case SAI_mode_TDM:
mySAI.TCR1 = different value for TCR1
mySAI.TCR2 = another value for TCR2
...
break;
}
}
// Configure specific groups
initSAI(*I2S1::group, my_mode1);
initSAI(*I2S2::group, my_mode2);