File indexing completed on 2025-05-11 08:22:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <bsp.h>
0021 #include <rtems/libio.h>
0022 #include <termios.h>
0023
0024 #include <at91rm9200.h>
0025 #include <at91rm9200_usart.h>
0026 #include <at91rm9200_pmc.h>
0027 #include <rtems/bspIo.h>
0028 #include <libchip/serial.h>
0029 #include <libchip/sersupp.h>
0030
0031
0032 static int usart_first_open(int major, int minor, void *arg);
0033 static int usart_last_close(int major, int minor, void *arg);
0034 static int usart_read_polled(int minor);
0035 static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len);
0036 static void usart_init(int minor);
0037 static void usart_write_polled(int minor, char c);
0038 static int usart_set_attributes(int minor, const struct termios *t);
0039 at91rm9200_usart_regs_t *usart_get_base(int minor);
0040
0041
0042 const console_fns usart_polling_fns = {
0043 libchip_serial_default_probe,
0044 usart_first_open,
0045 usart_last_close,
0046 usart_read_polled,
0047 usart_write_polled_support,
0048 usart_init,
0049 usart_write_polled,
0050 usart_set_attributes,
0051 FALSE
0052 };
0053
0054 at91rm9200_usart_regs_t *usart_get_base(int minor)
0055 {
0056 console_tbl *console_entry;
0057 at91rm9200_usart_regs_t *port;
0058
0059 console_entry = BSP_get_uart_from_minor(minor);
0060
0061 if (console_entry == NULL)
0062 return 0;
0063
0064 port = (at91rm9200_usart_regs_t *) console_entry->ulCtrlPort1;
0065
0066
0067 return port;
0068 }
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 static int usart_first_open(int major, int minor, void *arg)
0080 {
0081 at91rm9200_usart_regs_t *usart;
0082
0083 usart = usart_get_base(minor);
0084 if ( !usart )
0085 return -1;
0086
0087
0088
0089
0090 usart->cr = (US_CR_RXEN | US_CR_TXEN);
0091 return 0;
0092 }
0093
0094
0095
0096
0097
0098
0099 static int usart_last_close(int major, int minor, void *arg)
0100 {
0101 at91rm9200_usart_regs_t *usart;
0102
0103 usart = usart_get_base(minor);
0104 if ( !usart )
0105 return -1;
0106
0107 return 0;
0108 }
0109
0110
0111
0112
0113
0114
0115
0116 static int usart_read_polled(int minor)
0117 {
0118 at91rm9200_usart_regs_t *usart;
0119
0120 usart = usart_get_base(minor);
0121 if ( !usart )
0122 return -1;
0123
0124
0125 if ( (usart->sr & US_IER_RXRDY) == 0 )
0126 return -1;
0127
0128 return usart->rhr;
0129 }
0130
0131
0132
0133
0134
0135 static void usart_write_polled(int minor, char c)
0136 {
0137 at91rm9200_usart_regs_t *usart;
0138
0139 usart = usart_get_base(minor);
0140 if ( !usart )
0141 return;
0142
0143
0144 while ( (usart->sr & US_IER_TXEMPTY) == 0 )
0145 ;
0146
0147 usart->thr = c;
0148 }
0149
0150
0151
0152
0153
0154
0155 static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len)
0156 {
0157 at91rm9200_usart_regs_t *usart;
0158 int nwrite=0;
0159
0160
0161
0162
0163 usart = usart_get_base(minor);
0164 if ( !usart )
0165 return -1;
0166
0167
0168
0169
0170 while (nwrite < len) {
0171 usart_write_polled(minor, *buf++);
0172 nwrite++;
0173 }
0174
0175
0176
0177
0178 return nwrite;
0179
0180 return 1;
0181 }
0182
0183
0184
0185 static void usart_init(int minor)
0186 {
0187 at91rm9200_usart_regs_t *usart;
0188
0189 usart = usart_get_base(minor);
0190 if ( !usart )
0191 return;
0192
0193 }
0194
0195
0196
0197 static int usart_set_attributes(int minor, const struct termios *t)
0198 {
0199 uint32_t brgr;
0200 uint32_t mode, baud, baud_requested;
0201 at91rm9200_usart_regs_t *usart;
0202
0203 usart = usart_get_base(minor);
0204 if ( !usart )
0205 return -1;
0206
0207
0208 mode = usart->mr & ~(US_MR_USMODE | US_MR_USCLKS | US_MR_CHRL
0209 | US_MR_PAR | US_MR_NBSTOP);
0210
0211
0212 switch (t->c_cflag & CSIZE){
0213 case CS5:
0214 mode |= US_MR_CHRL_5;
0215 break;
0216 case CS6:
0217 mode |= US_MR_CHRL_6;
0218 break;
0219 case CS7:
0220 mode |= US_MR_CHRL_7;
0221 break;
0222 default:
0223 mode |= US_MR_CHRL_8;
0224 break;
0225 }
0226
0227
0228 if (t->c_cflag & CSTOPB){
0229 mode |= US_MR_NBSTOP_2;
0230 } else
0231 mode |= US_MR_NBSTOP_1;
0232
0233
0234 if (t->c_cflag & PARENB){
0235
0236 if (t->c_cflag & PARODD){
0237 mode |= US_MR_PAR_ODD;
0238 } else
0239 mode |= US_MR_PAR_EVEN;
0240 } else
0241 mode |= US_MR_PAR_NONE;
0242
0243 baud_requested = t->c_ospeed;
0244
0245
0246 if (!baud_requested)
0247 baud_requested = BSP_get_baud();
0248
0249 baud = rtems_termios_baud_to_number(baud_requested);
0250
0251 brgr = (at91rm9200_get_mck() / 16) / baud;
0252
0253 if (brgr > 65535){
0254 brgr /= 8;
0255 mode |= US_MR_USCLKS_MCK_DIV8;
0256 }
0257
0258 usart->mr = mode;
0259 usart->brgr = brgr;
0260 return 0;
0261 }