Skip to content

Commit 13b6633

Browse files
committed
STM-can-api: Added usage of prescaler
- This enables more frequencies, but without regard to the accuracy. May still require manual clock setup, to remain in tolerance window
1 parent 35c9e7a commit 13b6633

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

targets/TARGET_STM/can_api.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,24 @@ static void _can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz
135135
int ntq = 10000000 / hz;
136136
#endif
137137

138+
int nominalPrescaler = 1;
139+
// !When the sample point should be lower than 50%, this must be changed to
140+
// !IS_FDCAN_NOMINAL_TSEG2(ntq/nominalPrescaler), since
141+
// NTSEG2 and SJW max values are lower. For now the sample point is fix @75%
142+
while (!IS_FDCAN_NOMINAL_TSEG1(ntq/nominalPrescaler)){
143+
nominalPrescaler ++;
144+
if (!IS_FDCAN_NOMINAL_PRESCALER(nominalPrescaler)){
145+
error("Could not determine good nominalPrescaler. Bad clock value\n");
146+
}
147+
}
148+
ntq = ntq/nominalPrescaler;
149+
138150
obj->CanHandle.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
139151
obj->CanHandle.Init.Mode = FDCAN_MODE_NORMAL;
140152
obj->CanHandle.Init.AutoRetransmission = ENABLE;
141153
obj->CanHandle.Init.TransmitPause = DISABLE;
142154
obj->CanHandle.Init.ProtocolException = ENABLE;
143-
obj->CanHandle.Init.NominalPrescaler = 1; // Prescaler
155+
obj->CanHandle.Init.NominalPrescaler = nominalPrescaler; // Prescaler
144156
obj->CanHandle.Init.NominalTimeSeg1 = ntq * 0.75; // Phase_segment_1
145157
obj->CanHandle.Init.NominalTimeSeg2 = ntq - 1 - obj->CanHandle.Init.NominalTimeSeg1; // Phase_segment_2
146158
obj->CanHandle.Init.NominalSyncJumpWidth = obj->CanHandle.Init.NominalTimeSeg2; // Synchronization_Jump_width
@@ -278,6 +290,19 @@ int can_frequency(can_t *obj, int f)
278290
int ntq = 10000000 / hz;
279291
#endif
280292

293+
int nominalPrescaler = 1;
294+
// !When the sample point should be lower than 50%, this must be changed to
295+
// !IS_FDCAN_DATA_TSEG2(ntq/nominalPrescaler), since
296+
// NTSEG2 and SJW max values are lower. For now the sample point is fix @75%
297+
while (!IS_FDCAN_DATA_TSEG1(ntq/nominalPrescaler)){
298+
nominalPrescaler ++;
299+
if (!IS_FDCAN_NOMINAL_PRESCALER(nominalPrescaler)){
300+
error("Could not determine good nominalPrescaler. Bad clock value\n");
301+
}
302+
}
303+
ntq = ntq/nominalPrescaler;
304+
305+
obj->CanHandle.Init.NominalPrescaler = nominalPrescaler;
281306
obj->CanHandle.Init.NominalTimeSeg1 = ntq * 0.75; // Phase_segment_1
282307
obj->CanHandle.Init.NominalTimeSeg2 = ntq - 1 - obj->CanHandle.Init.NominalTimeSeg1; // Phase_segment_2
283308
obj->CanHandle.Init.NominalSyncJumpWidth = obj->CanHandle.Init.NominalTimeSeg2; // Synchronization_Jump_width

0 commit comments

Comments
 (0)