Glomation
 
Advanced Search
Welcome, Guest. Please login or register.

Login with username, password and session length
May 22, 2012, 04:02:02 AM
News: Glomation introduces new GECM-9G25 SODIMM system on module
Pages: [1]
Topic Tools  
Read October 23, 2010, 11:51:04 AM #0
EuMatBa

Timer init fails

Hello, is any sample code, which using external clock source? I have spent 2 days on it and I haven't any result. I also tried to build an app based on sample KEIL code:

Code:
#include "AT91SAM9260.h"
#include <stdio.h>
#define CLOCK_FREQ  96109714

volatile char TimeFlag;
volatile long TimeTick;

void wait (void) {
  while (!TimeFlag);
  TimeFlag = 0;
}

__attribute__ ((interrupt ("IRQ"))) void  PIT_Handler (void)   {
  if (TimeTick++ >= 1000) {
    TimeFlag = 1;
    TimeTick = 0;
  }
  puts("Test 999\n");
  *AT91C_AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;
}

int main (void) {
  int i;

  // Enable the Clock of the PIO for LEDs
  AT91C_BASE_PMC->PMC_PCER  = 1 << AT91C_ID_PIOA;
  puts("Test 1\n");

  // System Timer initialization
  AT91C_BASE_SYS->PITC_PIMR  = CLOCK_FREQ/16/100;     // Interrupt time interval ~10 ms
  puts("Test 2\n");
  AT91C_BASE_SYS->PITC_PIMR |= AT91C_PITC_PITIEN;
  puts("Test 3\n");
  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (unsigned int) PIT_Handler;
  puts("Test 4\n");
  AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE;
  puts("Test 5\n");

  // Enable ST interrupt
  AT91C_BASE_AIC->AIC_IECR = (1<<AT91C_ID_SYS);
  puts("Test 6\n");

  // Run System Timer
  AT91C_BASE_SYS->PITC_PIMR |= AT91C_PITC_PITEN;
  puts("Test 7\n");

  // Loop forever
  for (;;) wait();
}

I can't recognize, what I doing wrong. Thank for help.
« Last Edit: October 30, 2010, 04:22:47 PM by EuMatBa »
 
Read October 25, 2010, 07:43:58 AM #1
admin

Re: Timer 1 sample code

The Keil sample code assumes the application program has full control of the entire system which is not the case when running Linux.  Each application program is assigned a virtual address space.  Special techniques must be used to map to the the hardware physical address.   The devmem2.c can be used as a good example to map physical memory, http://sources.buildroot.net/devmem2.c.
 
Read October 28, 2010, 04:36:23 AM #2
EuMatBa

Re: Timer 1 sample code

I have written a new code for TC4 IRQ, but it insn't working, what I doing wrong? It died on first attempt to change TC4_IDR. Thanks for any help.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>
#include "tc_def.h"

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

unsigned long TC4repeat=0;

 void __attribute__ ((interrupt)) intTC4 (void) {
    if (TC4repeat < 750000) TC4repeat++;
    else {
TC4repeat = 0;
printf("TC4 interupt\n");
fflush(stdout);
    }
    return;
}

