Check max read frequency

Jose
Jose New Member Posts: 5
I was trying to write 15bits to UPBoard from a microcontroller. I have an additional IO (CTL) to inform UP Board that there is new data to read. To test it I wrote a simple program on a microcontroller that increment a 15bits number and write it to 15 IOs that are connected to UP Board. Using a logic analyzer the data looks ok.

s4vYJ1w.png

On the UP Board side I check when there is a rising edge on the CTL pin and read the 15 IOs. I'm doing this to check what is the max frequency I can write the data.

I changed the twd (time after write data to the ios) and trd (time that UP Board have to read the data) from around 500us to 5000us. The higher the value the less data failures I get but there is always a failure. I'm going to increase trd to 100ms and let it run during the weekend to check if it can get the data without errors.

Change some settings about CPU scaling help a little but there is always an error after some time. From the results I can say that the error is caused because UPBoard skip a CTL rising edge. It should read per example 1004 and it reads 1005 and last value read was 1003.

You can check the code below:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>

#include "mraa.h"

#define DEFAULT_IOPIN 0

int running = 0;
static int iopins[16] = {3,5,7,11,13,15,19,21,23,27,29,31,33,35,37,8};
volatile int state = 0;
volatile uint16_t last_value = 0;
volatile int samples = 0;

void sig_handler(int signo)
{
    if (signo == SIGINT) {
        printf("closing IOs nicely\n");
        running = -1;
    }
}

main(int argc, char** argv)
{
    mraa_result_t r = MRAA_SUCCESS;
    mraa_init();
    fprintf(stdout, "MRAA Version: %s\n", mraa_get_version());

    mraa_gpio_context gpio[16];

    int i = 0; 
    for(i=0;i<16;i++){
        gpio[i] = mraa_gpio_init(iopins[i]);
        if (gpio[i] == NULL) {
            fprintf(stderr, "Are you sure that pin%d you requested is valid on your platform?", iopins[i]);
            exit(1);
        }

        r = mraa_gpio_dir(gpio[i], MRAA_GPIO_IN);
        if (r != MRAA_SUCCESS) {
            mraa_result_print(r);
        }

        printf("Initialised pin%d\n", iopins[i]);
    }

    signal(SIGINT, sig_handler);

    while (running == 0) {

        if( state == 0 && mraa_gpio_read(gpio[0]) == 0 ){

            state = 1;
            uint16_t value = 0;	

	    for(i=1;i<16;i++)
	        value |= mraa_gpio_read(gpio[i]) << (i-1);

	    if( (last_value+1) != value )
	    	printf("Error! last_value:%d != value:%d\n",last_value,value);

	    last_value = value;

        }else if( state == 1 && mraa_gpio_read(gpio[0]) == 1){
            state = 0;
        }
        usleep(1);
    }

    for(i=0;i<16;i++){
        r = mraa_gpio_close(gpio[i]);
        if (r != MRAA_SUCCESS) {
            mraa_result_print(r);
        }
    }
    return r;
}

I tried with interruptions and while it have less failures it still fail.

Any idea to improve it?

Comments