Changeset 779847a5 in rtems
- Timestamp:
- 01/12/22 15:12:20 (2 years ago)
- Branches:
- 5
- Children:
- 9942ff80
- Parents:
- d9c0dd3
- git-author:
- Christian Mauderer <christian.mauderer@…> (01/12/22 15:12:20)
- git-committer:
- Christian Mauderer <christian.mauderer@…> (01/18/22 07:50:06)
- Location:
- bsps/arm/atsam
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
bsps/arm/atsam/console/console.c
rd9c0dd3 r779847a5 17 17 #include <bsp/fatal.h> 18 18 #include <rtems/console.h> 19 #include <rtems/seterr.h> 19 20 20 21 #include <rtems/termiostypes.h> … … 23 24 24 25 #include <unistd.h> 26 27 #define UART_RX_DMA_BUF_SIZE 32l 28 29 typedef struct { 30 char buf[UART_RX_DMA_BUF_SIZE]; 31 LinkedListDescriporView3 desc; 32 } atsam_uart_rx_dma; 25 33 26 34 typedef struct { … … 33 41 #ifdef ATSAM_CONSOLE_USE_INTERRUPTS 34 42 bool transmitting; 43 bool rx_dma_enabled; 44 uint32_t rx_dma_channel; 45 atsam_uart_rx_dma *rx_dma; 46 char *volatile*rx_dma_da; 47 char *rx_next_read_pos; 35 48 #endif 36 49 } atsam_uart_context; … … 110 123 uint32_t sr = regs->UART_SR; 111 124 112 while ((sr & UART_SR_RXRDY) != 0) { 113 char c = (char) regs->UART_RHR; 114 115 rtems_termios_enqueue_raw_characters(tty, &c, 1); 116 117 sr = regs->UART_SR; 125 if (!ctx->rx_dma_enabled) { 126 while ((sr & UART_SR_RXRDY) != 0) { 127 char c = (char) regs->UART_RHR; 128 129 rtems_termios_enqueue_raw_characters(tty, &c, 1); 130 131 sr = regs->UART_SR; 132 } 133 } else { 134 while (*ctx->rx_dma_da != ctx->rx_next_read_pos) { 135 char c; 136 137 c = *ctx->rx_next_read_pos; 138 139 ++ctx->rx_next_read_pos; 140 if (ctx->rx_next_read_pos >= &ctx->rx_dma->buf[UART_RX_DMA_BUF_SIZE]) { 141 ctx->rx_next_read_pos = &ctx->rx_dma->buf[0]; 142 } 143 144 rtems_termios_enqueue_raw_characters(tty, &c, 1); 145 } 118 146 } 119 147 … … 197 225 } 198 226 227 static void atsam_uart_disable_rx_dma(atsam_uart_context *ctx) 228 { 229 if (ctx->rx_dma) { 230 rtems_cache_coherent_free(ctx->rx_dma); 231 ctx->rx_dma = NULL; 232 } 233 234 if (ctx->rx_dma_channel != XDMAD_ALLOC_FAILED) { 235 XDMAD_FreeChannel(&XDMAD_Instance, ctx->rx_dma_channel); 236 } 237 238 ctx->rx_dma_enabled = false; 239 } 240 241 static rtems_status_code atsam_uart_enable_rx_dma(atsam_uart_context *ctx) 242 { 243 eXdmadRC rc; 244 int channel_id; 245 246 if (ctx->rx_dma_enabled) { 247 return RTEMS_SUCCESSFUL; 248 } 249 250 /* 251 * Make sure everything is in a clean default state so that the cleanup works 252 * in an error case. 253 */ 254 ctx->rx_dma = NULL; 255 ctx->rx_dma_channel = XDMAD_ALLOC_FAILED; 256 257 ctx->rx_dma = rtems_cache_coherent_allocate(sizeof(*ctx->rx_dma), 0, 0); 258 if (ctx->rx_dma == NULL) { 259 atsam_uart_disable_rx_dma(ctx); 260 return RTEMS_NO_MEMORY; 261 } 262 263 ctx->rx_next_read_pos = &ctx->rx_dma->buf[0]; 264 265 ctx->rx_dma_channel = XDMAD_AllocateChannel( 266 &XDMAD_Instance, 267 XDMAD_TRANSFER_MEMORY, 268 ctx->id 269 ); 270 271 if (ctx->rx_dma_channel == XDMAD_ALLOC_FAILED) { 272 atsam_uart_disable_rx_dma(ctx); 273 return RTEMS_IO_ERROR; 274 } 275 276 rc = XDMAD_PrepareChannel(&XDMAD_Instance, ctx->rx_dma_channel); 277 if (rc != XDMAD_OK) { 278 atsam_uart_disable_rx_dma(ctx); 279 return RTEMS_IO_ERROR; 280 } 281 282 channel_id = ctx->rx_dma_channel & 0xff; 283 ctx->rx_dma_da = 284 (char *volatile*) &XDMAD_Instance.pXdmacs->XDMAC_CHID[channel_id].XDMAC_CDA; 285 286 ctx->rx_dma->desc.mbr_nda = (uint32_t)&ctx->rx_dma->desc; 287 ctx->rx_dma->desc.mbr_ubc = 288 1 | 289 XDMA_UBC_NVIEW_NDV3 | 290 XDMA_UBC_NDE_FETCH_EN | 291 XDMA_UBC_NDEN_UPDATED | 292 XDMA_UBC_NSEN_UPDATED; 293 ctx->rx_dma->desc.mbr_sa = (uint32_t) &ctx->regs->UART_RHR; 294 ctx->rx_dma->desc.mbr_da = (uint32_t) &ctx->rx_dma->buf[0]; 295 ctx->rx_dma->desc.mbr_cfg = 296 XDMAC_CC_TYPE_PER_TRAN | 297 XDMAC_CC_MBSIZE_SINGLE | 298 XDMAC_CC_DSYNC_PER2MEM | 299 XDMAC_CC_SWREQ_HWR_CONNECTED | 300 XDMAC_CC_MEMSET_NORMAL_MODE | 301 XDMAC_CC_CSIZE_CHK_1 | 302 XDMAC_CC_DWIDTH_BYTE | 303 XDMAC_CC_SIF_AHB_IF1 | 304 XDMAC_CC_DIF_AHB_IF1 | 305 XDMAC_CC_SAM_FIXED_AM | 306 XDMAC_CC_DAM_UBS_AM | 307 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ctx->id, XDMAD_TRANSFER_RX)); 308 ctx->rx_dma->desc.mbr_bc = UART_RX_DMA_BUF_SIZE - 1; 309 ctx->rx_dma->desc.mbr_ds = 0; 310 ctx->rx_dma->desc.mbr_sus = 0; 311 ctx->rx_dma->desc.mbr_dus = 0; 312 313 rc = XDMAD_ConfigureTransfer( 314 &XDMAD_Instance, 315 ctx->rx_dma_channel, 316 NULL, 317 XDMAC_CNDC_NDE_DSCR_FETCH_EN | 318 XDMAC_CNDC_NDVIEW_NDV3 | 319 XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED | 320 XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED, 321 (uint32_t)&ctx->rx_dma->desc, 322 0); 323 if (rc != XDMAD_OK) { 324 atsam_uart_disable_rx_dma(ctx); 325 return RTEMS_IO_ERROR; 326 } 327 328 rc = XDMAD_StartTransfer(&XDMAD_Instance, ctx->rx_dma_channel); 329 if (rc != XDMAD_OK) { 330 atsam_uart_disable_rx_dma(ctx); 331 return RTEMS_IO_ERROR; 332 } 333 334 ctx->rx_dma_enabled = true; 335 336 return RTEMS_SUCCESSFUL; 337 } 338 199 339 static bool atsam_uart_first_open( 200 340 rtems_termios_tty *tty, … … 247 387 #endif 248 388 389 if (ctx->rx_dma_enabled) { 390 atsam_uart_disable_rx_dma(ctx); 391 } 392 249 393 if (!ctx->console) { 250 394 PMC_DisablePeripheral(ctx->id); … … 297 441 #endif 298 442 443 #ifdef ATSAM_CONSOLE_USE_INTERRUPTS 444 static int atsam_uart_ioctl( 445 rtems_termios_device_context *base, 446 ioctl_command_t request, 447 void *buffer 448 ) 449 { 450 atsam_uart_context *ctx = (atsam_uart_context *) base; 451 rtems_status_code sc; 452 453 switch (request) { 454 case ATSAM_UART_ENABLE_RX_DMA: 455 sc = atsam_uart_enable_rx_dma(ctx); 456 if (sc != RTEMS_SUCCESSFUL) { 457 rtems_set_errno_and_return_minus_one(EIO); 458 } else { 459 ctx->rx_dma_enabled = true; 460 } 461 break; 462 default: 463 rtems_set_errno_and_return_minus_one(EINVAL); 464 } 465 466 return 0; 467 } 468 #endif 469 299 470 static const rtems_termios_device_handler atsam_uart_handler = { 300 471 .first_open = atsam_uart_first_open, … … 303 474 .set_attributes = atsam_uart_set_attributes, 304 475 #ifdef ATSAM_CONSOLE_USE_INTERRUPTS 305 .mode = TERMIOS_IRQ_DRIVEN 476 .mode = TERMIOS_IRQ_DRIVEN, 477 .ioctl = atsam_uart_ioctl, 306 478 #else 307 479 .poll_read = atsam_uart_read, -
bsps/arm/atsam/include/bsp.h
rd9c0dd3 r779847a5 34 34 #include <bspopts.h> 35 35 #include <bsp/default-initial-extension.h> 36 #include <sys/ioccom.h> 36 37 37 38 #include <rtems.h> … … 110 111 void bsp_restart( const void *const addr ); 111 112 113 /* 114 * This ioctl enables the receive DMA for an UART. The DMA can be usefull if you 115 * loose characters in high interrupt load situations. 116 * 117 * Disabling the DMA again is only possible by closing all file descriptors of 118 * that UART. 119 * 120 * Note that every UART needs one DMA channel and the system has only a limited 121 * amount of DMAs. So only use it if you need it. 122 */ 123 #define ATSAM_UART_ENABLE_RX_DMA _IO('d', 0) 124 112 125 #ifdef __cplusplus 113 126 }
Note: See TracChangeset
for help on using the changeset viewer.