aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spi_usi.h25
-rw-r--r--src/avr25/spi_usi.c56
2 files changed, 81 insertions, 0 deletions
diff --git a/spi_usi.h b/spi_usi.h
new file mode 100644
index 0000000..2e603ac
--- /dev/null
+++ b/spi_usi.h
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <inttypes.h>
+
+#include "mcu/mcu.h"
+
+#ifndef _IOE_SPI_USI_H_
+#define _IOE_SPI_USI_H_
+
+inline void ioe_spi_usi_init(void);
+#ifdef IOE_SPI_USI_MASTER
+inline int8_t ioe_spi_usi_transfer(int8_t data);
+#else
+inline void ioe_spi_usi_expose(int8_t data);
+inline void ioe_spi_usi_expect(void);
+inline int ioe_spi_usi_ready(void);
+inline void ioe_spi_usi_join(void);
+
+// Following function must be user defined
+inline void ioe_spi_usi_retrieve(int8_t data);
+#endif /* IOE_SPI_USI_MASTER */
+
+
+#endif /* _IOE_SPI_USI_H_ */
diff --git a/src/avr25/spi_usi.c b/src/avr25/spi_usi.c
new file mode 100644
index 0000000..e63721a
--- /dev/null
+++ b/src/avr25/spi_usi.c
@@ -0,0 +1,56 @@
+#include "../../spi_usi.h"
+
+#if __AVR_ARCH__ == 25
+
+#ifdef IOE_SPI_USI_MASTER
+
+// TODO counter settings with interups
+inline void ioe_spi_usi_init(void) {
+ USI_DIR_REG |= _BV(USI_USCK_PIN) | _BV(USI_DO_PIN);
+ USI_OUT_REG |= _BV(USI_DI_PIN);
+
+ USICR |= _BV(USIWM0) | _BV(USICS1) | _BV(USICLK);
+}
+
+inline int8_t ioe_spi_usi_transfer(int8_t d) {
+ USISR |= _BV(USIOIF);
+ USIDR = d;
+ do {
+ USICR |= _BV(USITC);
+ } while (!(USISR & _BV(USIOIF)));
+ return USIDR;
+}
+
+#else /* IOE_SPI_USI_MASTER */
+
+inline void ioe_spi_usi_init(void) {
+ USI_DIR_REG |= _BV(USI_DO_PIN);
+ USI_OUT_REG |= _BV(USI_USCK_PIN) | _BV(USI_DI_PIN);
+
+ USICR |= _BV(USIWM0) | _BV(USICS1) | _BV(USIOIE);
+}
+
+inline void ioe_spi_usi_expose(int8_t data) {
+ USIDR = data;
+}
+
+inline void ioe_spi_usi_expect(void) {
+ USISR |= _BV(USIOIF);
+}
+
+inline int ioe_spi_usi_busy(void) {
+ return USISR & 0x0F;
+}
+
+inline void ioe_spi_usi_join(void) {
+ while (ioe_spi_usi_busy()) {
+ }
+}
+
+SIGNAL(USI_OVF_vect) {
+ ioe_spi_usi_retrieve(USIDR);
+}
+
+#endif /* IOE_SPI_USI_MASTER */
+
+#endif /* __AVR_ARCH__ == 25 */