[ECOS] eCos and eb40a capture mode

Transferencia de Archivos transfers@phaber.com
Tue Oct 14 17:12:00 GMT 2003


Im working now on the at91eb40a target of ecos, and I'm using the cvs 
version of ecos, I have succesfully used ecos for his own things, until now. 
I have now to read an external pwm signal and I have found that the micro 
has a capture mode that does the reading almos from himself, I have been 
trying to  configure the micro using hal_write and as gdb says it has been 
done succesfully.
the micro is the AT91R40008
But outside, the line is i/o so I need it as an input, as my configuration 
plans to do the line must go as an input, the line never goes from the logic 
1.
Is ecos using the timers of the eb40a for any of his functions?
I need some advice here.
To be more explicit. 

I have configured the three timers of the R40008, TC0, TC1, TC2 in capture 
mode, so in the rising edge of  TIOA(the line that gets the pwm)  the TC_V 
is loaded in RA and the, when the falling edge comes, he loads the RB.
When I cheked the physical line of the r40008 after configuring, the line is 
at logic 1!. 

Here's the code. 
-------------- next part --------------
#include <cyg/kernel/kapi.h>
#include <cyg/hal/hal_io.h>
#include "CIF.h"
#include "fft.h"
#include "timer_counter.h"
#include "pio_control.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//include <cyg/hal/hal_arch.h>
#define PS_BASE 0xFFFF4000
#define PS_PCER 0x04
#define PS_PCDR 0x04
/* now declare (and allocate space for) some kernel objects,
   like the two threads we will use */
cyg_thread thread_s[2];		/* space for two thread objects */
static cyg_interrupt intTC0;
static cyg_handle_t intTC0_handle;
static cyg_sem_t TC0_data_ready;
static cyg_sem_t TC0_transmitir;
static cyg_sem_t TC0_fin_transmision;
cyg_count32 TC0_data_ready_counter;
cyg_count32 TC0_transmitir_counter;
cyg_count32 TC0_fin_transmision_counter;
#define CYGNUM_HAL_PRI_HIGH 0
cyg_uint16 TC0_TALTO;
cyg_uint16 TC0_PERIODO;

char stack[2][4096];		/* space for two 4K stacks */
#define TC0_MAX_DATA 2048
#define TC0_NDAT 5
cyg_uint16 TC0_RAM[TC0_MAX_DATA]; /*Espacio para 2048 datos de 16bits para el canal0*/
cyg_uint16 TC0_RBM[TC0_MAX_DATA]; /*8K en total */
cyg_uint16 TC0_CUENTA1=0;
cyg_uint16 TC0_CUENTA2=0;
/* now the handles for the threads */
cyg_handle_t main_thread;
cyg_handle_t instrumentation_thread;
/* and now variables for the procedure which is the thread */
cyg_thread_entry_t main_program;
cyg_thread_entry_t instrumentation_program;

/* and now a mutex to protect calls to the C library */
cyg_mutex_t cliblock;

  cyg_vector_t intTC0_vector = TC0_IRQ;