int main(void) {
    int fd;
    void *TC4_base,*AIC_base;
    unsigned long read_result, writeval,mapped_TC4, mappped_AIC;
    off_t TC4_target,AIC_target;

    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) printf("/dev/mem can not be opened.\n");
    printf("/dev/mem opened.\n");
    fflush(stdout);
    
    // Segment map for TC3,TC4,TC5
    TC4_target = 0xFFFDC000;
    TC4_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (unsigned) TC4_target & ~MAP_MASK);
    if(TC4_base == (void *) -1) printf("Memory segment can not be opened.\n");
    printf("Memory mapped at address 0xFFFDC000, as adress 0x%X.\n",TC4_base);
    fflush(stdout);
    
    TC4_base +=(TC4_target & ~MAP_MASK);
    
    // Segment map for  AIC
    AIC_target = 0xFFFFF000;
    AIC_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (unsigned) AIC_target & ~MAP_MASK);
    if(AIC_base == (void *) -1) printf("Memory segment can not be opened.\n");
    printf("Memory mapped at address 0xFFFFF000, as adress 0x%X.\n",AIC_base);
    fflush(stdout);
    
    AIC_base +=(AIC_target & ~MAP_MASK);
    
    // INIT TC4
    
    printf("Attempt to INIT TC4.\n");
    fflush(stdout);
    
    *((unsigned long *) TC4_base + TC4_IDR) = 0x000000FF;  
    
    printf("IDR\n");
    fflush(stdout);
    
    *((unsigned long *) TC4_base + TC4_CMR) = 0x00000003;    
    
    printf("CMR\n");
    fflush(stdout);
        
    *((unsigned long *) TC4_base + TC345_BCR) = 0x00000000;
    
    printf("BCR\n");
    fflush(stdout);
    
    *((unsigned long *) TC4_base + TC345_BMR) = 0x00000000;
    
    printf("BMR\n");
    fflush(stdout);
    
    *((unsigned long *) TC4_base + TC4_CCR) = 0x00000004;
        
    printf("CCT\n");
    fflush(stdout);
    
    *((unsigned long *) TC4_base + TC4_IER) = 0x00000001;
    
    printf("IER\n");
    fflush(stdout);
    
    printf("TC4 INIT END.\n");
    fflush(stdout);
    
    // INIT AIC
    
    printf("Attempt to INIT AIC.\n");
    fflush(stdout);
    
    // IDCR
    *((unsigned long *) AIC_base +  0x00000124) = 1 << 27;
    
    printf("IDCR\n");
    fflush(stdout);
    
    // ICCR
    *((unsigned long *) AIC_base + 0x00000124) = 1 << 27;
    
    printf("ICCR\n");
    fflush(stdout);
    
    // SMR27
    *((unsigned long *) AIC_base + 0x0000006C) = 0x46;
    
    printf("SMR27\n");
    fflush(stdout);
        
    // SVR27
    *((unsigned long *) AIC_base + 0x000000EC) = &intTC4;
    
    printf("SVR27\n");
    fflush(stdout);
    
    // IECR
    *((unsigned long *) AIC_base + 0x00000120) = 1 << 27;
    
    printf("IECR\n");
    fflush(stdout);
    
    printf("All registers have been set.\n============================\n");
    fflush(stdout);
    
    // Deataching segments
    if(munmap(TC4_base, MAP_SIZE) == -1) printf("/dev/mem1 can not be closed.\n");
    if(munmap(AIC_base, MAP_SIZE) == -1) printf("/dev/mem2 can not be closed.\n");
    close(fd);
    
    while (1);
    
    return 0;
}
« Last Edit: October 28, 2010, 04:12:58 PM by EuMatBa »
 
Read October 30, 2010, 04:05:20 PM #3
EuMatBa

Re: Timer 1 sample code

I've found a source code for TC3 external event measuring here.

I have re-writen code as example source, but init of any TC in TC block 1 (TC3,TC4,TC5) have failed.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>

#define TC_BCR 0xC0 //Block Control Register
#define TC_BMR 0xC4 //Block Mode Register

#define TC_CCR 0x00004000 //Channel Control Register
#define TC_CMR 0x00004004 //Channel Mode Register
#define TC_CV  0x00004010 //Counter Value
#define TC_RA  0x00004014 //Register A
#define TC_RB  0x00004018 //Register B
#define TC_RC  0x0000401C //Register C
#define TC_SR  0x00004020 //Status Register
#define TC_IER 0x00004024 //Interrupt Enable Register
#define TC_IDR 0x00004028 //Interrupt Disable Register
#define TC_IMR 0x0000402C //Interrupt Mask Register

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

