Skip to content

Commit

Permalink
support DATAREADY interrupt processing in hardware
Browse files Browse the repository at this point in the history
Fix issue #36
  • Loading branch information
MasterPlayer committed Jan 2, 2022
2 parents 6b6c997 + 7128e50 commit f5dc8e7
Show file tree
Hide file tree
Showing 9 changed files with 1,768 additions and 32 deletions.
65 changes: 39 additions & 26 deletions src_hw/axi_adxl345.sv
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,10 @@ module axi_adxl345 #(
TX_WRITE_ACT_TAP_STATUS_PTR_ST ,
TX_READ_ACT_TAP_STATUS_ST ,
RX_ACT_TAP_STATUS_ST ,
TX_WRITE_ACT_TAP_DATA_PTR_ST ,
TX_READ_ACT_TAP_DATA_ST ,
RX_ACT_TAP_DATA_ST ,

TX_WRITE_INTR_DATA_PTR_ST ,
TX_READ_INTR_DATA_ST ,
RX_INTR_DATA_ST ,

CHECK_INTR_DEASSERT //

Expand All @@ -215,7 +216,7 @@ module axi_adxl345 #(
logic out_awfull ;

logic [ 7:0] version_major = 8'h01 ; // read only,
logic [ 7:0] version_minor = 8'h09 ; // read only,
logic [ 7:0] version_minor = 8'h0A ; // read only,
logic [ 6:0] i2c_address = DEFAULT_DEVICE_ADDRESS ; // reg[0][14:8]
logic link_on = 1'b0 ;
logic on_work = 1'b0 ; // reg[0][4]
Expand All @@ -241,11 +242,20 @@ module axi_adxl345 #(

logic intr_ack;

logic has_dataready_intr;
logic has_st_intr;
logic has_dt_intr;
logic has_act_intr;
logic has_inact_intr;

always_comb begin : has_dataready_intr_proc
if ((int_source_reg[7] & int_enable_reg[7]))
has_dataready_intr = 1'b1;
else
has_dataready_intr = 1'b0;
end


always_comb begin : has_st_intr_proc
if ((int_source_reg[6] & int_enable_reg[6]))
has_st_intr = 1'b1;
Expand Down Expand Up @@ -395,7 +405,7 @@ module axi_adxl345 #(
register[reg_index][byte_index] <= S_AXIS_TDATA;
end

RX_ACT_TAP_DATA_ST:
RX_INTR_DATA_ST:
if (S_AXIS_TVALID)
if (address[5:2] == reg_index)
for ( byte_index = 0; byte_index <= 3; byte_index = byte_index + 1 ) begin
Expand Down Expand Up @@ -567,11 +577,11 @@ module axi_adxl345 #(
if (~out_awfull)
write_cmd_word_cnt <= write_cmd_word_cnt + 1;

TX_WRITE_ACT_TAP_DATA_PTR_ST:
TX_WRITE_INTR_DATA_PTR_ST:
if (~out_awfull)
write_cmd_word_cnt <= write_cmd_word_cnt + 1;

TX_READ_ACT_TAP_DATA_ST:
TX_READ_INTR_DATA_ST:
if (~out_awfull)
write_cmd_word_cnt <= write_cmd_word_cnt + 1;

Expand Down Expand Up @@ -659,7 +669,10 @@ module axi_adxl345 #(
if (has_st_intr | has_dt_intr | has_act_intr | has_inact_intr)
current_state <= TX_WRITE_ACT_TAP_STATUS_PTR_ST;
else
current_state <= IDLE_ST;
if (has_dataready_intr)
current_state <= TX_WRITE_INTR_DATA_PTR_ST;
else
current_state <= IDLE_ST;

// SINGLE/DOUBLE TAP interrupt processsing states

Expand All @@ -675,19 +688,19 @@ module axi_adxl345 #(

RX_ACT_TAP_STATUS_ST:
if (S_AXIS_TVALID & S_AXIS_TLAST)
current_state <= TX_WRITE_ACT_TAP_DATA_PTR_ST;
current_state <= TX_WRITE_INTR_DATA_PTR_ST;

