⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 altera_avalon_uart_init.c

📁 用v-hdl写的基于fpga的串口驱动程序希望对大家有帮助
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*                                                                             *
* License Agreement                                                           *
*                                                                             *
* Copyright (c) 2006 Altera Corporation, San Jose, California, USA.           *
* All rights reserved.                                                        *
*                                                                             *
* Permission is hereby granted, free of charge, to any person obtaining a     *
* copy of this software and associated documentation files (the "Software"),  *
* to deal in the Software without restriction, including without limitation   *
* the rights to use, copy, modify, merge, publish, distribute, sublicense,    *
* and/or sell copies of the Software, and to permit persons to whom the       *
* Software is furnished to do so, subject to the following conditions:        *
*                                                                             *
* The above copyright notice and this permission notice shall be included in  *
* all copies or substantial portions of the Software.                         *
*                                                                             *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         *
* DEALINGS IN THE SOFTWARE.                                                   *
*                                                                             *
* This agreement shall be governed in all respects by the laws of the State   *
* of California and by the laws of the United States of America.              *
*                                                                             *
******************************************************************************/

#include <fcntl.h>

#include "sys/alt_dev.h"
#include "sys/alt_irq.h"
#include "sys/ioctl.h"
#include "sys/alt_errno.h"

#include "altera_avalon_uart.h"
#include "altera_avalon_uart_regs.h"

/*software FSM(finite state machine)*/

/*function pointer array*/


#define _start 0x7e
#define _end   0x7d

unsigned char length;
unsigned char commond;
unsigned char data[20];
unsigned char verify;
unsigned char rd_buffer;
unsigned char state=1;
unsigned char length2;

unsigned char   write_ok[]={0x7e,0x01,0x01,0x02,0x7d};
unsigned char write_fail[]={0x7e,0x01,0x02,0x03,0x7d};

/*state:1*/
int  s_syn(altera_avalon_uart_state* sp)
{
length=0;
commond=0;
data[20];
verify=0;
length2=0;
altera_avalon_uart_read2(sp,&rd_buffer,1);
if (rd_buffer==_start)
   {state=2;}
else
   {state=1;}
}

/*state:2*/
int  s_len(altera_avalon_uart_state* sp)

{
if(altera_avalon_uart_read2(sp,&rd_buffer,1)==1)
 {
  length=rd_buffer;
  verify=rd_buffer;
  state=3;
 }
 else
 {
 return;
 }
}

/*state:3*/
int  s_data(altera_avalon_uart_state* sp)
{
 if (length2<length)
  {
   altera_avalon_uart_read2(sp,&rd_buffer,1);
   verify+=rd_buffer;
   data[length2]=rd_buffer;
   length2++;
  }
 else
  {
  state=4;
  }
}

/*state:4*/
int  s_verify(altera_avalon_uart_state* sp)
{
  altera_avalon_uart_read2(sp,&rd_buffer,1);
  if(rd_buffer==verify)
   {state=5;}
  else
   {state=1;}
}

/*state:5*/
int  s_end(altera_avalon_uart_state* sp)
{
  altera_avalon_uart_read2(sp,&rd_buffer,1);
  if(rd_buffer==_end)
    {state=6;}
  else
    {state=7;}
}

/*state:6*/
int  s_modify_fifo(altera_avalon_uart_state* sp)
{
  int i,next;
  next=(sp->fifo_end+1)&protocol_buf_depth_mask;
  if(next == sp->fifo_start) /*fifo buf is full*/
   {state=1;}
  else
   {
    sp->fifo[sp->tx_end][0]=length;
    for(i=1;i<=length;i++)
        {
         sp->fifo[sp->tx_end][i]=data[i];
        }
    sp->fifo_end = next;
   }
  state=1;


}

/*state:7*/
int  s_retx(altera_avalon_uart_state* sp)
{
  altera_avalon_uart_write2(sp,&write_fail,5);
  state=1;
}

int (*fsm[7])(altera_avalon_uart_state*)={s_syn,s_len,s_data,s_verify,s_end,s_modify_fifo,s_retx};
//fsm[0]={s_syn,s_len(sp),s_data(sp),s_verify(sp),s_end(sp),s_modify_fifo(sp),s_retx(sp)};

//int s_syn(altera_avalon_uart_state*);
//int s_len(altera_avalon_uart_state*);
//int s_data(altera_avalon_uart_state*);
//int s_verify(altera_avalon_uart_state*);
//int s_end(altera_avalon_uart_state*);
//int s_modify_fifo(altera_avalon_uart_state*);
//int s_retx(altera_avalon_uart_state*);


/*define the protocol start and end word*/




/*used to count the commond and the data byte readed*/


unsigned int prl_com;
unsigned int newduanzu;

