static int altera_avalon_uart_tiocmset(altera_avalon_uart_state* sp, struct termios* term) { speed_t speed; speed = sp->termios.c_ispeed; /* Update the settings if the hardware supports it */ if (!(sp->flags & ALT_AVALON_UART_FB)) { sp->termios.c_ispeed = sp->termios.c_ospeed = term->c_ispeed; } /* * If the request was for an unsupported setting, return an error. */ if (memcmp(term, &sp->termios, sizeof (struct termios))) { sp->termios.c_ispeed = sp->termios.c_ospeed = speed; return -EIO; } /* * Otherwise, update the hardware. */ IOWR_ALTERA_AVALON_UART_DIVISOR(sp->base, ((sp->freq/sp->termios.c_ispeed) - 1)); return 0; }
static bool altera_avalon_uart_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) { altera_avalon_uart_dev *uart_chan = (altera_avalon_uart_dev *)chan->dev_priv; /* * There's no software control over the number of stop bits, parity or word * length, so make sure it's not these that we're attempting to change. */ if ((new_config->stop != chan->config.stop) || (new_config->parity != chan->config.parity) || (new_config->word_length != chan->config.word_length)) { return false; } /* * Changing the Baud rate is only possible if the hardware has been * configured to support it. */ if ((uart_chan->flags & ALT_AVALON_UART_FB) && (new_config->baud != chan->config.baud)) { return false; } /* * Similarly we can only change the CTS/RTS settings if there's support for * hardware flow control - and even in that case case, we can only change the * transmit, not the receive behaviour. */ if ((!(uart_chan->flags & ALT_AVALON_UART_FC) && (new_config->flags != chan->config.flags)) || ((new_config->flags & ~CYGNUM_SERIAL_FLOW_RTSCTS_TX) != (chan->config.flags & ~CYGNUM_SERIAL_FLOW_RTSCTS_TX))) { return false; } /* * Given that the request is good, update the hardware and the status in * software. */ IOWR_ALTERA_AVALON_UART_DIVISOR(uart_chan->base, ((uart_chan->freq/altera_avalon_uart_speed[new_config->baud - 1]) - 1)); if (&chan->config != new_config) { chan->config = *new_config; } return true; }
/** * Initiating UART Core with: * 115200 Baudrate * refer to /documentation/n2cpu_nii51010.pdf for more info */ void diverInitUART(int baud) { //Each Bit in the control register enables an IRQ for a corresponding bit in the status register. int control = ALTERA_AVALON_UART_CONTROL_RRDY_MSK | //enable Read Interrupts ALTERA_AVALON_UART_CONTROL_E_MSK; //enable Exceptions for each Interrupt IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, control); //write contorl bitmask in the control register IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0x00); //writing 0 in the status Register clears the dcts,e,toe,roe,brk,fe, and pe bits //writing up the Baudrate-divisor //setting Baudrate-divisor: div = clk / desired Baudrate + 0,5 int divisor = (int) (50000000 / baud + 0.5); //div will be 434 IOWR_ALTERA_AVALON_UART_DIVISOR(UART_0_BASE, divisor); //install IRQ service routine alt_irq_register(UART_0_IRQ, 0, (alt_isr_func) ISRUART); alt_irq_enable(UART_0_IRQ); }
static void set_baudrate(unsigned int baudrate) { IOWR_ALTERA_AVALON_UART_DIVISOR(RS232_BASE, (unsigned int)(ALT_CPU_FREQ/baudrate+0.5) ); }
// Entry point int main() { struct uart_pkt { unsigned char magic; #define UART_PKT_MAGIC 'N' // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | // | dir | dev | cnt | unsigned char mode; #define UART_PKT_MODE_CNT_MASK 0xF #define UART_PKT_MODE_CNT_SHIFT 0 #define UART_PKT_MODE_DEV_MASK 0x30 #define UART_PKT_MODE_DEV_SHIFT 4 #define UART_PKT_DEV_GPIO (0<<UART_PKT_MODE_DEV_SHIFT) #define UART_PKT_DEV_LMS (1<<UART_PKT_MODE_DEV_SHIFT) #define UART_PKT_DEV_VCTCXO (2<<UART_PKT_MODE_DEV_SHIFT) #define UART_PKT_DEV_SI5338 (3<<UART_PKT_MODE_DEV_SHIFT) #define UART_PKT_MODE_DIR_MASK 0xC0 #define UART_PKT_MODE_DIR_SHIFT 6 #define UART_PKT_MODE_DIR_READ (2<<UART_PKT_MODE_DIR_SHIFT) #define UART_PKT_MODE_DIR_WRITE (1<<UART_PKT_MODE_DIR_SHIFT) }; struct uart_cmd { unsigned char addr; unsigned char data; }; // Set the prescaler for 400kHz with an 80MHz clock (prescaer = clock / (5*desired) - 1) IOWR_16DIRECT(I2C, OC_I2C_PRESCALER, 39 ) ; IOWR_8DIRECT(I2C, OC_I2C_CTRL, OC_I2C_ENABLE ) ; // Set the UART divisor to 14 to get 4000000bps UART (baud rate = clock/(divisor + 1)) IOWR_ALTERA_AVALON_UART_DIVISOR(UART_0_BASE, 19) ; // Set the IQ Correction parameters to 0 IOWR_ALTERA_AVALON_PIO_DATA(IQ_CORR_RX_PHASE_GAIN_BASE, DEFAULT_CORRECTION); IOWR_ALTERA_AVALON_PIO_DATA(IQ_CORR_TX_PHASE_GAIN_BASE, DEFAULT_CORRECTION); /* Event loop never exits. */ { char state; enum { LOOKING_FOR_MAGIC, READING_MODE, READING_CMDS, EXECUTE_CMDS }; unsigned short i, cnt; unsigned char mode; unsigned char buf[14]; struct uart_cmd *cmd_ptr; uint16_t dacval; state = LOOKING_FOR_MAGIC; while(1) { // Check if anything is in the FSK UART if( IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE) & ALTERA_AVALON_UART_STATUS_RRDY_MSK ) { uint8_t val ; val = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE) ; switch (state) { case LOOKING_FOR_MAGIC: if (val == UART_PKT_MAGIC) state = READING_MODE; break; case READING_MODE: mode = val; if ((mode & UART_PKT_MODE_CNT_MASK) > 7) { mode &= ~UART_PKT_MODE_CNT_MASK; mode |= 7; } i = 0; cnt = (mode & UART_PKT_MODE_CNT_MASK) * sizeof(struct uart_cmd); state = READING_CMDS; break; case READING_CMDS: // cnt here means the number of bytes to read buf[i++] = val; if (!--cnt) state = EXECUTE_CMDS; break; default: break; } void write_uart(unsigned char val) { while (!(IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE) & ALTERA_AVALON_UART_STATUS_TRDY_MSK)); IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE, val); } if (state == EXECUTE_CMDS) { write_uart(UART_PKT_MAGIC); write_uart(mode); // cnt here means the number of commands cnt = (mode & UART_PKT_MODE_CNT_MASK); cmd_ptr = (struct uart_cmd *)buf; if ((mode & UART_PKT_MODE_DEV_MASK) == UART_PKT_DEV_LMS) { for (i = 0; i < cnt; i++) { if ((mode & UART_PKT_MODE_DIR_MASK) == UART_PKT_MODE_DIR_READ) { lms_spi_read(cmd_ptr->addr, &cmd_ptr->data); } else if ((mode & UART_PKT_MODE_DIR_MASK) == UART_PKT_MODE_DIR_WRITE) { lms_spi_write(cmd_ptr->addr, cmd_ptr->data); cmd_ptr->data = 0; } else { cmd_ptr->addr = 0; cmd_ptr->data = 0; } cmd_ptr++; } } if ((mode & UART_PKT_MODE_DEV_MASK) == UART_PKT_DEV_SI5338) { for (i = 0; i < cnt; i++) { if ((mode & UART_PKT_MODE_DIR_MASK) == UART_PKT_MODE_DIR_READ) { uint8_t tmpvar; si5338_read(cmd_ptr->addr, &tmpvar); cmd_ptr->data = tmpvar; } else if ((mode & UART_PKT_MODE_DIR_MASK) == UART_PKT_MODE_DIR_WRITE) { si5338_write(cmd_ptr->addr, cmd_ptr->data); cmd_ptr->data = 0; } else { cmd_ptr->addr = 0; cmd_ptr->data = 0; } cmd_ptr++; } } if ((mode & UART_PKT_MODE_DEV_MASK) == UART_PKT_DEV_GPIO) { uint32_t device; switch(cmd_ptr->addr) { case 0:case 1:case 2: case 3: device = PIO_0_BASE;break; case 4: case 5: case 6: case 7: device = IQ_CORR_RX_PHASE_GAIN_BASE; cmd_ptr->addr -= 4; break; case 8: case 9: case 10: case 11: device = IQ_CORR_TX_PHASE_GAIN_BASE; cmd_ptr->addr -= 8; break; case 12: case 13: case 14: case 15: device = FPGA_VERSION_ID; cmd_ptr->addr -= 12; break; default: //error device = PIO_0_BASE; } if ((mode & UART_PKT_MODE_DIR_MASK) == UART_PKT_MODE_DIR_READ) { if (device == FPGA_VERSION_ID) { cmd_ptr->data = (FPGA_VERSION >> (cmd_ptr->addr * 8)); } else { cmd_ptr->data = (IORD_ALTERA_AVALON_PIO_DATA(device)) >> (cmd_ptr->addr * 8); } } else if ((mode & UART_PKT_MODE_DIR_MASK) == UART_PKT_MODE_DIR_WRITE) {
// Entry point int main() { struct uart_pkt { unsigned char magic; #define UART_PKT_MAGIC 'N' // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | // | dir | dev | cnt | unsigned char mode; #define UART_PKT_MODE_CNT_MASK 0xF #define UART_PKT_MODE_CNT_SHIFT 0 #define UART_PKT_MODE_DEV_MASK 0x30 #define UART_PKT_MODE_DEV_SHIFT 4 #define UART_PKT_DEV_GPIO (0<<UART_PKT_MODE_DEV_SHIFT) #define UART_PKT_DEV_LMS (1<<UART_PKT_MODE_DEV_SHIFT) #define UART_PKT_DEV_VCTCXO (2<<UART_PKT_MODE_DEV_SHIFT) #define UART_PKT_DEV_SI5338 (3<<UART_PKT_MODE_DEV_SHIFT) #define UART_PKT_MODE_DIR_MASK 0xC0 #define UART_PKT_MODE_DIR_SHIFT 6 #define UART_PKT_MODE_DIR_READ (2<<UART_PKT_MODE_DIR_SHIFT) #define UART_PKT_MODE_DIR_WRITE (1<<UART_PKT_MODE_DIR_SHIFT) }; struct uart_cmd { unsigned char addr; unsigned char data; }; // Set the prescaler for 400kHz with an 80MHz clock (prescaer = clock / (5*desired) - 1) IOWR_16DIRECT(I2C, OC_I2C_PRESCALER, 39 ) ; IOWR_8DIRECT(I2C, OC_I2C_CTRL, OC_I2C_ENABLE ) ; // Set the UART divisor to 14 to get 4000000bps UART (baud rate = clock/(divisor + 1)) IOWR_ALTERA_AVALON_UART_DIVISOR(UART_0_BASE, 19) ; // Set the IQ Correction parameters to 0 IOWR_ALTERA_AVALON_PIO_DATA(IQ_CORR_RX_PHASE_GAIN_BASE, DEFAULT_CORRECTION); IOWR_ALTERA_AVALON_PIO_DATA(IQ_CORR_TX_PHASE_GAIN_BASE, DEFAULT_CORRECTION); /* Event loop never exits. */ { char state; enum { LOOKING_FOR_MAGIC, READING_MODE, READING_CMDS, EXECUTE_CMDS }; unsigned short i, cnt; unsigned char mode; unsigned char buf[14]; struct uart_cmd *cmd_ptr; uint32_t tmpvar = 0; state = LOOKING_FOR_MAGIC; while(1) { // Check if anything is in the FSK UART if( IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE) & ALTERA_AVALON_UART_STATUS_RRDY_MSK ) { uint8_t val ; int isRead; int isWrite; val = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE) ; switch (state) { case LOOKING_FOR_MAGIC: if (val == UART_PKT_MAGIC) state = READING_MODE; break; case READING_MODE: mode = val; if ((mode & UART_PKT_MODE_CNT_MASK) > 7) { mode &= ~UART_PKT_MODE_CNT_MASK; mode |= 7; } i = 0; cnt = (mode & UART_PKT_MODE_CNT_MASK) * sizeof(struct uart_cmd); state = READING_CMDS; break; case READING_CMDS: // cnt here means the number of bytes to read buf[i++] = val; if (!--cnt) state = EXECUTE_CMDS; break; default: break; } void write_uart(unsigned char val) { while (!(IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE) & ALTERA_AVALON_UART_STATUS_TRDY_MSK)); IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE, val); } isRead = (mode & UART_PKT_MODE_DIR_MASK) == UART_PKT_MODE_DIR_READ; isWrite = (mode & UART_PKT_MODE_DIR_MASK) == UART_PKT_MODE_DIR_WRITE; if (state == EXECUTE_CMDS) { write_uart(UART_PKT_MAGIC); write_uart(mode); // cnt here means the number of commands cnt = (mode & UART_PKT_MODE_CNT_MASK); cmd_ptr = (struct uart_cmd *)buf; if ((mode & UART_PKT_MODE_DEV_MASK) == UART_PKT_DEV_LMS) { for (i = 0; i < cnt; i++) { if (isRead) { lms_spi_read(cmd_ptr->addr, &cmd_ptr->data); } else if (isWrite) { lms_spi_write(cmd_ptr->addr, cmd_ptr->data); cmd_ptr->data = 0; } else { cmd_ptr->addr = 0; cmd_ptr->data = 0; } cmd_ptr++; } } if ((mode & UART_PKT_MODE_DEV_MASK) == UART_PKT_DEV_SI5338) { for (i = 0; i < cnt; i++) { if (isRead) { uint8_t tmpvar; si5338_read(cmd_ptr->addr, &tmpvar); cmd_ptr->data = tmpvar; } else if (isWrite) { si5338_write(cmd_ptr->addr, cmd_ptr->data); cmd_ptr->data = 0; } else { cmd_ptr->addr = 0; cmd_ptr->data = 0; } cmd_ptr++; } } const struct { enum { GDEV_UNKNOWN, GDEV_GPIO, GDEV_IQ_CORR_RX, GDEV_IQ_CORR_TX, GDEV_FPGA_VERSION, GDEV_TIME_TIMER, GDEV_VCTXCO, GDEV_XB_LO, GDEV_EXPANSION, GDEV_EXPANSION_DIR, } gdev; int start, len; } gdev_lut[] = { {GDEV_GPIO, 0, 4}, {GDEV_IQ_CORR_RX, 4, 4}, {GDEV_IQ_CORR_TX, 8, 4}, {GDEV_FPGA_VERSION, 12, 4}, {GDEV_TIME_TIMER, 16, 16}, {GDEV_VCTXCO, 34, 2}, {GDEV_XB_LO, 36, 4}, {GDEV_EXPANSION, 40, 4}, {GDEV_EXPANSION_DIR, 44, 4}, }; #define ARRAY_SZ(x) (sizeof(x)/sizeof(x[0])) #define COLLECT_BYTES(x) tmpvar &= ~ ( 0xff << ( 8 * cmd_ptr->addr)); \ tmpvar |= cmd_ptr->data << (8 * cmd_ptr->addr); \ if (lastByte) { x; tmpvar = 0; } \ cmd_ptr->data = 0; if ((mode & UART_PKT_MODE_DEV_MASK) == UART_PKT_DEV_GPIO) { uint32_t device; int lut, lastByte; for (i = 0; i < cnt; i++) { device = GDEV_UNKNOWN; lastByte = 0; for (lut = 0; lut < ARRAY_SZ(gdev_lut); lut++) { if (gdev_lut[lut].start <= cmd_ptr->addr && (gdev_lut[lut].start + gdev_lut[lut].len) > cmd_ptr->addr) { cmd_ptr->addr -= gdev_lut[lut].start; device = gdev_lut[lut].gdev; lastByte = cmd_ptr->addr == (gdev_lut[lut].len - 1); break; } } if (isRead) { if (device == GDEV_FPGA_VERSION) cmd_ptr->data = (FPGA_VERSION >> (cmd_ptr->addr * 8)); else if (device == GDEV_TIME_TIMER) cmd_ptr->data = IORD_8DIRECT(TIME_TAMER, cmd_ptr->addr); else if (device == GDEV_GPIO) cmd_ptr->data = (IORD_ALTERA_AVALON_PIO_DATA(PIO_0_BASE)) >> (cmd_ptr->addr * 8); else if (device == GDEV_EXPANSION) cmd_ptr->data = (IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE)) >> (cmd_ptr->addr * 8); else if (device == GDEV_EXPANSION_DIR) cmd_ptr->data = (IORD_ALTERA_AVALON_PIO_DATA(PIO_2_BASE)) >> (cmd_ptr->addr * 8); else if (device == GDEV_IQ_CORR_RX) cmd_ptr->data = (IORD_ALTERA_AVALON_PIO_DATA(IQ_CORR_RX_PHASE_GAIN_BASE)) >> (cmd_ptr->addr * 8); else if (device == GDEV_IQ_CORR_TX)