cyg_uint32 interrupt_TC0_isr(
			   cyg_vector_t vector,
			   cyg_addrword_t data) //BASADO EN eCos book, pag 48
{
  cyg_interrupt_mask(vector);
  cyg_interrupt_acknowledge(vector);
  return(CYG_ISR_HANDLED | CYG_ISR_CALL_DSR);

}
void interrupt_TC0_dsr(
		      cyg_vector_t vector,
		      cyg_ucount32 count,
		      cyg_addrword_t data)
{
  HAL_IO_REGISTER REGISTER;
  cyg_semaphore_post(&TC0_data_ready);
  REGISTER=TC_BASE+TC_CHANNEL0+TC_RA;
  HAL_READ_UINT16(REGISTER,TC0_PERIODO);
  REGISTER=TC_BASE+TC_CHANNEL0+TC_RB;
  HAL_READ_UINT16(REGISTER,TC0_TALTO);
  cyg_interrupt_unmask(vector);
}
void cyg_user_start(void)
{
  HAL_IO_REGISTER REGISTER;
  cyg_uint32 TC_REGISTER;
  printf(STR_HEADER);
  cyg_priority_t intTC0_priority = CYGNUM_HAL_PRI_HIGH;
  printf("Iniciando la configuración del TC,Medición PWM");
  //Hay que activar el periferico
  TC_REGISTER=0x00;
  TC_REGISTER=TC_REGISTER | (PIO_PER_ENABLE<<PIO_P1);
  TC_REGISTER=TC_REGISTER | (PIO_PER_ENABLE<<PIO_P4);
  TC_REGISTER=TC_REGISTER | (PIO_PER_ENABLE<<PIO_P7);
  TC_REGISTER=TC_REGISTER ^ 0xFFFFFFFF;
  printf("\n%x\n",TC_REGISTER);
  REGISTER=PIO_BASE+PIO_PER;
  printf("\n%x\n",REGISTER);

  HAL_WRITE_UINT32(REGISTER,!TC_REGISTER);
  TC_REGISTER=0x000000000;
  TC_REGISTER=TC_REGISTER | (PIO_PDR_DISABLE<<PIO_P1);
  TC_REGISTER=TC_REGISTER | (PIO_PDR_DISABLE<<PIO_P4);
  TC_REGISTER=TC_REGISTER | (PIO_PDR_DISABLE<<PIO_P7);
  printf("\n%x\n",TC_REGISTER);
  REGISTER=PIO_BASE+PIO_PDR;
  printf("\n%x\n",REGISTER);
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  // Primero armo el registro
  TC_REGISTER=0;
  TC_REGISTER=TC_REGISTER | (TC_BMR_NONE<<TC_BMR_XC0);
  TC_REGISTER=TC_REGISTER | (TC_BMR_NONE<<TC_BMR_XC1);
  TC_REGISTER=TC_REGISTER | (TC_BMR_NONE<<TC_BMR_XC2);
  REGISTER=TC_BASE+TC_BMR;
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);

  // Se prepara la configuracion del canal, Chanel Control Register
  TC_REGISTER=0;
  TC_REGISTER=(TC_CCR_CLKEN_ENABLE<<TC_CLKEN);
  TC_REGISTER=TC_REGISTER | (TC_CCR_CLKDIS_NONE<<TC_CLKDIS);
  TC_REGISTER=TC_REGISTER |(TC_SWTRG_TRIGGER<<TC_SWTRG);
  printf("\n%x\n",TC_REGISTER);
  // Se configuran de igual manera los tres canales
  REGISTER=TC_BASE+TC_CCR+TC_CHANNEL0;
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  REGISTER=TC_BASE+TC_CCR+TC_CHANNEL1;
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  REGISTER=TC_BASE+TC_CCR+TC_CHANNEL2;
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  // Se prepara la configuración de canal
  TC_REGISTER=0;
  TC_REGISTER=TC_REGISTER | (TC_CMR_CLSKS_MCK2<<TC_CMR_CLKS);
  TC_REGISTER=TC_REGISTER | (TC_CMR_CLKI_RISING<<TC_CMR_CLKI);
  TC_REGISTER=TC_REGISTER | (TC_CMR_BURST_MODE<<TC_CMR_BURST);
  TC_REGISTER=TC_REGISTER | (TC_CMR_LDBSTOP_NONE<<TC_CMR_LDBSTOP);
  TC_REGISTER=TC_REGISTER | (TC_CMR_LDBDIS_NONE<<TC_CMR_LDBDIS);
  TC_REGISTER=TC_REGISTER | (TC_CMR_ETREDG_RISING_EDGE<<TC_CMR_ETRGEDG);
  TC_REGISTER=TC_REGISTER | (TC_CMR_ABETRG_TIOA<<TC_CMR_ABETRG);
  TC_REGISTER=TC_REGISTER | (TC_CMR_CPCTRG_NONE<<TC_CMR_CPCTRG);
  TC_REGISTER=TC_REGISTER | (TC_CMR_WAVE_CAPTURE<<TC_CMR_WAVE);
  TC_REGISTER=TC_REGISTER | (TC_CMR_LDRA_RISING_EDGE<<TC_CMR_LDRA);
  TC_REGISTER=TC_REGISTER | (TC_CMR_LDRB_RISING_EDGE<<TC_CMR_LDRB);
  printf("%x\n",TC_REGISTER);
  // Se configuran de igual manera los 3 canales
  REGISTER=TC_BASE+TC_CMR+TC_CHANNEL0; // Canal 0
  printf("%x\n",REGISTER);
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  REGISTER=TC_BASE+TC_CMR+TC_CHANNEL1; //Canal 1
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  REGISTER=TC_BASE+TC_CMR+TC_CHANNEL2; //Canal 2
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  // Se prepara la configuracion de la Interrupcion
  //Se abilitan en el IER
  TC_REGISTER=0;
  TC_REGISTER=TC_REGISTER | (TC_IER_ENABLE<<TC_IER_LDRAS);
  printf("%x\n",TC_REGISTER);
  // Se configuran de igual manera los 3 canales
  REGISTER=TC_BASE+TC_IER+TC_CHANNEL0; // Canal 0
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  REGISTER=TC_BASE+TC_IER+TC_CHANNEL1; //Canal 1
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  REGISTER=TC_BASE+TC_IER+TC_CHANNEL2; //Canal 2
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  //Se confirma en el IDR
  TC_REGISTER=TC_REGISTER ^ 0xFFFFFFFF;
  printf("%x\n",TC_REGISTER);
  // Se configuran de igual manera los 3 canales
  REGISTER=TC_BASE+TC_IDR+TC_CHANNEL0; // Canal 0
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  REGISTER=TC_BASE+TC_IDR+TC_CHANNEL1; //Canal 1
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  REGISTER=TC_BASE+TC_IDR+TC_CHANNEL2; //Canal 2
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  //Una ves configurados se activan en el PS
  TC_REGISTER=0xFFFFFFFF;
  REGISTER=PS_BASE+PS_PCER;
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  TC_REGISTER=0x00;
  REGISTER=PS_BASE+PS_PCDR;
  HAL_WRITE_UINT32(REGISTER,TC_REGISTER);
  // Preparando el sistem para antender las interrupciones
  cyg_interrupt_create(
		       intTC0_vector,
		       intTC0_priority,
		       0,
		       &interrupt_TC0_isr,
		       &interrupt_TC0_dsr,
		       &intTC0_handle,
		       &intTC0);
  cyg_interrupt_attach(intTC0_handle);
  cyg_interrupt_unmask(intTC0_vector);

  cyg_semaphore_init(&TC0_data_ready,TC0_data_ready_counter);
  cyg_semaphore_init(&TC0_transmitir,TC0_transmitir_counter);
  cyg_semaphore_init(&TC0_fin_transmision,TC0_fin_transmision_counter);

  cyg_mutex_init(&cliblock);

  cyg_thread_create(6, main_program, (cyg_addrword_t) 0,
		    "MAIN THREAD", (void *) stack[0], 4096,
		    &main_thread, &thread_s[0]);
  cyg_thread_create(3, instrumentation_program, (cyg_addrword_t) 0,
		    "Instrumentation THREAD", (void *) stack[1], 4096,
		    &instrumentation_thread, &thread_s[1]);
  cyg_thread_resume(main_thread);
  cyg_thread_resume(instrumentation_thread);
}

