#include #include #include #include #include #include const int CTRL_OUT = 16; const int INTR_IN = 19; const int SPI_CHAN = 0; const int SPI_SPEED = 1000000; const uint8_t REG_MDR0 = 0b00001000; const uint8_t REG_MDR1 = 0b00010000; const uint8_t REG_DTR = 0b00011000; const uint8_t REG_CNTR = 0b00100000; const uint8_t REG_OTR = 0b00101000; const uint8_t REG_STR = 0b00110000; const uint8_t CMD_CLR = 0b00000000; const uint8_t CMD_RD = 0b01000000; const uint8_t CMD_WR = 0b10000000; const uint8_t CMD_LOAD = 0b11000000; const uint8_t STR_CY = 0b10000000; const uint8_t STR_BW = 0b01000000; const uint8_t STR_CMP = 0b00100000; const uint8_t STR_IDX = 0b00010000; const uint8_t STR_CEN = 0b00001000; const uint8_t STR_PLS = 0b00000100; const uint8_t STR_UD = 0b00000010; const uint8_t STR_S = 0b00000001; const uint8_t MDR0_NOQ = 0b00000000; const uint8_t MDR0_Q1 = 0b00000001; const uint8_t MDR0_Q2 = 0b00000010; const uint8_t MDR0_Q4 = 0b00000011; const uint8_t MDR0_FRC = 0b00000000; const uint8_t MDR0_SCC = 0b00000100; const uint8_t MDR0_RLC = 0b00001000; const uint8_t MDR0_MNC = 0b00001100; const uint8_t MDR0_DI = 0b00000000; const uint8_t MDR0_ILC = 0b00010000; const uint8_t MDR0_IRC = 0b00100000; const uint8_t MDR0_ILO = 0b00110000; const uint8_t MDR0_AI = 0b00000000; const uint8_t MDR0_SI = 0b01000000; const uint8_t MDR0_FC1 = 0b00000000; const uint8_t MDR0_FC2 = 0b10000000; const uint8_t MDR1_4CM = 0b00000000; const uint8_t MDR1_3CM = 0b00000001; const uint8_t MDR1_2CM = 0b00000010; const uint8_t MDR1_1CM = 0b00000011; const uint8_t MDR1_EC = 0b00000000; const uint8_t MDR1_DC = 0b00000100; const uint8_t MDR1_F_IDX = 0b00010000; const uint8_t MDR1_F_CMP = 0b00100000; const uint8_t MDR1_F_BW = 0b01000000; const uint8_t MDR1_F_CY = 0b10000000; uint32_t ec = 0; uint32_t counter = 0; uint32_t diff = 0; pthread_mutex_t counterMutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t eventMutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t eventSignal = PTHREAD_COND_INITIALIZER; void writeCmd(uint8_t c) { uint8_t buf[1]; buf[0] = c; wiringPiSPIDataRW(SPI_CHAN, buf, 1); } void writeCmdData(uint8_t c, uint8_t d) { uint8_t buf[2]; buf[0] = c; buf[1] = d; wiringPiSPIDataRW(SPI_CHAN, buf, 2); } uint8_t read8(uint8_t c) { uint8_t buf[2]; buf[0] = c; wiringPiSPIDataRW(SPI_CHAN, buf, 2); return buf[1]; } uint32_t read32(uint8_t c) { uint8_t buf[5]; buf[0] = c; wiringPiSPIDataRW(SPI_CHAN, buf, 5); uint32_t r = ((uint32_t)buf[1] << 24) | ((uint32_t)buf[2] << 16) | ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4]); return r; } void isr() { static uint32_t lastCounter = 0; uint32_t currentCounter = read32(CMD_RD | REG_OTR); pthread_mutex_lock(&counterMutex); diff = currentCounter - lastCounter; counter = currentCounter; ec++; pthread_mutex_unlock(&counterMutex); lastCounter = currentCounter; pthread_mutex_lock(&eventMutex); pthread_cond_signal(&eventSignal); pthread_mutex_unlock(&eventMutex); } void init() { wiringPiSetupGpio(); wiringPiSPISetup(SPI_CHAN, SPI_SPEED); pinMode(CTRL_OUT, OUTPUT); digitalWrite(CTRL_OUT, 0); pinMode(INTR_IN, INPUT); wiringPiISR(INTR_IN, INT_EDGE_RISING, isr); } void initCounter() { writeCmd(CMD_CLR | REG_STR); writeCmd(CMD_CLR | REG_CNTR); writeCmdData(CMD_WR | REG_MDR0, MDR0_ILO); } int main (void) { static uint32_t lastDiff = 0; uint32_t my_ec = 0; uint32_t my_counter = 0; uint32_t my_diff = 0; init(); initCounter(); while (1) { pthread_mutex_lock(&eventMutex); pthread_cond_wait(&eventSignal, &eventMutex); pthread_mutex_unlock(&eventMutex); pthread_mutex_lock(&counterMutex); my_ec = ec; my_counter = counter; my_diff = diff; pthread_mutex_unlock(&counterMutex); if (my_diff != lastDiff || 1) { lastDiff = my_diff; double f = 1.0 / (((double) my_diff) / 1000000.0); printf("%d %d %d %f\n", my_ec, my_counter, my_diff, f); } } }