int main(void) {
    int fd;
    void *TC3_base,*PMC_base,*PIOB_base;
    unsigned long read_result;
    off_t TC3_target,AIC_target,PMC_target,PIOB_target;

    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) printf("/dev/mem can not be opened.\n");
    printf("/dev/mem opened.\n");
    fflush(stdout);
    
    // Segment map for TC3,TC4,TC5
    TC3_target = 0xFFFDC000;
    TC3_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (unsigned) TC3_target & ~MAP_MASK);
    if(TC3_base == (void *) -1) printf("Memory segment can not be opened.\n");
    printf("Memory mapped at address 0xFFFDC000, as adress 0x%X.\n",TC3_base);
    fflush(stdout);
    
    TC3_base +=(TC3_target & ~MAP_MASK);
    
    // Segment map for  PMC
    PMC_target = 0xFFFFF000;
    PMC_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (unsigned) PMC_target & ~MAP_MASK);
    if(PMC_base == (void *) -1) printf("Memory segment can not be opened.\n");
    printf("Memory mapped at address 0xFFFFF000, as adress 0x%X.\n",PMC_base);
    fflush(stdout);
    
    PMC_base +=(PMC_target & ~MAP_MASK);
    
    // Segment map for  PIOB
    PIOB_target = 0xFFFFF600;
    PIOB_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (unsigned) PIOB_target & ~MAP_MASK);
    if(PIOB_base == (void *) -1) printf("Memory segment can not be opened.\n");
    printf("Memory mapped at address 0xFFFFF600, as adress 0x%X.\n",PIOB_base);
    fflush(stdout);
    
    PIOB_base +=(PIOB_target & ~MAP_MASK);
    
    printf("Attempt to INIT PDC.\n");
    fflush(stdout);
    
    *((unsigned long *) PMC_base + 0x0010) = (1 << 26);  
    
    printf("Attempt to INIT PIOB.\n");
    fflush(stdout);
    
    *((unsigned long *) PIOB_base + 0x0004) = (1 << 17);
    *((unsigned long *) PIOB_base + 0x0014) = (1 << 17);
    *((unsigned long *) PIOB_base + 0x0060) = (1 << 17);
    *((unsigned long *) PIOB_base + 0x0074) = (1 << 17);
    
    printf("Attempt to INIT TC4.\n");
    fflush(stdout);
    
    *((unsigned long *) TC3_base + TC_IDR) = ~1;  
    
    printf("IDR\n");
    fflush(stdout);
    
    *((unsigned long *) TC3_base + TC_CMR) = 0x6|0x8;    
    
    printf("CMR\n");
    fflush(stdout);
    
    *((unsigned long *) TC3_base + TC_CCR) = 0x00000004;
        
    printf("CCR\n");
    fflush(stdout);
        
    printf("TC3 INIT END.\n");
    fflush(stdout);
    
    printf("All registers have been set.\n============================\n");
    fflush(stdout);
    
    // Deataching segments
    
    if(munmap(PIOB_base, MAP_SIZE) == -1) printf("/dev/mem2 can not be closed.\n");
    if(munmap(PMC_base, MAP_SIZE) == -1) printf("/dev/mem3 can not be closed.\n");
  
    while (1) {
     usleep(1000);
     read_result = *((unsigned long *) TC3_base + TC_CV);
     printf("Value is: %u RPM\n",read_result);
     fflush(stdout);
    }
    
    if(munmap(TC3_base, MAP_SIZE) == -1) printf("/dev/mem1 can not be closed.\n");
    close(fd);
    
    return 0;
}

Error:

Code:
# /mnt/arm/tc2
/dev/mem opened.
Memory mapped at address 0xFFFDC000, as adress 0x40001000.
Memory mapped at address 0xFFFFF000, as adress 0x40002000.
Memory mapped at address 0xFFFFFC00, as adress 0x40003000.
Memory mapped at address 0xFFFFF600, as adress 0x40004000.
Attempt to INIT PDC.
Attempt to INIT PIOB.
Attempt to INIT TC4.
Segmentation fault
« Last Edit: October 30, 2010, 04:25:37 PM by EuMatBa »
 
Pages: [1]
Jump to:  

Theme Update by Runic Warrior Originally created by m3talc0re