Skip to content

Commit b33c84a

Browse files
committed
add PWM output. Works for T1-3, T1-4, T2-2, T2-3. Does not work for T1-1, T1-2, T2-1
1 parent f56aee7 commit b33c84a

7 files changed

Lines changed: 542 additions & 44 deletions

File tree

sduino/pins_arduino.h

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,29 @@ static const uint8_t A4 = PIN_A4;
100100
#define A3 PIN_A3
101101
#define A4 PIN_A4
102102

103+
/* on the STM8S the logical pin numbers are really confusing instead
104+
* of beeing helpful. So maybe it is better to use these Portpin-Names
105+
* instead?
106+
*/
107+
enum portpin {
108+
PA1, /* 0 */
109+
PA2,
110+
PA3,
111+
PB5, /* 3 */
112+
PB4,
113+
PC3, /* 5 */
114+
PC4,
115+
PC5,
116+
PC6,
117+
PC7,
118+
PD1, /* 10 */
119+
PD2,
120+
PD3,
121+
PD4,
122+
PD5,
123+
PD6 /* 15 */
124+
};
125+
103126

104127
/*FIXME
105128
#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))
@@ -238,18 +261,18 @@ const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
238261
const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
239262
NOT_ON_TIMER,
240263
NOT_ON_TIMER,
241-
TIMER23,
264+
TIMER23, // 2
242265
NOT_ON_TIMER,
243266
NOT_ON_TIMER,
244-
TIMER13,
245-
TIMER14,
246-
TIMER21,
247-
TIMER11,
248-
TIMER12,
267+
TIMER13, // 5
268+
TIMER14, // 6
269+
TIMER21, // 7
270+
TIMER11, // 8
271+
TIMER12, // 9
249272
NOT_ON_TIMER,
250-
TIMER23, /* only alternate function */
251-
TIMER22,
252-
TIMER21, /* only alternate function */
273+
TIMER23, /* 11, only alternate function */
274+
TIMER22, // 12
275+
TIMER21, /* 13, only alternate function */
253276
NOT_ON_TIMER,
254277
NOT_ON_TIMER,
255278
};

sduino/wiring.c

Lines changed: 75 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,12 @@ unsigned long micros()
9696
*/
9797
END_CRITICAL
9898

99-
return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
99+
// return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
100+
// return ((m*250+t) * (64/16) ); // FIXME: use calculated value
101+
m *= 250;
102+
m += t;
103+
m <<= 2;
104+
return m;
100105
}
101106

102107

@@ -278,49 +283,84 @@ void init()
278283
TIM4_Cmd(ENABLE); // TIM4->CR1 |= TIM4_CR1_CEN;
279284

280285

281-
#if 0 //FIXME
282286
// timers 1 and 2 are used for phase-correct hardware pwm
283287
// this is better for motors as it ensures an even waveform
284288
// note, however, that fast pwm mode can achieve a frequency of up
285289
// 8 MHz (with a 16 MHz clock) at 50% duty cycle
286290

287-
#if defined(TCCR1B) && defined(CS11) && defined(CS10)
288-
TCCR1B = 0;
291+
TIM1_DeInit();
292+
TIM1_TimeBaseInit(64, TIM1_COUNTERMODE_UP, 255, 0);
293+
TIM1_Cmd(ENABLE);
294+
295+
TIM1_OC1Init(
296+
TIM1_OCMODE_PWM2,
297+
TIM1_OUTPUTSTATE_DISABLE,
298+
TIM1_OUTPUTNSTATE_DISABLE,
299+
0,
300+
TIM1_OCPOLARITY_HIGH,
301+
TIM1_OCNPOLARITY_HIGH,
302+
TIM1_OCIDLESTATE_SET,
303+
TIM1_OCNIDLESTATE_SET
304+
);
305+
TIM1_OC2Init(
306+
TIM1_OCMODE_PWM2,
307+
TIM1_OUTPUTSTATE_DISABLE,
308+
TIM1_OUTPUTNSTATE_DISABLE,
309+
0,
310+
TIM1_OCPOLARITY_HIGH,
311+
TIM1_OCNPOLARITY_HIGH,
312+
TIM1_OCIDLESTATE_SET,
313+
TIM1_OCNIDLESTATE_SET
314+
);
315+
TIM1_OC3Init(
316+
TIM1_OCMODE_PWM2,
317+
TIM1_OUTPUTSTATE_DISABLE,
318+
TIM1_OUTPUTNSTATE_DISABLE,
319+
0,
320+
TIM1_OCPOLARITY_HIGH,
321+
TIM1_OCNPOLARITY_HIGH,
322+
TIM1_OCIDLESTATE_SET,
323+
TIM1_OCNIDLESTATE_SET
324+
);
325+
TIM1_OC4Init(
326+
TIM1_OCMODE_PWM2,
327+
TIM1_OUTPUTSTATE_DISABLE,
328+
0,
329+
TIM1_OCPOLARITY_HIGH,
330+
TIM1_OCIDLESTATE_SET
331+
);
332+
TIM1_Cmd(ENABLE);
333+
TIM1_CtrlPWMOutputs(ENABLE);
289334

