/* generate an interrupt after the specified time (in microseconds) */ void clock_generate_interrupt(uint64_t time) { uint64_t clock = clock_read(); while(timer_timeout(timer_device.ti, us_to_ticks(timer_device.frequency, clock + time))) time *= 2; }
/* this program illustrates how to use void* as a generic pointer, how to use pointer casts to get the generic pointer interpreted according to what type of value it points to, and the danger of making an incorrect cast */ int main (int argc, char ** argv) { struct tm now; /* standard struct for storing a time value */ double lightspeed; Person * albert; /* pointer to our custom struct person */ void * generic_pointer; /* let's read the clock, it gets stored in a standard struct tm (from the time.h header) */ if (0 != clock_read (&now)) { printf ("failed to read the clock\n"); return 1; } /* the speed of light as a double-precision floating point number */ lightspeed = 299792458.0; /* Albert Einstein was born on March 14, 1879. His age depends on today's date... */ albert = person_create ("Albert Einstein", (now.tm_mon >= 3 && now.tm_mday >= 14) ? now.tm_year + 1901 - 1879 : now.tm_year + 1900 - 1879); /* ************************************************** * NOW FOR THE FUN PART ***************************** * **************************************************/ /* the generic pointer can store the address of any of our variables */ generic_pointer = &now; printf ("the date and time is\n"); clock_print (&now); generic_pointer = &lightspeed; printf ("the speed of light is\n %g m/s\n", *(double*)generic_pointer); generic_pointer = albert; printf ("the person is\n"); person_print (generic_pointer); return 0; }
/* Wait for the specified time (in microseconds) */ void clock_wait(uint64_t time) { int error; uint64_t clock = clock_read(); uint64_t timeout = clock + time; error = okn_syscall_interrupt_register(CLOCK_IRQ); assert(!error); if (timer_timeout(timer_device.ti, us_to_ticks(timer_device.frequency, timeout))) { error = okn_syscall_interrupt_deregister(CLOCK_IRQ); assert(!error); return; /* Already expired */ } /* wait for the interrupt */ while(!device_interrupt(timer_device.di, okn_syscall_interrupt_wait())); error = okn_syscall_interrupt_deregister(CLOCK_IRQ); assert(!error); }
uint8_t noinline input_nibble(uint8_t rs, uint8_t en) { /* WR setzen = lesen */ lcd_data |= _BV(HD44780_PCF8574x_WR); /* Wenn rs gesetzt, */ if (rs) /* dann RS setzen */ lcd_data |= _BV(HD44780_PCF8574x_RS); else /* sonst RS loeschen */ lcd_data &= ~(_BV(HD44780_PCF8574x_RS)); /* toggle EN, daten abholen */ uint8_t data = clock_read(en); /* WR loeschen = schreiben */ lcd_data &= ~(_BV(HD44780_PCF8574x_WR)); return data; }
uint8_t noinline input_nibble(uint8_t rs, uint8_t en) { /* configure data pins as input */ DATA_INPUT(); /* set write bit */ PIN_SET(HD44780_RW); /* set rs, if given */ PIN_CLEAR(HD44780_RS); if (rs) PIN_SET(HD44780_RS); uint8_t data = clock_read(en); /* reconfigure data pins as output */ DATA_OUTPUT(); /* delete RW bit */ PIN_CLEAR(HD44780_RW); return data; }