summaryrefslogtreecommitdiff
path: root/cesar/hal/phy/src/bridgedma.c
diff options
context:
space:
mode:
authorlaranjeiro2008-07-07 15:59:13 +0000
committerlaranjeiro2008-07-07 15:59:13 +0000
commitaedfd518357a4f288e0431c394472d90694e6346 (patch)
tree040924ae706266f6720aecd11c9c6165b8eb8866 /cesar/hal/phy/src/bridgedma.c
parent5359a0519fad6c5be6ad80e5453cdbe58ffd55b1 (diff)
hal/phy/bridgedma: Tested the hardware bridgedma (interruption only on
TX way). git-svn-id: svn+ssh://pessac/svn/cesar/trunk@2567 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/hal/phy/src/bridgedma.c')
-rw-r--r--cesar/hal/phy/src/bridgedma.c72
1 files changed, 67 insertions, 5 deletions
diff --git a/cesar/hal/phy/src/bridgedma.c b/cesar/hal/phy/src/bridgedma.c
index a9cad1a10d..7bdda4677e 100644
--- a/cesar/hal/phy/src/bridgedma.c
+++ b/cesar/hal/phy/src/bridgedma.c
@@ -13,19 +13,64 @@
*/
#include "common/std.h"
+#include "hal/arch/arch.h"
+#include "hal/leon/itc2.h"
+
#include "hal/phy/bridgedma.h"
#include "hal/phy/inc/bridgedma.h"
+#include "hal/phy/inc/bridgedma_regs.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)
-#define PHY_BRIDGEDMA_CURR_JOB_PTR (PHY_BRIDGEDMA_BASE + 0xC)
-
/** Bridge DMA context. */
static phy_bridgedma_t phy_bridgedma_global;
+/** eCos ISR called by eCos each time the bridgedma ends a job with the it
+ * flag setted.
+ * \param vector the IT vector.
+ * \param data the user data.
+ */
+static cyg_uint32
+_bridgedma_ecos_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ /* nothing to do except calling the bridgedma callback */
+ phy_bridgedma_t *bridgedma_ctx;
+
+ cyg_interrupt_mask(PHY_BRIDGEDMA_END_INTERRUPT);
+
+ bridgedma_ctx = (phy_bridgedma_t *)data;
+
+ if((*bridgedma_ctx->bridgedma_cb)(bridgedma_ctx->user_data,
+ *((u32 *)((void *)&bridgedma_ctx->status))))
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+ else
+ {
+ cyg_interrupt_unmask(PHY_BRIDGEDMA_END_INTERRUPT);
+ return CYG_ISR_HANDLED;
+ }
+}
+
+/** eCos DSR called by eCos each time the bridgedma ends a job with the it
+ * flag setted.
+ * \param vector the IT vector.
+ * \param data the user data.
+ */
+static void
+_bridgedma_ecos_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+
+ /* nothing to do except calling the phy dsr */
+ phy_bridgedma_t *bridgedma_ctx;
+ bridgedma_ctx = (phy_bridgedma_t *)data;
+ (*bridgedma_ctx->deferred_cb)(bridgedma_ctx->user_data);
+
+ /* ACK and unmask. */
+ cyg_interrupt_acknowledge(PHY_BRIDGEDMA_END_INTERRUPT);
+ cyg_interrupt_unmask(PHY_BRIDGEDMA_END_INTERRUPT);
+
+ return;
+}
+
/**
* Initialise the Bridge DMA.
* \param user_data User data passed to any callback
@@ -46,6 +91,19 @@ phy_bridgedma_init (void *user_data, phy_bridgedma_cb_t bridgedma_cb,
phy_bridgedma_global.bridgedma_cb = bridgedma_cb;
phy_bridgedma_global.deferred_cb = deferred_cb;
+ /* register ISR et DSR to eCos */
+ cyg_interrupt_create(PHY_BRIDGEDMA_END_INTERRUPT,
+ 0,
+ (cyg_addrword_t)&phy_bridgedma_global,
+ _bridgedma_ecos_isr,
+ _bridgedma_ecos_dsr,
+ &phy_bridgedma_global.it_mgr.interrupt_handle,
+ &phy_bridgedma_global.it_mgr.interrupt);
+ cyg_interrupt_attach(phy_bridgedma_global.it_mgr.interrupt_handle);
+
+ cyg_interrupt_acknowledge(PHY_BRIDGEDMA_END_INTERRUPT);
+ cyg_interrupt_unmask(PHY_BRIDGEDMA_END_INTERRUPT);
+
return &phy_bridgedma_global;
}
@@ -89,6 +147,7 @@ phy_bridgedma_start (phy_bridgedma_t *ctx, phy_bridgedma_job_t *job_first,
control = (u32*) PHY_BRIDGEDMA_CONTROL;
job_current = (u32 *)PHY_BRIDGEDMA_CURR_JOB_PTR;
+ arch_reorder_barrier ();
ctx->job_last->next = job_first;
ctx->job_last->last = false;
@@ -98,6 +157,9 @@ phy_bridgedma_start (phy_bridgedma_t *ctx, phy_bridgedma_job_t *job_first,
ctx->job_last->next = job_first;
ctx->job_last = job_last;
job_last->last = true;
+
+ if (!((phy_bridgedma_ctrl_t *) control)->start)
+ ((phy_bridgedma_ctrl_t *) control)->start = true;
}
else
{