GPIOTE et PPI pour le comptage et le suivi

Sur le schéma de kit monté pendant la Fête de la Science, le circuit de la LED qui clignote à chaque impulsion a été identifiée comme étant la cause d'erreurs de comptage.

Pour réintroduire une LED (ou a foritiori un buzzer), il faudrait insérer un ampli-op en suiveur pour éviter de déformer l'impulsion qui arrive sur la GPIO utilisée pour compter les coups. Cependant, des mécanismes internes du RFduino peuvent-être mise en oeuvre. Ils auront en outre l'avantage d'être contrôlables logiciellement, ce qui permettra de les désactiver, sans mobiliser de GPIO supplémentaire.

introduction au PPI

Le RFduino est basé sur le Nordic Semiconductor nRF51822. La documentation du SDK Nordic Semiconductors est accessible uniquement aux acheteurs du SDK. Toutefois, elle reste succinte. D'autres éléments d'information sont accessibles à partir du forum RFduino, et tout simplement dans les codes sources RFduino/cores/arduino.

Le PPI est le Peripheral-Peripheral-Interface. Il permet de connecter les GPIOTE, GPIO-Tasks-Events qui sont eux-même connectés aux GPIO.

Comptage :

void setup() {
  Serial.begin(9600);
 
  pinMode(6, INPUT);
 
  // Config GPIO Event (gpiote_channel, pin, polaritée)
  nrf_gpiote_event_config(0, 6, NRF_GPIOTE_POLARITY_LOTOHI);
 
  // Config counter
  NRF_TIMER1->MODE = TIMER_MODE_MODE_Counter;
  NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
  NRF_TIMER1->TASKS_START = 1;
 
  // Config PPI
  int ppi = find_free_PPI_channel(255);
  NRF_PPI->CH[ppi].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0]; // Input
  NRF_PPI->CH[ppi].TEP = (uint32_t)&NRF_TIMER1->TASKS_COUNT; // Output
 
  NRF_PPI->CHEN |= (1 << ppi); // Active le canal PPI
}
 
void loop() {
  delay(2000);
  NRF_TIMER1->TASKS_CAPTURE[0] = 1; // capture le comptage dans CC[0]
  Serial.println((uint8_t)NRF_TIMER1->CC[0], DEC);
  NRF_TIMER1->TASKS_CLEAR = 1; // count = 0;
}

Suiveur :

void setup() {
  pinMode(6, INPUT);
  pinMode(5, OUTPUT);
 
  // GPIO Event (gpiote_channel, pin, polaritée)
  nrf_gpiote_event_config(0, 6, NRF_GPIOTE_POLARITY_TOGGLE);
 
  // GPIO Task (gpiote_channel, pin, polaritée, etat_initial)
  nrf_gpiote_task_config(1, 5, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
 
  // Valeures possibles pour la polaritée :
  // NRF_GPIOTE_POLARITY_LOTOHI
  // NRF_GPIOTE_POLARITY_HITOLO
  // NRF_GPIOTE_POLARITY_TOGGLE
 
  // Config PPI
  int ppi = find_free_PPI_channel(255);
  NRF_PPI->CH[ppi].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0]; // Input
  NRF_PPI->CH[ppi].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1]; // Output
 
  NRF_PPI->CHEN |= (1 << ppi); // Active le canal PPI
}
 
void loop() {
  delay(1000);
}

Le nouveau code est placé sur Git.