summaryrefslogtreecommitdiff
path: root/cesar/hal/phy/src/bridgedma.c
diff options
context:
space:
mode:
authorlaranjeiro2008-06-13 13:01:02 +0000
committerlaranjeiro2008-06-13 13:01:02 +0000
commit80c888e1af92e27ca7abcbd2fe6ec6c29f5135ec (patch)
tree9d09b3e82d9f62d8b41fc532c3ba7834bbe60922 /cesar/hal/phy/src/bridgedma.c
parent687fa940f2da0fb5da20c21f48159570fcc0a634 (diff)
hal/phy/bridgedma : Add the HAL for the hardware bridgeDMA.
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@2325 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/hal/phy/src/bridgedma.c')
-rw-r--r--cesar/hal/phy/src/bridgedma.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/cesar/hal/phy/src/bridgedma.c b/cesar/hal/phy/src/bridgedma.c
new file mode 100644
index 0000000000..a5c9f3566b
--- /dev/null
+++ b/cesar/hal/phy/src/bridgedma.c
@@ -0,0 +1,117 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/phy/src/bridgedma.c
+ * \brief Phy bridgedma HAL functions.
+ * \ingroup hal_phy
+ *
+ */
+#include "common/std.h"
+
+#include "hal/phy/bridgedma.h"
+#include "hal/phy/inc/bridgedma.h"
+
+#include "string.h"
+
+#define PHY_BRIDGEDMA_BASE 0x10000000
+#define PHY_BRIDGEDMA_CONTROL (PHY_BRIDGEDMA_BASE)
+#define PHY_BRIDGEDMA_JOB_PTR (PHY_BRIDGEDMA_BASE + 0x8)
+
+/** Bridge DMA context. */
+static phy_bridgedma_t phy_bridgedma_global;
+
+/**
+ * Initialise the Bridge DMA.
+ * \param user_data User data passed to any callback
+ * \param bridgedma_cb Bridge DMA interrupt callback
+ * \param deferred_cb DSR callback
+ * \return the newly created context
+ */
+phy_bridgedma_t *
+phy_bridgedma_init (void *user_data, phy_bridgedma_cb_t bridgedma_cb,
+ phy_deferred_cb_t deferred_cb)
+{
+ dbg_assert (bridgedma_cb);
+ dbg_assert (deferred_cb);
+
+ memset (&phy_bridgedma_global, 0, sizeof (phy_bridgedma_t));
+
+ phy_bridgedma_global.user_data = user_data;
+ phy_bridgedma_global.bridgedma_cb = bridgedma_cb;
+ phy_bridgedma_global.deferred_cb = deferred_cb;
+
+ return &phy_bridgedma_global;
+}
+
+/**
+ * Reset and uninitialise the Bridge DMA.
+ * \param ctx Bridge DMA context
+ */
+void
+phy_bridgedma_uninit (phy_bridgedma_t *ctx)
+{
+ volatile u32 *control;
+ dbg_assert (ctx);
+
+ control = (u32 *)PHY_BRIDGEDMA_CONTROL;
+
+ // Set the current job as the last one.
+ ctx->job_first->last = true;
+
+ while (((phy_bridgedma_ctrl_t *)control)->start);
+}
+
+/**
+ * Enqueue and start a list of jobs.
+ * \param ctx Bridge DMA context
+ * \param job_first first job to enqueue
+ * \param job_last last job to enqueue
+ *
+ * The new jobs are added to the Bridge DMA queue and the Bridge DMA is
+ * restarted if it was stopped. The \c last flag must be set in the last
+ * enqueued job.
+ */
+void
+phy_bridgedma_start (phy_bridgedma_t *ctx, phy_bridgedma_job_t *job_first,
+ phy_bridgedma_job_t *job_last)
+{
+ volatile u32* control;
+ volatile u32* job_current;
+ dbg_assert (ctx);
+ dbg_assert (job_first);
+ dbg_assert (job_last);
+
+ control = (u32*) PHY_BRIDGEDMA_CONTROL;
+ job_current = (u32 *)PHY_BRIDGEDMA_JOB_PTR;
+
+ ctx->job_last->next = job_first;
+ ctx->job_last->last = false;
+
+ if (((phy_bridgedma_job_t *) job_current) != ctx->job_last)
+ {
+ ctx->job_last->next = job_first;
+ ctx->job_last = job_last;
+ job_last->last = true;
+ }
+ else
+ {
+ if (!((phy_bridgedma_job_t *)job_current)->last)
+ {
+ ctx->job_last->next = job_first;
+ ctx->job_last = job_last;
+ job_last->last = true;
+ }
+ else
+ {
+ job_current = (u32 *) job_first;
+ ctx->job_last = job_last;
+ ((phy_bridgedma_ctrl_t *) control)->start = true;
+ }
+ }
+}
+