mmapping must be aligned with memory pages. It just so happens that the 
GPIO module is already aligned, but since the eQEP is a subset of the PWM 
module, the eQEP base address is not page aligned.

I chose to page align mmap in a more dynamic way to try to avoid some of 
that confusion later. getpagesize() is included with the unistd.h header. 
eQEP_address_ is one of the eQEP addresses you expect ending in 180:

  int masked_address = eQEP_address_ & ~(getpagesize()-1);
  pwm_addr = (void *) mmap(NULL, PWM_BLOCK_LENGTH,
    PROT_READ | PROT_WRITE, MAP_SHARED, eQEPFd, masked_address);

  int offset = eQEP_address_ & (getpagesize()-1);
  position_p = (uint32_t *) ((uint8_t *)pwm_addr + QPOSCNT  + offset);
  pos_init_p = (uint32_t *) ((uint8_t *)pwm_addr + QPOSINIT + offset);
  max_pos_p  = (uint32_t *) ((uint8_t *)pwm_addr + QPOSMAX  + offset);

-
James

On Sunday, April 27, 2014 10:46:46 PM UTC-5, Strawson wrote:
>
> Cheers, John! Your suggestion of 0xFA300180 matches the MMU translations 
> and places it in the linux-arm map range: vmalloc : 0xf0000000 - 
> 0xff000000. This address does return values at both the base and the 
> hardware revision offset, but not correct ones :-/
>
> A little more stumbling on the internet turned up the below example of 
> mmapping the GPIO peripheral at GPIO1_START_ADDR 0x4804C000 which matches 
> exactly to the address in page 159 of the AM335x Technical Reference Manual.
>
> https://github.com/chiragnagpal/beaglebone_mmap/blob/master/gpi.c
>
> I'm not sure why this would work for GPIO but not the eQEP module. 
> Guiseppe, do you mind sharing the output of your physical address 
> function call?  eqepMap.at(channel).phAddress 
>
> Just to confirm, I have the PWM and eQEP modules enabled, pinmux set 
> correctly, and correct encoder readings being displayed with the eqep 
> driver in the original post.
>
> Thanks for any further input,
> Strawson
>
> On Saturday, April 26, 2014 10:55:40 AM UTC-7, john3909 wrote:
>>
>>
>> From: Strawson <[email protected]>
>> Reply-To: <[email protected]>
>> Date: Saturday, April 26, 2014 at 1:46 AM
>> To: <[email protected]>
>> Subject: Re: [beagleboard] Official eQEP driver Support
>>
>> Thank you Guiseppe. I had tried an failed in the past to use mmap, but I 
>> see your solution to the error I had before is to mmap starting at the base 
>> address of the PWM peripheral instead of just at eQEP with 
>> (target&~MAP_MASK). Since ~MAP_MASK is 0xFFFFFFFFF000, the mmap starts 
>> at address 0x48300000 instead of 0x48300180 (for eqep0). Then you seem to 
>> be getting back to the base eQEP position register by adding target&MAP_MASK 
>> (0x180)  back onto the virt_addr. Why the mmap function call fails 
>> without using the MAP_MASK is not entirely clear to me, but I won't worry 
>> about it.
>>
>> While my mmap errors are gone, I'm still only ever reading 0x83 when 
>> accessing the position value pointed to by virt-addr. If I try to access 
>> other parts of the eqep module I only get 0. For example the eqep hardware 
>> revision code which is at offset 0x5C according to the AM335xx reference 
>> manual returns 0 but should contain a value.
>>
>> Take a look at this E2E posting:
>>
>>
>> http://e2e.ti.com/support/arm/sitara_arm/f/791/p/330787/1156969.aspx#1156969
>>
>> I think the address you need is 0xFA300180
>>
>> I have attached a printout of the MMU translations. Hopefully this helps. 
>>
>> Regards,
>> John
>>
>>
>> My test code is below. Any thoughts?
>>
>> Thank you all,
>> Strawson
>>
>> #include <stdio.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <sys/types.h>
>> #include <sys/stat.h>
>> #include <unistd.h>
>> #include <fcntl.h>
>> #include <sys/mman.h>
>>
>> #define MAP_SIZE 4096UL
>> #define MAP_MASK (MAP_SIZE - 1)
>> #define EQEP0_BASE 0x48300180
>> #define EQEP1_BASE 0x48302180
>> #define EQEP2_BASE 0x48304180
>>
>>
>> int main(){
>> int fd;
>> volatile unsigned long *virt_addr;
>> volatile unsigned long *map_base;
>> unsigned long read_result;
>> int i;
>> for(i=0;i<10000;i++){
>> unsigned long target=EQEP2_BASE;
>> //O_SYNC makes the memory uncacheable
>> if ((fd = open("/dev/mem", O_RDWR | O_SYNC))==-1) {
>>   printf("Could not open memory\n");
>>   return 0;
>> }
>> //printf("opened /dev/mem \n");
>>  //EQEP0_BASE&~MAP_MASK truncates the last 12 bits of the target address
>> map_base=(ulong*)mmap(0, 4096, PROT_READ|PROT_WRITE,MAP_SHARED,fd, 
>> target&~MAP_MASK);
>> if(map_base == (void *) -1) {
>> printf("Unable to mmap eqep\n");
>> exit(-1);
>> }
>> //add the last 12 bits (0x180 for eqep) back onto to the address
>> //also add 0x5C to offset to hardware revision code
>> virt_addr = map_base + (target & MAP_MASK)+0x5C;
>> read_result = *((unsigned long *) virt_addr);
>>     printf("\rValue at addr: 0x%lX (%p): 0x%lX  ", map_base, virt_addr, 
>> read_result); 
>>  close(fd);
>> usleep(10000);
>> }
>> close(fd);
>> return 0;
>> }
>>
>>  
>>
>> -- 
>> For more options, visit http://beagleboard.org/discuss
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "BeagleBoard" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>>

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to