File indexing completed on 2025-05-11 08:22:42
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
0037 #include <bsp/alt_16550_uart.h>
0038 #include <bsp/alt_clock_manager.h>
0039 #include <bsp/socal/alt_rstmgr.h>
0040 #include <bsp/socal/alt_uart.h>
0041 #include <bsp/socal/hps.h>
0042 #include <bsp/socal/socal.h>
0043
0044
0045
0046 #define ALT_16550_HANDLE_DATA_UART_ENABLED_MSK (1UL << 31)
0047 #define ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(value) (value & 0xffff)
0048
0049 #define ALT_ALTERA_16550_CPR_OFST (0xF4)
0050 #define ALT_ALTERA_16550_CPR_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_ALTERA_16550_CPR_OFST))
0051 #define ALT_ALTERA_16550_CPR_FIFO_MODE_GET(value) (((value) >> 16) & 0xff)
0052 #define ALT_ALTERA_16550_CPR_AFCE_MODE_SET_MSK (1 << 4)
0053
0054
0055
0056
0057 #define ALT_UART_IER_DLH_VALUE_SET(value) ((value) & 0xff)
0058 #define ALT_UART_IER_DLH_ETBEI_DLH1_SET_MSK ALT_UART_IER_DLH_ETBEI_DLHL_SET_MSK
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 static inline uint32_t alt_read_word_helper(const void * addr)
0077 {
0078 return alt_read_word(addr);
0079 }
0080
0081
0082
0083
0084 static ALT_STATUS_CODE alt_16550_write_divisor_helper(ALT_16550_HANDLE_t * handle,
0085 uint32_t divisor)
0086 {
0087
0088 if (divisor > 0xffff)
0089 {
0090
0091 return ALT_E_ERROR;
0092 }
0093
0094 switch (handle->device)
0095 {
0096 case ALT_16550_DEVICE_SOCFPGA_UART0:
0097 case ALT_16550_DEVICE_SOCFPGA_UART1:
0098 case ALT_16550_DEVICE_ALTERA_16550_UART:
0099
0100 alt_setbits_word(ALT_UART_LCR_ADDR(handle->location), ALT_UART_LCR_DLAB_SET_MSK);
0101
0102
0103 alt_write_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location), ALT_UART_RBR_THR_DLL_VALUE_SET(divisor));
0104
0105
0106 alt_write_word(ALT_UART_IER_DLH_ADDR(handle->location), ALT_UART_IER_DLH_VALUE_SET(divisor >> 8));
0107
0108
0109 alt_clrbits_word(ALT_UART_LCR_ADDR(handle->location), ALT_UART_LCR_DLAB_SET_MSK);
0110
0111 break;
0112
0113 default:
0114 return ALT_E_ERROR;
0115 }
0116
0117
0118 if (divisor != 0)
0119 {
0120 handle->data |= ALT_16550_HANDLE_DATA_UART_ENABLED_MSK;
0121 }
0122 else
0123 {
0124 handle->data &= ~ALT_16550_HANDLE_DATA_UART_ENABLED_MSK;
0125 }
0126
0127 return ALT_E_SUCCESS;
0128 }
0129
0130
0131
0132
0133 static ALT_STATUS_CODE alt_16550_reset_helper(ALT_16550_HANDLE_t * handle, bool enable_init)
0134 {
0135 switch (handle->device)
0136 {
0137 case ALT_16550_DEVICE_SOCFPGA_UART0:
0138 case ALT_16550_DEVICE_SOCFPGA_UART1:
0139
0140 alt_write_word(ALT_UART_SRR_ADDR(handle->location), ALT_UART_SRR_UR_SET_MSK);
0141
0142
0143 alt_read_word_helper(ALT_UART_MSR_ADDR(handle->location));
0144 break;
0145
0146 case ALT_16550_DEVICE_ALTERA_16550_UART:
0147 alt_16550_write_divisor_helper(handle, 0);
0148 alt_16550_int_disable_all(handle);
0149 alt_16550_fifo_disable(handle);
0150 alt_write_word(ALT_UART_MCR_ADDR(handle->location), 0);
0151 break;
0152
0153 default:
0154 return ALT_E_ERROR;
0155 }
0156
0157
0158 if (enable_init)
0159 {
0160 ALT_STATUS_CODE status;
0161
0162
0163 alt_setbits_word(ALT_UART_IER_DLH_ADDR(handle->location), ALT_UART_IER_DLH_PTIME_DLH7_SET_MSK);
0164
0165
0166 status = alt_16550_line_config_set(handle, ALT_16550_DATABITS_8,
0167 ALT_16550_PARITY_DISABLE,
0168 ALT_16550_STOPBITS_1);
0169 if (status != ALT_E_SUCCESS)
0170 {
0171 return status;
0172 }
0173
0174 uint32_t divisor = ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(handle->data);
0175 if (divisor == 0)
0176 {
0177
0178 status = alt_16550_baudrate_set(handle, ALT_16550_BAUDRATE_57600);
0179 if (status != ALT_E_SUCCESS)
0180 {
0181 return status;
0182 }
0183 }
0184 }
0185
0186 return ALT_E_SUCCESS;
0187 }
0188
0189 ALT_STATUS_CODE alt_16550_init(ALT_16550_DEVICE_t device,
0190 void * location,
0191 alt_freq_t clock_freq,
0192 ALT_16550_HANDLE_t * handle)
0193 {
0194 handle->device = device;
0195 handle->data = 0;
0196 handle->fcr = 0;
0197
0198 switch (device)
0199 {
0200 case ALT_16550_DEVICE_SOCFPGA_UART0:
0201 case ALT_16550_DEVICE_SOCFPGA_UART1:
0202
0203 if (alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE)
0204 {
0205 return ALT_E_BAD_CLK;
0206 }
0207 else
0208 {
0209 ALT_STATUS_CODE status;
0210 status = alt_clk_freq_get(ALT_CLK_L4_SP, &handle->clock_freq);
0211 if (status != ALT_E_SUCCESS)
0212 {
0213 return status;
0214 }
0215
0216 if (device == ALT_16550_DEVICE_SOCFPGA_UART0)
0217 {
0218 handle->location = ALT_UART0_ADDR;
0219
0220
0221 alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_UART0_SET_MSK);
0222 }
0223 else
0224 {
0225 handle->location = ALT_UART1_ADDR;
0226
0227
0228 alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_UART1_SET_MSK);
0229 }
0230
0231
0232 uint32_t ucr = alt_read_word(ALT_UART_UCV_ADDR(handle->location));
0233 if (ucr != ALT_UART_UCV_UART_COMPONENT_VER_RESET)
0234 {
0235 return ALT_E_ERROR;
0236 }
0237 }
0238 break;
0239 case ALT_16550_DEVICE_ALTERA_16550_UART:
0240 handle->location = location;
0241 handle->clock_freq = clock_freq;
0242 break;
0243 default:
0244 return ALT_E_BAD_ARG;
0245 }
0246
0247 return alt_16550_reset_helper(handle, true);
0248 }
0249
0250 ALT_STATUS_CODE alt_16550_uninit(ALT_16550_HANDLE_t * handle)
0251 {
0252 switch (handle->device)
0253 {
0254 case ALT_16550_DEVICE_SOCFPGA_UART0:
0255 alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_UART0_SET_MSK);
0256 return ALT_E_SUCCESS;
0257 case ALT_16550_DEVICE_SOCFPGA_UART1:
0258 alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_UART1_SET_MSK);
0259 return ALT_E_SUCCESS;
0260 case ALT_16550_DEVICE_ALTERA_16550_UART:
0261 default:
0262 return alt_16550_reset_helper(handle, false);
0263 }
0264 }
0265
0266 ALT_STATUS_CODE alt_16550_reset(ALT_16550_HANDLE_t * handle)
0267 {
0268 return alt_16550_reset_helper(handle, true);
0269 }
0270
0271 ALT_STATUS_CODE alt_16550_enable(ALT_16550_HANDLE_t * handle)
0272 {
0273
0274
0275 return alt_16550_write_divisor_helper(handle,
0276 ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(handle->data));
0277 }
0278
0279 ALT_STATUS_CODE alt_16550_disable(ALT_16550_HANDLE_t * handle)
0280 {
0281
0282
0283 return alt_16550_write_divisor_helper(handle, 0);
0284 }
0285
0286 ALT_STATUS_CODE alt_16550_read(ALT_16550_HANDLE_t * handle,
0287 char * item)
0288 {
0289
0290 if (!(handle->data & ALT_16550_HANDLE_DATA_UART_ENABLED_MSK))
0291 {
0292 return ALT_E_ERROR;
0293 }
0294
0295
0296 if (handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK)
0297 {
0298 return ALT_E_ERROR;
0299 }
0300
0301 switch (handle->device)
0302 {
0303 case ALT_16550_DEVICE_SOCFPGA_UART0:
0304 case ALT_16550_DEVICE_SOCFPGA_UART1:
0305 case ALT_16550_DEVICE_ALTERA_16550_UART:
0306
0307 *item = ALT_UART_RBR_THR_DLL_VALUE_GET(alt_read_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location)));
0308 break;
0309 default:
0310 return ALT_E_ERROR;
0311 }
0312 return ALT_E_SUCCESS;
0313 }
0314
0315 ALT_STATUS_CODE alt_16550_write(ALT_16550_HANDLE_t * handle,
0316 char item)
0317 {
0318
0319 if (!(handle->data & ALT_16550_HANDLE_DATA_UART_ENABLED_MSK))
0320 {
0321 return ALT_E_ERROR;
0322 }
0323
0324
0325 if (handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK)
0326 {
0327 return ALT_E_ERROR;
0328 }
0329
0330 switch (handle->device)
0331 {
0332 case ALT_16550_DEVICE_SOCFPGA_UART0:
0333 case ALT_16550_DEVICE_SOCFPGA_UART1:
0334 case ALT_16550_DEVICE_ALTERA_16550_UART:
0335
0336 alt_write_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location), item);
0337 break;
0338 default:
0339 return ALT_E_ERROR;
0340 }
0341
0342 return ALT_E_SUCCESS;
0343 }
0344
0345
0346
0347 ALT_STATUS_CODE alt_16550_fifo_enable(ALT_16550_HANDLE_t * handle)
0348 {
0349 switch (handle->device)
0350 {
0351 case ALT_16550_DEVICE_SOCFPGA_UART0:
0352 case ALT_16550_DEVICE_SOCFPGA_UART1:
0353 case ALT_16550_DEVICE_ALTERA_16550_UART:
0354
0355 handle->fcr |= ALT_UART_FCR_FIFOE_SET_MSK;
0356 alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr);
0357 break;
0358 default:
0359 return ALT_E_ERROR;
0360 }
0361
0362
0363
0364 return ALT_E_SUCCESS;
0365 }
0366
0367 ALT_STATUS_CODE alt_16550_fifo_disable(ALT_16550_HANDLE_t * handle)
0368 {
0369 switch (handle->device)
0370 {
0371 case ALT_16550_DEVICE_SOCFPGA_UART0:
0372 case ALT_16550_DEVICE_SOCFPGA_UART1:
0373 case ALT_16550_DEVICE_ALTERA_16550_UART:
0374
0375 handle->fcr &= ~ALT_UART_FCR_FIFOE_SET_MSK;
0376 alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr);
0377 break;
0378 default:
0379 return ALT_E_ERROR;
0380 }
0381
0382 return ALT_E_SUCCESS;
0383 }
0384
0385 ALT_STATUS_CODE alt_16550_fifo_read(ALT_16550_HANDLE_t * handle,
0386 char * buffer,
0387 size_t count)
0388 {
0389
0390 if (!(handle->data & ALT_16550_HANDLE_DATA_UART_ENABLED_MSK))
0391 {
0392 return ALT_E_ERROR;
0393 }
0394
0395
0396 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
0397 {
0398 return ALT_E_ERROR;
0399 }
0400
0401 switch (handle->device)
0402 {
0403 case ALT_16550_DEVICE_SOCFPGA_UART0:
0404 case ALT_16550_DEVICE_SOCFPGA_UART1:
0405 case ALT_16550_DEVICE_ALTERA_16550_UART:
0406
0407 for (size_t i = 0; i < count; ++i)
0408 {
0409 buffer[i] = ALT_UART_RBR_THR_DLL_VALUE_GET(alt_read_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location)));
0410 }
0411 break;
0412 default:
0413 return ALT_E_ERROR;
0414 }
0415
0416 return ALT_E_SUCCESS;
0417 }
0418
0419 ALT_STATUS_CODE alt_16550_fifo_write(ALT_16550_HANDLE_t * handle,
0420 const char * buffer,
0421 size_t count)
0422 {
0423
0424 if (!(handle->data & ALT_16550_HANDLE_DATA_UART_ENABLED_MSK))
0425 {
0426 return ALT_E_ERROR;
0427 }
0428
0429
0430 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
0431 {
0432 return ALT_E_ERROR;
0433 }
0434
0435 switch (handle->device)
0436 {
0437 case ALT_16550_DEVICE_SOCFPGA_UART0:
0438 case ALT_16550_DEVICE_SOCFPGA_UART1:
0439 case ALT_16550_DEVICE_ALTERA_16550_UART:
0440
0441 for (size_t i = 0; i < count; ++i)
0442 {
0443 alt_write_word(ALT_UART_RBR_THR_DLL_ADDR(handle->location), buffer[i]);
0444 }
0445 break;
0446 default:
0447 return ALT_E_ERROR;
0448 }
0449
0450 return ALT_E_SUCCESS;
0451 }
0452
0453 ALT_STATUS_CODE alt_16550_fifo_clear_rx(ALT_16550_HANDLE_t * handle)
0454 {
0455
0456 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
0457 {
0458 return ALT_E_ERROR;
0459 }
0460
0461 switch (handle->device)
0462 {
0463 case ALT_16550_DEVICE_SOCFPGA_UART0:
0464 case ALT_16550_DEVICE_SOCFPGA_UART1:
0465
0466 alt_write_word(ALT_UART_SRR_ADDR(handle->location), ALT_UART_SRR_RFR_SET_MSK);
0467 break;
0468 case ALT_16550_DEVICE_ALTERA_16550_UART:
0469
0470 alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr | ALT_UART_FCR_RFIFOR_SET_MSK);
0471 break;
0472 default:
0473 return ALT_E_ERROR;
0474 }
0475
0476 return ALT_E_SUCCESS;
0477 }
0478
0479 ALT_STATUS_CODE alt_16550_fifo_clear_tx(ALT_16550_HANDLE_t * handle)
0480 {
0481
0482 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
0483 {
0484 return ALT_E_ERROR;
0485 }
0486
0487 switch (handle->device)
0488 {
0489 case ALT_16550_DEVICE_SOCFPGA_UART0:
0490 case ALT_16550_DEVICE_SOCFPGA_UART1:
0491
0492 alt_write_word(ALT_UART_SRR_ADDR(handle->location), ALT_UART_SRR_XFR_SET_MSK);
0493 break;
0494 case ALT_16550_DEVICE_ALTERA_16550_UART:
0495
0496 alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr | ALT_UART_FCR_XFIFOR_SET_MSK);
0497 break;
0498 default:
0499 return ALT_E_ERROR;
0500 }
0501
0502 return ALT_E_SUCCESS;
0503 }
0504
0505 ALT_STATUS_CODE alt_16550_fifo_clear_all(ALT_16550_HANDLE_t * handle)
0506 {
0507
0508 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
0509 {
0510 return ALT_E_ERROR;
0511 }
0512
0513 switch (handle->device)
0514 {
0515 case ALT_16550_DEVICE_SOCFPGA_UART0:
0516 case ALT_16550_DEVICE_SOCFPGA_UART1:
0517
0518
0519 alt_write_word(ALT_UART_SRR_ADDR(handle->location),
0520 ALT_UART_SRR_RFR_SET_MSK | ALT_UART_SRR_XFR_SET_MSK);
0521 break;
0522 case ALT_16550_DEVICE_ALTERA_16550_UART:
0523
0524
0525 alt_write_word(ALT_UART_FCR_ADDR(handle->location),
0526 handle->fcr | ALT_UART_FCR_RFIFOR_SET_MSK | ALT_UART_FCR_XFIFOR_SET_MSK);
0527 break;
0528 default:
0529 return ALT_E_ERROR;
0530 }
0531
0532 return ALT_E_SUCCESS;
0533 }
0534
0535 ALT_STATUS_CODE alt_16550_fifo_size_get_rx(ALT_16550_HANDLE_t * handle,
0536 uint32_t * size)
0537 {
0538 switch (handle->device)
0539 {
0540 case ALT_16550_DEVICE_SOCFPGA_UART0:
0541 case ALT_16550_DEVICE_SOCFPGA_UART1:
0542
0543
0544 *size = ALT_UART_CPR_FIFO_MOD_GET(alt_read_word(ALT_UART_CPR_ADDR(handle->location))) << 4;
0545 break;
0546 case ALT_16550_DEVICE_ALTERA_16550_UART:
0547
0548
0549 *size = ALT_ALTERA_16550_CPR_FIFO_MODE_GET(alt_read_word(ALT_ALTERA_16550_CPR_ADDR(handle->location))) << 4;
0550 break;
0551 default:
0552 return ALT_E_ERROR;
0553 }
0554
0555 return ALT_E_SUCCESS;
0556 }
0557
0558 ALT_STATUS_CODE alt_16550_fifo_size_get_tx(ALT_16550_HANDLE_t * handle,
0559 uint32_t * size)
0560 {
0561 switch (handle->device)
0562 {
0563 case ALT_16550_DEVICE_SOCFPGA_UART0:
0564 case ALT_16550_DEVICE_SOCFPGA_UART1:
0565
0566
0567 *size = ALT_UART_CPR_FIFO_MOD_GET(alt_read_word(ALT_UART_CPR_ADDR(handle->location))) << 4;
0568 break;
0569 case ALT_16550_DEVICE_ALTERA_16550_UART:
0570
0571
0572
0573 *size = ALT_ALTERA_16550_CPR_FIFO_MODE_GET(alt_read_word(ALT_ALTERA_16550_CPR_ADDR(handle->location))) << 4;
0574 break;
0575 default:
0576 return ALT_E_ERROR;
0577 }
0578
0579 return ALT_E_SUCCESS;
0580 }
0581
0582 ALT_STATUS_CODE alt_16550_fifo_level_get_rx(ALT_16550_HANDLE_t * handle,
0583 uint32_t * level)
0584 {
0585
0586 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
0587 {
0588 return ALT_E_ERROR;
0589 }
0590
0591 switch (handle->device)
0592 {
0593 case ALT_16550_DEVICE_SOCFPGA_UART0:
0594 case ALT_16550_DEVICE_SOCFPGA_UART1:
0595
0596 *level = alt_read_word(ALT_UART_RFL_ADDR(handle->location));
0597 break;
0598 case ALT_16550_DEVICE_ALTERA_16550_UART:
0599
0600 *level = 0;
0601 break;
0602 default:
0603 return ALT_E_ERROR;
0604 }
0605
0606 return ALT_E_SUCCESS;
0607 }
0608
0609 ALT_STATUS_CODE alt_16550_fifo_level_get_tx(ALT_16550_HANDLE_t * handle,
0610 uint32_t * level)
0611 {
0612
0613 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
0614 {
0615 return ALT_E_ERROR;
0616 }
0617
0618 switch (handle->device)
0619 {
0620 case ALT_16550_DEVICE_SOCFPGA_UART0:
0621 case ALT_16550_DEVICE_SOCFPGA_UART1:
0622
0623 *level = alt_read_word(ALT_UART_TFL_ADDR(handle->location));
0624 break;
0625 case ALT_16550_DEVICE_ALTERA_16550_UART:
0626
0627 *level = 0;
0628 break;
0629 default:
0630 return ALT_E_ERROR;
0631 }
0632
0633 return ALT_E_SUCCESS;
0634 }
0635
0636 ALT_STATUS_CODE alt_16550_fifo_trigger_set_rx(ALT_16550_HANDLE_t * handle,
0637 ALT_16550_FIFO_TRIGGER_RX_t trigger)
0638 {
0639
0640 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
0641 {
0642 return ALT_E_ERROR;
0643 }
0644
0645
0646 switch (trigger)
0647 {
0648 case ALT_16550_FIFO_TRIGGER_RX_ANY:
0649 case ALT_16550_FIFO_TRIGGER_RX_QUARTER_FULL:
0650 case ALT_16550_FIFO_TRIGGER_RX_HALF_FULL:
0651 case ALT_16550_FIFO_TRIGGER_RX_ALMOST_FULL:
0652 break;
0653 default:
0654 return ALT_E_BAD_ARG;
0655 }
0656
0657 switch (handle->device)
0658 {
0659 case ALT_16550_DEVICE_SOCFPGA_UART0:
0660 case ALT_16550_DEVICE_SOCFPGA_UART1:
0661 case ALT_16550_DEVICE_ALTERA_16550_UART:
0662
0663 handle->fcr &= ~ALT_UART_FCR_RT_SET_MSK;
0664 handle->fcr |= ALT_UART_FCR_RT_SET(trigger);
0665 alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr);
0666 break;
0667 default:
0668 return ALT_E_ERROR;
0669 }
0670
0671 return ALT_E_SUCCESS;
0672 }
0673
0674 ALT_STATUS_CODE alt_16550_fifo_trigger_set_tx(ALT_16550_HANDLE_t * handle,
0675 ALT_16550_FIFO_TRIGGER_TX_t trigger)
0676 {
0677
0678 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
0679 {
0680 return ALT_E_ERROR;
0681 }
0682
0683
0684 switch (trigger)
0685 {
0686 case ALT_16550_FIFO_TRIGGER_TX_EMPTY:
0687 case ALT_16550_FIFO_TRIGGER_TX_ALMOST_EMPTY:
0688 case ALT_16550_FIFO_TRIGGER_TX_QUARTER_FULL:
0689 case ALT_16550_FIFO_TRIGGER_TX_HALF_FULL:
0690 break;
0691 default:
0692 return ALT_E_BAD_ARG;
0693 }
0694
0695 switch (handle->device)
0696 {
0697 case ALT_16550_DEVICE_SOCFPGA_UART0:
0698 case ALT_16550_DEVICE_SOCFPGA_UART1:
0699 case ALT_16550_DEVICE_ALTERA_16550_UART:
0700
0701 handle->fcr &= ~ALT_UART_FCR_TET_SET_MSK;
0702 handle->fcr |= ALT_UART_FCR_TET_SET(trigger);
0703 alt_write_word(ALT_UART_FCR_ADDR(handle->location), handle->fcr);
0704 break;
0705 default:
0706 return ALT_E_ERROR;
0707 }
0708
0709 return ALT_E_SUCCESS;
0710 }
0711
0712
0713
0714 ALT_STATUS_CODE alt_16550_baudrate_get(ALT_16550_HANDLE_t * handle,
0715 uint32_t * baudrate)
0716 {
0717
0718 uint32_t divisor = ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(handle->data);
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728 *baudrate = (handle->clock_freq >> 4) / divisor;
0729
0730 return ALT_E_SUCCESS;
0731 }
0732
0733 ALT_STATUS_CODE alt_16550_baudrate_set(ALT_16550_HANDLE_t * handle,
0734 uint32_t baudrate)
0735 {
0736 if (baudrate == 0)
0737 {
0738 return ALT_E_ARG_RANGE;
0739 }
0740
0741
0742
0743
0744
0745
0746
0747
0748 uint32_t divisor = ((handle->clock_freq + (8 * baudrate)) / (16 * baudrate));
0749
0750
0751 return alt_16550_divisor_set(handle, divisor);
0752 }
0753
0754 ALT_STATUS_CODE alt_16550_divisor_get(ALT_16550_HANDLE_t * handle,
0755 uint32_t * divisor)
0756 {
0757
0758 *divisor = ALT_16550_HANDLE_DATA_DIVISOR_VALUE_GET(handle->data);
0759
0760 return ALT_E_SUCCESS;
0761 }
0762
0763 ALT_STATUS_CODE alt_16550_divisor_set(ALT_16550_HANDLE_t * handle,
0764 uint32_t divisor)
0765 {
0766
0767 if ((divisor > 0xffff) || (divisor == 0))
0768 {
0769 return ALT_E_ARG_RANGE;
0770 }
0771
0772
0773 handle->data &= ~(0xffff);
0774 handle->data |= divisor;
0775
0776
0777
0778
0779 return ALT_E_SUCCESS;
0780 }
0781
0782
0783
0784 static ALT_STATUS_CODE alt_16550_ier_mask_set_helper(ALT_16550_HANDLE_t * handle, uint32_t setmask)
0785 {
0786 switch (handle->device)
0787 {
0788 case ALT_16550_DEVICE_SOCFPGA_UART0:
0789 case ALT_16550_DEVICE_SOCFPGA_UART1:
0790 case ALT_16550_DEVICE_ALTERA_16550_UART:
0791
0792 alt_setbits_word(ALT_UART_IER_DLH_ADDR(handle->location), setmask);
0793 break;
0794 default:
0795 return ALT_E_ERROR;
0796 }
0797
0798 return ALT_E_SUCCESS;
0799 }
0800
0801 static ALT_STATUS_CODE alt_16550_ier_mask_clr_helper(ALT_16550_HANDLE_t * handle, uint32_t setmask)
0802 {
0803 switch (handle->device)
0804 {
0805 case ALT_16550_DEVICE_SOCFPGA_UART0:
0806 case ALT_16550_DEVICE_SOCFPGA_UART1:
0807 case ALT_16550_DEVICE_ALTERA_16550_UART:
0808
0809 alt_clrbits_word(ALT_UART_IER_DLH_ADDR(handle->location), setmask);
0810 break;
0811 default:
0812 return ALT_E_ERROR;
0813 }
0814
0815 return ALT_E_SUCCESS;
0816 }
0817
0818 ALT_STATUS_CODE alt_16550_int_enable_rx(ALT_16550_HANDLE_t * handle)
0819 {
0820
0821 return alt_16550_ier_mask_set_helper(handle, ALT_UART_IER_DLH_ERBFI_DLH0_SET_MSK);
0822 }
0823
0824 ALT_STATUS_CODE alt_16550_int_disable_rx(ALT_16550_HANDLE_t * handle)
0825 {
0826
0827 return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_ERBFI_DLH0_SET_MSK);
0828 }
0829
0830 ALT_STATUS_CODE alt_16550_int_enable_tx(ALT_16550_HANDLE_t * handle)
0831 {
0832
0833 return alt_16550_ier_mask_set_helper(handle, ALT_UART_IER_DLH_ETBEI_DLH1_SET_MSK);
0834 }
0835
0836 ALT_STATUS_CODE alt_16550_int_disable_tx(ALT_16550_HANDLE_t * handle)
0837 {
0838
0839 return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_ETBEI_DLH1_SET_MSK);
0840 }
0841
0842 ALT_STATUS_CODE alt_16550_int_enable_line(ALT_16550_HANDLE_t * handle)
0843 {
0844
0845 return alt_16550_ier_mask_set_helper(handle, ALT_UART_IER_DLH_ELSI_DHL2_SET_MSK);
0846 }
0847
0848 ALT_STATUS_CODE alt_16550_int_disable_line(ALT_16550_HANDLE_t * handle)
0849 {
0850
0851 return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_ELSI_DHL2_SET_MSK);
0852 }
0853
0854 ALT_STATUS_CODE alt_16550_int_enable_modem(ALT_16550_HANDLE_t * handle)
0855 {
0856
0857 return alt_16550_ier_mask_set_helper(handle, ALT_UART_IER_DLH_EDSSI_DHL3_SET_MSK);
0858 }
0859
0860 ALT_STATUS_CODE alt_16550_int_disable_modem(ALT_16550_HANDLE_t * handle)
0861 {
0862
0863 return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_EDSSI_DHL3_SET_MSK);
0864 }
0865
0866 ALT_STATUS_CODE alt_16550_int_disable_all(ALT_16550_HANDLE_t * handle)
0867 {
0868
0869
0870
0871
0872
0873 return alt_16550_ier_mask_clr_helper(handle, ALT_UART_IER_DLH_ERBFI_DLH0_SET_MSK |
0874 ALT_UART_IER_DLH_ETBEI_DLH1_SET_MSK |
0875 ALT_UART_IER_DLH_ELSI_DHL2_SET_MSK |
0876 ALT_UART_IER_DLH_EDSSI_DHL3_SET_MSK);
0877 }
0878
0879 ALT_STATUS_CODE alt_16550_int_status_get(ALT_16550_HANDLE_t * handle,
0880 ALT_16550_INT_STATUS_t * status)
0881 {
0882 switch (handle->device)
0883 {
0884 case ALT_16550_DEVICE_SOCFPGA_UART0:
0885 case ALT_16550_DEVICE_SOCFPGA_UART1:
0886 case ALT_16550_DEVICE_ALTERA_16550_UART:
0887
0888 *status = (ALT_16550_INT_STATUS_t) ALT_UART_IIR_ID_GET(alt_read_word(ALT_UART_IIR_ADDR(handle->location)));
0889 break;
0890 default:
0891 return ALT_E_ERROR;
0892 }
0893
0894 return ALT_E_SUCCESS;
0895 }
0896
0897
0898
0899 ALT_STATUS_CODE alt_16550_line_config_set(ALT_16550_HANDLE_t * handle,
0900 ALT_16550_DATABITS_t databits,
0901 ALT_16550_PARITY_t parity,
0902 ALT_16550_STOPBITS_t stopbits)
0903 {
0904
0905 switch (databits)
0906 {
0907 case ALT_16550_DATABITS_5:
0908 case ALT_16550_DATABITS_6:
0909 case ALT_16550_DATABITS_7:
0910 case ALT_16550_DATABITS_8:
0911 break;
0912 default:
0913 return ALT_E_ERROR;
0914 }
0915
0916
0917 switch (parity)
0918 {
0919 case ALT_16550_PARITY_DISABLE:
0920 case ALT_16550_PARITY_ODD:
0921 case ALT_16550_PARITY_EVEN:
0922 break;
0923 default:
0924 return ALT_E_ERROR;
0925 }
0926
0927
0928 switch (stopbits)
0929 {
0930 case ALT_16550_STOPBITS_1:
0931 case ALT_16550_STOPBITS_2:
0932 break;
0933 default:
0934 return ALT_E_ERROR;
0935 }
0936
0937
0938 uint32_t lcr = 0;
0939
0940 switch (handle->device)
0941 {
0942 case ALT_16550_DEVICE_SOCFPGA_UART0:
0943 case ALT_16550_DEVICE_SOCFPGA_UART1:
0944 case ALT_16550_DEVICE_ALTERA_16550_UART:
0945
0946
0947 lcr |= ALT_UART_LCR_DLS_SET(databits);
0948
0949
0950 lcr |= ALT_UART_LCR_STOP_SET(stopbits);
0951
0952
0953 if (parity != ALT_16550_PARITY_DISABLE)
0954 {
0955
0956 lcr |= ALT_UART_LCR_PEN_SET_MSK;
0957
0958 if (parity == ALT_16550_PARITY_EVEN)
0959 {
0960
0961 lcr |= ALT_UART_LCR_EPS_SET_MSK;
0962 }
0963 }
0964
0965
0966 alt_replbits_word(ALT_UART_LCR_ADDR(handle->location),
0967 ALT_UART_LCR_DLS_SET_MSK
0968 | ALT_UART_LCR_STOP_SET_MSK
0969 | ALT_UART_LCR_PEN_SET_MSK
0970 | ALT_UART_LCR_EPS_SET_MSK,
0971 lcr);
0972
0973 break;
0974
0975 default:
0976 return ALT_E_ERROR;
0977 }
0978
0979 return ALT_E_SUCCESS;
0980 }
0981
0982 ALT_STATUS_CODE alt_16550_line_break_enable(ALT_16550_HANDLE_t * handle)
0983 {
0984 switch (handle->device)
0985 {
0986 case ALT_16550_DEVICE_SOCFPGA_UART0:
0987 case ALT_16550_DEVICE_SOCFPGA_UART1:
0988 case ALT_16550_DEVICE_ALTERA_16550_UART:
0989
0990 alt_setbits_word(ALT_UART_LCR_ADDR(handle->location), ALT_UART_LCR_BREAK_SET_MSK);
0991 break;
0992
0993 default:
0994 return ALT_E_ERROR;
0995 }
0996
0997 return ALT_E_SUCCESS;
0998 }
0999
1000 ALT_STATUS_CODE alt_16550_line_break_disable(ALT_16550_HANDLE_t * handle)
1001 {
1002 switch (handle->device)
1003 {
1004 case ALT_16550_DEVICE_SOCFPGA_UART0:
1005 case ALT_16550_DEVICE_SOCFPGA_UART1:
1006 case ALT_16550_DEVICE_ALTERA_16550_UART:
1007
1008 alt_clrbits_word(ALT_UART_LCR_ADDR(handle->location), ALT_UART_LCR_BREAK_SET_MSK);
1009 break;
1010
1011 default:
1012 return ALT_E_ERROR;
1013 }
1014
1015
1016 return ALT_E_SUCCESS;
1017 }
1018
1019 ALT_STATUS_CODE alt_16550_line_status_get(ALT_16550_HANDLE_t * handle,
1020 uint32_t * status)
1021 {
1022 switch (handle->device)
1023 {
1024 case ALT_16550_DEVICE_SOCFPGA_UART0:
1025 case ALT_16550_DEVICE_SOCFPGA_UART1:
1026 case ALT_16550_DEVICE_ALTERA_16550_UART:
1027
1028 *status = alt_read_word(ALT_UART_LSR_ADDR(handle->location));
1029 break;
1030 default:
1031 return ALT_E_ERROR;
1032 }
1033
1034 return ALT_E_SUCCESS;
1035 }
1036
1037
1038
1039 static ALT_STATUS_CODE alt_16550_mcr_mask_set_helper(ALT_16550_HANDLE_t * handle,
1040 uint32_t setmask)
1041 {
1042 switch (handle->device)
1043 {
1044 case ALT_16550_DEVICE_SOCFPGA_UART0:
1045 case ALT_16550_DEVICE_SOCFPGA_UART1:
1046 case ALT_16550_DEVICE_ALTERA_16550_UART:
1047
1048 alt_setbits_word(ALT_UART_MCR_ADDR(handle->location), setmask);
1049 break;
1050 default:
1051 return ALT_E_ERROR;
1052 }
1053
1054 return ALT_E_SUCCESS;
1055 }
1056
1057 static ALT_STATUS_CODE alt_16550_mcr_mask_clr_helper(ALT_16550_HANDLE_t * handle, uint32_t setmask)
1058 {
1059 switch (handle->device)
1060 {
1061 case ALT_16550_DEVICE_SOCFPGA_UART0:
1062 case ALT_16550_DEVICE_SOCFPGA_UART1:
1063 case ALT_16550_DEVICE_ALTERA_16550_UART:
1064
1065 alt_clrbits_word(ALT_UART_MCR_ADDR(handle->location), setmask);
1066 break;
1067 default:
1068 return ALT_E_ERROR;
1069 }
1070
1071 return ALT_E_SUCCESS;
1072 }
1073
1074 ALT_STATUS_CODE alt_16550_flowcontrol_enable(ALT_16550_HANDLE_t * handle)
1075 {
1076
1077 if (!(handle->fcr & ALT_UART_FCR_FIFOE_SET_MSK))
1078 {
1079 return ALT_E_ERROR;
1080 }
1081
1082
1083 if (handle->device == ALT_16550_DEVICE_ALTERA_16550_UART)
1084 {
1085
1086 uint32_t cpr = alt_read_word(ALT_ALTERA_16550_CPR_ADDR(handle->location));
1087 if (!(ALT_ALTERA_16550_CPR_AFCE_MODE_SET_MSK & cpr))
1088 {
1089 return ALT_E_ERROR;
1090 }
1091 }
1092
1093
1094 return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_AFCE_SET_MSK);
1095 }
1096
1097 ALT_STATUS_CODE alt_16550_flowcontrol_disable(ALT_16550_HANDLE_t * handle)
1098 {
1099
1100 return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_AFCE_SET_MSK);
1101 }
1102
1103 ALT_STATUS_CODE alt_16550_loopback_enable(ALT_16550_HANDLE_t * handle)
1104 {
1105
1106 if (handle->device == ALT_16550_DEVICE_ALTERA_16550_UART)
1107 {
1108 return ALT_E_ERROR;
1109 }
1110
1111
1112 return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_LOOPBACK_SET_MSK);
1113 }
1114
1115 ALT_STATUS_CODE alt_16550_loopback_disable(ALT_16550_HANDLE_t * handle)
1116 {
1117
1118 return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_LOOPBACK_SET_MSK);
1119 }
1120
1121 ALT_STATUS_CODE alt_16550_modem_enable_out1(ALT_16550_HANDLE_t * handle)
1122 {
1123
1124 return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_OUT1_SET_MSK);
1125 }
1126
1127 ALT_STATUS_CODE alt_16550_modem_disable_out1(ALT_16550_HANDLE_t * handle)
1128 {
1129
1130 return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_OUT1_SET_MSK);
1131 }
1132
1133 ALT_STATUS_CODE alt_16550_modem_enable_out2(ALT_16550_HANDLE_t * handle)
1134 {
1135
1136 return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_OUT2_SET_MSK);
1137 }
1138
1139 ALT_STATUS_CODE alt_16550_modem_disable_out2(ALT_16550_HANDLE_t * handle)
1140 {
1141
1142 return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_OUT2_SET_MSK);
1143 }
1144
1145 ALT_STATUS_CODE alt_16550_modem_enable_rts(ALT_16550_HANDLE_t * handle)
1146 {
1147
1148 return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_RTS_SET_MSK);
1149 }
1150
1151 ALT_STATUS_CODE alt_16550_modem_disable_rts(ALT_16550_HANDLE_t * handle)
1152 {
1153
1154 return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_RTS_SET_MSK);
1155 }
1156
1157 ALT_STATUS_CODE alt_16550_modem_enable_dtr(ALT_16550_HANDLE_t * handle)
1158 {
1159
1160 return alt_16550_mcr_mask_set_helper(handle, ALT_UART_MCR_DTR_SET_MSK);
1161 }
1162
1163 ALT_STATUS_CODE alt_16550_modem_disable_dtr(ALT_16550_HANDLE_t * handle)
1164 {
1165
1166 return alt_16550_mcr_mask_clr_helper(handle, ALT_UART_MCR_DTR_SET_MSK);
1167 }
1168
1169 ALT_STATUS_CODE alt_16550_modem_status_get(ALT_16550_HANDLE_t * handle,
1170 uint32_t * status)
1171 {
1172 switch (handle->device)
1173 {
1174 case ALT_16550_DEVICE_SOCFPGA_UART0:
1175 case ALT_16550_DEVICE_SOCFPGA_UART1:
1176 case ALT_16550_DEVICE_ALTERA_16550_UART:
1177
1178 *status = alt_read_word(ALT_UART_MSR_ADDR(handle->location));
1179 break;
1180 default:
1181 return ALT_E_ERROR;
1182 }
1183
1184 return ALT_E_SUCCESS;
1185 }