openMSP430_IO interrupt

 Verilog file: omsp_gpio.v

 1 //============================================================================
 2 // 4) INTERRUPT GENERATION
 3 //============================================================================
 4 
 5 // Port 2 interrupt
 6 //------------------
 7 
 8 // Delay input // The p2in_dly stores former value of p2in, it will be used for edge detection
 9 reg    [7:0] p2in_dly;
10 always @ (posedge mclk or posedge puc_rst)
11   if (puc_rst)  p2in_dly <=  8'h00;
12   else          p2in_dly <=  p2in & P2_EN_MSK;    
13 
14 // Edge detection // Now we can detect rising and falling edge easily by combining p2in and p2in_dly
15 wire   [7:0] p2in_re   =   p2in & ~p2in_dly;
16 wire   [7:0] p2in_fe   =  ~p2in &  p2in_dly;
17 
18 // Set interrupt flag // p2ies register decide which edge is interrup signal; p2ifg_set is sent to p2ifg for interrupt flag
19 assign       p2ifg_set = {p2ies[7] ? p2in_fe[7] : p2in_re[7],
20                           p2ies[6] ? p2in_fe[6] : p2in_re[6],
21                           p2ies[5] ? p2in_fe[5] : p2in_re[5],
22                           p2ies[4] ? p2in_fe[4] : p2in_re[4],
23                           p2ies[3] ? p2in_fe[3] : p2in_re[3],
24                           p2ies[2] ? p2in_fe[2] : p2in_re[2],
25                           p2ies[1] ? p2in_fe[1] : p2in_re[1],
26                           p2ies[0] ? p2in_fe[0] : p2in_re[0]} & P2_EN_MSK;
27 
28 // Generate CPU interrupt // Interrupt is generated when interrupt is enabled and p2ifg (interrupt flag) is available 
29 assign       irq_port2 = |(p2ie & p2ifg) & P2_EN[0];

   

  Assume  P2_EN is 1'b1, interrupt is enabled(P2IE=1), interrupt edge is rising(P2IES=0), so the code is as following:

 1 // Delay input
 2 reg    [7:0] p2in_dly;
 3 always @ (posedge mclk or posedge puc_rst)
 4   if (puc_rst)  p2in_dly <=  8'h00;
 5   else          p2in_dly <=  p2in;    
 6 
 7 // Edge detection
 8 wire   [7:0] p2in_re   =   p2in & ~p2in_dly;
 9  
11 // Set interrupt flag
12 assign       p2ifg_set = { p2in_re[7],
13                            p2in_re[6],
14                            p2in_re[5],
15                            p2in_re[4],
16                            p2in_re[3],
17                            p2in_re[2],
18                            p2in_re[1],
19                            p2in_re[0]  };
20 
21 // Generate CPU interrupt
22 assign      irq_port2 = | p2ifg;

  

  P2IFG register is as following:

 1 // P2IFG Register
 2 //----------------
 3 reg  [7:0] p2ifg;
 4 
 5 wire       p2ifg_wr  = P2IFG[0] ? reg_hi_wr[P2IFG] : reg_lo_wr[P2IFG];
 6 wire [7:0] p2ifg_nxt = P2IFG[0] ? per_din[15:8]    : per_din[7:0];
 7 wire [7:0] p2ifg_set;
 8 
 9 always @ (posedge mclk or posedge puc_rst)
10   if (puc_rst)        p2ifg <=  8'h00;
11   else if (p2ifg_wr)  p2ifg <=  (p2ifg_nxt | p2ifg_set) & P2_EN_MSK;
12   else                p2ifg <=  (p2ifg     | p2ifg_set) & P2_EN_MSK;

 

  Assume P2_EN is 1'b1; P2IFG='h2B, so P2IFG[0]=1;  p2ifg_set = 8{1'b1}

 1  1 // P2IFG Register
 2  2 //----------------
 3  3 reg  [7:0] p2ifg;
 4  4 
 5  5 wire       p2ifg_wr  =  reg_hi_wr[43]; // If decoded address is P2IFG, then write it into data
 6  6 wire [7:0] p2ifg_nxt =  per_din[15:8]; // receive high byte data from openMSP
 7  7 wire [7:0] p2ifg_set;
 8  8 
 9  9 always @ (posedge mclk or posedge puc_rst)
10 10   if (puc_rst)        p2ifg <=  8'h00;
11 11   else if (p2ifg_wr)  p2ifg <=  p2ifg_nxt | p2ifg_set; // write into
12 12   else                p2ifg <=  p2ifg     | p2ifg_set; // read out

 

posted on 2015-04-17 19:49  mengdie  阅读(556)  评论(0编辑  收藏  举报