/* this is a simple program which runs in a thread */
void main_program(cyg_addrword_t data)
{
  //  int message = (int) data;
  // int delay;
  int datos_cuenta;
  printf("\nIniciando mediciones,esperando %i datos\n",TC0_MAX_DATA);

  for (;;) {
    cyg_semaphore_wait(&TC0_transmitir);
    for(datos_cuenta=0;datos_cuenta<TC0_MAX_DATA;datos_cuenta++){
      printf("%i\t%i",TC0_RAM[datos_cuenta],TC0_RBM[datos_cuenta]);
    }
    cyg_semaphore_post(&TC0_fin_transmision);
  }
}
void instrumentation_program(cyg_addrword_t data)
{
  while(1){
    cyg_semaphore_wait(&TC0_data_ready); // Espera a que exista un dato proveniente del PWM
    printf("1");
    if ((TC0_CUENTA1++)==TC0_NDAT){ // Espera que hayan pasado TC0_NDAT datos
      TC0_CUENTA1=0; // Renicia la cuenta de datos
      TC0_RAM[TC0_CUENTA2]=TC0_TALTO; //Guarda los datos correspondientes en los arreglos
      TC0_RBM[TC0_CUENTA2]=TC0_PERIODO;
      if(TC0_CUENTA2==TC0_MAX_DATA) // Si se ha llenado el arreglo de datos, se activa el semaforo de TC0_transmitir y espera que se haya terminado la transmision a traves del semaforo TC0_fin_transmision, para luego reiniciar la cuenta, desactiva la interrupcion y la activa al finalizar la transmision
	{
	  cyg_interrupt_mask(intTC0_vector);
	  cyg_semaphore_post(&TC0_transmitir);
	  TC0_CUENTA2=0;
	  cyg_semaphore_wait(&TC0_fin_transmision);
	  cyg_interrupt_unmask(intTC0_vector);
	}
      else{
	
	    TC0_CUENTA2++; //Incrementa el contador del arreglo
	  }
    }
  }

}


-------------- next part --------------
-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss


More information about the Ecos-discuss mailing list