int 
altera_avalon_uart_read2(altera_avalon_uart_state* sp, char* ptr, int len)
{
  alt_irq_context context;
  int             block;
  alt_u32         next;

  int count                = 0;

  /* 
   * Construct a flag to indicate whether the device is being accessed in
   * blocking or non-blocking mode.
   */

  /*block = !(flags & O_NONBLOCK);*/
  block =1;

  /*
   * When running in a multi threaded environment, obtain the "read_lock"
   * semaphore. This ensures that reading from the device is thread-safe.
   */

  ALT_SEM_PEND (sp->read_lock, 0);

  /*
   * Calculate which slot in the circular buffer is the next one to read
   * data from.
   */

  next = (sp->rx_start + 1) & ALT_AVALON_UART_BUF_MSK;

  /*
   * Loop, copying data from the circular buffer to the destination address
   * supplied in "ptr". This loop is terminated when the required number of
   * bytes have been read. If the circular buffer is empty, and no data has
   * been read, then the loop will block (when in blocking mode).
   *
   * If the circular buffer is empty, and some data has already been 
   * transferred, or the device is being accessed in non-blocking mode, then
   * the loop terminates without necessarily reading all the requested data.
   */

//  do
//  {
    /*
     * Read the required amount of data, until the circular buffer runs
     * empty
     */

    while ((count < len) && (sp->rx_start != sp->rx_end))
    {
      count++;
      *ptr++ = sp->rx_buf[sp->rx_start];
      
      sp->rx_start = (++sp->rx_start) & ALT_AVALON_UART_BUF_MSK;
    }

    /*
     * If no data has been transferred, the circular buffer is empty, and
     * this is not a non-blocking access, block waiting for data to arrive.
     */

    if (!count && (sp->rx_start == sp->rx_end))
    {
      if (!block)
      {
        /* Set errno to indicate the reason we're not returning any data */

        ALT_ERRNO = EWOULDBLOCK;
  //      break;
      }
      else
      {
       /* Block waiting for some data to arrive */

       /* First, ensure read interrupts are enabled to avoid deadlock */

       context = alt_irq_disable_all ();
       sp->ctrl |= ALTERA_AVALON_UART_CONTROL_RRDY_MSK;
       IOWR_ALTERA_AVALON_UART_CONTROL(sp->base, sp->ctrl);
       alt_irq_enable_all (context);

       /*
        * When running in a multi-threaded mode, we pend on the read event 
        * flag set in the interrupt service routine. This avoids wasting CPU
        * cycles waiting in this thread, when we could be doing something more 
        * profitable elsewhere.
        */

       ALT_FLAG_PEND (sp->events, 
                      ALT_UART_READ_RDY,
                      OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME,
                      0);
      }
    }
//  }
//  while (!count && len);

  /*
   * Now that access to the circular buffer is complete, release the read
   * semaphore so that other threads can access the buffer.
   */

  ALT_SEM_POST (sp->read_lock);

  /*
   * Ensure that interrupts are enabled, so that the circular buffer can
   * re-fill.
   */

  context = alt_irq_disable_all ();
  sp->ctrl |= ALTERA_AVALON_UART_CONTROL_RRDY_MSK;
  IOWR_ALTERA_AVALON_UART_CONTROL(sp->base, sp->ctrl);
  alt_irq_enable_all (context);

  /* Return the number of bytes read */

  return count;
}



int
altera_avalon_uart_write2(altera_avalon_uart_state* sp, const char* ptr, int len)
{
  alt_irq_context context;
  int             no_block;
  alt_u32         next;
  int             count = len;

  /* 
   * Construct a flag to indicate whether the device is being accessed in
   * blocking or non-blocking mode.
   */

  /*no_block = (flags & O_NONBLOCK);*/

  no_block =0;

  /*
   * When running in a multi threaded environment, obtain the "write_lock"
   * semaphore. This ensures that writing to the device is thread-safe.
   */

  ALT_SEM_PEND (sp->write_lock, 0);

  /*
   * Loop transferring data from the input buffer to the transmit circular
   * buffer. The loop is terminated once all the data has been transferred,
   * or, (if in non-blocking mode) the buffer becomes full.
   */

  while (count)
  {
    /* Determine the next slot in the buffer to access */

    next = (sp->tx_end + 1) & ALT_AVALON_UART_BUF_MSK;

    /* block waiting for space if necessary */

    if (next == sp->tx_start)
    {
      if (no_block)
      {
        /* Set errno to indicate why this function returned early */
 
        ALT_ERRNO = EWOULDBLOCK;
        break;
      }
      else
      {
        /* Block waiting for space in the circular buffer */

        /* First, ensure transmit interrupts are enabled to avoid deadlock */

        context = alt_irq_disable_all ();
        sp->ctrl |= (ALTERA_AVALON_UART_CONTROL_TRDY_MSK |
                        ALTERA_AVALON_UART_CONTROL_DCTS_MSK);
        IOWR_ALTERA_AVALON_UART_CONTROL(sp->base, sp->ctrl);
        alt_irq_enable_all (context);

        /* wait for space to come free */

        do
        {
          /*
           * When running in a multi-threaded mode, we pend on the write event 
           * flag set in the interrupt service routine. This avoids wasting CPU
           * cycles waiting in this thread, when we could be doing something
           * more profitable elsewhere.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -