Hello all !
I have some problem to understand how TC works on DUE.
I want to mesurate 10 fan speed, and 5 are critical, so i think Timer was the solution.
Here is a part of my code:
void Init_TC () {
REG_PIOA_PDR = 0x4;
REG_PIOB_PDR = 0x2000000;
REG_PIOC_PDR = 0x12000000;
REG_PIOD_PDR = 0x80;
REG_PIOB_ABSR = REG_PIOB_ABSR | 0x2000000u;
REG_PIOC_ABSR = REG_PIOC_ABSR | 0x12000000u;
REG_PIOD_ABSR = REG_PIOD_ABSR | 0x80u;
REG_PMC_PCER0 = REG_PMC_PCER0 | 0x18000000; // Activation des Timers, ID27 et ID28, bits 28 et 29 de PMC_PCSR0.
REG_PMC_PCER1 = REG_PMC_PCER1 | 0xE; // Activation des Timers, ID33, ID34 et ID35, bits 2, 3 et 4 de PMC_PCSR1
// Timer 0: Mesure de vitesse du ventilateur supérieur 1.
TC_Configure ( TC0, 0, TC_CMR_TCCLKS_TIMER_CLOCK5 | TC_CMR_ETRGEDG_RISING | TC_CMR_ABETRG | TC_CMR_LDRA_RISING );
// Timer 1: Mesure de vitesse du ventilateur supérieur 2.
TC_Configure ( TC0, 1, TC_CMR_TCCLKS_TIMER_CLOCK5 | TC_CMR_ETRGEDG_RISING | TC_CMR_ABETRG | TC_CMR_LDRA_RISING );
// Timer 6: Mesure de vitesse du ventilateur supérieur 3.
TC_Configure ( TC2, 0, TC_CMR_TCCLKS_TIMER_CLOCK5 | TC_CMR_ETRGEDG_RISING | TC_CMR_ABETRG | TC_CMR_LDRA_RISING );
// Timer 7: Mesure de vitesse de la pompe 1.
TC_Configure ( TC2, 1, TC_CMR_TCCLKS_TIMER_CLOCK5 | TC_CMR_ETRGEDG_RISING | TC_CMR_ABETRG | TC_CMR_LDRA_RISING );
// Timer 8: Mesure de vitesse de la pompe 2.
TC_Configure ( TC2, 2, TC_CMR_TCCLKS_TIMER_CLOCK5 | TC_CMR_ETRGEDG_RISING | TC_CMR_ABETRG | TC_CMR_LDRA_RISING );
}
void read_WATERPUMPS_speed () {
if ( REG_PWM_CDTY6 >= MINIMAL_HDW_WATERPUMP1_SPEED ) {
const uint32_t tc7ra = TC2->TC_CHANNEL[1].TC_RA; // La pompe 1 tourne.
const uint32_t tc7cv = TC_ReadCV ( TC2, 1 );
if ( ( tc7cv < PULSE_TIMEOUT ) && ( tc7ra < BLOCK_TIMEOUT ) ) WATERPUMP1_speed = ( 960000 / tc7ra );
else if ( tc7ra >= BLOCK_TIMEOUT ) Serial.println ( ERRORMSG_WATERPUMP1_BLOCKED );
else WATERPUMP1_speed = 0;
WATERPUMP2_speed = 0;
}
else if ( REG_PWM_CDTY5 >= MINIMAL_HDW_WATERPUMP2_SPEED ) {
const uint32_t tc8ra = TC2->TC_CHANNEL[2].TC_RA; // La pompe 2 tourne.
const uint32_t tc8cv = TC_ReadCV ( TC2, 2 );
if ( ( tc8cv < PULSE_TIMEOUT ) && ( tc8ra < BLOCK_TIMEOUT ) ) WATERPUMP2_speed = ( 960000 / tc8ra );
else if ( tc8ra >= BLOCK_TIMEOUT ) Serial.println ( ERRORMSG_WATERPUMP2_BLOCKED );
else WATERPUMP2_speed = 0;
WATERPUMP1_speed = 0;
}
else if ( ( REG_PWM_CDTY6 >= MINIMAL_HDW_WATERPUMP1_SPEED ) && ( REG_PWM_CDTY5 >= MINIMAL_HDW_WATERPUMP2_SPEED ) ) {
const uint32_t tc7ra = TC2->TC_CHANNEL[1].TC_RA; // Les deux pompes tournent.
const uint32_t tc8ra = TC2->TC_CHANNEL[2].TC_RA;
const uint32_t tc7cv = TC_ReadCV ( TC2, 1 );
const uint32_t tc8cv = TC_ReadCV ( TC2, 2 );
if ( ( tc7cv < PULSE_TIMEOUT ) && ( tc7ra < BLOCK_TIMEOUT ) ) WATERPUMP1_speed = ( 960000 / tc7ra );
else if ( tc7ra >= BLOCK_TIMEOUT ) Serial.println ( ERRORMSG_WATERPUMP1_BLOCKED );
else WATERPUMP1_speed = 0;
if ( ( tc8cv < PULSE_TIMEOUT ) && ( tc8ra < BLOCK_TIMEOUT ) ) WATERPUMP2_speed = ( 960000 / tc8ra );
else if ( tc8ra >= BLOCK_TIMEOUT ) Serial.println ( ERRORMSG_WATERPUMP2_BLOCKED );
else WATERPUMP2_speed = 0;
}
}
void read_TOP_fans () {
if ( REG_PWM_CDTY0 != TOP_FAN_STOP ) {
const uint32_t tc0ra = TC0->TC_CHANNEL[0].TC_RA;
const uint32_t tc1ra = TC0->TC_CHANNEL[1].TC_RA;
const uint32_t tc6ra = TC2->TC_CHANNEL[0].TC_RA;
const uint32_t tc0cv = TC_ReadCV ( TC0, 0 );
const uint32_t tc1cv = TC_ReadCV ( TC0, 1 );
const uint32_t tc6cv = TC_ReadCV ( TC2, 0 );
if ( ( tc0cv < PULSE_TIMEOUT ) && ( tc0ra < BLOCK_TIMEOUT ) ) TOP1_speed = ( 960000 / tc0ra );
else if ( tc0ra >= BLOCK_TIMEOUT ) Serial.println ( ERRORMSG_TOP1_BLOCKED );
else TOP1_speed = 0;
if ( ( tc1cv < PULSE_TIMEOUT ) && ( tc1ra < BLOCK_TIMEOUT ) ) TOP2_speed = ( 960000 / tc1ra );
else if ( tc1ra >= BLOCK_TIMEOUT ) Serial.println ( ERRORMSG_TOP2_BLOCKED );
else TOP2_speed = 0;
if ( ( tc6cv < PULSE_TIMEOUT ) && ( tc6ra < BLOCK_TIMEOUT ) ) TOP3_speed = ( 960000 / tc6ra );
else if ( tc6ra >= BLOCK_TIMEOUT ) Serial.println ( ERRORMSG_TOP3_BLOCKED );
else TOP3_speed = 0;
const uint32_t TOP_speed_out = 82031 / ( ( ( TOP1_speed + TOP2_speed + TOP3_speed ) / 3 ) / 30 );
REG_PWM_CPRDUPD4 = TOP_speed_out;
REG_PWM_CPRDUPD7 = TOP_speed_out;
}
else {
TOP1_speed = 0;
TOP2_speed = 0;
TOP3_speed = 0;
REG_PWM_CPRDUPD4 = 0;
REG_PWM_CPRDUPD7 = 0;
}
}
TC0, TC1 and TC6 are assembled to create a PWM mirror of them.
For now, it works, but sometime speed values are out of range. Is there a way to optimize this ?
I have try to modify TC options, but i cannot really understand.