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/lpc176x.h>
0037 #include <bsp/dma.h>
0038 #include <bsp/irq.h>
0039
0040 static rtems_id lpc176x_dma_sema_table[ GPDMA_CH_NUMBER ];
0041 static bool lpc176x_dma_status_table[ GPDMA_CH_NUMBER ];
0042
0043 static void lpc176x_dma_copy_handler( void *arg )
0044 {
0045
0046 uint32_t tc = GPDMA_INT_TCSTAT;
0047 uint32_t err = GPDMA_INT_ERR_STAT;
0048
0049
0050 GPDMA_INT_TCCLR = tc;
0051 GPDMA_INT_ERR_CLR = err;
0052
0053 if ( ( tc & GPDMA_STATUS_CH_0 ) != 0 ) {
0054 rtems_semaphore_release( lpc176x_dma_sema_table[ 0 ] );
0055 }
0056
0057
0058
0059
0060 lpc176x_dma_status_table[ 0 ] = ( err & GPDMA_STATUS_CH_0 ) == 0;
0061
0062 if ( ( tc & GPDMA_STATUS_CH_1 ) != 0 ) {
0063 rtems_semaphore_release( lpc176x_dma_sema_table[ 1 ] );
0064 }
0065
0066
0067
0068
0069 lpc176x_dma_status_table[ 1 ] = ( err & GPDMA_STATUS_CH_1 ) == 0;
0070 }
0071
0072 rtems_status_code lpc176x_dma_copy_initialize( void )
0073 {
0074 rtems_status_code status_code = RTEMS_SUCCESSFUL;
0075 rtems_id id0 = RTEMS_ID_NONE;
0076 rtems_id id1 = RTEMS_ID_NONE;
0077
0078
0079 status_code = rtems_semaphore_create( rtems_build_name( 'D', 'M', 'A', '0' ),
0080 0,
0081 RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE,
0082 0,
0083 &id0 );
0084
0085 if ( status_code != RTEMS_SUCCESSFUL ) {
0086 return status_code;
0087 }
0088
0089
0090
0091
0092
0093 status_code = rtems_semaphore_create( rtems_build_name( 'D', 'M', 'A', '1' ),
0094 0,
0095 RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE,
0096 0,
0097 &id1 );
0098
0099 if ( status_code != RTEMS_SUCCESSFUL ) {
0100 rtems_semaphore_delete( id0 );
0101
0102 return status_code;
0103 }
0104
0105
0106
0107
0108
0109 status_code = rtems_interrupt_handler_install( LPC176X_IRQ_DMA,
0110 "DMA copy",
0111 RTEMS_INTERRUPT_UNIQUE,
0112 lpc176x_dma_copy_handler,
0113 NULL );
0114
0115 if ( status_code != RTEMS_SUCCESSFUL ) {
0116 rtems_semaphore_delete( id0 );
0117 rtems_semaphore_delete( id1 );
0118
0119 return status_code;
0120 }
0121
0122
0123
0124
0125
0126 lpc176x_dma_sema_table[ 0 ] = id0;
0127 lpc176x_dma_sema_table[ 1 ] = id1;
0128
0129 return RTEMS_SUCCESSFUL;
0130 }
0131
0132 rtems_status_code lpc176x_dma_copy_release( void )
0133 {
0134 rtems_status_code status_code = RTEMS_SUCCESSFUL;
0135 rtems_status_code status_code_aux = RTEMS_SUCCESSFUL;
0136
0137 status_code = rtems_interrupt_handler_remove( LPC176X_IRQ_DMA,
0138 lpc176x_dma_copy_handler,
0139 NULL );
0140
0141 if ( status_code != RTEMS_SUCCESSFUL ) {
0142 status_code_aux = status_code;
0143 }
0144
0145
0146
0147
0148 status_code = rtems_semaphore_delete( lpc176x_dma_sema_table[ 0 ] );
0149
0150 if ( status_code != RTEMS_SUCCESSFUL ) {
0151 status_code_aux = status_code;
0152 }
0153
0154
0155
0156
0157 status_code = rtems_semaphore_delete( lpc176x_dma_sema_table[ 1 ] );
0158
0159 if ( status_code != RTEMS_SUCCESSFUL ) {
0160 status_code_aux = status_code;
0161 }
0162
0163
0164
0165
0166 return status_code_aux;
0167 }
0168
0169 rtems_status_code lpc176x_dma_copy(
0170 unsigned channel,
0171 const void *const dest,
0172 const void *const src,
0173 size_t n,
0174 const size_t width
0175 )
0176 {
0177 rtems_status_code status_code = RTEMS_SUCCESSFUL;
0178 volatile lpc176x_dma_channel *e = GPDMA_CH_BASE_ADDR( channel );
0179 uint32_t w = GPDMA_CH_CTRL_W_8;
0180
0181 switch ( width ) {
0182 case 4:
0183 w = GPDMA_CH_CTRL_W_32;
0184 break;
0185 case 2:
0186 w = GPDMA_CH_CTRL_W_16;
0187 break;
0188 }
0189
0190 n = n >> w;
0191
0192 if ( n > 0 && n < 4096 ) {
0193 e->desc.src = (uint32_t) src;
0194 e->desc.dest = (uint32_t) dest;
0195 e->desc.lli = 0;
0196 e->desc.ctrl = SET_GPDMA_CH_CTRL_TSZ( 0, n ) |
0197 SET_GPDMA_CH_CTRL_SBSZ( 0, GPDMA_CH_CTRL_BSZ_1 ) |
0198 SET_GPDMA_CH_CTRL_DBSZ( 0, GPDMA_CH_CTRL_BSZ_1 ) |
0199 SET_GPDMA_CH_CTRL_SW( 0, w ) |
0200 SET_GPDMA_CH_CTRL_DW( 0, w ) |
0201 GPDMA_CH_CTRL_ITC |
0202 GPDMA_CH_CTRL_SI |
0203 GPDMA_CH_CTRL_DI;
0204 e->cfg = SET_GPDMA_CH_CFG_FLOW( 0, GPDMA_CH_CFG_FLOW_MEM_TO_MEM_DMA ) |
0205 GPDMA_CH_CFG_IE |
0206 GPDMA_CH_CFG_ITC |
0207 GPDMA_CH_CFG_EN;
0208 } else {
0209 status_code = RTEMS_INVALID_SIZE;
0210 }
0211
0212 return status_code;
0213 }
0214
0215 rtems_status_code lpc176x_dma_copy_wait( const unsigned channel )
0216 {
0217 rtems_status_code status_code = RTEMS_SUCCESSFUL;
0218
0219 status_code = rtems_semaphore_obtain( lpc176x_dma_sema_table[ channel ],
0220 RTEMS_WAIT,
0221 RTEMS_NO_TIMEOUT );
0222
0223 if ( status_code != RTEMS_SUCCESSFUL ) {
0224 return status_code;
0225 }
0226
0227
0228
0229
0230 status_code = lpc176x_dma_status_table[ channel ]
0231 ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR;
0232
0233 return status_code;
0234 }