• Labs

Lab 8 - TC - RTC - RTT

Neste laboratório iremos trabalhar com os periféricos de contagem de tempo do nosso microcontrolador.

Lab 5
Data limite para entrega: 01/12/2023
Entregue o código pelo repositório do Classroom
Preencha para entregar Google forms

Os periféricos apresentados neste laboratório são:

  • Real Time Clock - RTC
  • Timer Counter - TC

O laboratório é formado por duas partes:

  • Parte 1 (mínimo):

    1. Entender os exemplos (TC/RTC)
    2. Incorporar todos os exemplos em um único projeto
    3. Pisca pisca
  • Parte 2:

    • C+: fazer outro LED piscar com TC
    • B : Exibir a hora atual no OLED
    • A : Usar IRQ do segundos do RTC

Exemplos

Nesse lab iremos trabalhar com três periféricos que lidam com "tempo": o TimerCounter (TC) que temos no total de quatro unidades TC (TC0 ~ TC3) e cada um com três contadores; o Real-time Timer (RTT) que só temos um e o Real-time Clock (RTC) que também só temos um e funciona como um relógio/calendário.

Um pouco mais sobre os periféricos:

  • TC: Faz várias coisas, mas na disciplina iremos utilizá-lo para gerar interrupções de tempo maiores que 2Hz (ele não consegue gerar tempos muito lentos!)
  • RTT: É um contador que consegue gerar praticamente qualquer frequência (vamos usar para gerar frequências lentas)
  • RTC: É um como um calendário com relógio, ele conta anos, meses, dias, horas, minutos e segundos. E possui um alarme que pode ser configurado para gerar uma interrupção em um determinado momento.

Nós fornecemos para cada periférico um exemplo diferente:

Periférico exemplos
Perifericos/TC-IRQ
Perifericos/RTC-IRQ

Cada exemplo possui o seu próprio README que explica de forma ampla os periféricos. Note que todos esses exemplos estão operando por interrupção! Onde cada periférico possui o seu handler para resolver a interrupção.

Exercise

Para cada exemplo (TC, RTC):

  1. Leia o README
  2. Programe a placa (e veja os LEDs piscando!)
  3. Entenda o código

Exercise

Qual frase a seguir é Correta?

Answer

  1. ❌ O TC pode ser configurado para gerar uma frequência de 10s

O tempo mínimo que ele pode contar é 1s.

  1. ❌ O RTC tem resolucão de ms

O RTC conta segundos!

  1. ❌ O nosso microcontrolador possui até 3 RTT

Não só possui um. Quem tem 3 é o TC

  1. ❌ Cada RTT possui três canais

Não! Quem possui três canais é o TC

  1. ✅ O RTT pode gerar duas interrupcões: incremento e alarme.

Sim!! Podemos configurar no RTT dois modos de IRQ

Exercise

Como deve ser a chamada de função para usarmos o TC2 canal 2 gerando interrupção a 20Hz?

