summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openpicc/Makefile2
-rw-r--r--openpicc/application/dbgu.h6
-rw-r--r--openpicc/application/main.c9
-rw-r--r--openpicc/application/pio_irq.c142
-rw-r--r--openpicc/application/pio_irq.h15
-rw-r--r--openpicc/application/pll.c58
-rw-r--r--openpicc/application/pll.h8
-rw-r--r--openpicc/config/atmel-rom.ld1
8 files changed, 239 insertions, 2 deletions
diff --git a/openpicc/Makefile b/openpicc/Makefile
index 50d07e4..0993dce 100644
--- a/openpicc/Makefile
+++ b/openpicc/Makefile
@@ -75,6 +75,8 @@ ARM_SRC= \
application/cmd.c \
application/env.c \
application/da.c \
+ application/pll.c \
+ application/pio_irq.c \
os/boot/Cstartup_SAM7.c \
os/core/list.c \
os/core/queue.c \
diff --git a/openpicc/application/dbgu.h b/openpicc/application/dbgu.h
new file mode 100644
index 0000000..535ea08
--- /dev/null
+++ b/openpicc/application/dbgu.h
@@ -0,0 +1,6 @@
+#ifndef DBGU_H_
+#define DBGU_H_
+
+#define DEBUGPCRF(...) ;
+
+#endif /*DBGU_H_*/
diff --git a/openpicc/application/main.c b/openpicc/application/main.c
index 9af44bf..e722daa 100644
--- a/openpicc/application/main.c
+++ b/openpicc/application/main.c
@@ -39,7 +39,8 @@
#include "env.h"
#include "cmd.h"
#include "da.h"
-//#include "pll.h"
+#include "pll.h"
+#include "pio_irq.h"
/**********************************************************************/
static inline void prvSetupHardware (void)
@@ -79,17 +80,21 @@ void vApplicationIdleHook(void)
int main (void)
{
prvSetupHardware ();
+
+ pio_irq_init();
vLedInit();
da_init();
+ pll_init();
+
xTaskCreate (vUSBCDCTask, (signed portCHAR *) "USB", TASK_USB_STACK,
NULL, TASK_USB_PRIORITY, NULL);
vCmdInit();
- vLedSetGreen(1);
+ //vLedSetGreen(1);
vTaskStartScheduler ();
diff --git a/openpicc/application/pio_irq.c b/openpicc/application/pio_irq.c
new file mode 100644
index 0000000..572a4e4
--- /dev/null
+++ b/openpicc/application/pio_irq.c
@@ -0,0 +1,142 @@
+/* PIO IRQ Implementation for OpenPCD
+ * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <lib_AT91SAM7.h>
+#include <string.h>
+#include "pio_irq.h"
+#include "dbgu.h"
+//#include <os/req_ctx.h>
+#include "openpicc.h"
+#include "board.h"
+#include "led.h"
+
+#include <FreeRTOS.h>
+#include <task.h>
+
+struct pioirq_state {
+ irq_handler_t *handlers[NR_PIO];
+ u_int32_t usbmask;
+ u_int32_t usb_throttled; /* atomic? */
+};
+
+static struct pioirq_state pirqs;
+
+/* low-level handler, used by Cstartup_app.S PIOA fast forcing and
+ * by regular interrupt handler below */
+void __ramfunc __pio_irq_demux(u_int32_t pio)
+{
+ u_int8_t send_usb = 0;
+ int i;
+
+ DEBUGPCRF("PIO_ISR_STATUS = 0x%08x", pio);
+
+ for (i = 0; i < NR_PIO; i++) {
+ if (pio & (1 << i) && pirqs.handlers[i])
+ pirqs.handlers[i](i);
+ if (pirqs.usbmask & (1 << i))
+ send_usb = 1;
+ }
+
+// if (send_usb && !pirqs.usb_throttled) {
+// struct req_ctx *irq_rctx;
+// irq_rctx = req_ctx_find_get(0, RCTX_STATE_FREE,
+// RCTX_STATE_PIOIRQ_BUSY);
+// if (!irq_rctx) {
+// /* we cannot disable the interrupt, since we have
+// * non-usb listeners */
+// pirqs.usb_throttled = 1;
+// } else {
+// struct openpcd_hdr *opcdh;
+// u_int32_t *regmask;
+// opcdh = (struct openpcd_hdr *) irq_rctx->data;
+// regmask = (u_int32_t *) (irq_rctx->data + sizeof(*opcdh));
+// opcdh->cmd = OPENPCD_CMD_PIO_IRQ;
+// opcdh->reg = 0x00;
+// opcdh->flags = 0x00;
+// opcdh->val = 0x00;
+//
+// irq_rctx->tot_len = sizeof(*opcdh) + sizeof(u_int32_t);
+// req_ctx_set_state(irq_rctx, RCTX_STATE_UDP_EP3_PENDING);
+// }
+// }
+
+ AT91F_AIC_AcknowledgeIt();
+ //AT91F_AIC_ClearIt(AT91C_ID_PIOA);
+}
+
+/* regular interrupt handler, in case fast forcing for PIOA disabled */
+static void pio_irq_demux(void)
+{
+ portSAVE_CONTEXT();
+ u_int32_t pio = AT91F_PIO_GetInterruptStatus(AT91C_BASE_PIOA);
+ __pio_irq_demux(pio);
+ portRESTORE_CONTEXT();
+}
+
+void pio_irq_enable(u_int32_t pio)
+{
+ AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA, pio);
+}
+
+void pio_irq_disable(u_int32_t pio)
+{
+ AT91F_PIO_InterruptDisable(AT91C_BASE_PIOA, pio);
+}
+
+int pio_irq_register(u_int32_t pio, irq_handler_t *handler)
+{
+ u_int8_t num = ffs(pio);
+
+ if (num == 0)
+ return -EINVAL;
+ num--;
+
+ if (pirqs.handlers[num])
+ return -EBUSY;
+
+ pio_irq_disable(pio);
+ AT91F_PIO_CfgInput(AT91C_BASE_PIOA, pio);
+ pirqs.handlers[num] = handler;
+ DEBUGPCRF("registering handler %p for PIOA %u", handler, num);
+
+ return 0;
+}
+
+void pio_irq_unregister(u_int32_t pio)
+{
+ u_int8_t num = ffs(pio);
+
+ if (num == 0)
+ return;
+ num--;
+
+ pio_irq_disable(pio);
+ pirqs.handlers[num] = NULL;
+}
+
+void pio_irq_init(void)
+{
+ AT91F_PIOA_CfgPMC();
+ AT91F_AIC_ConfigureIt(AT91C_ID_PIOA,
+ AT91C_AIC_PRIOR_LOWEST,
+ AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &pio_irq_demux);
+ AT91F_AIC_EnableIt(AT91C_ID_PIOA);
+}
diff --git a/openpicc/application/pio_irq.h b/openpicc/application/pio_irq.h
new file mode 100644
index 0000000..65a0f9d
--- /dev/null
+++ b/openpicc/application/pio_irq.h
@@ -0,0 +1,15 @@
+#ifndef _PIO_IRQ_H
+#define _PIO_IRQ_H
+
+#include "openpicc.h"
+
+#define NR_PIO 32
+typedef void irq_handler_t(u_int32_t pio);
+
+extern void pio_irq_enable(u_int32_t pio);
+extern void pio_irq_disable(u_int32_t pio);
+extern int pio_irq_register(u_int32_t pio, irq_handler_t *func);
+extern void pio_irq_unregister(u_int32_t pio);
+extern void pio_irq_init(void);
+
+#endif
diff --git a/openpicc/application/pll.c b/openpicc/application/pll.c
new file mode 100644
index 0000000..b9aa495
--- /dev/null
+++ b/openpicc/application/pll.c
@@ -0,0 +1,58 @@
+/* PLL routines for OpenPICC
+ * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#include <sys/types.h>
+#include <lib_AT91SAM7.h>
+#include "pio_irq.h"
+#include "dbgu.h"
+#include "led.h"
+#include "board.h"
+
+void pll_inhibit(int inhibit)
+{
+ if (inhibit)
+ AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPICC_PIO_PLL_INHIBIT);
+ else
+ AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPICC_PIO_PLL_INHIBIT);
+}
+
+int pll_is_locked(void)
+{
+ return AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC_PIO_PLL_LOCK);
+}
+
+static void pll_lock_change_cb(u_int32_t pio)
+{
+ (void)pio;
+ DEBUGPCRF("PLL LOCK: %d", pll_is_locked());
+#if 1
+ vLedSetRed(pll_is_locked());
+#endif
+}
+
+void pll_init(void)
+{
+ AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPICC_PIO_PLL_INHIBIT);
+ AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC_PIO_PLL_LOCK);
+ pll_inhibit(0);
+
+ pio_irq_register(OPENPICC_PIO_PLL_LOCK, &pll_lock_change_cb);
+ pio_irq_enable(OPENPICC_PIO_PLL_LOCK);
+}
diff --git a/openpicc/application/pll.h b/openpicc/application/pll.h
new file mode 100644
index 0000000..fc00105
--- /dev/null
+++ b/openpicc/application/pll.h
@@ -0,0 +1,8 @@
+#ifndef _PLL_H
+#define _PLL_H
+
+extern int pll_is_locked(void);
+extern void pll_inhibit(int inhibit);
+extern void pll_init(void);
+
+#endif
diff --git a/openpicc/config/atmel-rom.ld b/openpicc/config/atmel-rom.ld
index 9a74420..0a9a04d 100644
--- a/openpicc/config/atmel-rom.ld
+++ b/openpicc/config/atmel-rom.ld
@@ -29,6 +29,7 @@ SECTIONS
__data_beg_src__ = __end_of_text__;
*(.data)
*(.data.*)
+ *(.fastrun)
*(.ramfunc)
__data_end__ = .;
} >ram AT>flash
personal git repositories of Harald Welte. Your mileage may vary