#ifndef __AVR_IOPORT_H__
#define __AVR_IOPORT_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "sim_avr.h"
enum {
IOPORT_IRQ_PIN1,IOPORT_IRQ_PIN2,IOPORT_IRQ_PIN3,IOPORT_IRQ_PIN4,
IOPORT_IRQ_PIN5,IOPORT_IRQ_PIN6,IOPORT_IRQ_PIN7,
IOPORT_IRQ_PIN_ALL,
+ IOPORT_IRQ_DIRECTION_ALL,
IOPORT_IRQ_COUNT
};
+#define AVR_IOPORT_OUTPUT 0x100
+
// add port name (uppercase) to get the real IRQ
#define AVR_IOCTL_IOPORT_GETIRQ(_name) AVR_IOCTL_DEF('i','o','g',(_name))
+
+// this ioctl takes a avr_regbit_t, compares the register address
+// to PORT/PIN/DDR and return the corresponding IRQ(s) if it matches
+typedef struct avr_ioport_getirq_t {
+ avr_regbit_t bit; // bit wanted
+ avr_irq_t * irq[8]; // result, terminated by NULL if < 8
+} avr_ioport_getirq_t;
+
+#define AVR_IOCTL_IOPORT_GETIRQ_REGBIT AVR_IOCTL_DEF('i','o','g','r')
+
+/*
+ * ioctl used to get a port state.
+ *
+ * for (int i = 'A'; i <= 'F'; i++) {
+ * avr_ioport_state_t state;
+ * if (avr_ioctl(AVR_IOCTL_IOPORT_GETSTATE(i), &state) == 0)
+ * printf("PORT%c %02x DDR %02x PIN %02x\n",
+ * state.name, state.port, state.ddr, state.pin);
+ * }
+ */
+typedef struct avr_ioport_state_t {
+ unsigned long name : 7,
+ port : 8, ddr : 8, pin : 8;
+} avr_ioport_state_t;
+
+// add port name (uppercase) to get the port state
+#define AVR_IOCTL_IOPORT_GETSTATE(_name) AVR_IOCTL_DEF('i','o','s',(_name))
+
+/**
+ * pin structure
+ */
+typedef struct avr_iopin_t {
+ uint16_t port : 8; ///< port e.g. 'B'
+ uint16_t pin : 8; ///< pin number
+} avr_iopin_t;
+#define AVR_IOPIN(_port, _pin) { .port = _port, .pin = _pin }
+
+/*
+ * Definition for an IO port
+ */
typedef struct avr_ioport_t {
avr_io_t io;
char name;
void avr_ioport_init(avr_t * avr, avr_ioport_t * port);
+#ifdef __cplusplus
+};
+#endif
+
#endif /* __AVR_IOPORT_H__ */