void TC_init(Tc * TC, int ID_TC, int TC_CHANNEL, int freq){

Answer

O TC funciona diferente do PIO, onde o PIO possuia apenas uma conexão com o NVIC para avisar a interrupcão em qualquer um dos 32 pinos. O TC possui um sinal de conexão com o NVIC para cada canal e esses canais possuem um ID único, conforme figura a seguir:

Exercise

Se usarmos o TC1 canal 0 qual deve ser a funcão de handler?

Answer

O handler a ser usado tem realacão com o ID do canal, no caso do canal 0 do TC1 o ID é o ID_TC3 e o handler o TC3_Handler.

Exercise

Um colega está desenhando uma solução para um sistema embarcado que precisa processar dados nas frequências: 1Hz, 2Hz e 44200Hz. Pensando em otimizar o uso energético do uC ele propôs usar um único TC e configurar para cada canal uma frequência diferente:

  • TC0 / ID_TC0 @ 1Hz
  • TC0 / ID_TC1 @ 2Hz
  • TC0 / ID_TC2 @ 44200Hz

O que você faz?

Answer

Aqui tem uma pegadinha! Para o TC contar "tempo" ele precisa usar como base um clock gerado pelo PMC, o TC não consegue usar mais de uma base de tempo por periférico (a mesma base se aplica a todos os canais que ele controla). Para as frequências 1Hz e 2Hz pode ser que funcione usar o mesmo TC pois a base de tempo que a função tc_init vai encontrar deve ser a mesma, mas já para a frequência de 44200Hz a base deve ser outra (é ordens de grandeza maior que as outras frequências) e usar o mesmo TC não vai funcionar!

A melhor solução aqui seria, usar um TC para as frequências mais baixas e outro apenas para a maior frequência:

  • TC0 / ID_TC0 @ 1Hz
  • TC0 / ID_TC1 @ 2Hz
  • TC1 / ID_TC3 @ 44200Hz

Essa parte da escolha da frequência é realizado dentro da função TC_init nas linhas:

/** Configura o TC para operar em  freq hz e interrupçcão no RC compare */
tc_find_mck_divisor(freq, ul_sysclk, &ul_div, &ul_tcclks, ul_sysclk);
tc_init(TC, TC_CHANNEL, ul_tcclks | TC_CMR_CPCTRG);

Exercise

Qual item configura o RTT para gerar uma interrupção de alarme em 13s. Lembre dos argumentos da funcão:

/** 
* Configura RTT
*
* arg0 pllPreScale  : Frequência na qual o contador irá incrementar
* arg1 IrqNPulses   : Valor do alarme 
* arg2 rttIRQSource : Pode ser uma 
*     - 0: 
*     - RTT_MR_RTTINCIEN: Interrupção por incremento (pllPreScale)
*     - RTT_MR_ALMIEN : Interrupção por alarme
*/
static void RTT_init(float freqPrescale, uint32_t IrqNPulses, uint32_t rttIRQSource) {

Answer

Vamos recapitular o que a função RTT_init recebe de argumentos:

  • arg0: define a frequência na qual o contador interno do RTT irá operar.
  • arg1: se configurado a interrupção de alarme, qual o seu valor
  • arg2: quais modos de IRQ vão estar ativados.

Agora vamos analisar as respostas:

  1. ❌ RTT_init(4, 13, RTT_MR_ALMIEN)

Configura o RTT para operar a 4hz (0.25s) e configuramos o alarme para quando o contador chegar em 13, ou seja: 13*0.25 = 3.25s*. Poderíamos ter colocado 52 no lugar de 13, assim o alarme estaria certo: 0.25*52 = 13s*.

  1. ❌ RTT_init(13, 1, RTT_MR_ALMIEN);

Configura o RTT para operar com 13 incrementos por segundo, mas o alarme foi configurado para 1, ou seja: 1/13 * 1 = 0.078s.

  1. ✅ RTT_init(10, 130, RTT_MR_ALMIEN);

Essa aqui é uma opção de resposta correta. Incremento de 10x por segundo e alarme configurado para 130, ou seja: 130/10 = 13s

  1. ✅ RTT_init(1, 13, RTT_MR_ALMIEN);

Outra opção de resposta correta. Incremento de 1x por segundo e alarme configurado para 13, ou seja: 13/1= 13s

Notem que temos duas respostas corretas, mas elas possuem uma sutil e importante diferença: O valor que o contador do RTT atinge antes do alarme.

Exercise

Imagine que você está fazendo um datalogger que armazena Valores e TimeStamp(TS), como você faz para:

  1. Fazer com que o RTC sincronize com o horário/ calendário real?
  2. O que acontece se acabar a bateria do equipamento? Vamos perder a configuracão do RTC?

Answer

Bom.... não tem uma única resposta para essas perguntas, tudo vai depender um pouco de como é o sistema embarcado que você está desenvolvendo/ projetando, mas vamos analisar algumas alternativas aqui.

Fazer com que o RTC sincronize com o horário/ calendário real?

O sistema embarcado tem conexão com a internet? Se tiver facilita um pouco a solução. Com a internet podemos consutlar um dos servidor de relógio disponível, existe até um protocolo chamado de Network Time Protocol (NTP) criado para esse fim de sincronizacão de relógios e vários servidores são públicos e estão espalhados pelo globo:

Alguns servidores, fonte: http://www.pi-time.ca/

Se não tiver conexão com a internet, a solucão é configurar o relógio no próprio dispositivo (via botões e displays) ou conectar o dispositivo em algum outro device via bluetooth/usb/... e fazer a configuracão por um programa/aplicativo próprio.

O que acontece se acabar a bateria do equipamento? Vamos perder a configuracão do RTC?

Muitas vezes o RTC usa uma bateria auxiliar para que ele não se desconfigure quando o sistema principal fica sem energia. Pegue como exemplo o seu notebook, mesmo quando acaba a bateria ele volta com a hora correta. A vida útil dessa bateria depende de vários fatores, mas é comum durar anos.

Anti tamper RTC

O RTC é um dos itens de um sistema embarcado que os hackers gostam de atacar, deem uma olhada nisso:

Lab

Info

Lembre de sempre utilizar fila ou semáforo para comunicar IRQ e TASK

Use o código fornecido no repositório: RTOS-OLED-Xplained-Pro.

Conceito C

No código do RTOS-OLED, vocês devem configurar os botões e os LEDs da placa OLED e então utilizando os periféricos fazer:

  • Que o LED1 pisque na frequência de 4Hz, para isso utilize o TC;
  • Fazer com que o LED2 pisque a uma frequência de 0.25Hz, para isso utilize o RTT;
  • Piscar o LED3 depois de 20 segundos do botão 1 da placa OLED ter sido pressionado, para isso utilize o alarme do RTC.

Tip

Abrir o código atual e o exemplo e ir trazendo as funções e defines que precisa usar, não esqueça de chamar as funções no main.

Tip

Você vai precisar incluir no ASF WIZARD os drivers do: RTT e RTT

O TC já foi adicionado no código exemplo, não adicone o outro que vai dar problema!!!!

Tip

O RTC tem uma função que você consegue buscar no periférico a hora atual: rtc_get_time(), você pode então configurar um alarme para daqui 20s.

  • Leia a função e entenda os seus parâmetros!!

Exercise

No código do OLED1:

  1. Configurar os pinos e os LEDs da placa OLED1
  2. Faça o LED da placa piscar a 5Hz usando um TC.
  3. Fazer com que o LED1 pisque a 4Hz usando o TC
  4. Fazer com que o LED2 inverta seu estado a cada 4s usando o RTT
  5. Fazer com o que o LED3 inicie apagado e pisque uma vez após 20 segundos do botão 1 ter sido pressionado, use o RTC.
  6. Entrar em sleepmode sempre que possível

Exercise

Exiba a hora no formato (HH:MM:SS) no display OLED, a hora deve ser atualizada a todo segundo!

Tip

Para executar isso você deverá ser capaz de saber quando que o segundo mudou, duas são as opções:

  1. Usar um novo TC configurado com 1hz
  2. Pedir para o RTC gerar uma IRQ a cada mudança de segundo

A segunda opção você faz modificando a função de init_rtc:

RTC_init(RTC, ID_RTC, rtc_initial, RTC_IER_ALREN | RTC_IER_SECEN);

E agora você consegue dentro do RTC_handler saber quando você entrou na IRQ pelo segundo:

/*  Verifica por qual motivo entrou
*  na interrupcao, se foi por segundo
*  ou Alarm
*/
if ((ul_status & RTC_SR_SEC) == RTC_SR_SEC) {

    //    
    //  Entrou por segundo! 
    // 
    rtc_clear_status(RTC, RTC_SCCR_SECCLR);
}

Warning

Você nunca deve atualizar display dentro de interrupção (handler)! Sempre na task!.

Conceito B: Melhorando

Exercise

Quando o botão 1 da placa OLED for pressionado, após 20 segundos, faça o LED 3 piscar com um novo TC, substituindo essa função que antes era do RTC.

Conceito A:

Exercise

Usando os botões do OLED, permita ajustar a hora e o minuto!