• 【1213工作日志】ZYNQ的中断应用


    /*
     * main.c
     *
     *  Created on: 2018年12月3日
     *      Author: xizi.cheng
     */

    /*
     * main.c
     *
     *  Created on: 2018年10月7日
     *      Author: xizi.cheng
     */
    /*
     * main.c
     *
     *  Created on: 2018年9月27日
     *      Author: xizi.cheng
     */
    /*
     * main.c
     *
     *  Created on: 2016年11月12日
     *      Author: Administrator
     */
    #include <stdio.h>
    #include "xparameters.h"
    #include "xil_io.h"
    #include "sleep.h"
    #include "xil_types.h"
    #include "xscugic.h"
    #include "xil_exception.h"
    #define BASE_ADDR 0x43c00000
    //int rec_data;
    #define INT_CFG0_OFFSET 0x00000C00
    // Parameter definitions
    #define SW1_INT_ID              61
    #define SW2_INT_ID              62
    #define SW3_INT_ID              63
    #define INTC_DEVICE_ID          XPAR_PS7_SCUGIC_0_DEVICE_ID
    #define INT_TYPE_RISING_EDGE    0x03
    #define INT_TYPE_HIGHLEVEL      0x01
    #define INT_TYPE_MASK           0x03
    static XScuGic INTCInst;
    static void SW_intr_Handler(void *param);
    static int IntcInitFunction(u16 DeviceId);
    static void SW_intr_Handler(void *param)
    {
        int sw_id = (int)param;
        printf("SW%d int ", sw_id);
     Get_msg();
    }
    void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType)
    {
        int mask;
        intType &= INT_TYPE_MASK;
        mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);
        mask &= ~(INT_TYPE_MASK << (intId%16)*2);
        mask |= intType << ((intId%16)*2);
        XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);
    }
    int IntcInitFunction(u16 DeviceId)
    {
        XScuGic_Config *IntcConfig;
        int status;
        // Interrupt controller initialisation
        IntcConfig = XScuGic_LookupConfig(DeviceId);
        status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
        if(status != XST_SUCCESS) return XST_FAILURE;
        // Call to interrupt setup
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                                     (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                     &INTCInst);
        Xil_ExceptionEnable();
        // Connect SW1~SW3 interrupt to handler
        status = XScuGic_Connect(&INTCInst,
                                 SW1_INT_ID,
                                 (Xil_ExceptionHandler)SW_intr_Handler,
                                 (void *)1);
        if(status != XST_SUCCESS) return XST_FAILURE;
        status = XScuGic_Connect(&INTCInst,
                                 SW2_INT_ID,
                                 (Xil_ExceptionHandler)SW_intr_Handler,
                                 (void *)2);
        if(status != XST_SUCCESS) return XST_FAILURE;
        status = XScuGic_Connect(&INTCInst,
                                 SW3_INT_ID,
                                 (Xil_ExceptionHandler)SW_intr_Handler,
                                 (void *)3);
        if(status != XST_SUCCESS) return XST_FAILURE;
        // Set interrupt type of SW1~SW3 to rising edge
        IntcTypeSetup(&INTCInst, SW1_INT_ID, INT_TYPE_RISING_EDGE);
        IntcTypeSetup(&INTCInst, SW2_INT_ID, INT_TYPE_RISING_EDGE);
        IntcTypeSetup(&INTCInst, SW3_INT_ID, INT_TYPE_RISING_EDGE);
        // Enable SW1~SW3 interrupts in the controller
        XScuGic_Enable(&INTCInst, SW1_INT_ID);
        XScuGic_Enable(&INTCInst, SW2_INT_ID);
        XScuGic_Enable(&INTCInst, SW3_INT_ID);
        return XST_SUCCESS;
    }
    /**************************************************************
    crc_high_first
    指令描述:crc校验 x^8+x^2+x^1+1
    类型:
    延时:
    输入:
    ***************************************************************/
    u8 crc_high_first(u8  *ptr, u16 len)
    {
        u16 i;
        u8 crc=0x00; //计算的初始crc值
        while(len--)
        {
            crc ^= *ptr++;  //每次先与需要计算的数据异或,计算完指向下一数据
            for (i=8; i>0; --i)   //下面这段计算过程与计算一个字节crc一样
            {
                if (crc & 0x80)
                    crc = (crc << 1) ^ 0x07;
                else
                    crc = (crc << 1);
            }
        }
        return (crc);
    }
    #define ENCODE 0xAA
    void Auto_addr(u8 chip_num){
      u8 send_data[4];
      send_data[0]=0x01;
      send_data[1]=0x00;
      send_data[2]=chip_num;
      send_data[3]=crc_high_first(send_data,3);
      u32 send4byte[2];
      send4byte[0]=(
          ((0xaa&0x000000FF)<<24)|
          (((send_data[0]^ENCODE)&0x000000FF)<<16)|
          (((send_data[1]^ENCODE)&0x000000FF)<<8)|
          (((send_data[2]^ENCODE)&0x000000FF)<<0));
      send4byte[1]=(
          (((send_data[3]^ENCODE)&0x000000FF)<<24)|0xFFFFFF);
      Xil_Out32(BASE_ADDR,send4byte[0]);
      Xil_Out32(BASE_ADDR,send4byte[1]);
      Xil_Out32(BASE_ADDR+4,0x0);//发送长度
      Xil_Out32(BASE_ADDR+4,0x10005);//发送长度
      int c=0;
        while(1){
           u32 rdata=Xil_In32(BASE_ADDR+0x24);
           if(rdata&0x40==0x40)
            break;
           else
            c=c+1;
           if(c>10000)
            break;
           }
      //Xil_Out32(BASE_ADDR+4,0x0);//发送长度
    }

    void Write_reg(int chip_addr,int reg_addr,u32 wdata){
     u8 send_data[8];
     send_data[0]=0x05;
     send_data[1]=chip_addr&0xFF;
     send_data[2]=reg_addr&0xFF;
     send_data[3]=((wdata&0xFF000000)>>24);
     send_data[4]=((wdata&0xFF0000)>>16);
     send_data[5]=((wdata&0xFF00)>>8);
     send_data[6]=((wdata&0xFF));
     //send_data[7]=0xFF;
     send_data[7]=crc_high_first(send_data,7);
      u32 send4byte[3];
      send4byte[0]=(
          ((0xaa&0x000000FF)<<24)|
          (((send_data[0]^ENCODE)&0x000000FF)<<16)|
          (((send_data[1]^ENCODE)&0x000000FF)<<8)|
          (((send_data[2]^ENCODE)&0x000000FF)<<0));
      send4byte[1]=(
          (((send_data[3]^ENCODE)&0x000000FF)<<24)|
          (((send_data[4]^ENCODE)&0x000000FF)<<16)|
          (((send_data[5]^ENCODE)&0x000000FF)<<8)|
          (((send_data[6]^ENCODE)&0x000000FF)<<0));
      send4byte[2]=(
          (((send_data[7]^ENCODE)&0x000000FF)<<24)|0xFFFFFF);
      Xil_Out32(BASE_ADDR,send4byte[0]);
      Xil_Out32(BASE_ADDR,send4byte[1]);
      Xil_Out32(BASE_ADDR,send4byte[2]);
      Xil_Out32(BASE_ADDR+4,0x0);//发送长度
      Xil_Out32(BASE_ADDR+4,0x10009);//发送长度
      int b=0;
      while(1){
         u32 rdata=Xil_In32(BASE_ADDR+0x24);
         if(rdata&0x40==0x40)
          break;
         else
          b=b+1;
         if(b>10)
          break;
         }
    }
    void Get_msg(){
     u32 rdata;
     u32 read_data[4];
     for(int i =0;i<4;i++)
     {
       read_data[i]=0xffffffff;
     }
     rdata=Xil_In32(BASE_ADDR+0x24);
     xil_printf ("status is %8x ",rdata);
     if(rdata&0x80==0x80)
      {
       for(int i =0;i<4;i++)
       {read_data[i]=Xil_In32(BASE_ADDR+0x8);}
       for(int i =0;i<4;i++)
        {xil_printf ("%8x ",read_data[i]^0xaaaaaaaa);}
       printf(" ");
      }
     else if(((~rdata)&0x200)==0x200)
     {
      
      for(int i =0;i<4;i++)
      {read_data[i]=Xil_In32(BASE_ADDR+0x8);}
      for(int i =0;i<4;i++)
       {xil_printf ("%8x ",read_data[i]^0xaaaaaaaa);}
      printf(" ");
      
     }
     else
      printf("did not get message ");
    }

    //READ_REG
    void Read_reg(u8 chip_num,u8 reg_addr){
     u8 send_data[4];
     send_data[0]=0x06;
     send_data[1]=chip_num;
     send_data[2]=reg_addr;
     send_data[3]=crc_high_first(send_data,3);
      u32 send4byte[2];
      send4byte[0]=(
          ((0xaa&0x000000FF)<<24)|
          (((send_data[0]^ENCODE)&0x000000FF)<<16)|
          (((send_data[1]^ENCODE)&0x000000FF)<<8)|
          (((send_data[2]^ENCODE)&0x000000FF)<<0));
      send4byte[1]=(
          (((send_data[3]^ENCODE)&0x000000FF)<<24)|0xFFFFFF);
      Xil_Out32(BASE_ADDR,send4byte[0]);
      Xil_Out32(BASE_ADDR,send4byte[1]);
      Xil_Out32(BASE_ADDR+4,0x0);//发送长度
      Xil_Out32(BASE_ADDR+4,0x10005);//发送长度
      printf("Read reg ");
      int c=0;
        while(1){
           u32 rdata=Xil_In32(BASE_ADDR+0x24);
           if(rdata&0x40==0x40)
            break;
           else
            c=c+1;
           if(c>1000)
            break;
           }
     }
    void Spi_Test(u8 chip_id){
     u8 send_data[5];
     u8 b[4];
     int m;
     send_data[0]=0x09;
     send_data[1]=chip_id;
     send_data[2]=0x00;
     send_data[3]=crc_high_first(send_data,3);
      u32 send4byte[2];
      send4byte[0]=(
          ((0xaa&0x000000FF)<<24)|
          (((send_data[0]^ENCODE)&0x000000FF)<<16)|
          (((send_data[1]^ENCODE)&0x000000FF)<<8)|
          (((send_data[2]^ENCODE)&0x000000FF)<<0));
      send4byte[1]=(
          (((send_data[3]^ENCODE)&0x000000FF)<<24)|0xFFFFFF);
      Xil_Out32(BASE_ADDR,send4byte[0]);
      Xil_Out32(BASE_ADDR,send4byte[1]);
      Xil_Out32(BASE_ADDR+4,0x0);//发送长度
      Xil_Out32(BASE_ADDR+4,0x10005);//发送长度
      int c=0;
        while(1){
           u32 rdata=Xil_In32(BASE_ADDR+0x24);
           if(rdata&0x40==0x40)
            break;
           else
            c=c+1;
           if(c>1000)
            break;
           }
      //Xil_Out32(BASE_ADDR+4,0x0);//发送长度
     }
    void Bist_Start(u8 chip_addr){
     u8 send_data[5];
     u8 b[4];
     int m;
     send_data[0]=0x02;
     send_data[1]=chip_addr;
     send_data[2]=0x00;
     send_data[3]=crc_high_first(send_data,3);
      u32 send4byte[2];
      send4byte[0]=(
          ((0xaa&0x000000FF)<<24)|
          (((send_data[0]^ENCODE)&0x000000FF)<<16)|
          (((send_data[1]^ENCODE)&0x000000FF)<<8)|
          (((send_data[2]^ENCODE)&0x000000FF)<<0));
      send4byte[1]=(
          (((send_data[3]^ENCODE)&0x000000FF)<<24)|0xFFFFFF);
      Xil_Out32(BASE_ADDR,send4byte[0]);
      Xil_Out32(BASE_ADDR,send4byte[1]);
      Xil_Out32(BASE_ADDR+4,0x0);//发送长度
      Xil_Out32(BASE_ADDR+4,0x10005);//发送长度
      int c=0;
        while(1){
           u32 rdata=Xil_In32(BASE_ADDR+0x24);
           if(rdata&0x40==0x40)
            break;
           else
            c=c+1;
           if(c>1000)
            break;
           }
     // Xil_Out32(BASE_ADDR+4,0x0);//发送长度
     }
    #define COUNT 4
    int main()
    {
     u32 rec_data[4],rdata;
     //配置SCI控制寄存器。SCI_TDY 、LSB_first、CPOL、CPHA。
     Xil_Out32(BASE_ADDR+0x14,0x3);
     //配置波特率寄存器。
     Xil_Out32(BASE_ADDR+0x10,80);
     //设置TX-FIFO控制寄存器SPI_TXFIFO_CTRL中的TX_EN比特位,使能TX-FIFO。
     Xil_Out32(BASE_ADDR+0x18,0x1);
     Xil_Out32(BASE_ADDR+0x20,0xc0);
     //rec_data=Xil_In32(BASE_ADDR+0x24);
     Xil_Out32(BASE_ADDR+0x1c,0x0);//接收端使能
     Xil_Out32(BASE_ADDR+0x1c,0x1);//接收端使能
     Xil_Out32(BASE_ADDR+0x0c,0xa0a);//接收端使能
     //将待发送数据通过写SCI_TX_DATA寄存器依次存入TX-FIFO。
     Xil_Out32(BASE_ADDR+4,0x0);//发送长度
     //----------chip config--------------
     Auto_addr(0x01);
     Spi_Test(0x01);
     Spi_Test(0x01);
     Write_reg(0x01,0x01,0x1E002);
     Write_reg(0x01,0x01,0x1E002);
     Read_reg(0x01,0x01);
     Get_msg();
     Write_reg(0x01,0x10,0xFFFFFFFF);
     Write_reg(0x01,0x11,0xFFFFFFFF);
     Bist_Start(0x01);
     Get_msg();
     //3)发送完单次(一条完整的指令)传输的所有数据后,
     //设置SCI_TX_CTL寄存器,通知硬件准备发送已经需要发送的数据长度。
     //1)设置SCI接收数据控制寄存器SCI_RX_CTRL,配置单次接收的数据长度。
     //2)设置RX-FIFO控制寄存器SCI_RXFIFO_CTRL中的RX_EN比特位,启动RX-FIFO。
     //3)当接收到RX_END中断后,通过读取SCI_RX_DAT寄存器依次从RX-FIFO中读取相应长度的数据。
     //rec_data=Xil_In32(BASE_ADDR+0x24);
     //
     //rec_data=Xil_In32(BASE_ADDR+0x8);
    u32 status=0;
    int a=0;
    int b=0;
    Xil_Out32(BASE_ADDR+0x1c,0x0);//接收端使能
    Xil_Out32(BASE_ADDR+0x1c,0x1);//接收端使能
    Xil_Out32(BASE_ADDR+0x0c,0xa0a);//接收端使能
    b=1;
    rdata=Xil_In32(BASE_ADDR+0x04);
    Read_reg(0x01,1);
    for(int m;m<10000;m++)
       { }
    Get_msg();
    Get_msg();
    Read_reg(0x01,1);
    for(int m;m<10000;m++)
       { }
    Get_msg();
     
    Read_reg(0x01,1);
    for(int m;m<10000;m++)
       { }
    Get_msg();
    Get_msg();
    IntcInitFunction(INTC_DEVICE_ID);
     while(1){
      printf("==enter write thread== ");
         Read_reg(0x01,b);
      if(b==1)
       {b=3;}
      else if(b==3)
       {b=1;}
      Get_msg();
      Get_msg();
      Get_msg();
    //  Get_msg();
    //  Get_msg();
    //  Get_msg();
     }
    return 0;
    }
     
     
  • 相关阅读:
    直播报名| Kylin on Parquet 介绍及快速上手
    直播 | Apache Kylin & Apache Hudi Meetup
    1. MySQL体系结构和存储引擎——MySQL体系结构、存储引擎、连接MySQL
    深入理解Java虚拟机(第三版)-13.Java内存模型与线程
    Redis 字典实现
    JVM 判断对象已死亡?
    堆内存常见的分配策略、 经典的垃圾收集器、CMS与G1收集器及二者的比较
    String.intern() 和常量池
    Java 对象的创建过程(五步)、对象的内存布局、对象的访问定位
    Java内存区域(运行时数据区域)详解、JDK1.8与JDK1.7的区别
  • 原文地址:https://www.cnblogs.com/xiz-cheng/p/10115765.html
Copyright © 2020-2023  润新知