il y a 6 ans
So.....I'm attempting to sniff the SPI bus for a possible HDMI out using a raspberry pi.....the problem is, that my code only works well for clock speeds up to 2MHz, and our display is clocked at 24MHz. I thought maybe one of you has more experience with the raspberry pi and its GPIOs, as this is literally the first time i worked with that!
#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)
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
int mem_fd;
void *gpio_map;
// I/O access
volatile unsigned *gpio;
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#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 GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
#define GPIO_PULL *(gpio+37) // Pull up/pull down
#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
void setup_io();
const int pin_clock = 11;
const int pin_input = 9;
const int frame_threashold = 107058;
typedef unsigned char BYTE;
BYTE get_byte() {
BYTE b = 0;
int i;
for (i = 0; i < 8; i++) {
while(!GET_GPIO(pin_clock));
b <<= 1;
b |= (GET_GPIO(pin_input)?1:0);
while(GET_GPIO(pin_clock));
}
return b;
}
void find_start() {
int max = 0;
while(!GET_GPIO(pin_clock));
while(GET_GPIO(pin_clock));
unsigned start_time = (unsigned)time(NULL);
int i;
do {
i = 0;
while(!GET_GPIO(pin_clock))i++;
if (i > max) max = i;
while(GET_GPIO(pin_clock));
} while (start_time + 2 >= (unsigned)time(NULL));
max -= (max/10);
do {
i = 0;
while(!GET_GPIO(pin_clock))i++;
while(GET_GPIO(pin_clock));
} while (i < max);
for (i = 0; i < 7; i++) { // read the remaining byte
while(!GET_GPIO(pin_clock));
while(GET_GPIO(pin_clock));
}
}
int main(int argc, char **argv) {
setup_io();
INP_GPIO(pin_input);
INP_GPIO(pin_clock);
find_start();
BYTE data[10];
/*
while(1) {
if(get_byte() != 0x2A) continue;
if (get_byte() != 0) continue;
if (get_byte() != (160-1)) continue;
data[0] = 0x2A;
data[1] = 0;
data[2] = 160-1;
break;
}
*/
int i;
for (i = 0; i < 10; i++) {
data[i] = get_byte();
}
for (i = 0; i < 10; i++) {
printf("%02x ", data[i]);
}
printf("\n");
return 0;
}
void setup_io() {
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;
}
find_start
is for finding the start of a byte, as what if we start the program in the middle of a byte being sent? It is based on that on some byte eventually there will be a longer pause than between bytes, which is true, as we aren't using the SPI bus 100% of the time in any sketches.
As test sketch i used the following with the METAs library custom yeild
function disabled (as that would cause delay()
to sometimes do SPI stuff):
#include <Gamebuino-Meta.h>
static SPISettings mySPISettings;
void setup() {
gb.begin();
mySPISettings = SPISettings(2000000, MSBFIRST, SPI_MODE0);
SPI.beginTransaction(mySPISettings);
while(1) {
SPI.transfer(0x12);
SPI.transfer(0x34);
delay(1);
}
SPI.endTransaction();
}
void loop() {
}
So yeah, as I already said, I'm basically stuck currently as the receiving part on the raspberry pi only works well up to 2MHz but the screen is at 24MHz
NEW il y a 6 ans
There is a Benchmark: http://codeandlife.com/2012/07/03/benchmarking-raspberry-pi-gpio-speed/
and also this https://www.raspberrypi.org/forums/viewtopic.php?t=26907
Maybe this can help you.
NEW il y a 6 ans
Thank you for the links, i'll look more into it once i have time. Me having a gen 1 raspberry pi probably doesn't help this, then >.<
ripper121
il y a 6 ans
But I dont think you need to use SoftSPI, the HW spi goes up to 125MHz:
cdiv speed
2 125.0 MHz
https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md
NEW il y a 6 ans
But I dont think you need to use SoftSPI, the HW spi goes up to 125MHz:
cdiv speed
2 125.0 MHz
https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md