290-
// set timer 1 prescale factor to 64
291-
sbi(TCCR1B, CS11);
292-
#if F_CPU >= 8000000L
293-
sbi(TCCR1B, CS10);
294-
#endif
295-
#elif defined(TCCR1) && defined(CS11) && defined(CS10)
296-
sbi(TCCR1, CS11);
297-
#if F_CPU >= 8000000L
298-
sbi(TCCR1, CS10);
299-
#endif
300-
#endif
301-
// put timer 1 in 8-bit phase correct pwm mode
302-
#if defined(TCCR1A) && defined(WGM10)
303-
sbi(TCCR1A, WGM10);
304-
#endif
305335

306-
// set timer 2 prescale factor to 64
307-
#if defined(TCCR2) && defined(CS22)
308-
sbi(TCCR2, CS22);
309-
#elif defined(TCCR2B) && defined(CS22)
310-
sbi(TCCR2B, CS22);
311-
//#else
312-
// Timer 2 not finished (may not be present on this CPU)
313-
#endif
336+
TIM2_DeInit();
337+
TIM2_TimeBaseInit(TIM2_PRESCALER_64, 255);
314338

315-
// configure timer 2 for phase correct pwm (8-bit)
316-
#if defined(TCCR2) && defined(WGM20)
317-
sbi(TCCR2, WGM20);
318-
#elif defined(TCCR2A) && defined(WGM20)
319-
sbi(TCCR2A, WGM20);
320-
//#else
321-
// Timer 2 not finished (may not be present on this CPU)
322-
#endif
339+
TIM2_OC1Init(
340+
TIM2_OCMODE_PWM1,
341+
TIM2_OUTPUTSTATE_DISABLE,
342+
0,
343+
TIM2_OCPOLARITY_HIGH
344+
);
323345

346+
TIM2_OC2Init(
347+
TIM2_OCMODE_PWM1,
348+
TIM2_OUTPUTSTATE_DISABLE,
349+
0,
350+
TIM2_OCPOLARITY_HIGH
351+
);
352+
353+
TIM2_OC3Init(
354+
TIM2_OCMODE_PWM1,
355+
TIM2_OUTPUTSTATE_DISABLE,
356+
0,
357+
TIM2_OCPOLARITY_HIGH
358+
);
359+
TIM2_OC1PreloadConfig(ENABLE); // TIM2->CCMR1 |= (uint8_t)TIM2_CCMR_OCxPE;
360+
TIM2_OC2PreloadConfig(ENABLE); // TIM2->CCMR2 |= (uint8_t)TIM2_CCMR_OCxPE;
361+
TIM2_OC3PreloadConfig(ENABLE); // TIM2->CCMR3 |= (uint8_t)TIM2_CCMR_OCxPE;
362+
TIM2_Cmd(ENABLE); // TIM2->CR1 |= (uint8_t)TIM2_CR1_CEN;
363+
#if 0
324364
#if defined(TCCR3B) && defined(CS31) && defined(WGM30)
325365
sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64
326366
sbi(TCCR3B, CS30);

0 commit comments

Comments
 (0)