TX_WRITE_ACT_TAP_DATA_PTR_ST:
TX_WRITE_INTR_DATA_PTR_ST:
if (~out_awfull) begin
if (write_cmd_word_cnt == 2'b01)
current_state <= TX_READ_ACT_TAP_DATA_ST;
current_state <= TX_READ_INTR_DATA_ST;
end

TX_READ_ACT_TAP_DATA_ST:
TX_READ_INTR_DATA_ST:
if (~out_awfull)
current_state <= RX_ACT_TAP_DATA_ST;
current_state <= RX_INTR_DATA_ST;

RX_ACT_TAP_DATA_ST:
RX_INTR_DATA_ST:
if (S_AXIS_TVALID & S_AXIS_TLAST)
current_state <= CHECK_INTR_DEASSERT;

Expand Down Expand Up @@ -727,10 +740,10 @@ module axi_adxl345 #(
TX_WRITE_ACT_TAP_STATUS_PTR_ST:
address <= 8'h2B;

TX_WRITE_ACT_TAP_DATA_PTR_ST:
TX_WRITE_INTR_DATA_PTR_ST:
address <= 8'h32;

RX_ACT_TAP_DATA_ST:
RX_INTR_DATA_ST:
if (S_AXIS_TVALID)
address <= address + 1;

Expand Down Expand Up @@ -852,15 +865,15 @@ module axi_adxl345 #(
TX_READ_ACT_TAP_STATUS_ST:
out_din_data <= 8'h01;

TX_WRITE_ACT_TAP_DATA_PTR_ST:
TX_WRITE_INTR_DATA_PTR_ST:
case (write_cmd_word_cnt)
2'b00 : out_din_data <= 8'h06;
2'b00 : out_din_data <= 8'h01;
2'b01 : out_din_data <= 8'h32;
default : out_din_data <= out_din_data;
endcase // write_cmd_word_cnt

TX_READ_ACT_TAP_DATA_ST:
out_din_data <= 8'h01;
TX_READ_INTR_DATA_ST:
out_din_data <= 8'h06;

default :
out_din_data <= out_din_data;
Expand Down Expand Up @@ -912,13 +925,13 @@ module axi_adxl345 #(
else
out_wren <= 1'b0;

TX_WRITE_ACT_TAP_DATA_PTR_ST:
TX_WRITE_INTR_DATA_PTR_ST:
if (~out_awfull)
out_wren <= 1'b1;
else
out_wren <= 1'b0;

TX_READ_ACT_TAP_DATA_ST:
TX_READ_INTR_DATA_ST:
if (~out_awfull)
out_wren <= 1'b1;
else
Expand Down Expand Up @@ -953,10 +966,10 @@ module axi_adxl345 #(
TX_READ_ACT_TAP_STATUS_ST:
out_din_user <= {DEFAULT_DEVICE_ADDRESS, 1'b1};

TX_WRITE_ACT_TAP_DATA_PTR_ST:
TX_WRITE_INTR_DATA_PTR_ST:
out_din_user <= {DEFAULT_DEVICE_ADDRESS, 1'b0};

TX_READ_ACT_TAP_DATA_ST:
TX_READ_INTR_DATA_ST:
out_din_user <= {DEFAULT_DEVICE_ADDRESS, 1'b1};

default :
Expand Down Expand Up @@ -1009,15 +1022,15 @@ module axi_adxl345 #(
TX_READ_ACT_TAP_STATUS_ST:
out_din_last <= 1'b1;

TX_WRITE_ACT_TAP_DATA_PTR_ST:
TX_WRITE_INTR_DATA_PTR_ST:
case (write_cmd_word_cnt)
2'b01 :
out_din_last <= 1'b1;
default :
out_din_last <= 1'b0;
endcase // write_cmd_word_cnt

TX_READ_ACT_TAP_DATA_ST:
TX_READ_INTR_DATA_ST:
out_din_last <= 1'b1;


Expand Down
113 changes: 113 additions & 0 deletions src_sw/dataready_intr/app.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "axi_adxl.h"
#include <time.h>
#include <xscugic.h>

#include <xparameters.h>


int scugic_initialize(XScuGic *ptr, axi_adxl* adxl_ptr);
void adxl_intr_handler(void *callback);

int main(){

init_platform();

axi_adxl adxl_device;
XScuGic gic;

axi_adxl_init(&adxl_device, 0x40030000, 0x40040000);

scugic_initialize(&gic, &adxl_device);

int status = axi_adxl_enable(&adxl_device, 0x53, 10);
if (status != ADXL_OK){
printf("[MAIN] : enable device return code [%d]\r\n", status);
}

status = axi_adxl_calibration(&adxl_device);
if (status != ADXL_OK){
printf("[MAIN] : calibration device return code [%d]\r\n", status);
}

status = axi_adxl_disable_requesting(&adxl_device);
if (status != ADXL_OK){
xil_printf("[MAIN] : disable requests return code : [%d]\r\n", status);
return 0;
}

axi_adxl_set_int_map(&adxl_device, DATA_READY, 0x00);
// axi_adxl_set_inact_ctl(&adxl_device, DC_COUPLE, MASK_X | MASK_Y);
// axi_adxl_set_thresh_inact(&adxl_device, 0x02);
// axi_adxl_set_time_inact(&adxl_device, 0x01);
axi_adxl_int_enable(&adxl_device, DATA_READY);

volatile int change_mode = 0;
volatile int mode = 0;
while(1){
if (change_mode){

axi_adxl_change_bw(&adxl_device, mode);

change_mode = 0;
}

}
cleanup_platform();
return 0;
}




int scugic_initialize(XScuGic *ptr, axi_adxl* adxl_ptr){

int status = 0;

XScuGic_Config *cfg;

cfg = XScuGic_LookupConfig(XPAR_SCUGIC_0_DEVICE_ID);
if (!cfg){
return XST_FAILURE;
}

status = XScuGic_CfgInitialize(ptr, cfg, cfg->CpuBaseAddress);
if (status != XST_SUCCESS){
return XST_FAILURE;
}

XScuGic_SetPriorityTriggerType(ptr, XPAR_FABRIC_AXI_ADXL345_VHD_0_ADXL_IRQ_INTR, 0x00, 0x3);

status = XScuGic_Connect(ptr, XPAR_FABRIC_AXI_ADXL345_VHD_0_ADXL_IRQ_INTR, (Xil_InterruptHandler)adxl_intr_handler, adxl_ptr);
if (status != XST_SUCCESS){
return XST_FAILURE;
}

XScuGic_Enable(ptr, XPAR_FABRIC_AXI_ADXL345_VHD_0_ADXL_IRQ_INTR);

Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, ptr);
Xil_ExceptionEnable();

return status ;
}

int iter = 0;

void adxl_intr_handler(void *callback){
axi_adxl *ptr = (axi_adxl*)callback;
adxl_cfg_ack(ptr->cfg);

// printf("INTR[%5d]\r\n", iter);
// iter++;
// axi_adxl_debug(ptr);

// g_coord g;
//
// axi_adxl_get_gravity(ptr, &g);
//
// printf("[x] : %3.3f \t[y] : %3.3f \t [z] %3.3f\r\n", g.x, g.y, g.z);
return;
}

Loading

0 comments on commit f5dc8e7

Please sign in to comment.