123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- #ifndef IO_H
- #define IO_H
- #include <stdint.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include "ioregs.h"
- #include "picorv32.h"
- #include "irq.h"
- #define barrier() do { asm volatile("" : : : "memory"); } while (0)
- static __always_inline void relax(void)
- {
- /* Placeholder for anything that might want to be done while waiting */
- }
- static __always_inline void set_leds(unsigned int leds)
- {
- SYS_LED = leds;
- }
- static __always_inline void set_led(unsigned int led, bool on)
- {
- unsigned int leds = SYS_LED;
- unsigned int mask = 1 << led;
- leds &= ~mask;
- leds |= on ? mask : 0;
- SYS_LED = leds;
- }
- enum leds {
- LED_SDCARD,
- LED_DISKIO,
- LED_ABCBUS
- };
- static __always_inline no_return reset(unsigned int type)
- {
- disable_irqs();
- for (;;)
- SYS_RESET = type;
- }
- extern const uint32_t time_zero;
- static __always_inline uint32_t rdtime(void)
- {
- uint32_t t;
- asm volatile("rdtime %0" : "=r" (t));
- return t;
- }
- static __always_inline uint64_t rdtimeq(void)
- {
- uint32_t l, h1, h0;
- asm volatile("rdtimeh %0; rdtime %1; %rdtimeh %2"
- : "=r" (h1), "=r" (l), "=r" (h0));
- return ((uint64_t)(((int32_t)l < 0) ? h1 : h0) << 32) + l;
- }
- static __always_inline void cdelay(uint32_t cycles)
- {
- if (!__builtin_constant_p(cycles) || cycles >= 4) {
- uint32_t start = rdtime();
- while (rdtime() - start < cycles)
- relax();
- }
- }
- static __always_inline void udelay(uint32_t us)
- {
- cdelay(us * (CPU_HZ / 1000000));
- }
- static __always_inline void mdelay(uint32_t ms)
- {
- cdelay(ms * (CPU_HZ / 1000));
- }
- static inline void i2c_set_speed(unsigned int khz)
- {
- I2C_DIVISOR = ((CPU_HZ/4000)-1)/khz;
- }
- static __always_inline void wait_romcopy_done(void)
- {
- while (~irqmask() & (1 << ROMCOPY_IRQ))
- relax();
- barrier();
- }
- /* Read a random 32-bit number */
- static inline uint32_t rdrand(void)
- {
- waitfor(RANDOM_IRQ);
- return RANDOM_DATA;
- }
- /* Send EOI for some interrupt(s) */
- static inline void eoi_mask(uint32_t mask)
- {
- SYS_EOI = mask;
- }
- static inline void eoi(unsigned int irq)
- {
- SYS_EOI = 1 << irq;
- }
- #endif /* IO_H */
|