User avatar
Laurens-wuyts
Posts: 716
Joined: Wed Aug 21, 2013 7:35 pm
Location: Belgium
Contact: Website

8 - 10MHz interrupt

Mon Apr 13, 2015 9:01 am

Hey everyone

Is it in some way possible to have an interrupt between 8 and 10 MHz?
If not in Linux, is it possible using bare metal?

Thanks in advance
Laurens

User avatar
joan
Posts: 14959
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: 8 - 10MHz interrupt

Mon Apr 13, 2015 9:50 am

Under Linux you would have to sample to approach those speeds. Anything faster than around an interrupt every 50-100 microseconds on a gpio and the Pi will start to miss interrupts using the system calls (poll/select). It depends on the speed with which you can handle the "interrupt" in userland.

You could probably sample that fast with busy waits on the Pi. You'd have to accept you will miss events if you are scheduled out, but it might be ok on the Pi2, especially if you reserve a core for your program.

Bare metal should be fine (apart from getting at the data to process it after capture).

User avatar
Laurens-wuyts
Posts: 716
Joined: Wed Aug 21, 2013 7:35 pm
Location: Belgium
Contact: Website

Re: 8 - 10MHz interrupt

Mon Apr 13, 2015 10:02 am

Hi Joan

Thanks for the answer.
It's about this threat: viewtopic.php?f=32&t=107121&p=738031#p738031

I'll try in bare metal and see if I can process the data. ;)

Laurens

User avatar
joan
Posts: 14959
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: 8 - 10MHz interrupt

Mon Apr 13, 2015 10:20 am

Laurens-wuyts wrote:Hi Joan

Thanks for the answer.
It's about this threat: viewtopic.php?f=32&t=107121&p=738031#p738031

I'll try in bare metal and see if I can process the data. ;)

Laurens
I haven't looked too closely at your C code but you seemed to be doing an awful lot of writes to individual gpios. You can clear/set selected gpios in one operation. E.g. clear and set.

User avatar
Laurens-wuyts
Posts: 716
Joined: Wed Aug 21, 2013 7:35 pm
Location: Belgium
Contact: Website

Re: 8 - 10MHz interrupt

Mon Apr 13, 2015 10:32 am

Hi Joan

I did indeed, but I've changed it when I switched from library. :P
This is the actual code I'm using now, but I think I'm losing a lot of pulses :?
Also the pulses are not equal in length.

Code: Select all

#define BCM2708_PERI_BASE        0x20000000
#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) 

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

int mem_fd;
void *gpio_map;

volatile unsigned *gpio;

#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
 
#define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0

#define FLM 8
#define CL1 9
#define CL2 10

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

void setup_io();

int main()
{
	int rep, i, j;
	
	const char red[3] = {0b10010010,0b01001001,0b00100100};
	const char g[11] = {23,24,11,17,27,22,10,9,7,8,25};
	
	/****************************************************************
	Pin		IO		IO		pin
	===========================
			3.3V..	5V
			2	..	5V
			3	..	GND
			4	..	14		
			GND	..	15		
	D3		17	..	18		
	D4		27	..	GND
	D5		22	..	23		D0
			3.3V..	24		D1
	D6		10	..	GND	
	D7		9	..	25		CL2
	D2		11	..	8		CL1
			GND	..	7		FLM
	===========================
	
	IO Write all at the same time:
	
	0b0000 D4 0 CL2 D1 D0 D5 0000 D3 00000 D2 D6 D7 CL1 FLM 000000000
	
	32 bits/IO's
	****************************************************************/
	
		
	unsigned long red_on[3] = {	0b00000010100000100000010000000000,0b00001011000000000000001000000000,0b00000010010000000000100000010000};
	unsigned long red_off[3] = {0b00001011010000000000101000000000,0b00000010110000100000110000000000,0b00001011100000100000011000000000};
								
	setup_io();

	for (i=0; i<=11; i++)
	{
		INP_GPIO(g[i]); // must use INP_GPIO before we can use OUT_GPIO
		OUT_GPIO(g[i]);
	}
	

	while(i < 240)
	{
		GPIO_SET = red_on[i%3];
		GPIO_CLR = red_off[i%3];			
		i++;
	}

	return 0;
}
 
 
void setup_io()
{
   /* open /dev/mem */
   if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
      printf("can't open /dev/mem \n");
      exit(-1);
   }
 
   /* mmap GPIO */
   gpio_map = mmap(
      NULL,             //Any adddress in our space will do
      BLOCK_SIZE,       //Map length
      PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
      MAP_SHARED,       //Shared with other processes
      mem_fd,           //File to map
      GPIO_BASE         //Offset to GPIO peripheral
   );
 
   close(mem_fd); //No need to keep mem_fd open after mmap
 
   if (gpio_map == MAP_FAILED) {
      printf("mmap error %d\n", (int)gpio_map);//errno also set!
      exit(-1);
   }
 
   // Always use volatile pointer!
   gpio = (volatile unsigned *)gpio_map;
 
 
} // setup_io
Laurens

Return to “General programming discussion”