diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2013-03-06 15:42:08 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2013-03-06 15:42:08 +0000 |
commit | 0f61b7caf559944280099f991dcaa6b7b744123f (patch) | |
tree | 3bba03caf261272be2f4c73e30db5d3a0099f345 /os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c | |
parent | ff29b4539f662595fd6962d90dba18477a20aec2 (diff) | |
download | ChibiOS-0f61b7caf559944280099f991dcaa6b7b744123f.tar.gz ChibiOS-0f61b7caf559944280099f991dcaa6b7b744123f.tar.bz2 ChibiOS-0f61b7caf559944280099f991dcaa6b7b744123f.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5369 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c')
-rw-r--r-- | os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c | 138 |
1 files changed, 70 insertions, 68 deletions
diff --git a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c index 0998289c2..617f58072 100644 --- a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c +++ b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c @@ -60,11 +60,28 @@ static const edma_channel_config_t *channels[SPC5_EDMA_NCHANNELS]; * @isr
*/
CH_IRQ_HANDLER(vector10) {
+ edma_channel_t channel;
+ uint32_t erl, esr = EDMA.ESR.R;
CH_IRQ_PROLOGUE();
- /* TODO: Pass to the drivers somehow.*/
- chSysHalt();
+ /* Scanning for errors.*/
+ channel = 0;
+ while (((erl = EDMA.ERL.R) != 0) && (channel < SPC5_EDMA_NCHANNELS)) {
+
+ if ((erl & (1U << channel)) != 0) {
+ /* Error flag cleared.*/
+ EDMA.CER.R = channel;
+
+ /* If the channel is not associated then the error is simply discarded
+ else the error callback is invoked.*/
+ if (channels[channel] != NULL)
+ channels[channel]->dma_error_func(channel,
+ channels[channel]->dma_param,
+ esr);
+ channel++;
+ }
+ }
CH_IRQ_EPILOGUE();
}
@@ -82,8 +99,7 @@ CH_IRQ_HANDLER(vector11) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 0;
- if (channels[0] != NULL)
- channels[0]->dma_func(0, channels[0]->dma_param);
+ channels[0]->dma_func(0, channels[0]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -101,8 +117,7 @@ CH_IRQ_HANDLER(vector12) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 1;
- if (channels[1] != NULL)
- channels[1]->dma_func(1, channels[1]->dma_param);
+ channels[1]->dma_func(1, channels[1]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -120,8 +135,7 @@ CH_IRQ_HANDLER(vector13) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 2;
- if (channels[2] != NULL)
- channels[2]->dma_func(2, channels[2]->dma_param);
+ channels[2]->dma_func(2, channels[2]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -139,8 +153,7 @@ CH_IRQ_HANDLER(vector14) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 3;
- if (channels[3] != NULL)
- channels[3]->dma_func(3, channels[3]->dma_param);
+ channels[3]->dma_func(3, channels[3]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -158,8 +171,7 @@ CH_IRQ_HANDLER(vector15) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 4;
- if (channels[4] != NULL)
- channels[4]->dma_func(4, channels[4]->dma_param);
+ channels[4]->dma_func(4, channels[4]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -177,8 +189,7 @@ CH_IRQ_HANDLER(vector16) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 5;
- if (channels[5] != NULL)
- channels[5]->dma_func(5, channels[5]->dma_param);
+ channels[5]->dma_func(5, channels[5]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -196,8 +207,7 @@ CH_IRQ_HANDLER(vector17) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 6;
- if (channels[6] != NULL)
- channels[6]->dma_func(6, channels[6]->dma_param);
+ channels[6]->dma_func(6, channels[6]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -215,8 +225,7 @@ CH_IRQ_HANDLER(vector18) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 7;
- if (channels[7] != NULL)
- channels[7]->dma_func(7, channels[7]->dma_param);
+ channels[7]->dma_func(7, channels[7]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -234,8 +243,7 @@ CH_IRQ_HANDLER(vector19) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 8;
- if (channels[8] != NULL)
- channels[8]->dma_func(8, channels[8]->dma_param);
+ channels[8]->dma_func(8, channels[8]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -253,8 +261,7 @@ CH_IRQ_HANDLER(vector20) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 9;
- if (channels[9] != NULL)
- channels[9]->dma_func(9, channels[9]->dma_param);
+ channels[9]->dma_func(9, channels[9]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -272,8 +279,7 @@ CH_IRQ_HANDLER(vector21) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 10;
- if (channels[10] != NULL)
- channels[10]->dma_func(10, channels[10]->dma_param);
+ channels[10]->dma_func(10, channels[10]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -291,8 +297,7 @@ CH_IRQ_HANDLER(vector22) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 11;
- if (channels[11] != NULL)
- channels[11]->dma_func(11, channels[11]->dma_param);
+ channels[11]->dma_func(11, channels[11]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -310,8 +315,7 @@ CH_IRQ_HANDLER(vector23) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 12;
- if (channels[12] != NULL)
- channels[12]->dma_func(12, channels[12]->dma_param);
+ channels[12]->dma_func(12, channels[12]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -329,8 +333,7 @@ CH_IRQ_HANDLER(vector24) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 13;
- if (channels[13] != NULL)
- channels[13]->dma_func(13, channels[13]->dma_param);
+ channels[13]->dma_func(13, channels[13]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -348,8 +351,7 @@ CH_IRQ_HANDLER(vector25) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 14;
- if (channels[14] != NULL)
- channels[14]->dma_func(14, channels[14]->dma_param);
+ channels[14]->dma_func(14, channels[14]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -367,8 +369,7 @@ CH_IRQ_HANDLER(vector26) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 15;
- if (channels[15] != NULL)
- channels[15]->dma_func(15, channels[15]->dma_param);
+ channels[15]->dma_func(15, channels[15]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -387,8 +388,7 @@ CH_IRQ_HANDLER(vector27) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 16;
- if (channels[16] != NULL)
- channels[16]->dma_func(16, channels[16]->dma_param);
+ channels[16]->dma_func(16, channels[16]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -406,8 +406,7 @@ CH_IRQ_HANDLER(vector28) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 17;
- if (channels[17] != NULL)
- channels[17]->dma_func(17, channels[17]->dma_param);
+ channels[17]->dma_func(17, channels[17]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -425,8 +424,7 @@ CH_IRQ_HANDLER(vector29) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 18;
- if (channels[18] != NULL)
- channels[18]->dma_func(18, channels[18]->dma_param);
+ channels[18]->dma_func(18, channels[18]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -444,8 +442,7 @@ CH_IRQ_HANDLER(vector30) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 19;
- if (channels[19] != NULL)
- channels[19]->dma_func(19, channels[19]->dma_param);
+ channels[19]->dma_func(19, channels[19]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -463,8 +460,7 @@ CH_IRQ_HANDLER(vector31) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 20;
- if (channels[20] != NULL)
- channels[20]->dma_func(20, channels[20]->dma_param);
+ channels[20]->dma_func(20, channels[20]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -482,8 +478,7 @@ CH_IRQ_HANDLER(vector32) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 21;
- if (channels[21] != NULL)
- channels[21]->dma_func(21, channels[21]->dma_param);
+ channels[21]->dma_func(21, channels[21]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -501,8 +496,7 @@ CH_IRQ_HANDLER(vector33) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 22;
- if (channels[22] != NULL)
- channels[22]->dma_func(22, channels[22]->dma_param);
+ channels[22]->dma_func(22, channels[22]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -520,8 +514,7 @@ CH_IRQ_HANDLER(vector34) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 23;
- if (channels[23] != NULL)
- channels[23]->dma_func(23, channels[23]->dma_param);
+ channels[23]->dma_func(23, channels[23]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -539,8 +532,7 @@ CH_IRQ_HANDLER(vector35) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 24;
- if (channels[24] != NULL)
- channels[24]->dma_func(24, channels[24]->dma_param);
+ channels[24]->dma_func(24, channels[24]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -558,8 +550,7 @@ CH_IRQ_HANDLER(vector36) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 25;
- if (channels[25] != NULL)
- channels[25]->dma_func(25, channels[25]->dma_param);
+ channels[25]->dma_func(25, channels[25]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -577,8 +568,7 @@ CH_IRQ_HANDLER(vector37) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 26;
- if (channels[26] != NULL)
- channels[26]->dma_func(26, channels[26]->dma_param);
+ channels[26]->dma_func(26, channels[26]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -596,8 +586,7 @@ CH_IRQ_HANDLER(vector38) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 27;
- if (channels[27] != NULL)
- channels[27]->dma_func(27, channels[27]->dma_param);
+ channels[27]->dma_func(27, channels[27]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -615,8 +604,7 @@ CH_IRQ_HANDLER(vector39) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 28;
- if (channels[28] != NULL)
- channels[28]->dma_func(28, channels[28]->dma_param);
+ channels[28]->dma_func(28, channels[28]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -634,8 +622,7 @@ CH_IRQ_HANDLER(vector40) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 29;
- if (channels[29] != NULL)
- channels[29]->dma_func(29, channels[29]->dma_param);
+ channels[29]->dma_func(29, channels[29]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -653,8 +640,7 @@ CH_IRQ_HANDLER(vector41) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 30;
- if (channels[30] != NULL)
- channels[30]->dma_func(30, channels[30]->dma_param);
+ channels[30]->dma_func(30, channels[30]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -672,8 +658,7 @@ CH_IRQ_HANDLER(vector42) { SPC5_EDMA_ERROR_HANDLER();
}
EDMA.CIRQR.R = 31;
- if (channels[31] != NULL)
- channels[31]->dma_func(31, channels[31]->dma_param);
+ channels[31]->dma_func(31, channels[31]->dma_param);
CH_IRQ_EPILOGUE();
}
@@ -698,6 +683,9 @@ void edmaInit(void) { EDMA.ERL.R = 0xFFFFFFFF;
for (i = 0; i < SPC5_EDMA_NCHANNELS; i++)
EDMA.CPR[i].R = 0;
+
+ /* Error interrupt source.*/
+ INTC.PSR[10].R = SPC5_EDMA_ERROR_IRQ_PRIO;
}
/**
@@ -720,14 +708,24 @@ edma_channel_t edmaChannelAllocate(const edma_channel_config_t *ccfg) { #if SPC5_EDMA_HAS_MUX
/* TODO: MUX handling.*/
channel = EDMA_ERROR;
- return channel;
#else /* !SPC5_EDMA_HAS_MUX */
channel = (edma_channel_t)ccfg->dma_periph;
if (channels[channel] != NULL)
return EDMA_ERROR; /* Already taken.*/
+#endif /* !SPC5_EDMA_HAS_MUX */
+
+ /* Associating the configuration to the channel.*/
channels[channel] = ccfg;
+
+ /* If an error callback is defined then the erro interrupt source is
+ enabled for the channel.*/
+ if (ccfg->dma_error_func != NULL)
+ EDMA.SEEIR.R = channel;
+
+ /* Setting up IRQ priority for the selected channel.*/
+ INTC.PSR[11 + channel].R = ccfg->dma_irq_prio;
+
return channel;
-#endif /* !SPC5_EDMA_HAS_MUX */
}
/**
@@ -745,6 +743,10 @@ void edmaChannelRelease(edma_channel_t channel) { "edmaChannelRelease(), #1",
"not allocated");
+ /* Error IRQ masked for the released channel.*/
+ EDMA.CEEIR.R = channel;
+
+ /* The channels is flagged as available.*/
channels[channel] = NULL;
}
|