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);
}
Beispiel #4
0
static void set_baudrate(unsigned int baudrate)
{
    IOWR_ALTERA_AVALON_UART_DIVISOR(RS232_BASE,
                                    (unsigned int)(ALT_CPU_FREQ/baudrate+0.5) );
}
Beispiel #5
0
// 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)