File indexing completed on 2025-05-11 08:23:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <bsp/lpc24xx.h>
0037 #include <bsp/dma.h>
0038 #include <bsp/irq.h>
0039
0040 static rtems_id lpc24xx_dma_sema_table [GPDMA_CH_NUMBER];
0041
0042 static bool lpc24xx_dma_status_table [GPDMA_CH_NUMBER];
0043
0044 static void lpc24xx_dma_copy_handler(void *arg)
0045 {
0046
0047 uint32_t tc = GPDMA_INT_TCSTAT;
0048 uint32_t err = GPDMA_INT_ERR_STAT;
0049
0050
0051 GPDMA_INT_TCCLR = tc;
0052 GPDMA_INT_ERR_CLR = err;
0053
0054
0055 if ((tc & GPDMA_STATUS_CH_0) != 0) {
0056 rtems_semaphore_release(lpc24xx_dma_sema_table [0]);
0057 }
0058 lpc24xx_dma_status_table [0] = (err & GPDMA_STATUS_CH_0) == 0;
0059
0060
0061 if ((tc & GPDMA_STATUS_CH_1) != 0) {
0062 rtems_semaphore_release(lpc24xx_dma_sema_table [1]);
0063 }
0064 lpc24xx_dma_status_table [1] = (err & GPDMA_STATUS_CH_1) == 0;
0065 }
0066
0067 rtems_status_code lpc24xx_dma_copy_initialize(void)
0068 {
0069 rtems_status_code sc = RTEMS_SUCCESSFUL;
0070 rtems_id id0 = RTEMS_ID_NONE;
0071 rtems_id id1 = RTEMS_ID_NONE;
0072
0073
0074 sc = rtems_semaphore_create(
0075 rtems_build_name('D', 'M', 'A', '0'),
0076 0,
0077 RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE,
0078 0,
0079 &id0
0080 );
0081 if (sc != RTEMS_SUCCESSFUL) {
0082 return sc;
0083 }
0084
0085
0086 sc = rtems_semaphore_create(
0087 rtems_build_name('D', 'M', 'A', '1'),
0088 0,
0089 RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE,
0090 0,
0091 &id1
0092 );
0093 if (sc != RTEMS_SUCCESSFUL) {
0094 rtems_semaphore_delete(id0);
0095
0096 return sc;
0097 }
0098
0099
0100 sc = rtems_interrupt_handler_install(
0101 LPC24XX_IRQ_DMA,
0102 "DMA copy",
0103 RTEMS_INTERRUPT_UNIQUE,
0104 lpc24xx_dma_copy_handler,
0105 NULL
0106 );
0107 if (sc != RTEMS_SUCCESSFUL) {
0108 rtems_semaphore_delete(id0);
0109 rtems_semaphore_delete(id1);
0110
0111 return sc;
0112 }
0113
0114
0115 lpc24xx_dma_sema_table [0] = id0;
0116 lpc24xx_dma_sema_table [1] = id1;
0117
0118 return RTEMS_SUCCESSFUL;
0119 }
0120
0121 rtems_status_code lpc24xx_dma_copy_release(void)
0122 {
0123 rtems_status_code sc = RTEMS_SUCCESSFUL;
0124 rtems_status_code rsc = RTEMS_SUCCESSFUL;
0125
0126 sc = rtems_interrupt_handler_remove(
0127 LPC24XX_IRQ_DMA,
0128 lpc24xx_dma_copy_handler,
0129 NULL
0130 );
0131 if (sc != RTEMS_SUCCESSFUL) {
0132 rsc = sc;
0133 }
0134
0135 sc = rtems_semaphore_delete(lpc24xx_dma_sema_table [0]);
0136 if (sc != RTEMS_SUCCESSFUL) {
0137 rsc = sc;
0138 }
0139
0140 sc = rtems_semaphore_delete(lpc24xx_dma_sema_table [1]);
0141 if (sc != RTEMS_SUCCESSFUL) {
0142 rsc = sc;
0143 }
0144
0145 return rsc;
0146 }
0147
0148 rtems_status_code lpc24xx_dma_copy(
0149 unsigned channel,
0150 void *dest,
0151 const void *src,
0152 size_t n,
0153 size_t width
0154 )
0155 {
0156 volatile lpc24xx_dma_channel *e = GPDMA_CH_BASE_ADDR(channel);
0157 uint32_t w = GPDMA_CH_CTRL_W_8;
0158
0159 switch (width) {
0160 case 4:
0161 w = GPDMA_CH_CTRL_W_32;
0162 break;
0163 case 2:
0164 w = GPDMA_CH_CTRL_W_16;
0165 break;
0166 }
0167
0168 n = n >> w;
0169
0170 if (n > 0U && n < 4096U) {
0171 e->desc.src = (uint32_t) src;
0172 e->desc.dest = (uint32_t) dest;
0173 e->desc.lli = 0;
0174 e->desc.ctrl = SET_GPDMA_CH_CTRL_TSZ(0, n)
0175 | SET_GPDMA_CH_CTRL_SBSZ(0, GPDMA_CH_CTRL_BSZ_1)
0176 | SET_GPDMA_CH_CTRL_DBSZ(0, GPDMA_CH_CTRL_BSZ_1)
0177 | SET_GPDMA_CH_CTRL_SW(0, w)
0178 | SET_GPDMA_CH_CTRL_DW(0, w)
0179 | GPDMA_CH_CTRL_ITC
0180 | GPDMA_CH_CTRL_SI
0181 | GPDMA_CH_CTRL_DI;
0182 e->cfg = SET_GPDMA_CH_CFG_FLOW(0, GPDMA_CH_CFG_FLOW_MEM_TO_MEM_DMA)
0183 | GPDMA_CH_CFG_IE
0184 | GPDMA_CH_CFG_ITC
0185 | GPDMA_CH_CFG_EN;
0186 } else {
0187 return RTEMS_INVALID_SIZE;
0188 }
0189
0190 return RTEMS_SUCCESSFUL;
0191 }
0192
0193 rtems_status_code lpc24xx_dma_copy_wait(unsigned channel)
0194 {
0195 rtems_status_code sc = RTEMS_SUCCESSFUL;
0196
0197 sc = rtems_semaphore_obtain(
0198 lpc24xx_dma_sema_table [channel],
0199 RTEMS_WAIT,
0200 RTEMS_NO_TIMEOUT
0201 );
0202 if (sc != RTEMS_SUCCESSFUL) {
0203 return sc;
0204 }
0205
0206 return lpc24xx_dma_status_table [channel]
0207 ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR;
0208 }