diff --git a/example/template/demo/hal_demo/i2c_demo.c b/example/template/demo/hal_demo/i2c_demo.c index 95fb92a5c..5a9ccc461 100644 --- a/example/template/demo/hal_demo/i2c_demo.c +++ b/example/template/demo/hal_demo/i2c_demo.c @@ -203,6 +203,7 @@ static const hal_option_t __cmd_options[] = { static const hal_option_t __irq_options[] = { HAL_DEMO_OPTION(VSF_I2C_IRQ_MASK_MASTER_STARTED, VSF_I2C_IRQ_MASK_MASTER_STARTED), + HAL_DEMO_OPTION(VSF_I2C_IRQ_MASK_MASTER_STOPPED, VSF_I2C_IRQ_MASK_MASTER_STOPPED), HAL_DEMO_OPTION(VSF_I2C_IRQ_MASK_MASTER_STOP_DETECT, VSF_I2C_IRQ_MASK_MASTER_STOP_DETECT), HAL_DEMO_OPTION(VSF_I2C_IRQ_MASK_MASTER_NACK_DETECT, VSF_I2C_IRQ_MASK_MASTER_NACK_DETECT), HAL_DEMO_OPTION(VSF_I2C_IRQ_MASK_MASTER_ARBITRATION_LOST, VSF_I2C_IRQ_MASK_MASTER_ARBITRATION_LOST), diff --git a/source/hal/driver/IPCore/Synopsys/DW_apb_i2c/vsf_dw_apb_i2c.c b/source/hal/driver/IPCore/Synopsys/DW_apb_i2c/vsf_dw_apb_i2c.c index a47c41b2c..07d574c42 100644 --- a/source/hal/driver/IPCore/Synopsys/DW_apb_i2c/vsf_dw_apb_i2c.c +++ b/source/hal/driver/IPCore/Synopsys/DW_apb_i2c/vsf_dw_apb_i2c.c @@ -230,9 +230,14 @@ void vsf_dw_apb_i2c_irqhandler(vsf_dw_apb_i2c_t *dw_apb_i2c_ptr) } } - if (!(mask_notify & __VSF_DW_APB_I2C_ERROR_MASK) && (dw_apb_i2c_ptr->count > 0)) { - __vsf_dw_apb_i2c_continue(dw_apb_i2c_ptr); + if (dw_apb_i2c_ptr->count > 0) { + if (!(mask_notify & __VSF_DW_APB_I2C_ERROR_MASK)) { + __vsf_dw_apb_i2c_continue(dw_apb_i2c_ptr); + } } else { + if (!(mask_notify & __VSF_DW_APB_I2C_ERROR_MASK) && dw_apb_i2c_ptr->need_stop) { + mask_notify |= VSF_I2C_IRQ_MASK_MASTER_STOPPED; + } mask_notify |= VSF_I2C_IRQ_MASK_MASTER_TRANSFER_COMPLETE; } __vsf_dw_apb_i2c_notify(dw_apb_i2c_ptr, mask_notify); diff --git a/source/hal/driver/IPCore/Synopsys/DW_apb_i2c/vsf_dw_apb_i2c.h b/source/hal/driver/IPCore/Synopsys/DW_apb_i2c/vsf_dw_apb_i2c.h index ace9a45ba..e6de6470a 100644 --- a/source/hal/driver/IPCore/Synopsys/DW_apb_i2c/vsf_dw_apb_i2c.h +++ b/source/hal/driver/IPCore/Synopsys/DW_apb_i2c/vsf_dw_apb_i2c.h @@ -91,6 +91,7 @@ typedef enum vsf_i2c_cmd_t { typedef enum vsf_i2c_irq_mask_t { VSF_I2C_IRQ_MASK_MASTER_STARTED = (0x01ul << 16), // virtual, issued in vsf_dw_apb_i2c_master_request if VSF_I2C_CMD_START is set in cmd + VSF_I2C_IRQ_MASK_MASTER_STOPPED = (0x01ul << 17), // virtual, issued in vsf_dw_apb_i2c_irqhandler if VSF_I2C_CMD_STOP is set in cmd VSF_I2C_IRQ_MASK_MASTER_STOP_DETECT = (0x01ul << 9), // INTR.STOP_DET VSF_I2C_IRQ_MASK_MASTER_NACK_DETECT = (0x01ul << 3), // TX_ABRT.ABRT_TXDATA_NOACK VSF_I2C_IRQ_MASK_MASTER_TX_EMPTY = (0x01ul << 4), // INTR.TX_EMPTY @@ -98,7 +99,7 @@ typedef enum vsf_i2c_irq_mask_t { VSF_I2C_IRQ_MASK_MASTER_ARBITRATION_LOST = (0x01ul << 12), // TX_ABRT.ARB_LOST VSF_I2C_IRQ_MASK_MASTER_ERROR = 0, - VSF_I2C_IRQ_MASK_MASTER_TRANSFER_COMPLETE = (0x01ul << 17), // virtual + VSF_I2C_IRQ_MASK_MASTER_TRANSFER_COMPLETE = (0x01ul << 18), // virtual VSF_I2C_IRQ_MASK_MASTER_ADDRESS_NACK = ((0x01ul << 0) | (0x01ul << 1) | (0x01ul << 2)), // TX_ABRT.ABRT_7B_ADDR_NOACK | TX_ABRT.ABRT_10ADDR1_NOACK | TX_ABRT.ABRT_10ADDR2_NOACK diff --git a/source/hal/driver/common/i2c/multiplex_i2c.c b/source/hal/driver/common/i2c/multiplex_i2c.c index d0fd50dd9..3cdb88661 100644 --- a/source/hal/driver/common/i2c/multiplex_i2c.c +++ b/source/hal/driver/common/i2c/multiplex_i2c.c @@ -108,7 +108,7 @@ static void __i2c_isr_handler(void *target_ptr, vsf_i2c_t *i2c_ptr, vsf_i2c_irq_ // // The current request may end without generating a STOP when the NAK is received. // So the next request must have START. - vsf_i2c_irq_mask_t cpl_irq_mask = VSF_I2C_IRQ_MASK_MASTER_STOP_DETECT + vsf_i2c_irq_mask_t cpl_irq_mask = VSF_I2C_IRQ_MASK_MASTER_STOPPED | VSF_I2C_IRQ_MASK_MASTER_NACK_DETECT | VSF_I2C_IRQ_MASK_MASTER_ADDRESS_NACK | VSF_I2C_IRQ_MASK_MASTER_ARBITRATION_LOST diff --git a/source/hal/driver/common/template/vsf_template_i2c.h b/source/hal/driver/common/template/vsf_template_i2c.h index 86ec1b012..c4bbafdfe 100644 --- a/source/hal/driver/common/template/vsf_template_i2c.h +++ b/source/hal/driver/common/template/vsf_template_i2c.h @@ -159,22 +159,23 @@ enum { VSF_I2C_CMD_START_MASK = VSF_I2C_CMD_START | VSF_I2C_CMD_NO_START, VSF_I2C_CMD_STOP_RESTART_COUNT = 3, - VSF_I2C_CMD_STOP_RESTART_MASK = VSF_I2C_CMD_STOP | - VSF_I2C_CMD_RESTART | - VSF_I2C_CMD_NO_STOP_RESTART, + VSF_I2C_CMD_STOP_RESTART_MASK = VSF_I2C_CMD_STOP + | VSF_I2C_CMD_RESTART + | VSF_I2C_CMD_NO_STOP_RESTART, VSF_I2C_CMD_MASK_COUNT = 5, - VSF_I2C_CMD_ALL_BITS_MASK = VSF_I2C_CMD_RW_MASK | - VSF_I2C_CMD_START | - VSF_I2C_CMD_STOP | - VSF_I2C_CMD_RESTART | - VSF_I2C_CMD_BITS_MASK, + VSF_I2C_CMD_ALL_BITS_MASK = VSF_I2C_CMD_RW_MASK + | VSF_I2C_CMD_START + | VSF_I2C_CMD_STOP + | VSF_I2C_CMD_RESTART + | VSF_I2C_CMD_BITS_MASK, }; #if VSF_I2C_CFG_REIMPLEMENT_TYPE_IRQ_MASK == DISABLED typedef enum vsf_i2c_irq_mask_t { VSF_I2C_IRQ_MASK_MASTER_STARTED = (0x1ul << 0), - VSF_I2C_IRQ_MASK_MASTER_STOP_DETECT = (0x1ul << 3), + VSF_I2C_IRQ_MASK_MASTER_STOPPED = (0x1ul << 1), + VSF_I2C_IRQ_MASK_MASTER_STOP_DETECT = (0x1ul << 2), // for multi master VSF_I2C_IRQ_MASK_MASTER_NACK_DETECT = (0x1ul << 4), VSF_I2C_IRQ_MASK_MASTER_ARBITRATION_LOST = (0x1ul << 5), VSF_I2C_IRQ_MASK_MASTER_TX_EMPTY = (0x1ul << 6), @@ -187,14 +188,15 @@ typedef enum vsf_i2c_irq_mask_t { enum { VSF_I2C_IRQ_COUNT = 8, - VSF_I2C_IRQ_ALL_BITS_MASK = VSF_I2C_IRQ_MASK_MASTER_STARTED | - VSF_I2C_IRQ_MASK_MASTER_STOP_DETECT | - VSF_I2C_IRQ_MASK_MASTER_NACK_DETECT | - VSF_I2C_IRQ_MASK_MASTER_ARBITRATION_LOST | - VSF_I2C_IRQ_MASK_MASTER_TX_EMPTY | - VSF_I2C_IRQ_MASK_MASTER_ERROR | - VSF_I2C_IRQ_MASK_MASTER_TRANSFER_COMPLETE | - VSF_I2C_IRQ_MASK_MASTER_ADDRESS_NACK, + VSF_I2C_IRQ_ALL_BITS_MASK = VSF_I2C_IRQ_MASK_MASTER_STARTED + | VSF_I2C_IRQ_MASK_MASTER_STOPPED + | VSF_I2C_IRQ_MASK_MASTER_STOP_DETECT + | VSF_I2C_IRQ_MASK_MASTER_NACK_DETECT + | VSF_I2C_IRQ_MASK_MASTER_ARBITRATION_LOST + | VSF_I2C_IRQ_MASK_MASTER_TX_EMPTY + | VSF_I2C_IRQ_MASK_MASTER_ERROR + | VSF_I2C_IRQ_MASK_MASTER_TRANSFER_COMPLETE + | VSF_I2C_IRQ_MASK_MASTER_ADDRESS_NACK, }; #if VSF_I2C_CFG_REIMPLEMENT_TYPE_STATUS == DISABLED @@ -254,7 +256,7 @@ typedef struct vsf_i2c_t vsf_i2c_t; // do something } - if (irq_mask & I2C_IRQ_MASK_MASTER_STOP) { + if (irq_mask & VSF_I2C_IRQ_MASK_MASTER_STOPPED) { // do something } }